diff --git a/src/chainparams.cpp b/src/chainparams.cpp --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -142,7 +142,7 @@ consensus.phononHeight = 635258; // Nov 15, 2020 12:00:00 UTC protocol upgrade - consensus.axionActivationTime = 1605441600; + consensus.axionHeight = 661647; // May 15, 2022 12:00:00 UTC protocol upgrade consensus.gluonActivationTime = 1652616000; @@ -304,7 +304,7 @@ consensus.phononHeight = 1378460; // Nov 15, 2020 12:00:00 UTC protocol upgrade - consensus.axionActivationTime = 1605441600; + consensus.axionHeight = 1421481; // May 15, 2022 12:00:00 UTC protocol upgrade consensus.gluonActivationTime = 1652616000; @@ -440,7 +440,7 @@ consensus.phononHeight = 0; // Nov 15, 2020 12:00:00 UTC protocol upgrade - consensus.axionActivationTime = 1605441600; + consensus.axionHeight = 0; // May 15, 2022 12:00:00 UTC protocol upgrade consensus.gluonActivationTime = 1652616000; diff --git a/src/consensus/activation.cpp b/src/consensus/activation.cpp --- a/src/consensus/activation.cpp +++ b/src/consensus/activation.cpp @@ -75,14 +75,17 @@ return IsPhononEnabled(params, pindexPrev->nHeight); } +static bool IsAxionEnabled(const Consensus::Params ¶ms, int32_t nHeight) { + return nHeight >= params.axionHeight; +} + bool IsAxionEnabled(const Consensus::Params ¶ms, const CBlockIndex *pindexPrev) { if (pindexPrev == nullptr) { return false; } - return pindexPrev->GetMedianTimePast() >= - gArgs.GetArg("-axionactivationtime", params.axionActivationTime); + return IsAxionEnabled(params, pindexPrev->nHeight); } bool IsGluonEnabled(const Consensus::Params ¶ms, diff --git a/src/consensus/params.h b/src/consensus/params.h --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -80,8 +80,8 @@ int gravitonHeight; /** Block height at which the phonon activation becomes active */ int phononHeight; - /** Unix time used for MTP activation of 15 Nov 2020 12:00:00 UTC upgrade */ - int axionActivationTime; + /** Block height at which the axion activation becomes active */ + int axionHeight; /** Unix time used for MTP activation of 15 May 2022 12:00:00 UTC upgrade */ int gluonActivationTime; /** Unix time used for MTP activation of 15 Nov 2022 12:00:00 UTC upgrade */ diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -425,8 +425,6 @@ "-rootcertificates=", "-splash", "-uiplatform", - // TODO remove after the November 2020 upgrade - "-axionactivationtime", // TODO remove after the May 2022 upgrade "-gluonactivationtime", }; diff --git a/src/pow/test/aserti32d_tests.cpp b/src/pow/test/aserti32d_tests.cpp --- a/src/pow/test/aserti32d_tests.cpp +++ b/src/pow/test/aserti32d_tests.cpp @@ -532,11 +532,14 @@ } } -class ChainParamsWithDAAActivation : public CChainParams { +class ChainParamsWithCustomActivation : public CChainParams { public: - ChainParamsWithDAAActivation(const CChainParams &chainParams, int daaHeight) + ChainParamsWithCustomActivation(const CChainParams &chainParams, + int daaHeight, int axionHeight) : CChainParams(chainParams) { + BOOST_REQUIRE_GT(axionHeight, daaHeight); consensus.daaHeight = daaHeight; + consensus.axionHeight = axionHeight; } }; @@ -549,11 +552,11 @@ // at a lower height than usual, so we don't need to waste time making a // 504000-long chain. const auto mainChainParams = CreateChainParams(CBaseChainParams::MAIN); - const ChainParamsWithDAAActivation chainParams(*mainChainParams, 2016); + const int asertActivationHeight = 4000; + const ChainParamsWithCustomActivation chainParams(*mainChainParams, 2016, + asertActivationHeight); const Consensus::Params ¶ms = chainParams.GetConsensus(); - const int64_t activationTime = - gArgs.GetArg("-axionactivationtime", params.axionActivationTime); CBlockHeader blkHeaderDummy; // an arbitrary compact target for our chain (based on BCH chain ~ Aug 10 @@ -573,32 +576,21 @@ // Pile up a random number of blocks to establish some history of random // height. cw144 DAA requires us to have height at least 2016, dunno why - // that much. - const int initialBlockCount = 2000 + int(InsecureRandRange(1000)); - for (int i = 1; i < initialBlockCount; i++) { - blocks[bidx] = GetBlockIndex(&blocks[bidx - 1], 600, initialBits); - bidx++; + // that much. Keep going up to 145 blocks prior to ASERT activation. + for (int i = 1; i < asertActivationHeight - 145; i++) { BOOST_REQUIRE(bidx < int(blocks.size())); - } - - // Start making blocks prior to activation. First, make a block about 1 day - // before activation. Then put down 145 more blocks with 500 second - // solvetime each, such that the MTP on the final block is 1 second short of - // activationTime. - { blocks[bidx] = GetBlockIndex(&blocks[bidx - 1], 600, initialBits); - blocks[bidx].nTime = activationTime - 140 * 500 - 1; bidx++; } + // Then put down 145 more blocks with 500 second solvetime each, such that + // the final block is the one prior to activation. for (int i = 0; i < 145; i++) { BOOST_REQUIRE(bidx < int(blocks.size())); blocks[bidx] = GetBlockIndex(&blocks[bidx - 1], 500, initialBits); bidx++; } CBlockIndex *pindexPreActivation = &blocks[bidx - 1]; - BOOST_CHECK_EQUAL(pindexPreActivation->nTime, activationTime + 5 * 500 - 1); - BOOST_CHECK_EQUAL(pindexPreActivation->GetMedianTimePast(), - activationTime - 1); + BOOST_CHECK_EQUAL(pindexPreActivation->nHeight, asertActivationHeight - 1); BOOST_CHECK(IsDAAEnabled(params, pindexPreActivation)); // If we consult DAA, then it uses cw144 which returns a significantly lower @@ -693,8 +685,7 @@ // timestamp jump so the resulting target is 1.2% lower. CBlockIndex indexActivation4 = GetBlockIndex(pindexPreActivation, 0, 0x18011111); - indexActivation4.nTime = activationTime; - BOOST_CHECK_EQUAL(indexActivation4.GetMedianTimePast(), activationTime); + indexActivation4.nTime = pindexPreActivation->GetMedianTimePast(); BOOST_CHECK(IsAxionEnabled(params, &indexActivation4)); BOOST_CHECK_EQUAL( GetNextWorkRequired(&indexActivation4, &blkHeaderDummy, chainParams), 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 @@ -47,30 +47,7 @@ testPastActivation(IsGravitonEnabled, consensus, consensus.gravitonHeight); testPastActivation(IsPhononEnabled, consensus, consensus.phononHeight); -} - -BOOST_AUTO_TEST_CASE(isaxionenabled) { - const Consensus::Params ¶ms = Params().GetConsensus(); - const auto activation = - gArgs.GetArg("-axionactivationtime", params.axionActivationTime); - SetMockTime(activation - 1000000); - - BOOST_CHECK(!IsAxionEnabled(params, nullptr)); - - std::array blocks; - for (size_t i = 1; i < blocks.size(); ++i) { - blocks[i].pprev = &blocks[i - 1]; - } - BOOST_CHECK(!IsAxionEnabled(params, &blocks.back())); - - SetMTP(blocks, activation - 1); - BOOST_CHECK(!IsAxionEnabled(params, &blocks.back())); - - SetMTP(blocks, activation); - BOOST_CHECK(IsAxionEnabled(params, &blocks.back())); - - SetMTP(blocks, activation + 1); - BOOST_CHECK(IsAxionEnabled(params, &blocks.back())); + testPastActivation(IsAxionEnabled, consensus, consensus.axionHeight); } BOOST_AUTO_TEST_CASE(isgluonenabled) { 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 @@ -13,7 +13,6 @@ from test_framework.txtools import pad_tx from test_framework.util import assert_equal, assert_greater_than_or_equal -AXION_ACTIVATION_TIME = 2000000600 GLUON_ACTIVATION_TIME = 2100000600 MINER_FUND_RATIO = 8 @@ -28,7 +27,6 @@ self.num_nodes = 1 self.extra_args = [[ '-enableminerfund', - '-axionactivationtime={}'.format(AXION_ACTIVATION_TIME), '-gluonactivationtime={}'.format(GLUON_ACTIVATION_TIME), ]] @@ -44,25 +42,23 @@ address = node.get_deterministic_priv_key().address - # Move MTP forward to axion activation - node.setmocktime(AXION_ACTIVATION_TIME) + def get_best_coinbase(): + return node.getblock(node.getbestblockhash(), 2)['tx'][0] + + coinbase = get_best_coinbase() + assert_greater_than_or_equal(len(coinbase['vout']), 2) + block_reward = sum([vout['value'] for vout in coinbase['vout']]) + + # Move MTP forward to gluon activation + node.setmocktime(GLUON_ACTIVATION_TIME) node.generatetoaddress(6, address) assert_equal( node.getblockchaininfo()['mediantime'], - AXION_ACTIVATION_TIME) + GLUON_ACTIVATION_TIME) # Let's remember the hash of this block for later use. - axion_fork_block_hash = int(node.getbestblockhash(), 16) - - def get_best_coinbase(): - return node.getblock(node.getbestblockhash(), 2)['tx'][0] - - # No money goes to the fund. - coinbase = get_best_coinbase() - assert_equal(len(coinbase['vout']), 1) - block_reward = coinbase['vout'][0]['value'] + gluon_fork_block_hash = int(node.getbestblockhash(), 16) - # Now we send part of the coinbase to the fund. def check_miner_fund_output(expected_address): coinbase = get_best_coinbase() assert_equal(len(coinbase['vout']), 2) @@ -79,12 +75,15 @@ coinbase['vout'][1]['value'], (MINER_FUND_RATIO * total) / 100) - # First block with the new rules. - node.generatetoaddress(1, address) + # The coinbase has an output to the legacy miner fund address + # Now we send part of the coinbase to the fund. check_miner_fund_output(MINER_FUND_ADDR_AXION) - # Invalidate top block, submit a custom block that do not send anything - # to the fund and check it is rejected. + # First block with the miner fund address. + node.generatetoaddress(1, address) + check_miner_fund_output(MINER_FUND_ADDR) + + # Invalidate top block. node.invalidateblock(node.getbestblockhash()) def check_bad_miner_fund(prev_hash, time, coinbase=None): @@ -96,29 +95,6 @@ assert_equal(node.submitblock(ToHex(block)), 'bad-cb-minerfund') - check_bad_miner_fund(axion_fork_block_hash, AXION_ACTIVATION_TIME + 1) - - # Move MTP forward to gluon activation - node.setmocktime(GLUON_ACTIVATION_TIME) - node.generatetoaddress(6, address) - assert_equal( - node.getblockchaininfo()['mediantime'], - GLUON_ACTIVATION_TIME) - - # Let's remember the hash of this block for later use. - gluon_fork_block_hash = int(node.getbestblockhash(), 16) - - # The coinbase has an output to the legacy miner fund address - # Now we send part of the coinbase to the fund. - check_miner_fund_output(MINER_FUND_ADDR_AXION) - - # First block with the miner fund address. - node.generatetoaddress(1, address) - check_miner_fund_output(MINER_FUND_ADDR) - - # Invalidate top block. - node.invalidateblock(node.getbestblockhash()) - # A block with no miner fund coinbase should be rejected. check_bad_miner_fund(gluon_fork_block_hash, GLUON_ACTIVATION_TIME + 1) diff --git a/test/functional/abc_mining_basic.py b/test/functional/abc_mining_basic.py --- a/test/functional/abc_mining_basic.py +++ b/test/functional/abc_mining_basic.py @@ -17,7 +17,6 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, assert_greater_than_or_equal -AXION_ACTIVATION_TIME = 2000000600 GLUON_ACTIVATION_TIME = 2100000600 MINER_FUND_ADDR_AXION = 'ecregtest:pqnqv9lt7e5vjyp0w88zf2af0l92l8rxdgz0wv9ltl' @@ -33,12 +32,10 @@ self.extra_args = [ [ '-enableminerfund', - '-axionactivationtime={}'.format(AXION_ACTIVATION_TIME), '-gluonactivationtime={}'.format(GLUON_ACTIVATION_TIME), ], [ '-enableminerfund', '-usecashaddr=0', - '-axionactivationtime={}'.format(AXION_ACTIVATION_TIME), '-gluonactivationtime={}'.format(GLUON_ACTIVATION_TIME), ], ] * 2 @@ -47,7 +44,8 @@ self.setup_nodes() # Don't connect the nodes - def run_for_node(self, node, activation_time, expectedMinerFundAddress): + def run_for_node(self, node, beforedMinerFundAddress, + afterMinerFundAddress): # Connect to a peer so getblocktemplate will return results # (getblocktemplate has a sanity check that ensures it's connected to a # network). @@ -68,31 +66,30 @@ assert_equal(blockTemplate[key], value) # Move block time to just before axion activation - node.setmocktime(activation_time) + node.setmocktime(GLUON_ACTIVATION_TIME) node.generatetoaddress(5, address) - # Before axion activation, the miner fund list is empty + def get_best_coinbase(): + return node.getblock(node.getbestblockhash(), 2)['tx'][0] + + coinbase = get_best_coinbase() + assert_greater_than_or_equal(len(coinbase['vout']), 2) + block_reward = sum([vout['value'] for vout in coinbase['vout']]) + assert_getblocktemplate({ 'coinbasetxn': { 'minerfund': { - 'addresses': [], - 'minimumvalue': 0, + 'addresses': [beforedMinerFundAddress], + 'minimumvalue': block_reward * 8 // 100 * XEC, }, }, }) - # Move MTP forward to axion activation + # Move MTP forward to activation node.generatetoaddress(1, address) assert_equal( node.getblockchaininfo()['mediantime'], - activation_time) - - def get_best_coinbase(): - return node.getblock(node.getbestblockhash(), 2)['tx'][0] - - coinbase = get_best_coinbase() - assert_equal(len(coinbase['vout']), 1) - block_reward = coinbase['vout'][0]['value'] + GLUON_ACTIVATION_TIME) # We don't need to test all fields in getblocktemplate since many of # them are covered in mining_basic.py @@ -102,7 +99,7 @@ # We expect to start seeing the miner fund addresses since the # next block will start enforcing them. 'minerfund': { - 'addresses': [expectedMinerFundAddress], + 'addresses': [afterMinerFundAddress], 'minimumvalue': block_reward * 8 // 100 * XEC, }, }, @@ -111,7 +108,7 @@ # since we are not crossing a halving boundary and there are no # transactions in the mempool. 'coinbasevalue': block_reward * XEC, - 'mintime': activation_time + 1, + 'mintime': GLUON_ACTIVATION_TIME + 1, }) # First block with the new rules @@ -128,45 +125,37 @@ assert_getblocktemplate({ 'coinbasetxn': { 'minerfund': { - 'addresses': [expectedMinerFundAddress], + 'addresses': [afterMinerFundAddress], 'minimumvalue': block_reward * 8 // 100 * XEC, }, }, # Again, we assume the coinbase value is the same as prior blocks. 'coinbasevalue': block_reward * XEC, - 'mintime': activation_time + 1, + 'mintime': GLUON_ACTIVATION_TIME + 1, }) # Move MTP forward - node.setmocktime(activation_time + 1) + node.setmocktime(GLUON_ACTIVATION_TIME + 1) node.generatetoaddress(6, address) assert_getblocktemplate({ 'coinbasetxn': { 'minerfund': { - 'addresses': [expectedMinerFundAddress], + 'addresses': [afterMinerFundAddress], 'minimumvalue': block_reward * 8 // 100 * XEC, }, }, 'coinbasevalue': block_reward * XEC, - 'mintime': activation_time + 2, + 'mintime': GLUON_ACTIVATION_TIME + 2, }) def run_test(self): self.run_for_node( self.nodes[0], - AXION_ACTIVATION_TIME, - MINER_FUND_ADDR_AXION) - self.run_for_node( - self.nodes[1], - AXION_ACTIVATION_TIME, - MINER_FUND_LEGACY_ADDR_AXION) - self.run_for_node( - self.nodes[2], - GLUON_ACTIVATION_TIME, + MINER_FUND_ADDR_AXION, MINER_FUND_ADDR_GLUON) self.run_for_node( - self.nodes[3], - GLUON_ACTIVATION_TIME, + self.nodes[1], + MINER_FUND_LEGACY_ADDR_AXION, MINER_FUND_LEGACY_ADDR_GLUON) diff --git a/test/lint/check-doc.py b/test/lint/check-doc.py --- a/test/lint/check-doc.py +++ b/test/lint/check-doc.py @@ -53,8 +53,6 @@ '-automaticunparking', # Removed arguments that now just print a helpful error message '-zapwallettxes', - # Remove after November 2020 upgrade - '-axionactivationtime', # Remove after May 2022 upgrade '-gluonactivationtime', '-replayprotectionactivationtime',