forked from lthn/blockchain
Moved genesis-related generated files and logic from currency_core/generated and genesis_generator to a new src/genesis directory. Updated CMakeLists and include paths to reflect the new structure. Adjusted test and db build scripts to use ZLIB::ZLIB and miniupnpc::miniupnpc targets. Added README with instructions for genesis block updates. Removed premine wallet generation logic from config CMakeLists.
153 lines
6.1 KiB
C++
153 lines
6.1 KiB
C++
// Copyright (c) 2014-2018 Zano Project
|
||
// Copyright (c) 2014-2018 The Louisdor Project
|
||
// Copyright (c) 2012-2013 The Boolberry developers
|
||
// Copyright (c) 2017-2025 Lethean (https://lt.hn)
|
||
//
|
||
// Licensed under the European Union Public Licence (EUPL) version 1.2.
|
||
// You may obtain a copy of the licence at:
|
||
//
|
||
// https://joinup.ec.europa.eu/software/page/eupl/licence-eupl
|
||
//
|
||
// The EUPL is a copyleft licence that is compatible with the MIT/X11
|
||
// licence used by the original projects; the MIT terms are therefore
|
||
// considered “grandfathered” under the EUPL for this code.
|
||
//
|
||
// SPDX‑License‑Identifier: EUPL-1.2
|
||
//
|
||
|
||
#include "misc_log_ex.h"
|
||
#include "currency_core/currency_format_utils.h"
|
||
#include "common/command_line.h"
|
||
#include <boost/multiprecision/integer.hpp>
|
||
|
||
namespace po = boost::program_options;
|
||
|
||
bool generate_test_genesis(std::string address, std::string proof, std::string out_dir)
|
||
{
|
||
using namespace std;
|
||
currency::block bl = boost::value_initialized<currency::block>();
|
||
|
||
#ifndef TESTNET
|
||
constexpr auto posfix = "";
|
||
#else
|
||
constexpr auto posfix = "_tn";
|
||
#endif
|
||
|
||
vector<currency::tx_destination_entry> destinations;
|
||
currency::tx_destination_entry de = AUTO_VAL_INIT(de);
|
||
de.addr.resize(1);
|
||
|
||
bool r = get_account_address_from_str(de.addr.back(), address);
|
||
CHECK_AND_ASSERT_MES(r, false, "wrong address string: " << address);
|
||
|
||
de.amount = PREMINE_AMOUNT;
|
||
destinations.push_back(de);
|
||
|
||
//make sure it initialized with zeros
|
||
uint64_t summary_premine_coins = de.amount;
|
||
|
||
const currency::account_public_address dummy_address = AUTO_VAL_INIT(dummy_address);
|
||
uint64_t block_reward_without_fee = 0;
|
||
uint64_t block_reward = 0;
|
||
construct_miner_tx(0, 0, 0, 0, 0,
|
||
dummy_address, dummy_address, bl.miner_tx, block_reward_without_fee, block_reward,
|
||
TRANSACTION_VERSION_PRE_HF4, 0, proof, CURRENCY_MINER_TX_MAX_OUTS, false, currency::pos_entry(),
|
||
nullptr, nullptr, destinations);
|
||
|
||
currency::blobdata txb = tx_to_blob(bl.miner_tx);
|
||
|
||
//self validate block
|
||
if (currency::get_outs_money_amount(bl.miner_tx) != summary_premine_coins )
|
||
{
|
||
LOG_ERROR("Internal error: total_this = " << summary_premine_coins << " didn't match with miner_tx total = " << currency::get_outs_money_amount(bl.miner_tx));
|
||
}
|
||
|
||
string hex_tx_represent = epee::string_tools::buff_to_hex_nodelimer(txb);
|
||
|
||
auto ret = epee::file_io_utils::save_string_to_file(out_dir + ".genesis.txt", hex_tx_represent);
|
||
CHECK_AND_ASSERT_MES_NO_RET(ret, "failed to create " << out_dir << ".genesis.txt");
|
||
|
||
uint64_t* parray = (uint64_t*)txb.data();
|
||
size_t count = txb.size() / sizeof(uint64_t);
|
||
size_t rest_bytes = txb.size() - count * sizeof(uint64_t);
|
||
|
||
basic_stringstream<char> genesis_h_stream;
|
||
basic_stringstream<char> genesis_cpp_stream;
|
||
genesis_h_stream << "struct genesis_tx_raw_data" << ENDL
|
||
<< "{" << ENDL
|
||
<< " uint64_t const v[" << count << "];" << ENDL
|
||
<< " uint8_t const r[" << rest_bytes << "];" << ENDL
|
||
<< "};" << ENDL;
|
||
|
||
genesis_cpp_stream << "const genesis_tx_raw_data ggenesis_tx_raw = {{" << ENDL;
|
||
|
||
for (size_t i = 0; i != count; i++)
|
||
{
|
||
genesis_cpp_stream << (i == 0 ? "0x":",0x")<< hex << setw(16) << setfill('0') << parray[i];
|
||
}
|
||
genesis_cpp_stream << "}," << ENDL << "{";
|
||
uint8_t* ptail_array = (uint8_t*)&parray[count];
|
||
for (size_t i = 0; i != rest_bytes; i++)
|
||
{
|
||
genesis_cpp_stream << (i == 0 ? "0x":",0x") << hex << setw(2) << setfill('0') << +ptail_array[i];
|
||
}
|
||
genesis_cpp_stream << "}};" << ENDL;
|
||
|
||
// Generate _genesis.cpp.gen
|
||
// Generate _genesis.h.gen
|
||
ret = epee::file_io_utils::save_string_to_file(out_dir + "_genesis" + posfix + ".h.gen", genesis_h_stream.str());
|
||
CHECK_AND_ASSERT_MES_NO_RET(ret, "failed to create " << out_dir << "_genesis.h.gen");
|
||
|
||
ret = epee::file_io_utils::save_string_to_file(out_dir + "_genesis" + posfix + ".cpp.gen", genesis_cpp_stream.str());
|
||
CHECK_AND_ASSERT_MES_NO_RET(ret, "failed to create " << out_dir << "_genesis.cpp.gen");
|
||
|
||
// Single address for now
|
||
uint64_t key = currency::get_string_uint64_hash(address);
|
||
|
||
// Generate _genesis_acc.cpp.gen
|
||
basic_stringstream<char> genesis_acc_stream;
|
||
genesis_acc_stream << "const std::string ggenesis_tx_pub_key_str = \"" <<
|
||
epee::string_tools::pod_to_hex(get_tx_pub_key_from_extra(bl.miner_tx)) << "\";" << ENDL;
|
||
genesis_acc_stream << "const crypto::public_key ggenesis_tx_pub_key = epee::string_tools::parse_tpod_from_hex_string<crypto::public_key>(ggenesis_tx_pub_key_str);" << ENDL
|
||
<< "extern const genesis_tx_dictionary_entry ggenesis_dict[" << 1 << "];" << ENDL
|
||
<< "const genesis_tx_dictionary_entry ggenesis_dict[" << 1 << "] = {";
|
||
genesis_acc_stream << "" << ENDL << "{" << key << "ULL," << 0 << "}";
|
||
genesis_acc_stream << ENDL << "};" << ENDL;
|
||
|
||
ret = epee::file_io_utils::save_string_to_file(out_dir + "_genesis_acc" + posfix + ".cpp.gen", genesis_acc_stream.str());
|
||
CHECK_AND_ASSERT_MES_NO_RET(ret, "failed to create " << out_dir << ".genesis.dictionary.txt");
|
||
return ret;
|
||
}
|
||
|
||
|
||
const command_line::arg_descriptor<std::string> arg_target_address("address", "Premine wallet address");
|
||
const command_line::arg_descriptor<std::string> arg_proof("proof", "Genesis proof string");
|
||
const command_line::arg_descriptor<std::string> arg_dir("output", "Direcory output for generated files");
|
||
po::options_description desc_cmd("Command line options");
|
||
|
||
int main(int argc, char** argv) {
|
||
command_line::add_arg(desc_cmd, arg_target_address);
|
||
command_line::add_arg(desc_cmd, arg_proof);
|
||
command_line::add_arg(desc_cmd, arg_dir);
|
||
|
||
epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
|
||
po::variables_map vm;
|
||
bool r = command_line::handle_error_helper(desc_cmd, [&]()
|
||
{
|
||
po::store(po::parse_command_line(argc, argv, desc_cmd), vm);
|
||
po::notify(vm);
|
||
return true;
|
||
});
|
||
if (!r) {
|
||
LOG_ERROR("Param parsing failed!");
|
||
return 1;
|
||
}
|
||
|
||
std::string premine_address = command_line::get_arg(vm, arg_target_address);
|
||
std::string proof = command_line::get_arg(vm, arg_proof);
|
||
std::string dir = command_line::get_arg(vm, arg_dir);
|
||
|
||
LOG_PRINT_L0("addr:" << premine_address << " proof:" << proof << " amount:" << PREMINE_AMOUNT);
|
||
generate_test_genesis(premine_address, proof, dir);
|
||
return 0;
|
||
}
|