diff --git a/doc/release-notes-6189.md b/doc/release-notes-6189.md index b88a030d82..b4b2678516 100644 --- a/doc/release-notes-6189.md +++ b/doc/release-notes-6189.md @@ -2,7 +2,5 @@ Tests ----- - For the `regtest` network the activation heights of several softforks were - changed. (dash#6189) - * BIP 34 (blockheight in coinbase) from 500 to 2 - * BIP 66 (DERSIG) from 1251 to 102 - * BIP 65 (CLTV) from 1351 to 111 + set to block height 1. They can be changed by the runtime setting + `-testactivationheight=name@height`. (dash#6214) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index c67d349e54..a24fc2858a 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -794,12 +794,12 @@ public: consensus.nGovernanceMinQuorum = 1; consensus.nGovernanceFilterElements = 100; consensus.nMasternodeMinimumConfirmations = 1; - consensus.BIP34Height = 2; // BIP34 activated on regtest (Block at height 1 not enforced for testing purposes) + consensus.BIP34Height = 1; // Always active unless overridden consensus.BIP34Hash = uint256(); - consensus.BIP65Height = 111; // BIP65 activated on regtest (Block at height 110 and earlier not enforced for testing purposes) - consensus.BIP66Height = 102; // BIP66 activated on regtest (Block at height 101 and earlier not enforced for testing purposes) - consensus.BIP147Height = 432; // BIP147 activated on regtest (Used in functional tests) - consensus.CSVHeight = 432; // CSV activated on regtest (Used in rpc activation tests) + consensus.BIP65Height = 1; // Always active unless overridden + consensus.BIP66Height = 1; // Always active unless overridden + consensus.BIP147Height = 1; // Always active unless overridden + consensus.CSVHeight = 1; // Always active unless overridden consensus.DIP0001Height = 2000; consensus.DIP0003Height = 432; consensus.DIP0003EnforcementHeight = 500; @@ -1031,8 +1031,39 @@ public: void UpdateLLMQInstantSendDIP0024FromArgs(const ArgsManager& args); }; +static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& consensus) +{ + for (const std::string& arg : args.GetArgs("-testactivationheight")) { + const auto found{arg.find('@')}; + if (found == std::string::npos) { + throw std::runtime_error(strprintf("Invalid format (%s) for -testactivationheight=name@height.", arg)); + } + const auto name{arg.substr(0, found)}; + const auto value{arg.substr(found + 1)}; + int32_t height; + if (!ParseInt32(value, &height) || height < 0 || height >= std::numeric_limits::max()) { + throw std::runtime_error(strprintf("Invalid height value (%s) for -testactivationheight=name@height.", arg)); + } + if (name == "bip147") { + consensus.BIP147Height = int{height}; + } else if (name == "bip34") { + consensus.BIP34Height = int{height}; + } else if (name == "dersig") { + consensus.BIP66Height = int{height}; + } else if (name == "cltv") { + consensus.BIP65Height = int{height}; + } else if (name == "csv") { + consensus.CSVHeight = int{height}; + } else { + throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg)); + } + } +} + void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args) { + MaybeUpdateHeights(args, consensus); + if (!args.IsArgSet("-vbparams")) return; for (const std::string& strDeployment : args.GetArgs("-vbparams")) { diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index d18ba6da8d..7fa30ed220 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -22,6 +22,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman) argsman.AddArg("-dip3params=:", "Override DIP3 activation and enforcement heights (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); argsman.AddArg("-dip8params=", "Override DIP8 activation height (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); argsman.AddArg("-bip147height=", "Override BIP147 activation height (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); + argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (bip147, bip34, dersig, cltv, csv). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-highsubsidyblocks=", "The number of blocks with a higher than normal subsidy to mine at the start of a chain. Block after that height will have fixed subsidy base. (default: 0, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); argsman.AddArg("-highsubsidyfactor=", "The factor to multiply the normal block subsidy by while in the highsubsidyblocks window of a chain (default: 1, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); argsman.AddArg("-llmqchainlocks=", "Override the default LLMQ type used for ChainLocks. Allows using ChainLocks with smaller LLMQs. (default: llmq_devnet, devnet-only)", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp index b6ad88af57..f8db20c73e 100644 --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -12,11 +12,16 @@ #include +struct Dersig100Setup : public TestChain100Setup { + Dersig100Setup() + : TestChain100Setup{{"-testactivationheight=dersig@102"}} {} +}; + bool CheckInputScripts(const CTransaction& tx, TxValidationState &state, const CCoinsViewCache &inputs, unsigned int flags, bool cacheSigStore, bool cacheFullScriptStore, PrecomputedTransactionData& txdata, std::vector *pvChecks); BOOST_AUTO_TEST_SUITE(txvalidationcache_tests) -BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup) +BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, Dersig100Setup) { // Make sure skipping validation of transactions that were // validated going into the memory pool does not allow @@ -144,7 +149,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail } } -BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup) +BOOST_FIXTURE_TEST_CASE(checkinputs_test, Dersig100Setup) { // Test that passing CheckInputScripts with one set of script flags doesn't imply // that we would pass again with a different set of flags. diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 72b723645e..f3bc1184d8 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -306,6 +306,11 @@ TestingSetup::~TestingSetup() m_node.banman.reset(); } +TestChain100Setup::TestChain100Setup(const std::vector& extra_args) + : TestChainSetup{100, extra_args} +{ +} + TestChainSetup::TestChainSetup(int num_blocks, const std::vector& extra_args) : RegTestingSetup(extra_args) { diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h index 7b623355bf..28af81f0f1 100644 --- a/src/test/util/setup_common.h +++ b/src/test/util/setup_common.h @@ -177,7 +177,7 @@ struct TestChainSetup : public RegTestingSetup * Testing fixture that pre-creates a 100-block REGTEST-mode block chain */ struct TestChain100Setup : public TestChainSetup { - TestChain100Setup() : TestChainSetup(100) {} + TestChain100Setup(const std::vector& extra_args = {}); }; struct TestChainDIP3Setup : public TestChainSetup diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py index db95f28a51..d434a51da5 100755 --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -38,8 +38,14 @@ class BIP68Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.extra_args = [ - ["-acceptnonstdtxn=1"], - ["-acceptnonstdtxn=0"], + [ + '-testactivationheight=csv@432', + "-acceptnonstdtxn=1", + ], + [ + '-testactivationheight=csv@432', + "-acceptnonstdtxn=0", + ], ] def skip_test_if_missing_module(self): diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py index e4bc12a46a..59136efc28 100755 --- a/test/functional/feature_block.py +++ b/test/functional/feature_block.py @@ -83,7 +83,11 @@ class FullBlockTest(BitcoinTestFramework): # which causes RPC to hang, so we need to increase RPC timeouts self.rpc_timeout = 180 # Must set '-dip3params=2000:2000' to create pre-dip3 blocks only - self.extra_args = [['-dip3params=2000:2000', '-acceptnonstdtxn=1']] # This is a consensus block test, we don't care about tx policy + self.extra_args = [[ + '-dip3params=2000:2000', + '-acceptnonstdtxn=1', # This is a consensus block test, we don't care about tx policy + '-testactivationheight=bip34@2', + ]] def setup_nodes(self): self.add_nodes(self.num_nodes, self.extra_args) diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py index 60a0ec4538..00b0800e97 100755 --- a/test/functional/feature_cltv.py +++ b/test/functional/feature_cltv.py @@ -8,7 +8,6 @@ Test that the CHECKLOCKTIMEVERIFY soft-fork activates. """ from test_framework.blocktools import ( - CLTV_HEIGHT, create_block, create_coinbase, ) @@ -79,10 +78,14 @@ def cltv_validate(tx, height): cltv_modify_tx(tx, prepend_scriptsig=scheme[0], nsequence=scheme[1], nlocktime=scheme[2]) +CLTV_HEIGHT = 111 + + class BIP65Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 self.extra_args = [[ + f'-testactivationheight=cltv@{CLTV_HEIGHT}', '-whitelist=noban@127.0.0.1', '-dip3params=9000:9000', '-par=1', # Use only one script thread to get the exact reject reason for testing diff --git a/test/functional/feature_csv_activation.py b/test/functional/feature_csv_activation.py index 503f3eb243..4502c74a29 100755 --- a/test/functional/feature_csv_activation.py +++ b/test/functional/feature_csv_activation.py @@ -40,7 +40,6 @@ bip112tx_emptystack - test empty stack (= no argument) OP_CSV from itertools import product from test_framework.blocktools import ( - CSV_ACTIVATION_HEIGHT, create_block, create_coinbase, TIME_GENESIS_BLOCK, @@ -89,6 +88,9 @@ def all_rlt_txs(txs): return [tx['tx'] for tx in txs] +CSV_ACTIVATION_HEIGHT = 432 + + class BIP68_112_113Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 @@ -98,6 +100,7 @@ class BIP68_112_113Test(BitcoinTestFramework): '-peertimeout=999999', # bump because mocktime might cause a disconnect otherwise '-whitelist=noban@127.0.0.1', '-dip3params=2000:2000', + f'-testactivationheight=csv@{CSV_ACTIVATION_HEIGHT}', '-par=1', # Use only one script thread to get the exact reject reason for testing ]] self.supports_cli = False diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py index 597bce5a7e..834e07e6fe 100755 --- a/test/functional/feature_dersig.py +++ b/test/functional/feature_dersig.py @@ -8,7 +8,6 @@ Test the DERSIG soft-fork activation on regtest. """ from test_framework.blocktools import ( - DERSIG_HEIGHT, create_block, create_coinbase, ) @@ -43,10 +42,18 @@ def unDERify(tx): tx.vin[0].scriptSig = CScript(newscript) +DERSIG_HEIGHT = 102 + + class BIP66Test(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [['-whitelist=noban@127.0.0.1', '-dip3params=9000:9000', '-par=1', '-vbparams=v20:0:999999999999:0:480:384:288:5:0']] # Use only one script thread to get the exact reject reason for testing + self.extra_args = [[ + f'-testactivationheight=dersig@{DERSIG_HEIGHT}', + '-whitelist=noban@127.0.0.1', + '-dip3params=9000:9000', + '-par=1', # Use only one script thread to get the exact log msg for testing + '-vbparams=v20:0:999999999999:0:480:384:288:5:0']] self.setup_clean_chain = True self.rpc_timeout = 240 @@ -81,7 +88,6 @@ class BIP66Test(BitcoinTestFramework): tip = self.nodes[0].getbestblockhash() block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 block = create_block(int(tip, 16), create_coinbase(DERSIG_HEIGHT - 1), block_time) - block.nVersion = 2 block.vtx.append(spendtx) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() @@ -108,7 +114,7 @@ class BIP66Test(BitcoinTestFramework): peer.sync_with_ping() self.log.info("Test that transactions with non-DER signatures cannot appear in a block") - block.nVersion = 3 + block.nVersion = 4 spendtx = self.create_tx(self.coinbase_txids[1]) unDERify(spendtx) @@ -129,7 +135,7 @@ class BIP66Test(BitcoinTestFramework): assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip) peer.sync_with_ping() - self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted") + self.log.info("Test that a block with a DERSIG-compliant transaction is accepted") block.vtx[1] = self.create_tx(self.coinbase_txids[1]) block.hashMerkleRoot = block.calc_merkle_root() block.rehash() diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py index 6769aa6b54..ecae987613 100755 --- a/test/functional/feature_nulldummy.py +++ b/test/functional/feature_nulldummy.py @@ -50,7 +50,7 @@ class NULLDUMMYTest(BitcoinTestFramework): self.extra_args = [[ '-whitelist=127.0.0.1', '-dip3params=105:105', - '-bip147height=105', + f'-testactivationheight=bip147@{COINBASE_MATURITY + 5}', '-par=1', # Use only one script thread to get the exact reject reason for testing ]] * 2 diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 10c8d96136..c8059e8311 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -27,8 +27,6 @@ import subprocess from test_framework.address import ADDRESS_BCRT1_P2SH_OP_TRUE from test_framework.blocktools import ( - CLTV_HEIGHT, - DERSIG_HEIGHT, create_block, create_coinbase, TIME_GENESIS_BLOCK, @@ -144,11 +142,11 @@ class BlockchainTest(BitcoinTestFramework): assert_equal(res['prune_target_size'], 576716800) assert_greater_than(res['size_on_disk'], 0) assert_equal(res['softforks'], { - 'bip34': {'type': 'buried', 'active': True, 'height': 2}, - 'bip66': {'type': 'buried', 'active': True, 'height': DERSIG_HEIGHT}, - 'bip65': {'type': 'buried', 'active': True, 'height': CLTV_HEIGHT}, - 'bip147': { 'type': 'buried', 'active': False, 'height': 432}, - 'csv': {'type': 'buried', 'active': False, 'height': 432}, + 'bip34': {'type': 'buried', 'active': True, 'height': 1}, + 'bip66': {'type': 'buried', 'active': True, 'height': 1}, + 'bip65': {'type': 'buried', 'active': True, 'height': 1}, + 'bip147': { 'type': 'buried', 'active': True, 'height': 1}, + 'csv': {'type': 'buried', 'active': True, 'height': 1}, 'dip0001': { 'type': 'buried', 'active': False, 'height': 2000}, 'dip0003': { 'type': 'buried', 'active': False, 'height': 432}, 'dip0008': { 'type': 'buried', 'active': False, 'height': 432}, diff --git a/test/functional/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py index a77a11669c..388fd5b5b9 100644 --- a/test/functional/test_framework/blocktools.py +++ b/test/functional/test_framework/blocktools.py @@ -35,11 +35,6 @@ TIME_GENESIS_BLOCK = 1417713337 # Coinbase transaction outputs can only be spent after this number of new blocks (network rule) COINBASE_MATURITY = 100 -# Soft-fork activation heights -DERSIG_HEIGHT = 102 # BIP 66 -CLTV_HEIGHT = 111 # BIP 65 -CSV_ACTIVATION_HEIGHT = 432 - NORMAL_GBT_REQUEST_PARAMS = {"rules": []} # type: ignore[var-annotated] VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4 diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 9f0930e409..ec3c6dcde1 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -601,17 +601,6 @@ def mine_large_block(node, utxos=None): node.generate(1) -def generate_to_height(node, target_height): - """Generates blocks until a given target block height has been reached. - To prevent timeouts, only up to 200 blocks are generated per RPC call. - Can be used to activate certain soft-forks (e.g. CSV, CLTV).""" - current_height = node.getblockcount() - while current_height < target_height: - nblocks = min(200, target_height - current_height) - current_height += len(node.generate(nblocks)) - assert_equal(node.getblockcount(), target_height) - - def find_vout_for_address(node, txid, addr): """ Locate the vout index of the given transaction sending to the