From 2ff24cfbceacac36c08d629f1367c604a6f90d02 Mon Sep 17 00:00:00 2001 From: Newton <17086936+livenet123@users.noreply.github.com> Date: Thu, 15 Nov 2018 21:11:14 +0200 Subject: [PATCH] apply governance reward at block 196000 --- src/CryptoNoteConfig.h | 31 ++- src/CryptoNoteCore/Core.cpp | 56 +++-- src/CryptoNoteCore/Currency.cpp | 216 +++++++++++++----- src/CryptoNoteCore/Currency.h | 13 ++ .../TransactionValidationErrors.h | 7 +- 5 files changed, 247 insertions(+), 76 deletions(-) diff --git a/src/CryptoNoteConfig.h b/src/CryptoNoteConfig.h index dcb1314..a06e5f0 100644 --- a/src/CryptoNoteConfig.h +++ b/src/CryptoNoteConfig.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace CryptoNote { namespace parameters { @@ -47,6 +48,9 @@ const size_t DIFFICULTY_WINDOW_V2 = 60; const size_t ZAWY_LWMA2_DIFFICULTY_N = DIFFICULTY_WINDOW_V2; const uint64_t DIFFICULTY_BLOCKS_COUNT_V2 = DIFFICULTY_WINDOW_V2 + 1; +const uint16_t GOVERNANCE_PERCENT = 20; // 20 percent of block reward +const uint32_t GOVERNANCE_HEIGHT = 196000; + const unsigned EMISSION_SPEED_FACTOR = 18; static_assert(EMISSION_SPEED_FACTOR <= 8 * sizeof(uint64_t), "Bad EMISSION_SPEED_FACTOR"); @@ -90,7 +94,7 @@ const size_t FUSION_TX_MIN_IN_OUT_COUNT_RATIO = 4; const uint32_t KEY_IMAGE_CHECKING_BLOCK_INDEX = 0; const uint32_t UPGRADE_HEIGHT_V2 = 145000; -const uint32_t UPGRADE_HEIGHT_V3 = 600000; +const uint32_t UPGRADE_HEIGHT_V3 = 4294967294; const unsigned UPGRADE_VOTING_THRESHOLD = 90; // percent const uint32_t UPGRADE_VOTING_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; // blocks const uint32_t UPGRADE_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; // blocks @@ -148,6 +152,13 @@ const char* const SEED_NODES[] = { }; +std::string const GOVERNANCE_WALLET_ADDRESS = "cczJoyYFvf5gBPndTdZHsQSu4MRU4hsg2h7gr4hZXrqpa3YLy1aeMixh2rQtUTQkib6uRUyNaYpya4yHiBm81AKe3JMPeosA7p"; +std::string const GOVERNANCE_VIEW_SECRET_KEY = "ec0dcadca1936177c4cd7b98629cc80d49f4deef2ef046a8f2b047271d229704"; + +std::string const TESTNET_GOVERNANCE_WALLET_ADDRESS = "cczJijPPtCa6K2kQ2LxGpU9kU1oBCgmoaCE6o4naV64p3YsehAeF2MqbPts7FedfLJEPnW49HdDUq9reRy6bmb4u9qmJWXRMtT"; +std::string const TESTNET_GOVERNANCE_VIEW_SECRET_KEY = "7626ee1dcf5492754b8a90c8bb3dcb42f4b71ab0e5d7478b72baa713a1e59706"; + + struct CheckpointData { uint32_t index; const char* blockId; @@ -187,8 +198,22 @@ const std::initializer_list CHECKPOINTS = { {116000, "fd904d5c4c9b7217c9aef8e7a46a450d326676a847024be533fc55524d46ac2c"}, {120000, "7ce836e22e53d2a35816e42a98e1322af30e33620bf7d469b3f0bc0fb0ac98b3"}, {124000, "1a038acc443317a58933d5ececa974486edf4936ef7cf52d27797e023fe6a281"}, - {128000, "7c33bd046eaa95da1ed89faa1f98ab961963755ca77c72a1682d82c5185afbb9"}, - {132000, "b5bc1b8c496bcf4da14a496f2430a2338d39ff9e4ea6a2bd85b00624bd976bf6"} + {128000, "7c33bd046eaa95da1ed89faa1f98ab961963755ca77c72a1682d82c5185afbb9"}, + {132000, "b5bc1b8c496bcf4da14a496f2430a2338d39ff9e4ea6a2bd85b00624bd976bf6"}, + {136000, "e20bf930e52a239c2333339ba92f3ecd7940e79ced5631d035a36792acadeb78"}, + {140000, "6915889a9a52c12b2f43a97a7fbb278678058ec439b7084a2d4de9d13001a7ea"}, + {144000, "933bf4fcc6d195b19948cac600b9f665caea1d280c33c01ee9353e20e1b10bae"}, + {148000, "75e3bfdf46c7bc1287b4de3ea2146c5991c2cffb965778ea9cf2fff2a9bceaf1"}, + {152000, "a78decfcf3fff41b927655b9cfbe640b7c599e37e73b5fa41b0ce2fbe6e6eb59"}, + {156000, "b399bf53df460b3c3aeae7bf830ed95ed21da2dfb8046f69cdec386340206f73"}, + {160000, "56b9a3edf1adb02cceca3307eaa1694fd3d22b54e8b25e5567e28f9791d9a1ca"}, + {164000, "bb1567fdac2b9b05884566cfb7911d604f1c48e782c5eba4e666eaf3e4ab5b8b"}, + {168000, "70655b33c799369557d1a63e614e67896396ab709d85f4cf7473b3e6a6d2f7d8"}, + {172000, "02172bb159f7760b2aae1698a730bfb01525b2e952d96c3e2223966869a41e66"}, + {176000, "141c4ab276c7fc66a6d4fd79c9cf8948b2f9f4b44719b5da2b04b70dcfb1ed8f"}, + {180000, "29589d17e10de9488c44f6a87b7965c32d85f7c250c4e02fb211480dd9b3bff0"}, + {184000, "53fb8da65f4e8b9591382cd81d3034a3e755b878a8f21a3d4c7ee5f05665e2df"} + }; } // CryptoNote diff --git a/src/CryptoNoteCore/Core.cpp b/src/CryptoNoteCore/Core.cpp index 49423f9..ae856c1 100644 --- a/src/CryptoNoteCore/Core.cpp +++ b/src/CryptoNoteCore/Core.cpp @@ -1090,7 +1090,7 @@ bool Core::getBlockTemplate(BlockTemplate& b, const AccountPublicAddress& adr, c b.timestamp = medianTimestamp; } } - + size_t medianSize = calculateCumulativeBlocksizeLimit(height) / 2; assert(!chainsStorage.empty()); @@ -1463,23 +1463,45 @@ std::error_code Core::validateBlock(const CachedBlock& cachedBlock, IBlockchainC } for (const auto& output : block.baseTransaction.outputs) { - if (output.amount == 0) { - return error::TransactionValidationError::OUTPUT_ZERO_AMOUNT; - } + if (output.amount == 0) { + return error::TransactionValidationError::OUTPUT_ZERO_AMOUNT; + } + + if (output.target.type() == typeid(KeyOutput)) { + if (!check_key(boost::get(output.target).key)) { + return error::TransactionValidationError::OUTPUT_INVALID_KEY; + } + } + else { + return error::TransactionValidationError::OUTPUT_UNKNOWN_TYPE; + } + + if (std::numeric_limits::max() - output.amount < minerReward) { + return error::TransactionValidationError::OUTPUTS_AMOUNT_OVERFLOW; + } - if (output.target.type() == typeid(KeyOutput)) { - if (!check_key(boost::get(output.target).key)) { - return error::TransactionValidationError::OUTPUT_INVALID_KEY; - } - } else { - return error::TransactionValidationError::OUTPUT_UNKNOWN_TYPE; - } + minerReward += output.amount; + } - if (std::numeric_limits::max() - output.amount < minerReward) { - return error::TransactionValidationError::OUTPUTS_AMOUNT_OVERFLOW; - } + bool enable_Governace = currency.isGovernanceEnabled(cachedBlock.getBlockIndex()); + if (enable_Governace) { - minerReward += output.amount; + uint64_t governanceReward = currency.getGovernanceReward(minerReward); + if (block.baseTransaction.outputs.back().amount != governanceReward) { + return error::TransactionValidationError::BASE_WRONG_GOVERNANCE_AMOUNT; + } + + AccountKeys governanceKeys; + currency.getGovernanceAddressAndKey(governanceKeys); + + Crypto::PublicKey tx_pub_key = CryptoNote::getTransactionPublicKeyFromExtra(block.baseTransaction.extra); + CryptoNote::KeyOutput governanceOutputTarget = boost::get(block.baseTransaction.outputs.back().target); + + size_t pos = block.baseTransaction.outputs.size(); + if (!CryptoNote::is_out_to_acc(governanceKeys, governanceOutputTarget, tx_pub_key, pos - 1)) + { + return error::TransactionValidationError::BASE_INVALID_GOVERNANCE_KEY; + } } return error::BlockValidationError::VALIDATION_SUCCESS; @@ -1991,7 +2013,7 @@ BlockDetails Core::getBlockDetails(const Crypto::Hash& blockHash) const { uint32_t blockIndex = segment->getBlockIndex(blockHash); BlockTemplate blockTemplate = restoreBlockTemplate(segment, blockIndex); - + BlockDetails blockDetails; blockDetails.majorVersion = blockTemplate.majorVersion; blockDetails.minorVersion = blockTemplate.minorVersion; @@ -2154,7 +2176,7 @@ TransactionDetails Core::getTransactionDetails(const Crypto::Hash& transactionHa } transactionDetails.extra.publicKey = transaction->getTransactionPublicKey(); transaction->getExtraNonce(transactionDetails.extra.nonce); - + transactionDetails.signatures = rawTransaction.signatures; transactionDetails.inputs.reserve(transaction->getInputCount()); diff --git a/src/CryptoNoteCore/Currency.cpp b/src/CryptoNoteCore/Currency.cpp index 7f1b552..d91f21e 100644 --- a/src/CryptoNoteCore/Currency.cpp +++ b/src/CryptoNoteCore/Currency.cpp @@ -81,9 +81,11 @@ bool Currency::init() { } if (isTestnet()) { - m_zawyLWMA2DifficultyBlockIndex = 3; - m_upgradeHeightV2 = 3; - m_upgradeHeightV3 = 600000; //static_cast(-1); + m_upgradeHeightV2 = 3; + m_zawyLWMA2DifficultyBlockIndex = 3; + m_governancePercent = 20; + m_governanceHeight = 10; + m_upgradeHeightV3 = 4294967294; //(static_cast(-1) - 1); m_blocksFileName = "testnet_" + m_blocksFileName; m_blockIndexesFileName = "testnet_" + m_blockIndexesFileName; m_txPoolFileName = "testnet_" + m_txPoolFileName; @@ -157,12 +159,12 @@ size_t Currency::difficultyCutByBlockVersion(uint8_t blockMajorVersion) const { } size_t Currency::difficultyBlocksCountByBlockVersion(uint8_t blockMajorVersion, uint32_t height) const { - + if (height >= m_zawyLWMA2DifficultyBlockIndex) { return CryptoNote::parameters::DIFFICULTY_BLOCKS_COUNT_V2; } - + return difficultyWindowByBlockVersion(blockMajorVersion) + difficultyLagByBlockVersion(blockMajorVersion); } @@ -220,6 +222,52 @@ size_t Currency::maxBlockCumulativeSize(uint64_t height) const { return maxSize; } +bool Currency::isGovernanceEnabled(uint32_t height) const { + return height >= m_governanceHeight; +} + +// governance reward is 20 % of block reward +uint64_t Currency::getGovernanceReward(uint64_t base_reward) const { + + // minimum is 1% to avoid zero amount and maximum is 50% + uint16_t percent = (m_governancePercent < 1) ? 1 : (m_governancePercent > 50) ? 50 : m_governancePercent; + return (uint64_t)(base_reward * (percent * 0.01)); +} + +bool Currency::getGovernanceAddressAndKey(AccountKeys& governanceKeys) const +{ + std::string address; + std::string viewSecretkey; + + if (isTestnet()) + { + address = TESTNET_GOVERNANCE_WALLET_ADDRESS; + viewSecretkey = TESTNET_GOVERNANCE_VIEW_SECRET_KEY; + } + else + { + address = GOVERNANCE_WALLET_ADDRESS; + viewSecretkey = GOVERNANCE_VIEW_SECRET_KEY; + } + + AccountPublicAddress governanceAddress = boost::value_initialized(); + if (!parseAccountAddressString(address, governanceAddress)) { + logger(Logging::ERROR) << "failed to parse governance wallet address"; + return false; + } + + Crypto::SecretKey governanceViewSecretKey; + if (!Common::podFromHex(viewSecretkey, governanceViewSecretKey)) { + logger(Logging::ERROR) << "failed to parse governance view secret key"; + return false; + } + + governanceKeys.address = governanceAddress; + governanceKeys.viewSecretKey = governanceViewSecretKey; + + return true; +} + bool Currency::constructMinerTx(uint8_t blockMajorVersion, uint32_t height, size_t medianSize, uint64_t alreadyGeneratedCoins, size_t currentBlockSize, uint64_t fee, const AccountPublicAddress& minerAddress, Transaction& tx, const BinaryArray& extraNonce/* = BinaryArray()*/, size_t maxOuts/* = 1*/) const { @@ -230,14 +278,16 @@ bool Currency::constructMinerTx(uint8_t blockMajorVersion, uint32_t height, size KeyPair txkey = generateKeyPair(); addTransactionPublicKeyToExtra(tx.extra, txkey.publicKey); if (!extraNonce.empty()) { - if (!addExtraNonceToTransactionExtra(tx.extra, extraNonce)) { - return false; - } + if (!addExtraNonceToTransactionExtra(tx.extra, extraNonce)) { + return false; + } } BaseInput in; in.blockIndex = height; + uint64_t governanceReward = 0; + uint64_t TotalReward = 0; uint64_t blockReward; int64_t emissionChange; if (!getBlockReward(blockMajorVersion, medianSize, currentBlockSize, alreadyGeneratedCoins, fee, blockReward, emissionChange)) { @@ -245,53 +295,103 @@ bool Currency::constructMinerTx(uint8_t blockMajorVersion, uint32_t height, size return false; } + TotalReward = blockReward; + uint64_t summaryAmounts = 0; + + bool enable_Governace = isGovernanceEnabled(height); + if (enable_Governace) { + + governanceReward = getGovernanceReward(blockReward); + + if (alreadyGeneratedCoins != 0) + { + blockReward -= governanceReward; + TotalReward = blockReward + governanceReward; + } + } + std::vector outAmounts; decompose_amount_into_digits(blockReward, m_defaultDustThreshold, - [&outAmounts](uint64_t a_chunk) { outAmounts.push_back(a_chunk); }, - [&outAmounts](uint64_t a_dust) { outAmounts.push_back(a_dust); }); + [&outAmounts](uint64_t a_chunk) { outAmounts.push_back(a_chunk); }, + [&outAmounts](uint64_t a_dust) { outAmounts.push_back(a_dust); }); if (!(1 <= maxOuts)) { logger(ERROR, BRIGHT_RED) << "max_out must be non-zero"; return false; } while (maxOuts < outAmounts.size()) { - outAmounts[outAmounts.size() - 2] += outAmounts.back(); - outAmounts.resize(outAmounts.size() - 1); + outAmounts[outAmounts.size() - 2] += outAmounts.back(); + outAmounts.resize(outAmounts.size() - 1); } - uint64_t summaryAmounts = 0; for (size_t no = 0; no < outAmounts.size(); no++) { - Crypto::KeyDerivation derivation = boost::value_initialized(); - Crypto::PublicKey outEphemeralPubKey = boost::value_initialized(); + Crypto::KeyDerivation derivation = boost::value_initialized(); + Crypto::PublicKey outEphemeralPubKey = boost::value_initialized(); - bool r = Crypto::generate_key_derivation(minerAddress.viewPublicKey, txkey.secretKey, derivation); + bool r = Crypto::generate_key_derivation(minerAddress.viewPublicKey, txkey.secretKey, derivation); - if (!(r)) { - logger(ERROR, BRIGHT_RED) - << "while creating outs: failed to generate_key_derivation(" - << minerAddress.viewPublicKey << ", " << txkey.secretKey << ")"; - return false; - } + if (!(r)) { + logger(ERROR, BRIGHT_RED) + << "while creating outs: failed to generate_key_derivation(" + << minerAddress.viewPublicKey << ", " << txkey.secretKey << ")"; + return false; + } - r = Crypto::derive_public_key(derivation, no, minerAddress.spendPublicKey, outEphemeralPubKey); + r = Crypto::derive_public_key(derivation, no, minerAddress.spendPublicKey, outEphemeralPubKey); - if (!(r)) { - logger(ERROR, BRIGHT_RED) - << "while creating outs: failed to derive_public_key(" - << derivation << ", " << no << ", " - << minerAddress.spendPublicKey << ")"; - return false; - } + if (!(r)) { + logger(ERROR, BRIGHT_RED) + << "while creating outs: failed to derive_public_key(" + << derivation << ", " << no << ", " + << minerAddress.spendPublicKey << ")"; + return false; + } - KeyOutput tk; - tk.key = outEphemeralPubKey; + KeyOutput tk; + tk.key = outEphemeralPubKey; - TransactionOutput out; - summaryAmounts += out.amount = outAmounts[no]; - out.target = tk; - tx.outputs.push_back(out); + TransactionOutput out; + summaryAmounts += out.amount = outAmounts[no]; + out.target = tk; + tx.outputs.push_back(out); } - if (!(summaryAmounts == blockReward)) { - logger(ERROR, BRIGHT_RED) << "Failed to construct miner tx, summaryAmounts = " << summaryAmounts << " not equal blockReward = " << blockReward; - return false; + if (enable_Governace) { + + AccountKeys governanceKeys; + getGovernanceAddressAndKey(governanceKeys); + + Crypto::KeyDerivation derivation = boost::value_initialized(); + Crypto::PublicKey outEphemeralPubKey = boost::value_initialized(); + + bool r = Crypto::generate_key_derivation(governanceKeys.address.viewPublicKey, txkey.secretKey, derivation); + if (!(r)) { + logger(ERROR, BRIGHT_RED) + << "while creating outs: failed to generate_key_derivation(" + << governanceKeys.address.viewPublicKey << ", " << txkey.secretKey << ")"; + return false; + } + size_t pos = tx.outputs.size(); + r = Crypto::derive_public_key(derivation, pos++, governanceKeys.address.spendPublicKey, outEphemeralPubKey); + + if (!(r)) { + logger(ERROR, BRIGHT_RED) + << "while creating outs: failed to derive_public_key(" + << derivation << ", " << 0 << ", " + << governanceKeys.address.spendPublicKey << ")"; + return false; + } + + KeyOutput tk; + tk.key = outEphemeralPubKey; + + TransactionOutput out; + summaryAmounts += out.amount = governanceReward; + out.target = tk; + tx.outputs.push_back(out); + } + + + if (!(summaryAmounts == TotalReward)) { + logger(ERROR, BRIGHT_RED) << "Failed to construct miner tx, summaryAmounts = " << summaryAmounts << " not equal blockReward = " << TotalReward; + return false; } tx.version = CURRENT_TRANSACTION_VERSION; @@ -364,7 +464,7 @@ bool Currency::isAmountApplicableInFusionTransactionInput(uint64_t amount, uint6 auto it = std::lower_bound(PRETTY_AMOUNTS.begin(), PRETTY_AMOUNTS.end(), amount); if (it == PRETTY_AMOUNTS.end() || amount != *it) { return false; - } + } amountPowerOfTen = static_cast(std::distance(PRETTY_AMOUNTS.begin(), it) / 9); return true; @@ -504,8 +604,8 @@ Difficulty Currency::getNextDifficulty(uint8_t version, uint32_t blockIndex, std Difficulty Currency::nextDifficultyV2(uint8_t version, uint32_t blockIndex, std::vector timestamps, std::vector cumulativeDifficulties) const { - -// LWMA-2 difficulty algorithm + +// LWMA-2 difficulty algorithm // Copyright (c) 2017-2018 Zawy, MIT License // https://github.com/zawy12/difficulty-algorithms/issues/3 @@ -514,7 +614,7 @@ std::vector cumulativeDifficulties) const { int64_t FTL = static_cast(m_blockFutureTimeLimitV2); // (3 * DIFFICULTY_TARGET)= 360 sec int64_t LWMA(0), solveTime(0), sum_3_ST(0); Difficulty next_D, prev_D; - + if (timestamps.size() > N + 1) { timestamps.resize(N + 1); cumulativeDifficulties.resize(N + 1); @@ -525,33 +625,33 @@ std::vector cumulativeDifficulties) const { assert(n <= N); if (n <= 1) return 1; - - uint64_t initial_difficulty_guess = 1000; + + uint64_t initial_difficulty_guess = 1000; if (timestamps.size() <= static_cast(N)) { return initial_difficulty_guess; } // Loop through N most recent blocks. - for (int64_t i = 1; i <= N; i++) { + for (int64_t i = 1; i <= N; i++) { solveTime = std::max(-FTL, std::min( static_cast(timestamps[i]) - static_cast(timestamps[i - 1]), 6 * T)); LWMA += solveTime * i; if ( i > N - 3 ) { sum_3_ST += solveTime; } } - - next_D = (static_cast(cumulativeDifficulties[N] - cumulativeDifficulties[0]) * T * (N + 1) * 99) / (100 * 2 * LWMA); + + next_D = (static_cast(cumulativeDifficulties[N] - cumulativeDifficulties[0]) * T * (N + 1) * 99) / (100 * 2 * LWMA); prev_D = cumulativeDifficulties[N] - cumulativeDifficulties[N - 1]; - - // Make sure we don't divide by zero if 50x attacker + + // Make sure we don't divide by zero if 50x attacker next_D = std::max((prev_D * 75)/100, std::min(next_D, (prev_D * 133)/100)); - + if ( sum_3_ST < (8 * T)/10) { next_D = (prev_D * 110)/100; } - - + + return static_cast(next_D); } - + Difficulty Currency::nextDifficultyDefault(uint8_t version, uint32_t blockIndex, std::vector timestamps, std::vector cumulativeDifficulties) const { @@ -727,6 +827,9 @@ m_cryptonoteCoinVersion(currency.m_cryptonoteCoinVersion), m_zawyLWMA2DifficultyBlockIndex(currency.m_zawyLWMA2DifficultyBlockIndex), m_zawyLWMA2DifficultyN(currency.m_zawyLWMA2DifficultyN), +m_governancePercent(currency.m_governancePercent), +m_governanceHeight(currency.m_governanceHeight), + m_testnet(currency.m_testnet), genesisBlockTemplate(std::move(currency.genesisBlockTemplate)), cachedGenesisBlock(new CachedBlock(genesisBlockTemplate)), @@ -744,7 +847,7 @@ CurrencyBuilder::CurrencyBuilder(Logging::ILogger& log) : m_currency(log) { timestampCheckWindow(parameters::BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW); timestampCheckWindowV2(parameters::BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2); - blockFutureTimeLimit(parameters::CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT); + blockFutureTimeLimit(parameters::CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT); blockFutureTimeLimitV2(parameters::CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2); moneySupply(parameters::MONEY_SUPPLY); @@ -754,6 +857,9 @@ CurrencyBuilder::CurrencyBuilder(Logging::ILogger& log) : m_currency(log) { zawyLWMA2DifficultyBlockIndex(parameters::ZAWY_LWMA2_DIFFICULTY_BLOCK_INDEX); zawyLWMA2DifficultyN(parameters::ZAWY_LWMA2_DIFFICULTY_N); + governancePercent(parameters::GOVERNANCE_PERCENT); + governanceHeight(parameters::GOVERNANCE_HEIGHT); + rewardBlocksWindow(parameters::CRYPTONOTE_REWARD_BLOCKS_WINDOW); blockGrantedFullRewardZone(parameters::CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE); minerTxBlobReservedSize(parameters::CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE); diff --git a/src/CryptoNoteCore/Currency.h b/src/CryptoNoteCore/Currency.h index 272ef4b..aceb30e 100644 --- a/src/CryptoNoteCore/Currency.h +++ b/src/CryptoNoteCore/Currency.h @@ -78,6 +78,9 @@ class Currency { uint32_t zawyLWMA2DifficultyBlockIndex() const { return m_zawyLWMA2DifficultyBlockIndex; } size_t zawyLWMA2DifficultyN() const { return m_zawyLWMA2DifficultyN; } + uint32_t governancePercent() const { return m_governancePercent; } + uint32_t governanceHeight() const { return m_governanceHeight; } + size_t rewardBlocksWindow() const { return m_rewardBlocksWindow; } size_t blockGrantedFullRewardZone() const { return m_blockGrantedFullRewardZone; } size_t blockGrantedFullRewardZoneByBlockVersion(uint8_t blockMajorVersion) const; @@ -170,6 +173,10 @@ class Currency { static const std::vector PRETTY_AMOUNTS; + bool isGovernanceEnabled(uint32_t height) const; + uint64_t getGovernanceReward(uint64_t base_reward) const; + bool getGovernanceAddressAndKey(AccountKeys& m_account_keys) const; + private: Currency(Logging::ILogger& log) : logger(log, "currency") { } @@ -198,6 +205,9 @@ class Currency { uint32_t m_zawyLWMA2DifficultyBlockIndex; size_t m_zawyLWMA2DifficultyN; + uint32_t m_governancePercent; + uint32_t m_governanceHeight; + size_t m_rewardBlocksWindow; size_t m_blockGrantedFullRewardZone; size_t m_minerTxBlobReservedSize; @@ -283,6 +293,9 @@ class CurrencyBuilder : boost::noncopyable { CurrencyBuilder& zawyLWMA2DifficultyBlockIndex(uint32_t val) { m_currency.m_zawyLWMA2DifficultyBlockIndex = val; return *this; } CurrencyBuilder& zawyLWMA2DifficultyN(size_t val) { m_currency.m_zawyLWMA2DifficultyN = val; return *this; } + CurrencyBuilder& governancePercent(uint32_t val) { m_currency.m_governancePercent = val; return *this; } + CurrencyBuilder& governanceHeight(uint32_t val) { m_currency.m_governanceHeight = val; return *this; } + CurrencyBuilder& rewardBlocksWindow(size_t val) { m_currency.m_rewardBlocksWindow = val; return *this; } CurrencyBuilder& blockGrantedFullRewardZone(size_t val) { m_currency.m_blockGrantedFullRewardZone = val; return *this; } CurrencyBuilder& minerTxBlobReservedSize(size_t val) { m_currency.m_minerTxBlobReservedSize = val; return *this; } diff --git a/src/CryptoNoteCore/TransactionValidationErrors.h b/src/CryptoNoteCore/TransactionValidationErrors.h index 9996157..551c954 100644 --- a/src/CryptoNoteCore/TransactionValidationErrors.h +++ b/src/CryptoNoteCore/TransactionValidationErrors.h @@ -46,7 +46,9 @@ enum class TransactionValidationError { OUTPUT_UNKNOWN_TYPE, OUTPUTS_AMOUNT_OVERFLOW, WRONG_AMOUNT, - WRONG_TRANSACTION_UNLOCK_TIME + WRONG_TRANSACTION_UNLOCK_TIME, + BASE_WRONG_GOVERNANCE_AMOUNT, + BASE_INVALID_GOVERNANCE_KEY }; // custom category: @@ -89,6 +91,9 @@ class TransactionValidationErrorCategory : public std::error_category { case TransactionValidationError::OUTPUTS_AMOUNT_OVERFLOW: return "Transaction has outputs amount overflow"; case TransactionValidationError::WRONG_AMOUNT: return "Transaction wrong amount"; case TransactionValidationError::WRONG_TRANSACTION_UNLOCK_TIME: return "Transaction has wrong unlock time"; + case TransactionValidationError::BASE_WRONG_GOVERNANCE_AMOUNT: return "Base wrong governance amount"; + case TransactionValidationError::BASE_INVALID_GOVERNANCE_KEY: return "Base incorrect governance address"; + default: return "Unknown error"; } }