diff --git a/src/chainparams.cpp b/src/chainparams.cpp --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -130,9 +130,6 @@ // Nov 15, 2020 12:00:00 UTC protocol upgrade consensus.axionHeight = 661647; - // May 15, 2022 12:00:00 UTC protocol upgrade - consensus.gluonHeight = 739535; - // May 15, 2023 12:00:00 UTC protocol upgrade consensus.wellingtonActivationTime = 1684152000; @@ -282,9 +279,6 @@ // Nov 15, 2020 12:00:00 UTC protocol upgrade consensus.axionHeight = 1421481; - // May 15, 2022 12:00:00 UTC protocol upgrade - consensus.gluonHeight = 1503556; - // May 15, 2023 12:00:00 UTC protocol upgrade consensus.wellingtonActivationTime = 1684152000; @@ -415,9 +409,6 @@ // Nov 15, 2020 12:00:00 UTC protocol upgrade consensus.axionHeight = 0; - // May 15, 2022 12:00:00 UTC protocol upgrade - consensus.gluonHeight = 0; - // May 15, 2023 12:00:00 UTC protocol upgrade consensus.wellingtonActivationTime = 1684152000; diff --git a/src/consensus/activation.h b/src/consensus/activation.h --- a/src/consensus/activation.h +++ b/src/consensus/activation.h @@ -39,10 +39,6 @@ bool IsAxionEnabled(const Consensus::Params ¶ms, const CBlockIndex *pindexPrev); -/** Check if May 15th, 2022 protocol upgrade has activated. */ -bool IsGluonEnabled(const Consensus::Params ¶ms, - const CBlockIndex *pindexPrev); - /** Check if May 15th, 2023 protocol upgrade has activated. */ bool IsWellingtonEnabled(const Consensus::Params ¶ms, int64_t nMedianTimePast); diff --git a/src/consensus/activation.cpp b/src/consensus/activation.cpp --- a/src/consensus/activation.cpp +++ b/src/consensus/activation.cpp @@ -88,19 +88,6 @@ return IsAxionEnabled(params, pindexPrev->nHeight); } -static bool IsGluonEnabled(const Consensus::Params ¶ms, int32_t nHeight) { - return nHeight >= params.gluonHeight; -} - -bool IsGluonEnabled(const Consensus::Params ¶ms, - const CBlockIndex *pindexPrev) { - if (pindexPrev == nullptr) { - return false; - } - - return IsGluonEnabled(params, pindexPrev->nHeight); -} - bool IsWellingtonEnabled(const Consensus::Params ¶ms, int64_t nMedianTimePast) { return nMedianTimePast >= gArgs.GetIntArg("-wellingtonactivationtime", diff --git a/src/consensus/params.h b/src/consensus/params.h --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -56,8 +56,6 @@ int phononHeight; /** Block height at which the axion activation becomes active */ int axionHeight; - /** Block height at which the gluon activation becomes active */ - int gluonHeight; /** Unix time used for MTP activation of 15 May 2023 12:00:00 UTC upgrade */ int wellingtonActivationTime; /** Unix time used for MTP activation of 15 Nov 2023 12:00:00 UTC upgrade */ diff --git a/src/minerfund.h b/src/minerfund.h --- a/src/minerfund.h +++ b/src/minerfund.h @@ -21,14 +21,12 @@ Amount GetMinerFundAmount(const Amount &coinbaseValue); std::unordered_set -GetMinerFundWhitelist(const Consensus::Params ¶ms, - const CBlockIndex *pindexPrev); +GetMinerFundWhitelist(const Consensus::Params ¶ms); /** * Returns false if there is an invalid miner fund. True otherwise. */ bool CheckMinerFund(const Consensus::Params ¶ms, - const CBlockIndex *pindexPrev, const std::vector &coinbaseTxOut, const Amount &blockReward); diff --git a/src/minerfund.cpp b/src/minerfund.cpp --- a/src/minerfund.cpp +++ b/src/minerfund.cpp @@ -27,16 +27,7 @@ return DecodeDestination(dest, *mainNetParams); } -static const CTxDestination & -GetMinerFundDestination(const bool useAxionDestination) { - static const std::string ecashMinerFundAxion = - "ecash:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdg2jj94l5j"; - static const std::string bitcoinCashMinerFundAxion = - "bitcoincash:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgnlxww9j9"; - static CTxDestination destAxion = BuildDestination( - gArgs.GetBoolArg("-ecash", DEFAULT_ECASH) ? ecashMinerFundAxion - : bitcoinCashMinerFundAxion); - +static const CTxDestination &GetMinerFundDestination() { static const std::string ecashMinerFund = "ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07"; static const std::string bitcoinCashMinerFund = @@ -45,28 +36,22 @@ gArgs.GetBoolArg("-ecash", DEFAULT_ECASH) ? ecashMinerFund : bitcoinCashMinerFund); - return useAxionDestination ? destAxion : dest; + return dest; } std::unordered_set -GetMinerFundWhitelist(const Consensus::Params ¶ms, - const CBlockIndex *pindexPrev) { +GetMinerFundWhitelist(const Consensus::Params ¶ms) { if (!gArgs.GetBoolArg("-enableminerfund", params.enableMinerFund)) { return {}; } - if (!IsAxionEnabled(params, pindexPrev)) { - return {}; - } - - return {GetMinerFundDestination(!IsGluonEnabled(params, pindexPrev))}; + return {GetMinerFundDestination()}; } bool CheckMinerFund(const Consensus::Params ¶ms, - const CBlockIndex *pindexPrev, const std::vector &coinbaseTxOut, const Amount &blockReward) { - const auto whitelist = GetMinerFundWhitelist(params, pindexPrev); + const auto whitelist = GetMinerFundWhitelist(params); if (whitelist.empty()) { return true; } diff --git a/src/node/miner.cpp b/src/node/miner.cpp --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -188,7 +188,7 @@ nFees + GetBlockSubsidy(nHeight, consensusParams); coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0; - const auto whitelisted = GetMinerFundWhitelist(consensusParams, pindexPrev); + const auto whitelisted = GetMinerFundWhitelist(consensusParams); if (!whitelisted.empty()) { const Amount fund = GetMinerFundAmount(coinbaseTx.vout[0].nValue); coinbaseTx.vout[0].nValue -= fund; diff --git a/src/policy/block/minerfund.cpp b/src/policy/block/minerfund.cpp --- a/src/policy/block/minerfund.cpp +++ b/src/policy/block/minerfund.cpp @@ -16,8 +16,8 @@ } assert(m_block.vtx.size()); - if (!CheckMinerFund(m_consensusParams, m_blockIndex.pprev, - m_block.vtx[0]->vout, m_blockReward)) { + if (!CheckMinerFund(m_consensusParams, m_block.vtx[0]->vout, + m_blockReward)) { return state.Invalid(BlockPolicyValidationResult::POLICY_VIOLATION, "policy-bad-miner-fund", strprintf("Block %s violates miner fund policy", diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -1043,7 +1043,7 @@ const Consensus::Params &consensusParams = chainparams.GetConsensus(); for (const auto &fundDestination : - GetMinerFundWhitelist(consensusParams, pindexPrev)) { + GetMinerFundWhitelist(consensusParams)) { minerFundList.push_back( EncodeDestination(fundDestination, config)); } diff --git a/src/test/activation_tests.cpp b/src/test/activation_tests.cpp --- a/src/test/activation_tests.cpp +++ b/src/test/activation_tests.cpp @@ -45,7 +45,6 @@ testPastActivation(IsGravitonEnabled, consensus, consensus.gravitonHeight); testPastActivation(IsPhononEnabled, consensus, consensus.phononHeight); testPastActivation(IsAxionEnabled, consensus, consensus.axionHeight); - testPastActivation(IsGluonEnabled, consensus, consensus.gluonHeight); } BOOST_AUTO_TEST_CASE(iswellingtonenabled) { diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -700,6 +700,9 @@ // NOTE: These tests rely on CreateNewBlock doing its own self-validation! BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) { + // FIXME Update the below blocks to create a valid miner fund coinbase. + // This requires to update the blockinfo nonces. + gArgs.ForceSetArg("-enableminerfund", "0"); // Note that by default, these tests run with size accounting enabled. GlobalConfig config; const CChainParams &chainparams = config.GetChainParams(); @@ -774,6 +777,8 @@ TestPrioritisedMining(chainparams, scriptPubKey, txFirst); fCheckpointsEnabled = true; + + gArgs.ClearForcedArg("-enableminerfund"); } static void CheckBlockMaxSize(const Config &config, const CTxMemPool &mempool, diff --git a/src/test/minerfund_tests.cpp b/src/test/minerfund_tests.cpp --- a/src/test/minerfund_tests.cpp +++ b/src/test/minerfund_tests.cpp @@ -21,7 +21,7 @@ const CBlockIndex *pindexPrev, const std::unordered_set &expectedWhitelist) { - auto whitelist = GetMinerFundWhitelist(consensusParams, pindexPrev); + auto whitelist = GetMinerFundWhitelist(consensusParams); BOOST_CHECK_EQUAL(whitelist.size(), expectedWhitelist.size()); for (const auto &expectedDest : expectedWhitelist) { BOOST_CHECK_EQUAL(whitelist.count(expectedDest), 1); @@ -42,26 +42,9 @@ "-wellingtonactivationtime", consensusParams.wellingtonActivationTime); SetMTP(blocks, activation - 100000); - // Consensus whitelist has not activated yet - block.nHeight = consensusParams.axionHeight - 1; - CheckWhitelist(consensusParams, &block, {}); - - // Axion whitelist is active - const std::unordered_set - expectedAxion = {DecodeDestination( - "ecash:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdg2jj94l5j", chainparams)}; - block.nHeight = consensusParams.axionHeight; - CheckWhitelist(consensusParams, &block, expectedAxion); - - // Does not change up to Gluon activation - block.nHeight = consensusParams.gluonHeight - 1; - CheckWhitelist(consensusParams, &block, expectedAxion); - - // Miner fund address changed with Gluon const std::unordered_set expectedMinerFund = {DecodeDestination( "ecash:prfhcnyqnl5cgrnmlfmms675w93ld7mvvqd0y8lz07", chainparams)}; - block.nHeight = consensusParams.gluonHeight; CheckWhitelist(consensusParams, &block, expectedMinerFund); // Test address does not change around Wellington activation diff --git a/src/test/policy_block_tests.cpp b/src/test/policy_block_tests.cpp --- a/src/test/policy_block_tests.cpp +++ b/src/test/policy_block_tests.cpp @@ -52,40 +52,20 @@ blockhashes[i] = BlockHash(uint256(i)); blocks[i].phashBlock = &blockhashes[i]; blocks[i].pprev = &blocks[i - 1]; - blocks[i].nHeight = consensusParams.gluonHeight + i; + blocks[i].nHeight = i; + blocks[i].nTime = consensusParams.wellingtonActivationTime - 5 + i; } + CBlockIndex &firstBlockIndexRef = blocks[1]; CBlockIndex &lastBlockIndexRef = blocks.back(); const Amount blockReward = GetBlockSubsidy(lastBlockIndexRef.nHeight, consensusParams); - const Amount minerFund = GetMinerFundAmount(blockReward); - - const auto wellingtonActivation = gArgs.GetIntArg( - "-wellingtonactivationtime", consensusParams.wellingtonActivationTime); - - auto checkEarlyBlocks = [&]() { - // Check genesis block (pprev is nullptr) and early blocks before - // Wellington rules are enforced. We skip the last block index - // because we explicitly test activation cases with it. - BOOST_CHECK(!blocks[0].pprev); - for (size_t i = 0; i < blocks.size() - 2; i++) { - const CBlockIndex &blockIndex = blocks[i]; - BOOST_CHECK( - !IsWellingtonEnabled(consensusParams, blockIndex.pprev)); - CBlock block = BlockWithoutMinerFund(blockReward); - MinerFundPolicy check(consensusParams, blockIndex, block, - blockReward); - - BlockPolicyValidationState state; - BOOST_CHECK(check(state)); - BOOST_CHECK(state.IsValid()); - } - }; - auto checkMinerFundPolicy = [&](CBlock block, bool expected) { + auto checkMinerFundPolicy = [&](CBlock block, const CBlockIndex &blockIndex, + bool expected) { BlockPolicyValidationState state; - BOOST_CHECK_EQUAL(MinerFundPolicy(consensusParams, lastBlockIndexRef, - block, blockReward)(state), + BOOST_CHECK_EQUAL(MinerFundPolicy(consensusParams, blockIndex, block, + blockReward)(state), expected); BOOST_CHECK_EQUAL(state.IsValid(), expected); if (!expected) { @@ -93,42 +73,33 @@ } }; + // Before wellington activation, the block policy is not enforced + BOOST_CHECK( + !IsWellingtonEnabled(consensusParams, firstBlockIndexRef.pprev)); + checkMinerFundPolicy(BlockWithoutMinerFund(blockReward), firstBlockIndexRef, + true); + + // After wellington activation, the block policy is enforced + BOOST_CHECK(IsWellingtonEnabled(consensusParams, lastBlockIndexRef.pprev)); + checkMinerFundPolicy(BlockWithoutMinerFund(blockReward), lastBlockIndexRef, + false); + + const Amount minerFund = GetMinerFundAmount(blockReward); const std::vector minerFundsTooSmall = {1 * SATOSHI, minerFund / 2, minerFund - 1 * SATOSHI}; const std::vector minerFundsSufficient = { minerFund, minerFund + 1 * SATOSHI, blockReward}; - // Miner fund policy always passes prior to Wellington rules enforcement. - // Note that Wellington rules are enforced on the block after activation. - for (auto activation : {wellingtonActivation - 1, wellingtonActivation}) { - SetMTP(blocks, activation); - BOOST_CHECK_EQUAL( - IsWellingtonEnabled(consensusParams, &lastBlockIndexRef), - activation == wellingtonActivation); - checkEarlyBlocks(); - checkMinerFundPolicy(BlockWithoutMinerFund(blockReward), true); - - // Blocks with miner fund of various amounts - for (const Amount &amount : - Cat(minerFundsTooSmall, minerFundsSufficient)) { - checkMinerFundPolicy(BlockWithMinerFund(chainparams, amount), true); - } - } - - // Wellington rules are now enforced. Miner fund checks are now applied. - SetMTP(blocks, wellingtonActivation + 1); - BOOST_CHECK(IsWellingtonEnabled(consensusParams, &lastBlockIndexRef)); - checkEarlyBlocks(); - checkMinerFundPolicy(BlockWithoutMinerFund(blockReward), false); - // Blocks with not enough miner fund for (const Amount &amount : minerFundsTooSmall) { - checkMinerFundPolicy(BlockWithMinerFund(chainparams, amount), false); + checkMinerFundPolicy(BlockWithMinerFund(chainparams, amount), + lastBlockIndexRef, false); } // Blocks with sufficient miner fund for (const Amount &amount : minerFundsSufficient) { - checkMinerFundPolicy(BlockWithMinerFund(chainparams, amount), true); + checkMinerFundPolicy(BlockWithMinerFund(chainparams, amount), + lastBlockIndexRef, true); } } diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2108,13 +2108,6 @@ *blockFees = nFees; } - if (!IsWellingtonEnabled(consensusParams, pindex->pprev) && - !CheckMinerFund(consensusParams, pindex->pprev, block.vtx[0]->vout, - blockReward)) { - return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, - "bad-cb-minerfund"); - } - if (!control.Wait()) { return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "blk-bad-inputs", "parallel script check failed"); diff --git a/test/functional/abc_feature_minerfund.py b/test/functional/abc_feature_minerfund.py --- a/test/functional/abc_feature_minerfund.py +++ b/test/functional/abc_feature_minerfund.py @@ -16,7 +16,6 @@ WELLINGTON_ACTIVATION_TIME = 2100000600 MINER_FUND_RATIO = 8 MINER_FUND_ADDR = "ecregtest:prfhcnyqnl5cgrnmlfmms675w93ld7mvvq9jcw0zsn" -MINER_FUND_ADDR_AXION = "ecregtest:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgz0wv9ltl" class MinerFundTest(BitcoinTestFramework): @@ -66,19 +65,13 @@ # Now we send part of the coinbase to the fund. check_miner_fund_output(MINER_FUND_ADDR) - def check_bad_miner_fund(prev_hash, coinbase=None): - if coinbase is None: - coinbase = create_coinbase(node.getblockcount() + 1) - - block_time = node.getblock(prev_hash)["time"] + 1 - block = create_block(int(prev_hash, 16), coinbase, block_time, version=4) - block.solve() - - assert_equal(node.submitblock(ToHex(block)), "bad-cb-minerfund") - - # A block with no miner fund coinbase should be rejected. + # Before wellington activation, the block policy is not applicable tip = node.getbestblockhash() - check_bad_miner_fund(tip) + coinbase = create_coinbase(node.getblockcount() + 1) + block_time = node.getblock(tip)["time"] + 1 + block = create_block(int(tip, 16), coinbase, block_time, version=4) + block.solve() + node.submitblock(ToHex(block)) def create_cb_pay_to_address(address): _, _, script_hash = decode(address) @@ -104,10 +97,7 @@ return cb - # Build a custom coinbase that spend to the legacy miner fund address - # and check it is rejected. - check_bad_miner_fund(tip, create_cb_pay_to_address(MINER_FUND_ADDR_AXION)) - + tip = node.getbestblockhash() # Build a custom coinbase that spend to the new miner fund address # and check it is accepted. good_block = create_block(