From 45d7e0acbeffd093719abc58b718aecbd08e4310 Mon Sep 17 00:00:00 2001 From: RealEther Date: Thu, 11 Jul 2024 20:57:11 +0530 Subject: [PATCH] Genesis Blockreward test --- src/CryptoNoteConfig.h | 3 +- src/CryptoNoteCore/Currency.cpp | 173 +++++++++++++++++++++----------- 2 files changed, 119 insertions(+), 57 deletions(-) diff --git a/src/CryptoNoteConfig.h b/src/CryptoNoteConfig.h index 1615253286..04ea2248b5 100644 --- a/src/CryptoNoteConfig.h +++ b/src/CryptoNoteConfig.h @@ -9,7 +9,6 @@ #include namespace CryptoNote { - const std::string DEVELOPER_ADDRESS = "dmzGHGJdKQnfuUoXfUb37nYDNgQDS8NGWhLBo5pf4kDj4MzH9YBhVnW26xpwREXvMraJKzifutKUQBEVxX8gSrbZ3mtMMdsYGx"; namespace parameters { const uint64_t CRYPTONOTE_MAX_BLOCK_NUMBER = 500000000; @@ -55,6 +54,8 @@ const uint64_t CRYPTONOTE_NUMBER_OF_PERIODS_TO_FORGET_TX_DELETED_FROM_POOL = 7; const size_t FUSION_TX_MAX_SIZE = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 30 / 100; const size_t FUSION_TX_MIN_INPUT_COUNT = 12; const size_t FUSION_TX_MIN_IN_OUT_COUNT_RATIO = 4; +const std::string GENESIS_DEVELOPER_ADDRESS = "dmzGHGJdKQnfuUoXfUb37nYDNgQDS8NGWhLBo5pf4kDj4MzH9YBhVnW26xpwREXvMraJKzifutKUQBEVxX8gSrbZ3mtMMdsYGx"; +const uint64_t GENESIS_BLOCK_REWARD = 30000000000 * 1000000000; // 30 million coins in atomic units const char CRYPTONOTE_BLOCKS_FILENAME[] = "blocks.dat"; const char CRYPTONOTE_BLOCKINDEXES_FILENAME[] = "blockindexes.dat"; diff --git a/src/CryptoNoteCore/Currency.cpp b/src/CryptoNoteCore/Currency.cpp index c3f92ee767..0cf24e52ed 100755 --- a/src/CryptoNoteCore/Currency.cpp +++ b/src/CryptoNoteCore/Currency.cpp @@ -72,19 +72,15 @@ bool Currency::init() { bool Currency::generateGenesisBlock() { m_genesisBlock = boost::value_initialized(); - // Hard code coinbase tx in genesis block, because "tru" generating tx use random, but genesis should be always the same - std::string genesisCoinbaseTxHex = GENESIS_COINBASE_TX_HEX; - BinaryArray minerTxBlob; - - bool r = - fromHex(genesisCoinbaseTxHex, minerTxBlob) && - fromBinaryArray(m_genesisBlock.baseTransaction, minerTxBlob); - - if (!r) { - logger(ERROR, BRIGHT_RED) << "failed to parse coinbase tx from hard coded blob"; + Transaction genesisTransaction; + if (!constructGenesisTransaction(genesisTransaction)) { + logger(ERROR, BRIGHT_RED) << "Failed to construct genesis transaction"; return false; } + BinaryArray minerTxBlob = toBinaryArray(genesisTransaction); + m_genesisBlock.baseTransaction = genesisTransaction; + m_genesisBlock.majorVersion = BLOCK_MAJOR_VERSION_1; m_genesisBlock.minorVersion = BLOCK_MINOR_VERSION_0; m_genesisBlock.timestamp = 0; @@ -97,6 +93,57 @@ bool Currency::generateGenesisBlock() { return true; } +bool Currency::constructGenesisTransaction(Transaction& tx) const { + tx.inputs.clear(); + tx.outputs.clear(); + tx.extra.clear(); + + KeyPair txkey = generateKeyPair(); + addTransactionPublicKeyToExtra(tx.extra, txkey.publicKey); + + BaseInput in; + in.blockIndex = 0; + tx.inputs.push_back(in); + + // Parse the developer address + AccountPublicAddress devAddress; + bool parseSuccess = parseAccountAddressString(parameters::GENESIS_DEVELOPER_ADDRESS, devAddress); + if (!parseSuccess) { + logger(ERROR, BRIGHT_RED) << "Failed to parse developer address"; + return false; + } + + // Generate key derivation + Crypto::KeyDerivation derivation; + bool keyDerivationSuccess = Crypto::generate_key_derivation(devAddress.viewPublicKey, txkey.secretKey, derivation); + if (!keyDerivationSuccess) { + logger(ERROR, BRIGHT_RED) << "Failed to generate key derivation for developer address"; + return false; + } + + // Derive the public key + Crypto::PublicKey outEphemeralPubKey; + bool derivePubKeySuccess = Crypto::derive_public_key(derivation, 0, devAddress.spendPublicKey, outEphemeralPubKey); + if (!derivePubKeySuccess) { + logger(ERROR, BRIGHT_RED) << "Failed to derive public key for developer address"; + return false; + } + + // Create the transaction output + KeyOutput tk; + tk.key = outEphemeralPubKey; + + TransactionOutput out; + out.amount = parameters::GENESIS_BLOCK_REWARD; + out.target = tk; + tx.outputs.push_back(out); + + tx.version = CURRENT_TRANSACTION_VERSION; + tx.unlockTime = 0; + + return true; +} + bool Currency::getBlockReward(size_t medianSize, size_t currentBlockSize, uint64_t alreadyGeneratedCoins, uint64_t fee, uint64_t& reward, int64_t& emissionChange) const { assert(alreadyGeneratedCoins <= m_moneySupply); @@ -152,13 +199,11 @@ bool Currency::constructMinerTx(uint32_t height, size_t medianSize, uint64_t alr return false; } - // Calculate dev fee (10% of base reward + fee) - uint64_t devFee = static_cast(blockReward * 0.10) + fee; - uint64_t minerReward = blockReward - devFee; // Subtracting the dev fee from the block reward + uint64_t minerReward = blockReward + fee; // Adding the fee to the block reward - logger(INFO) << "Block reward: " << blockReward << ", Dev fee: " << devFee << ", Miner reward: " << minerReward << ", Fee: " << fee; + logger(INFO) << "Block reward: " << blockReward << ", Miner reward: " << minerReward << ", Fee: " << fee; - // Decompose amounts for miner and dev fee + // Decompose amounts for miner std::vector outAmounts; decompose_amount_into_digits(minerReward, m_defaultDustThreshold, [&outAmounts](uint64_t a_chunk) { outAmounts.push_back(a_chunk); }, @@ -204,44 +249,9 @@ bool Currency::constructMinerTx(uint32_t height, size_t medianSize, uint64_t alr tx.outputs.push_back(out); } - // Add developer fee output - AccountPublicAddress devAddress; - bool parseSuccess = parseAccountAddressString(DEVELOPER_ADDRESS, devAddress); - logger(INFO) << "Parse developer address: " << (parseSuccess ? "success" : "failure"); - if (!parseSuccess) { - logger(ERROR, BRIGHT_RED) << "Failed to parse developer address"; - return false; - } - - Crypto::KeyDerivation devDerivation; - bool keyDerivationSuccess = Crypto::generate_key_derivation(devAddress.viewPublicKey, txkey.secretKey, devDerivation); - logger(INFO) << "Key derivation for developer address: " << (keyDerivationSuccess ? "success" : "failure"); - if (!keyDerivationSuccess) { - logger(ERROR, BRIGHT_RED) << "Failed to generate key derivation for developer address"; - return false; - } - - Crypto::PublicKey devOutEphemeralPubKey; - bool derivePubKeySuccess = Crypto::derive_public_key(devDerivation, 0, devAddress.spendPublicKey, devOutEphemeralPubKey); - logger(INFO) << "Public key derivation for developer address: " << (derivePubKeySuccess ? "success" : "failure"); - if (!derivePubKeySuccess) { - logger(ERROR, BRIGHT_RED) << "Failed to derive public key for developer address"; - return false; - } - - KeyOutput devTk; - devTk.key = devOutEphemeralPubKey; - - TransactionOutput devOut; - devOut.amount = devFee; - devOut.target = devTk; - tx.outputs.push_back(devOut); - - summaryAmounts += devFee; - - // Ensure summary amounts match block reward - if (summaryAmounts != blockReward) { - logger(ERROR, BRIGHT_RED) << "Failed to construct miner tx, summaryAmounts = " << summaryAmounts << " not equal blockReward = " << blockReward; + // Ensure summary amounts match block reward + fee + if (summaryAmounts != minerReward) { + logger(ERROR, BRIGHT_RED) << "Failed to construct miner tx, summaryAmounts = " << summaryAmounts << " not equal minerReward = " << minerReward; return false; } @@ -535,12 +545,63 @@ CurrencyBuilder::CurrencyBuilder(Logging::ILogger& log) : m_currency(log) { Transaction CurrencyBuilder::generateGenesisTransaction() { CryptoNote::Transaction tx; - CryptoNote::AccountPublicAddress ac = boost::value_initialized(); - m_currency.constructMinerTx(0, 0, 0, 0, 0, ac, tx); // zero fee in genesis - + if (!m_currency.constructGenesisTransaction(tx)) { + throw std::runtime_error("Failed to construct genesis transaction"); + } return tx; } +CurrencyBuilder::CurrencyBuilder(Logging::ILogger& log) : m_currency(log) { + maxBlockNumber(parameters::CRYPTONOTE_MAX_BLOCK_NUMBER); + maxBlockBlobSize(parameters::CRYPTONOTE_MAX_BLOCK_BLOB_SIZE); + maxTxSize(parameters::CRYPTONOTE_MAX_TX_SIZE); + publicAddressBase58Prefix(parameters::CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX); + minedMoneyUnlockWindow(parameters::CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW); + + timestampCheckWindow(parameters::BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW); + blockFutureTimeLimit(parameters::CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT); + + moneySupply(parameters::MONEY_SUPPLY); + emissionSpeedFactor(parameters::EMISSION_SPEED_FACTOR); + + rewardBlocksWindow(parameters::CRYPTONOTE_REWARD_BLOCKS_WINDOW); + blockGrantedFullRewardZone(parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE); + minerTxBlobReservedSize(parameters::CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE); + + numberOfDecimalPlaces(parameters::CRYPTONOTE_DISPLAY_DECIMAL_POINT); + + mininumFee(parameters::MINIMUM_FEE); + defaultDustThreshold(parameters::DEFAULT_DUST_THRESHOLD); + + difficultyTarget(parameters::DIFFICULTY_TARGET); + difficultyWindow(parameters::DIFFICULTY_WINDOW); + difficultyLag(parameters::DIFFICULTY_LAG); + difficultyCut(parameters::DIFFICULTY_CUT); + + maxBlockSizeInitial(parameters::MAX_BLOCK_SIZE_INITIAL); + maxBlockSizeGrowthSpeedNumerator(parameters::MAX_BLOCK_SIZE_GROWTH_SPEED_NUMERATOR); + maxBlockSizeGrowthSpeedDenominator(parameters::MAX_BLOCK_SIZE_GROWTH_SPEED_DENOMINATOR); + + lockedTxAllowedDeltaSeconds(parameters::CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS); + lockedTxAllowedDeltaBlocks(parameters::CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS); + + mempoolTxLiveTime(parameters::CRYPTONOTE_MEMPOOL_TX_LIVETIME); + mempoolTxFromAltBlockLiveTime(parameters::CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME); + numberOfPeriodsToForgetTxDeletedFromPool(parameters::CRYPTONOTE_NUMBER_OF_PERIODS_TO_FORGET_TX_DELETED_FROM_POOL); + + fusionTxMaxSize(parameters::FUSION_TX_MAX_SIZE); + fusionTxMinInputCount(parameters::FUSION_TX_MIN_INPUT_COUNT); + fusionTxMinInOutCountRatio(parameters::FUSION_TX_MIN_IN_OUT_COUNT_RATIO); + + blocksFileName(parameters::CRYPTONOTE_BLOCKS_FILENAME); + blocksCacheFileName(parameters::CRYPTONOTE_BLOCKSCACHE_FILENAME); + blockIndexesFileName(parameters::CRYPTONOTE_BLOCKINDEXES_FILENAME); + txPoolFileName(parameters::CRYPTONOTE_POOLDATA_FILENAME); + blockchinIndicesFileName(parameters::CRYPTONOTE_BLOCKCHAIN_INDICES_FILENAME); + + testnet(false); +} + CurrencyBuilder& CurrencyBuilder::emissionSpeedFactor(unsigned int val) { if (val <= 0 || val > 8 * sizeof(uint64_t)) { throw std::invalid_argument("val at emissionSpeedFactor()");