diff --git a/doc/release-notes-6189.md b/doc/release-notes-6189.md index b4b2678516dfe..465068e2d773a 100644 --- a/doc/release-notes-6189.md +++ b/doc/release-notes-6189.md @@ -3,4 +3,4 @@ Tests - For the `regtest` network the activation heights of several softforks were set to block height 1. They can be changed by the runtime setting - `-testactivationheight=name@height`. (dash#6214) + `-testactivationheight=name@height`. Command line arguments -dip8params, -bip147height are removed in favour of -testactivationheight. (dash#6214) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 89d124475dc80..5b571328d41de 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -189,7 +189,6 @@ class CMainParams : public CChainParams { consensus.DIP0008Height = 1088640; // 00000000000000112e41e4b3afda8b233b8cc07c532d2eac5de097b68358c43e consensus.BRRHeight = 1374912; // 000000000000000c5a124f3eccfbe6e17876dca79cec9e63dfa70d269113c926 consensus.DIP0020Height = 1516032; // 000000000000000f64ed3bd9af1078177ac026f6aa2677aa4d8beeae43be56cc - consensus.DIP0024Height = 1737792; // 0000000000000001342be9c0b75ad40c276beaad91616423c4d9cb101b3db438 consensus.DIP0024QuorumsHeight = 1738698; // 000000000000001aa25181e4c466e593992c98f9eb21c69ee757b8bb0af50244 consensus.V19Height = 1899072; // 0000000000000015e32e73052d663626327004c81c5c22cb8b42c361015c0eae consensus.V20Height = 1987776; // 000000000000001bf41cff06b76780050682ca29e61a91c391893d4745579777 @@ -375,7 +374,6 @@ class CTestNetParams : public CChainParams { consensus.DIP0008Height = 78800; // 000000000e9329d964d80e7dab2e704b43b6bd2b91fea1e9315d38932e55fb55 consensus.BRRHeight = 387500; // 0000001537dbfd09dea69f61c1f8b2afa27c8dc91c934e144797761c9f10367b consensus.DIP0020Height = 414100; // 000000cf961868662fbfbb5d1af6f1caa1809f6a4e390efe5f8cd3031adea668 - consensus.DIP0024Height = 769700; // 0000008d84e4efd890ae95c70a7a6126a70a80e5c19e4cb264a5b3469aeef172 consensus.DIP0024QuorumsHeight = 770730; // 0000003c43b3ae7fffe61278ca5537a0e256ebf4d709d45f0ab040271074d51e consensus.V19Height = 850100; // 000004728b8ff2a16b9d4eebb0fd61eeffadc9c7fe4b0ec0b5a739869401ab5b consensus.V20Height = 905100; // 0000020c5e0f86f385cbf8e90210de9a9fd63633f01433bf47a6b3227a2851fd @@ -536,12 +534,11 @@ class CDevNetParams : public CChainParams { consensus.DIP0008Height = 2; // DIP0008 activated immediately on devnet consensus.BRRHeight = 2; // BRR (realloc) activated immediately on devnet consensus.DIP0020Height = 2; // DIP0020 activated immediately on devnet - consensus.DIP0024Height = 2; // DIP0024 activated immediately on devnet consensus.DIP0024QuorumsHeight = 2; // DIP0024 activated immediately on devnet consensus.V19Height = 2; // V19 activated immediately on devnet consensus.V20Height = 2; // V20 activated immediately on devnet consensus.MN_RRHeight = 2; // MN_RR activated immediately on devnet - consensus.MinBIP9WarningHeight = 2 + 2016; // v19 activation height + miner confirmation window + consensus.MinBIP9WarningHeight = 2 + 2016; // mn_rr activation height + miner confirmation window consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1 consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes @@ -752,17 +749,17 @@ class CRegTestParams : public CChainParams { consensus.BIP34Hash = uint256(); consensus.BIP65Height = 1; // Always active unless overridden consensus.BIP66Height = 1; // Always active unless overridden - consensus.BIP147Height = 1; // Always active unless overridden + consensus.BIP147Height = 0; // Always active unless overridden consensus.CSVHeight = 1; // Always active unless overridden consensus.DIP0001Height = 1; // Always active unless overridden - consensus.DIP0003Height = 432; + consensus.DIP0003Height = 432; // Always active for DashTestFramework in functional tests (see dip3params) + // For unit tests and for BitcoinTestFramework is disabled due to missing quorum commitment for blocks created by helpers such as create_blocks consensus.DIP0003EnforcementHeight = 500; consensus.DIP0003EnforcementHash = uint256(); consensus.DIP0008Height = 1; // Always active unless overridden consensus.BRRHeight = 1; // Always active unless overridden consensus.DIP0020Height = 1; // Always active unless overridden - consensus.DIP0024Height = 900; - consensus.DIP0024QuorumsHeight = 900; + consensus.DIP0024QuorumsHeight = 1; // Always have dip0024 quorums unless overridden consensus.V19Height = 900; consensus.V20Height = 900; consensus.MN_RRHeight = 900; @@ -801,8 +798,6 @@ class CRegTestParams : public CChainParams { UpdateActivationParametersFromArgs(args); UpdateDIP3ParametersFromArgs(args); - UpdateDIP8ParametersFromArgs(args); - UpdateBIP147ParametersFromArgs(args); UpdateBudgetParametersFromArgs(args); genesis = CreateGenesisBlock(1417713337, 1096447, 0x207fffff, 1, 50 * COIN); @@ -919,21 +914,6 @@ class CRegTestParams : public CChainParams { } void UpdateDIP3ParametersFromArgs(const ArgsManager& args); - /** - * Allows modifying the DIP8 activation height - */ - void UpdateDIP8Parameters(int nActivationHeight) - { - consensus.DIP0008Height = nActivationHeight; - } - void UpdateDIP8ParametersFromArgs(const ArgsManager& args); - - void UpdateBIP147Parameters(int nActivationHeight) - { - consensus.BIP147Height = nActivationHeight; - } - void UpdateBIP147ParametersFromArgs(const ArgsManager& args); - /** * Allows modifying the budget regtest parameters. */ @@ -999,6 +979,8 @@ static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& conse consensus.DIP0001Height = int{height}; } else if (name == "dip0008") { consensus.DIP0008Height = int{height}; + } else if (name == "dip0024") { + consensus.DIP0024QuorumsHeight = int{height}; } else if (name == "v20") { consensus.V20Height = int{height}; } else if (name == "mn_rr") { @@ -1090,35 +1072,6 @@ void CRegTestParams::UpdateDIP3ParametersFromArgs(const ArgsManager& args) UpdateDIP3Parameters(nDIP3ActivationHeight, nDIP3EnforcementHeight); } -void CRegTestParams::UpdateDIP8ParametersFromArgs(const ArgsManager& args) -{ - if (!args.IsArgSet("-dip8params")) return; - - std::string strParams = args.GetArg("-dip8params", ""); - std::vector vParams = SplitString(strParams, ':'); - if (vParams.size() != 1) { - throw std::runtime_error("DIP8 parameters malformed, expecting "); - } - int nDIP8ActivationHeight; - if (!ParseInt32(vParams[0], &nDIP8ActivationHeight)) { - throw std::runtime_error(strprintf("Invalid activation height (%s)", vParams[0])); - } - LogPrintf("Setting DIP8 parameters to activation=%ld\n", nDIP8ActivationHeight); - UpdateDIP8Parameters(nDIP8ActivationHeight); -} - -void CRegTestParams::UpdateBIP147ParametersFromArgs(const ArgsManager& args) -{ - if (!args.IsArgSet("-bip147height")) return; - int nBIP147Height; - const std::string strParams = args.GetArg("-bip147height", ""); - if (!ParseInt32(strParams, &nBIP147Height)) { - throw std::runtime_error(strprintf("Invalid activation height (%s)", strParams)); - } - LogPrintf("Setting BIP147 parameters to activation=%lld\n", nBIP147Height); - UpdateBIP147Parameters(nBIP147Height); -} - void CRegTestParams::UpdateBudgetParametersFromArgs(const ArgsManager& args) { if (!args.IsArgSet("-budgetparams")) return; diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index d7ef237c0eee8..1a05491f065ba 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -20,9 +20,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman) argsman.AddArg("-budgetparams=::", "Override masternode, budget and superblock start heights (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS); argsman.AddArg("-devnet=", "Use devnet chain with provided name", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); 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, brr, dip0001, dip0008, v20, mn_rr). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (bip147, bip34, dersig, cltv, csv, brr, dip0001, dip0008, dip0024, v20, mn_rr). (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/consensus/params.h b/src/consensus/params.h index 95918aa6dbcc9..1558bf95dff24 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -136,8 +136,6 @@ struct Params { int BRRHeight; /** Block height at which DIP0020, DIP0021 and LLMQ_100_67 quorums become active */ int DIP0020Height; - /** Block height at which DIP0024 (Quorum Rotation) and decreased governance proposal fee becomes active */ - int DIP0024Height; /** Block height at which the first DIP0024 quorum was mined */ int DIP0024QuorumsHeight; /** Block height at which V19 (Basic BLS and EvoNodes) becomes active */ @@ -204,7 +202,7 @@ struct Params { case DEPLOYMENT_DIP0020: return DIP0020Height; case DEPLOYMENT_DIP0024: - return DIP0024Height; + return DIP0024QuorumsHeight; case DEPLOYMENT_BRR: return BRRHeight; case DEPLOYMENT_V19: diff --git a/src/evo/specialtxman.cpp b/src/evo/specialtxman.cpp index e20a9e0d4f7b3..9c76b3b69324d 100644 --- a/src/evo/specialtxman.cpp +++ b/src/evo/specialtxman.cpp @@ -266,16 +266,20 @@ bool CSpecialTxProcessor::CheckCreditPoolDiffForBlock(const CBlock& block, const try { if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_DIP0003)) return true; + if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_DIP0008)) return true; if (!DeploymentActiveAt(*pindex, m_consensus_params, Consensus::DEPLOYMENT_V20)) return true; auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_chainman.m_blockman, m_qman, block, pindex->pprev, m_consensus_params, blockSubsidy, state); if (!creditPoolDiff.has_value()) return false; // If we get there we have v20 activated and credit pool amount must be included in block CbTx + if (block.vtx.empty()) { + return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-missing-cbtx"); + } const auto& tx = *block.vtx[0]; - assert(tx.IsCoinBase()); - assert(tx.IsSpecialTxVersion()); - assert(tx.nType == TRANSACTION_COINBASE); + if (!tx.IsCoinBase() || !tx.IsSpecialTxVersion() || tx.nType != TRANSACTION_COINBASE) { + return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cbtx-type"); + } const auto opt_cbTx = GetTxPayload(tx); if (!opt_cbTx) { diff --git a/src/llmq/options.cpp b/src/llmq/options.cpp index c1956e8a67a1b..d0723f7f12f29 100644 --- a/src/llmq/options.cpp +++ b/src/llmq/options.cpp @@ -116,26 +116,26 @@ std::map GetEnabledQuorumVvecSyncEntries() bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, gsl::not_null pindexPrev) { - return IsQuorumTypeEnabledInternal(llmqType, pindexPrev, std::nullopt, std::nullopt); + return IsQuorumTypeEnabledInternal(llmqType, pindexPrev, std::nullopt); } bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, gsl::not_null pindexPrev, - std::optional optDIP0024IsActive, std::optional optHaveDIP0024Quorums) + std::optional optIsDIP0024Active) { const Consensus::Params& consensusParams = Params().GetConsensus(); - const bool fDIP0024IsActive{optDIP0024IsActive.value_or(DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DIP0024))}; - const bool fHaveDIP0024Quorums{optHaveDIP0024Quorums.value_or(pindexPrev->nHeight >= consensusParams.DIP0024QuorumsHeight)}; + const bool fDIP0024IsActive{ + optIsDIP0024Active.value_or(DeploymentActiveAfter(pindexPrev, consensusParams, Consensus::DEPLOYMENT_DIP0024))}; switch (llmqType) { case Consensus::LLMQType::LLMQ_DEVNET: return true; case Consensus::LLMQType::LLMQ_50_60: - return !fDIP0024IsActive || !fHaveDIP0024Quorums || Params().NetworkIDString() == CBaseChainParams::TESTNET || + return !fDIP0024IsActive || Params().NetworkIDString() == CBaseChainParams::TESTNET || Params().NetworkIDString() == CBaseChainParams::DEVNET; case Consensus::LLMQType::LLMQ_TEST_INSTANTSEND: - return !fDIP0024IsActive || !fHaveDIP0024Quorums || - consensusParams.llmqTypeDIP0024InstantSend == Consensus::LLMQType::LLMQ_TEST_INSTANTSEND; + return !fDIP0024IsActive || + consensusParams.llmqTypeDIP0024InstantSend == Consensus::LLMQType::LLMQ_TEST_INSTANTSEND; case Consensus::LLMQType::LLMQ_TEST: case Consensus::LLMQType::LLMQ_TEST_PLATFORM: case Consensus::LLMQType::LLMQ_400_60: diff --git a/src/llmq/options.h b/src/llmq/options.h index f78f2362fdfc0..de220f499c014 100644 --- a/src/llmq/options.h +++ b/src/llmq/options.h @@ -44,7 +44,8 @@ bool IsWatchQuorumsEnabled(); std::map GetEnabledQuorumVvecSyncEntries(); bool IsQuorumTypeEnabled(Consensus::LLMQType llmqType, gsl::not_null pindexPrev); -bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, gsl::not_null pindexPrev, std::optional optDIP0024IsActive, std::optional optHaveDIP0024Quorums); +bool IsQuorumTypeEnabledInternal(Consensus::LLMQType llmqType, gsl::not_null pindexPrev, + std::optional optHaveDIP0024Quorums); std::vector GetEnabledQuorumTypes(gsl::not_null pindex); std::vector> GetEnabledQuorumParams(gsl::not_null pindex); diff --git a/src/test/evo_utils_tests.cpp b/src/test/evo_utils_tests.cpp index 4d555492469b4..65c405f9bda22 100644 --- a/src/test/evo_utils_tests.cpp +++ b/src/test/evo_utils_tests.cpp @@ -21,18 +21,14 @@ void Test(NodeContext& node) using namespace llmq; auto tip = node.chainman->ActiveTip(); const auto& consensus_params = Params().GetConsensus(); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, tip, false, false), false); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, tip, true, false), true); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, tip, true, true), true); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, tip, false, false), true); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, tip, true, false), true); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, tip, true, true), true); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, tip, false, false), Params().IsTestChain()); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, tip, true, false), Params().IsTestChain()); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, tip, true, true), Params().IsTestChain()); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, tip, false, false), true); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, tip, true, false), true); - BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, tip, true, true), true); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, tip, false), false); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeDIP0024InstantSend, tip, true), true); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, tip, false), true); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeChainLocks, tip, true), true); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, tip, false), Params().IsTestChain()); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypePlatform, tip, true), Params().IsTestChain()); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, tip, false), true); + BOOST_CHECK_EQUAL(IsQuorumTypeEnabledInternal(consensus_params.llmqTypeMnhf, tip, true), true); } BOOST_FIXTURE_TEST_CASE(utils_IsQuorumTypeEnabled_tests_regtest, RegTestingSetup) diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 2a5f252bff41a..daf1cd0e0aaca 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -353,9 +353,9 @@ TestChainSetup::TestChainSetup(int num_blocks, const std::vector& e /* TestChainDIP3BeforeActivationSetup */ { 430, uint256S("0x0bcefaa33fec56cd84d05d0e76cd6a78badcc20f627d91903646de6a07930a14") }, /* TestChainBRRBeforeActivationSetup */ - { 497, uint256S("0x23c31820ec5160b7181bfdf328e2b76cd12c9fa4544d892b7f01e74dd6220849") }, + { 497, uint256S("0x3c71d807d28b9b813434eb0679ec3d5bcf424c20088cf578f3757521c3e3eded") }, /* TestChainV19BeforeActivationSetup */ - { 894, uint256S("0x2885cf0fe8fdf29803b6c65002ba2570ff011531d8ea92be312a85d655e00c51") }, + { 894, uint256S("0x3f031e5cceade15bdfa559ddecb2ccb2b8d17083bdfd871a9d23b17d04b15292") }, } }; diff --git a/test/functional/feature_blockfilterindex_prune.py b/test/functional/feature_blockfilterindex_prune.py index 361a9cce01f1b..c133d71462001 100755 --- a/test/functional/feature_blockfilterindex_prune.py +++ b/test/functional/feature_blockfilterindex_prune.py @@ -15,6 +15,7 @@ class FeatureBlockfilterindexPruneTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 + # TODO: remove testactivationheight=v20@2000 when it will be activated from block 1 self.extra_args = [["-fastprune", "-prune=1", "-blockfilterindex=1", "-testactivationheight=v20@2000"]] def sync_index(self, height): @@ -53,7 +54,7 @@ def run_test(self): self.log.info("prune exactly up to the blockfilterindexes best block while blockfilters are disabled") pruneheight_2 = self.nodes[0].pruneblockchain(1000) - assert_equal(pruneheight_2, 932) + assert_equal(pruneheight_2, 946) self.restart_node(0, extra_args=["-fastprune", "-prune=1", "-blockfilterindex=1", "-testactivationheight=v20@2000"], expected_stderr=EXPECTED_STDERR_NO_GOV_PRUNE) self.log.info("make sure that we can continue with the partially synced index after having pruned up to the index height") self.sync_index(height=1500) diff --git a/test/functional/feature_dip4_coinbasemerkleroots.py b/test/functional/feature_dip4_coinbasemerkleroots.py index 844e26ea61192..598b0ba0fcbac 100755 --- a/test/functional/feature_dip4_coinbasemerkleroots.py +++ b/test/functional/feature_dip4_coinbasemerkleroots.py @@ -18,6 +18,7 @@ from test_framework.util import assert_equal DIP0008_HEIGHT = 432 +DIP0024_HEIGHT = 900 # TODO: this helper used in many tests, find a new home for it class TestP2PConn(P2PInterface): @@ -43,7 +44,7 @@ def getmnlistdiff(self, baseBlockHash, blockHash): class LLMQCoinbaseCommitmentsTest(DashTestFramework): def set_test_params(self): - self.extra_args = [[ f'-testactivationheight=dip0008@{DIP0008_HEIGHT}', "-vbparams=testdummy:999999999999:999999999999" ]] * 4 + self.extra_args = [[ f'-testactivationheight=dip0008@{DIP0008_HEIGHT}', f'-testactivationheight=dip0024@{DIP0024_HEIGHT}', "-vbparams=testdummy:999999999999:999999999999" ]] * 4 self.set_dash_test_params(4, 3, extra_args = self.extra_args) def run_test(self): # No IS or Chainlocks in this test diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index 31e637686b3b5..a85ce756145dc 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -81,11 +81,9 @@ def run_test(self): h_0 = self.mine_quorum() h_100_0 = QuorumId(100, int(h_0, 16)) h_106_0 = QuorumId(106, int(h_0, 16)) - h_104_0 = QuorumId(104, int(h_0, 16)) h_1 = self.mine_quorum() h_100_1 = QuorumId(100, int(h_1, 16)) h_106_1 = QuorumId(106, int(h_1, 16)) - h_104_1 = QuorumId(104, int(h_1, 16)) self.log.info("Mine single block, wait for chainlock") self.generate(self.nodes[0], 1, sync_fun=self.no_op) @@ -103,10 +101,10 @@ def run_test(self): assert_equal(dkg_info['active_dkgs'], 0) nonzero_dkgs += dkg_info['active_dkgs'] assert_equal(dkg_info['next_dkg'], next_dkg) - assert_equal(nonzero_dkgs, 11) # 2 quorums 4 nodes each and 1 quorum of 3 nodes + assert_equal(nonzero_dkgs, 7) # 1 quorums 4 nodes and 1 quorum of 3 nodes expectedDeleted = [] - expectedNew = [h_100_0, h_106_0, h_104_0, h_100_1, h_106_1, h_104_1] + expectedNew = [h_100_0, h_106_0, h_100_1, h_106_1] quorumList = self.test_getmnlistdiff_quorums(b_h_0, b_h_1, {}, expectedDeleted, expectedNew, testQuorumsCLSigs=False) projected_activation_height = 900 @@ -363,7 +361,6 @@ def get_llmq_size(self, llmq_type): 100: 4, # In this test size for llmqType 100 is overwritten to 4 102: 3, 103: 4, - 104: 4, # In this test size for llmqType 104 is overwritten to 4 106: 3 }.get(llmq_type, -1) diff --git a/test/functional/feature_llmq_signing.py b/test/functional/feature_llmq_signing.py index 8206e7dde41d3..88c941ad81b28 100755 --- a/test/functional/feature_llmq_signing.py +++ b/test/functional/feature_llmq_signing.py @@ -16,6 +16,7 @@ from test_framework.util import assert_equal, assert_raises_rpc_error, force_finish_mnsync, wait_until_helper +q_type=100 class LLMQSigningTest(DashTestFramework): def set_test_params(self): self.set_dash_test_params(6, 5) @@ -43,11 +44,11 @@ def run_test(self): def check_sigs(hasrecsigs, isconflicting1, isconflicting2): for mn in self.mninfo: - if mn.node.quorum("hasrecsig", 104, id, msgHash) != hasrecsigs: + if mn.node.quorum("hasrecsig", q_type, id, msgHash) != hasrecsigs: return False - if mn.node.quorum("isconflicting", 104, id, msgHash) != isconflicting1: + if mn.node.quorum("isconflicting", q_type, id, msgHash) != isconflicting1: return False - if mn.node.quorum("isconflicting", 104, id, msgHashConflict) != isconflicting2: + if mn.node.quorum("isconflicting", q_type, id, msgHashConflict) != isconflicting2: return False return True @@ -61,24 +62,24 @@ def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout): wait_for_sigs(False, False, False, 1) # Sign first share without any optional parameter, should not result in recovered sig - self.mninfo[0].node.quorum("sign", 104, id, msgHash) + self.mninfo[0].node.quorum("sign", q_type, id, msgHash) assert_sigs_nochange(False, False, False, 3) # Sign second share and test optional quorumHash parameter, should not result in recovered sig # 1. Providing an invalid quorum hash should fail and cause no changes for sigs - assert not self.mninfo[1].node.quorum("sign", 104, id, msgHash, msgHash) + assert not self.mninfo[1].node.quorum("sign", q_type, id, msgHash, msgHash) assert_sigs_nochange(False, False, False, 3) # 2. Providing a valid quorum hash should succeed and cause no changes for sigss - quorumHash = self.mninfo[1].node.quorum("selectquorum", 104, id)["quorumHash"] - assert self.mninfo[1].node.quorum("sign", 104, id, msgHash, quorumHash) + quorumHash = self.mninfo[1].node.quorum("selectquorum", q_type, id)["quorumHash"] + assert self.mninfo[1].node.quorum("sign", q_type, id, msgHash, quorumHash) assert_sigs_nochange(False, False, False, 3) # Sign third share and test optional submit parameter if spork21 is enabled, should result in recovered sig # and conflict for msgHashConflict if self.options.spork21: # 1. Providing an invalid quorum hash and set submit=false, should throw an error - assert_raises_rpc_error(-8, 'quorum not found', self.mninfo[2].node.quorum, "sign", 104, id, msgHash, id, False) + assert_raises_rpc_error(-8, 'quorum not found', self.mninfo[2].node.quorum, "sign", q_type, id, msgHash, id, False) # 2. Providing a valid quorum hash and set submit=false, should return a valid sigShare object - sig_share_rpc_1 = self.mninfo[2].node.quorum("sign", 104, id, msgHash, quorumHash, False) - sig_share_rpc_2 = self.mninfo[2].node.quorum("sign", 104, id, msgHash, "", False) + sig_share_rpc_1 = self.mninfo[2].node.quorum("sign", q_type, id, msgHash, quorumHash, False) + sig_share_rpc_2 = self.mninfo[2].node.quorum("sign", q_type, id, msgHash, "", False) assert_equal(sig_share_rpc_1, sig_share_rpc_2) assert_sigs_nochange(False, False, False, 3) # 3. Sending the sig share received from RPC to the recovery member through P2P interface, should result @@ -93,7 +94,7 @@ def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout): for mn in self.mninfo: assert mn.node.getconnectioncount() == self.llmq_size # Get the current recovery member of the quorum - q = self.nodes[0].quorum('selectquorum', 104, id) + q = self.nodes[0].quorum('selectquorum', q_type, id) mn = self.get_mninfo(q['recoveryMembers'][0]) # Open a P2P connection to it p2p_interface = mn.node.add_p2p_connection(P2PInterface()) @@ -101,7 +102,7 @@ def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout): p2p_interface.send_message(msg_qsigshare([sig_share])) else: # If spork21 is not enabled just sign regularly - self.mninfo[2].node.quorum("sign", 104, id, msgHash) + self.mninfo[2].node.quorum("sign", q_type, id, msgHash) wait_for_sigs(True, False, True, 15) @@ -110,19 +111,19 @@ def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout): # Test `quorum verify` rpc node = self.mninfo[0].node - recsig = node.quorum("getrecsig", 104, id, msgHash) + recsig = node.quorum("getrecsig", q_type, id, msgHash) # Find quorum automatically height = node.getblockcount() height_bad = node.getblockheader(recsig["quorumHash"])["height"] hash_bad = node.getblockhash(0) - assert node.quorum("verify", 104, id, msgHash, recsig["sig"]) - assert node.quorum("verify", 104, id, msgHash, recsig["sig"], "", height) - assert not node.quorum("verify", 104, id, msgHashConflict, recsig["sig"]) - assert not node.quorum("verify", 104, id, msgHash, recsig["sig"], "", height_bad) + assert node.quorum("verify", q_type, id, msgHash, recsig["sig"]) + assert node.quorum("verify", q_type, id, msgHash, recsig["sig"], "", height) + assert not node.quorum("verify", q_type, id, msgHashConflict, recsig["sig"]) + assert not node.quorum("verify", q_type, id, msgHash, recsig["sig"], "", height_bad) # Use specific quorum - assert node.quorum("verify", 104, id, msgHash, recsig["sig"], recsig["quorumHash"]) - assert not node.quorum("verify", 104, id, msgHashConflict, recsig["sig"], recsig["quorumHash"]) - assert_raises_rpc_error(-8, "quorum not found", node.quorum, "verify", 104, id, msgHash, recsig["sig"], hash_bad) + assert node.quorum("verify", q_type, id, msgHash, recsig["sig"], recsig["quorumHash"]) + assert not node.quorum("verify", q_type, id, msgHashConflict, recsig["sig"], recsig["quorumHash"]) + assert_raises_rpc_error(-8, "quorum not found", node.quorum, "verify", q_type, id, msgHash, recsig["sig"], hash_bad) # Mine one more quorum, so that we have 2 active ones, nothing should change self.mine_quorum() @@ -131,10 +132,10 @@ def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout): # Create a recovered sig for the oldest quorum i.e. the active quorum which will be moved # out of the active set when a new quorum appears request_id = 2 - oldest_quorum_hash = node.quorum("list")["llmq_test_instantsend"][-1] + oldest_quorum_hash = node.quorum("list")["llmq_test"][-1] # Search for a request id which selects the last active quorum while True: - selected_hash = node.quorum('selectquorum', 104, uint256_to_string(request_id))["quorumHash"] + selected_hash = node.quorum('selectquorum', q_type, uint256_to_string(request_id))["quorumHash"] if selected_hash == oldest_quorum_hash: break else: @@ -142,12 +143,12 @@ def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout): # Produce the recovered signature id = uint256_to_string(request_id) for mn in self.mninfo: - mn.node.quorum("sign", 104, id, msgHash) + mn.node.quorum("sign", q_type, id, msgHash) # And mine a quorum to move the quorum which signed out of the active set self.mine_quorum() # Verify the recovered sig. This triggers the "signHeight + dkgInterval" verification - recsig = node.quorum("getrecsig", 104, id, msgHash) - assert node.quorum("verify", 104, id, msgHash, recsig["sig"], "", node.getblockcount()) + recsig = node.quorum("getrecsig", q_type, id, msgHash) + assert node.quorum("verify", q_type, id, msgHash, recsig["sig"], "", node.getblockcount()) recsig_time = self.mocktime @@ -166,21 +167,21 @@ def assert_sigs_nochange(hasrecsigs, isconflicting1, isconflicting2, timeout): wait_for_sigs(False, False, False, 15) for i in range(2): - self.mninfo[i].node.quorum("sign", 104, id, msgHashConflict) + self.mninfo[i].node.quorum("sign", q_type, id, msgHashConflict) for i in range(2, 5): - self.mninfo[i].node.quorum("sign", 104, id, msgHash) + self.mninfo[i].node.quorum("sign", q_type, id, msgHash) wait_for_sigs(True, False, True, 15) if self.options.spork21: id = uint256_to_string(request_id + 1) # Isolate the node that is responsible for the recovery of a signature and assert that recovery fails - q = self.nodes[0].quorum('selectquorum', 104, id) + q = self.nodes[0].quorum('selectquorum', q_type, id) mn = self.get_mninfo(q['recoveryMembers'][0]) mn.node.setnetworkactive(False) self.wait_until(lambda: mn.node.getconnectioncount() == 0) for i in range(4): - self.mninfo[i].node.quorum("sign", 104, id, msgHash) + self.mninfo[i].node.quorum("sign", q_type, id, msgHash) assert_sigs_nochange(False, False, False, 3) # Need to re-connect so that it later gets the recovered sig mn.node.setnetworkactive(True) diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py index 8c5c51c511225..9bc6352ed54d0 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -147,7 +147,37 @@ def _test_getblockchaininfo(self): # should have exact keys assert_equal(sorted(res.keys()), keys) - self.restart_node(0, ['-stopatheight=207', '-prune=550', '-txindex=0']) + self.stop_node(0) + self.nodes[0].assert_start_raises_init_error( + extra_args=['-testactivationheight=name@2'], + expected_msg='Error: Invalid name (name@2) for -testactivationheight=name@height.', + ) + self.nodes[0].assert_start_raises_init_error( + extra_args=['-testactivationheight=bip34@-2'], + expected_msg='Error: Invalid height value (bip34@-2) for -testactivationheight=name@height.', + ) + self.nodes[0].assert_start_raises_init_error( + extra_args=['-testactivationheight='], + expected_msg='Error: Invalid format () for -testactivationheight=name@height.', + ) + self.start_node(0, extra_args=[ + '-stopatheight=207', + '-prune=550', + '-txindex=0', + '-testactivationheight=bip34@2', + '-testactivationheight=dersig@3', + '-testactivationheight=cltv@4', + '-testactivationheight=csv@5', + '-testactivationheight=bip147@6', + '-testactivationheight=dip0001@10', + '-dip3params=411:511', + '-testactivationheight=dip0008@12', + '-testactivationheight=dip0024@13', + '-testactivationheight=brr@14', + '-testactivationheight=v20@901', + '-testactivationheight=mn_rr@902', + ]) + res = self.nodes[0].getblockchaininfo() # result should have these additional pruning keys if prune=550 assert_equal(sorted(res.keys()), sorted(['pruneheight', 'automatic_pruning', 'prune_target_size'] + keys)) @@ -159,20 +189,20 @@ def _test_getblockchaininfo(self): 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': 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': True, 'height': 1}, - 'dip0003': { 'type': 'buried', 'active': False, 'height': 432}, - 'dip0008': { 'type': 'buried', 'active': True, 'height': 1}, + 'bip34': {'type': 'buried', 'active': True, 'height': 2}, + 'bip66': {'type': 'buried', 'active': True, 'height': 3}, + 'bip65': {'type': 'buried', 'active': True, 'height': 4}, + 'csv': {'type': 'buried', 'active': True, 'height': 5}, + 'bip147': {'type': 'buried', 'active': True, 'height': 6}, + 'dip0001': { 'type': 'buried', 'active': True, 'height': 10}, + 'dip0003': { 'type': 'buried', 'active': False, 'height': 411}, + 'dip0008': { 'type': 'buried', 'active': True, 'height': 12}, 'dip0020': { 'type': 'buried', 'active': True, 'height': 1}, - 'dip0024': { 'type': 'buried', 'active': False, 'height': 900}, - 'realloc': { 'type': 'buried', 'active': True, 'height': 1}, + 'dip0024': { 'type': 'buried', 'active': True, 'height': 13}, + 'realloc': { 'type': 'buried', 'active': True, 'height': 14}, 'v19': { 'type': 'buried', 'active': False, 'height': 900}, - 'v20': { 'type': 'buried', 'active': False, 'height': 900}, - 'mn_rr': { 'type': 'buried', 'active': False, 'height': 900}, + 'v20': { 'type': 'buried', 'active': False, 'height': 901}, + 'mn_rr': { 'type': 'buried', 'active': False, 'height': 902}, 'testdummy': { 'type': 'bip9', 'bip9': {