diff --git a/contrib/assets_tutorial/assets_tutorial.py b/contrib/assets_tutorial/assets_tutorial.py index 8e0919768a..3b933a17a0 100755 --- a/contrib/assets_tutorial/assets_tutorial.py +++ b/contrib/assets_tutorial/assets_tutorial.py @@ -482,7 +482,7 @@ extra_args = [ "-con_max_block_sig_size=150", # We also disable dynamic federations, since we are not going to do any # dynafed transitions in this tutorial. FIXME we probably should. - "-con_dyna_deploy_start=0", + "-evbparams=dynafed:0:::", ] print ("6b. Restart both nodes") diff --git a/src/chainparams.cpp b/src/chainparams.cpp index accd3727fd..f0086a6864 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -85,6 +85,96 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits return CreateGenesisBlock(params, genesisScriptSig, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); } +/** + * Allows modifying the Version Bits Elements regtest parameters (and liquidv1test). + * Ideally, this would be a method in the base class, inherited everywhere, but that might complicate future merges, + * so we settle for this static function. + */ +static void UpdateElementsActivationParametersFromArgs(Consensus::Params& consensus, const ArgsManager& args) +{ + if (!args.IsArgSet("-evbparams")) return; + + std::map map_deployments; + for (const std::string& strDeployment : args.GetArgs("-evbparams")) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":")); + if (vDeploymentParams.size() != 5) { + throw std::runtime_error("ElementsVersion bits parameters malformed, expecting deployment:start:end:period:threshold"); + } + int64_t nStartTime = 0, nTimeout = 0, nPeriod = 0, nThreshold = 0; + bool use_nStartTime = false, use_nTimeout = false, use_nPeriod = false, use_nThreshold = false; + if(vDeploymentParams[1].length()) { + if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { + throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); + } + use_nStartTime = true; + } + if(vDeploymentParams[2].length()) { + if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { + throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); + } + use_nTimeout = true; + } + if(vDeploymentParams[3].length()) { + if (!ParseInt64(vDeploymentParams[3], &nPeriod)) { + throw std::runtime_error(strprintf("Invalid nPeriod (%s)", vDeploymentParams[3])); + } + use_nPeriod = true; + } + if(vDeploymentParams[4].length()) { + if (!ParseInt64(vDeploymentParams[4], &nThreshold)) { + throw std::runtime_error(strprintf("Invalid nThreshold (%s)", vDeploymentParams[4])); + } + use_nThreshold = true; + } + bool found = false; + for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { + if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) { + if(map_deployments[vDeploymentParams[0]]) { + found = true; + LogPrintf("Ignoring duplicated version bits activation parameters for \"%s\"\n", strDeployment.c_str()); + break; + } + std::string extra_logging; + map_deployments[vDeploymentParams[0]]=1; + Consensus::DeploymentPos d=Consensus::DeploymentPos(j); + if (use_nStartTime) { + consensus.vDeployments[d].nStartTime = nStartTime; + } else { + nStartTime =consensus.vDeployments[d].nStartTime; + } + if (use_nTimeout) { + consensus.vDeployments[d].nTimeout = nTimeout; + } else { + nTimeout = consensus.vDeployments[d].nTimeout; + } + if (consensus.vDeployments[d].nPeriod) { + if(use_nPeriod) { + consensus.vDeployments[d].nPeriod = nPeriod; + } else { + nPeriod = *consensus.vDeployments[d].nPeriod; + } + extra_logging+= strprintf(", period=%ld", nPeriod); + } + if (consensus.vDeployments[d].nThreshold) { + if(use_nThreshold) { + consensus.vDeployments[d].nThreshold = nThreshold; + } else { + nThreshold = *consensus.vDeployments[d].nThreshold; + } + extra_logging+= strprintf(", threshold=%ld", nThreshold); + } + found = true; + LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld%s\n", vDeploymentParams[0], nStartTime, nTimeout, extra_logging.c_str()); + break; + } + } + if (!found) { + throw std::runtime_error(strprintf("Invalid deployment (%s)", vDeploymentParams[0])); + } + } +} + /** * Main network */ @@ -478,7 +568,7 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = 1199145601; // January 1, 2008 consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = 1230767999; // December 31, 2008 consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = gArgs.GetArg("-con_taproot_signal_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE); + consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nPeriod = 128; // test ability to change from default consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nThreshold = 128; @@ -749,8 +839,10 @@ class CCustomParams : public CRegTestParams { } consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25; - consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = args.GetArg("-con_dyna_deploy_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE); + consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; + + UpdateElementsActivationParametersFromArgs(consensus, args); // END ELEMENTS fields } @@ -1011,7 +1103,7 @@ public: // Activated from block 1,000,000. consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25; // Allow blocksigners to delay activation. - consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = gArgs.GetArg("-con_dyna_deploy_start", 1000000); + consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = 1000000; consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; @@ -1064,6 +1156,9 @@ public: // For testing purposes, default to the same junk keys that CustomParams uses (this can be overridden.) consensus.first_extension_space = {ParseHex("02fcba7ecf41bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f02fcba7ecf41bc7e1be4ee122d9d22e3333671eb0a3a87b5cdf099d59874e1940f")}; + // Don't use liquidv1's height to enable taproot + consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 0; + // Use all regtest rather than mainchain magic numbers: bech32_hrp = args.GetArg("-bech32_hrp", "ert"); blech32_hrp = args.GetArg("-blech32_hrp", "el"); @@ -1101,9 +1196,6 @@ public: // This is unlike the CCustomParams UpdateFromArgs method, which has lots of defaults in it. void UpdateFromArgs(const ArgsManager& args) { - // NOTE: We don't handle version bits, because I'm not sure we actually use them, and it would be messy to do so. - // UpdateVersionBitsParametersFromArgs(args); - consensus.nSubsidyHalvingInterval = args.GetArg("-con_nsubsidyhalvinginterval", consensus.nSubsidyHalvingInterval); if (args.IsArgSet("-con_bip16exception")) { consensus.BIP16Exception = uint256S(args.GetArg("-con_bip16exception", "")); @@ -1269,15 +1361,11 @@ public: consensus.subsidy_asset = CAsset(uint256S(args.GetArg("-subsidyasset", ""))); } - if (args.IsArgSet("-con_dyna_deploy_start")) { - consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25; - consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = args.GetArg("-con_dyna_deploy_start", Consensus::BIP9Deployment::ALWAYS_ACTIVE); - consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - } + consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].bit = 25; + consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_DYNA_FED].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - if (args.IsArgSet("-con_taproot_signal_start")) { - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = gArgs.GetArg("-con_taproot_signal_start", 0); - } + UpdateElementsActivationParametersFromArgs(consensus, args); // END ELEMENTS fields } diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index a37b5742a9..7173ccf69b 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -56,11 +56,10 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman) argsman.AddArg("-pak", "Sets the 'first extension space' field to the pak entries ala pre-dynamic federations. Only used for testing in custom chains.", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); argsman.AddArg("-multi_data_permitted", "Allow relay of multiple OP_RETURN outputs. (default: -enforce_pak)", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); argsman.AddArg("-con_csv_deploy_start", "Starting height for CSV deployment. (default: -1, which means ACTIVE from genesis)", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); - argsman.AddArg("-con_dyna_deploy_start", "Starting height for Dynamic Federations deployment. Once active, signblockscript becomes a BIP141 WSH scriptPubKey of the original signblockscript. All other dynamic parameters stay constant.(default: -1, which means ACTIVE from genesis)", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); - argsman.AddArg("-con_dyna_deploy_signal", "Whether to signal for the Dynamic Federations deployment (default: false).", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); + argsman.AddArg("-con_dyna_deploy_signal", "Whether to signal for the Dynamic Federations deployment (default: true).", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); argsman.AddArg("-dynamic_epoch_length", "Per-chain parameter that sets how many blocks dynamic federation voting and enforcement are in effect for.", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); argsman.AddArg("-total_valid_epochs", "Per-chain parameter that sets how long a particular fedpegscript is in effect for.", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); - argsman.AddArg("-con_taproot_signal_start", "Whether, and at what blockheight, to start signalling for Taproot activation (default: false) (regtest, Liquid testnet, or custom only).", ArgsManager::ALLOW_ANY, OptionsCategory::ELEMENTS); + argsman.AddArg("-evbparams=deployment:start:end:period:threshold", "Use given start/end times for specified version bits deployment (regtest or custom only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::ELEMENTS); // END ELEMENTS // } diff --git a/src/validation.cpp b/src/validation.cpp index ff2f81c5d8..a6819098e9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1982,7 +1982,7 @@ int32_t ComputeBlockVersion(const CBlockIndex* pindexPrev, const Consensus::Para } // Undo default signalling behavior for dynafed unless explicitly enabled. - if (!gArgs.GetBoolArg("-con_dyna_deploy_signal", false)) { + if (!gArgs.GetBoolArg("-con_dyna_deploy_signal", true)) { auto dynafed = Consensus::DeploymentPos::DEPLOYMENT_DYNA_FED; int bit = params.vDeployments[dynafed].bit; if (bit > 0 && bit < VERSIONBITS_NUM_BITS) { diff --git a/test/bitcoin_functional/functional/test_framework/util.py b/test/bitcoin_functional/functional/test_framework/util.py index 303f501488..cb83ec20de 100644 --- a/test/bitcoin_functional/functional/test_framework/util.py +++ b/test/bitcoin_functional/functional/test_framework/util.py @@ -322,7 +322,7 @@ def initialize_datadir(dirname, n): f.write("pubkeyprefix=111\n") f.write("scriptprefix=196\n") f.write("bech32_hrp=bcrt\n") - f.write("con_dyna_deploy_start="+str(2**31)+"\n") # Never starts + f.write("evbparams=dynafed:"+str(2**31)+":::\n") # Never starts f.write("minrelaytxfee=0.00001\n") os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True) os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True) diff --git a/test/functional/feature_blocksign.py b/test/functional/feature_blocksign.py index 363664afe2..b8c55af5b6 100755 --- a/test/functional/feature_blocksign.py +++ b/test/functional/feature_blocksign.py @@ -82,7 +82,7 @@ class BlockSignTest(BitcoinTestFramework): "-signblockscript={}".format(signblockscript), "-con_max_block_sig_size={}".format(self.required_signers*74+self.num_nodes*33), "-anyonecanspendaremine=1", - "-con_dyna_deploy_start=0", + "-evbparams=dynafed:0:::", "-con_dyna_deploy_signal=1", ]] * self.num_nodes diff --git a/test/functional/feature_dynafed.py b/test/functional/feature_dynafed.py index 1e219fc521..32322602ad 100755 --- a/test/functional/feature_dynafed.py +++ b/test/functional/feature_dynafed.py @@ -67,7 +67,7 @@ class DynaFedTest(BitcoinTestFramework): self.num_nodes = 2 # We want to test activation of dynafed self.extra_args = [[ - "-con_dyna_deploy_start=1000", + "-evbparams=dynafed:1000:::", "-enforce_pak=1", "-con_parent_chain_signblockscript=51", "-peginconfirmationdepth=1", @@ -78,7 +78,7 @@ class DynaFedTest(BitcoinTestFramework): # second node will not mine transactions self.extra_args[1].append("-blocksonly=1") # Make sure nothing breaks if peers have a different activation. - self.extra_args[1][0] = "-con_dyna_deploy_start=937" + self.extra_args[1][0] = "-evbparams=dynafed:937:::" def skip_test_if_missing_module(self): self.skip_if_no_wallet() diff --git a/test/functional/feature_elements_taproot_activation.py b/test/functional/feature_elements_taproot_activation.py index 5a476381e2..2fc477dff5 100755 --- a/test/functional/feature_elements_taproot_activation.py +++ b/test/functional/feature_elements_taproot_activation.py @@ -98,7 +98,7 @@ class TaprootActivationTest(BitcoinTestFramework): assert_equal(rpc.getblockheader(blocks[0])["versionHex"], "20000000") def run_test(self): - # Test that regtest nodes without -con_taproot_signal_start never signal + # Test that regtest nodes never signal taproot by default self.log.info("Testing node not configured to activate taproot") blocks = self.nodes[0].generatetoaddress(2500, self.nodes[0].getnewaddress()) assert_equal(self.nodes[0].getblockcount(), 2500) @@ -113,7 +113,7 @@ class TaprootActivationTest(BitcoinTestFramework): assert_equal (decode["versionHex"], "20000000") # Test activation starting from height 1000 - self.restart_node(0, ["-con_taproot_signal_start=500"]) + self.restart_node(0, ["-evbparams=taproot:500:::"]) self.nodes[0].invalidateblock(self.nodes[0].getblockhash(1)) self.test_activation(self.nodes[0], 500) diff --git a/test/functional/feature_fedpeg.py b/test/functional/feature_fedpeg.py index b727708b9c..7ad5e137df 100755 --- a/test/functional/feature_fedpeg.py +++ b/test/functional/feature_fedpeg.py @@ -140,7 +140,7 @@ class FedPegTest(BitcoinTestFramework): # Immediate activation of dynafed when requested versus "never" from conf if self.options.pre_transition or self.options.post_transition: - extra_args.extend(["-con_dyna_deploy_start=-1"]) + extra_args.extend(["-evbparams=dynafed:-1:::"]) # Use rpcuser auth only for first parent. if n==0: diff --git a/test/functional/feature_pak.py b/test/functional/feature_pak.py index 7fd8479f67..5eb3598bb5 100755 --- a/test/functional/feature_pak.py +++ b/test/functional/feature_pak.py @@ -18,7 +18,7 @@ class PAKTest (BitcoinTestFramework): def set_test_params(self): self.num_nodes = 3 self.setup_clean_chain = True - self.extra_args = [["-enforce_pak=1", "-con_dyna_deploy_start=-1", "-initialfreecoins=210000000000000", "-anyonecanspendaremine=1", "-parent_bech32_hrp=lol", "-pubkeyprefix=112", "-scriptprefix=197", "-con_connect_genesis_outputs=1"] for i in range(self.num_nodes)] + self.extra_args = [["-enforce_pak=1", "-evbparams=dynafed:-1:::", "-initialfreecoins=210000000000000", "-anyonecanspendaremine=1", "-parent_bech32_hrp=lol", "-pubkeyprefix=112", "-scriptprefix=197", "-con_connect_genesis_outputs=1"] for i in range(self.num_nodes)] # First node doesn't enforce PAK, a "HF" of the other two nodes self.extra_args[0] = ["-acceptnonstdtxn=1"] + self.extra_args[0][1:] ## FIXME -acceptnonstdtxn=1 should not be needed diff --git a/test/functional/feature_sighash_rangeproof.py b/test/functional/feature_sighash_rangeproof.py index 4ffdcf9ffc..0fb4dd7836 100755 --- a/test/functional/feature_sighash_rangeproof.py +++ b/test/functional/feature_sighash_rangeproof.py @@ -51,7 +51,7 @@ class SighashRangeproofTest(BitcoinTestFramework): self.num_nodes = 3 # We want to test activation of dynafed self.extra_args = [[ - "-con_dyna_deploy_start=1000", + "-evbparams=dynafed:1000:::", "-con_dyna_deploy_signal=1", "-blindedaddresses=1", "-initialfreecoins=2100000000000000", diff --git a/test/functional/rpc_tweakfedpeg.py b/test/functional/rpc_tweakfedpeg.py index 5f67b625ab..51685f27e2 100755 --- a/test/functional/rpc_tweakfedpeg.py +++ b/test/functional/rpc_tweakfedpeg.py @@ -26,7 +26,7 @@ class TweakFedpegTest(BitcoinTestFramework): [ "-fedpegscript="+LIQUID_SCRIPT, "-con_dyna_deploy_signal=1", - "-con_dyna_deploy_start=0", # test dynafed derivation + "-evbparams=dynafed:0:::", # test dynafed derivation ]] def setup_network(self): diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 7abb757a6d..01a677cf34 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -381,7 +381,7 @@ def initialize_datadir(dirname, n, chain): f.write("con_bip65height=1351\n") f.write("con_bip66height=1251\n") f.write("blindedaddresses=0\n") # Set to minimize broken tests in favor of custom - f.write("con_dyna_deploy_start="+str(2**31)+"\n") # Never starts unless overridden + f.write("evbparams=dynafed:"+str(2**31)+":::\n") # Never starts unless overridden f.write("minrelaytxfee=0.00001\n") #f.write("pubkeyprefix=111\n") #f.write("scriptprefix=196\n")