diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 5f05fc0262..671e08e4b1 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -794,7 +794,7 @@ public: consensus.DIP0008Height = 1; // Always active unless overridden consensus.BRRHeight = 1; // Always active unless overridden consensus.DIP0020Height = 1; // Always active unless overridden - consensus.DIP0024QuorumsHeight = 900; + consensus.DIP0024QuorumsHeight = 1; // Always have dip0024 quorums unless overridden consensus.V19Height = 900; consensus.V20Height = 900; consensus.MN_RRHeight = 900; @@ -1025,6 +1025,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") { diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp index 755025c17e..1a05491f06 100644 --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -20,7 +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("-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/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 25b355ef71..b97546f767 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -354,9 +354,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_dip4_coinbasemerkleroots.py b/test/functional/feature_dip4_coinbasemerkleroots.py index d8e05cb2e0..920633c08b 100755 --- a/test/functional/feature_dip4_coinbasemerkleroots.py +++ b/test/functional/feature_dip4_coinbasemerkleroots.py @@ -18,6 +18,7 @@ from test_framework.test_framework import DashTestFramework 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 @@ class TestP2PConn(P2PInterface): 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 remove_masternode(self, idx): diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index 233f39d495..1d4141c436 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -81,11 +81,9 @@ class LLMQQuorumRotationTest(DashTestFramework): 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 @@ class LLMQQuorumRotationTest(DashTestFramework): 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 @@ class LLMQQuorumRotationTest(DashTestFramework): 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 082bfe7e83..11bda6dbfa 100755 --- a/test/functional/feature_llmq_signing.py +++ b/test/functional/feature_llmq_signing.py @@ -16,6 +16,7 @@ from test_framework.test_framework import DashTestFramework from test_framework.util import assert_equal, assert_raises_rpc_error, force_finish_mnsync +q_type=100 class LLMQSigningTest(DashTestFramework): def set_test_params(self): self.set_dash_test_params(6, 5) @@ -43,11 +44,11 @@ class LLMQSigningTest(DashTestFramework): 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 @@ class LLMQSigningTest(DashTestFramework): 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 @@ class LLMQSigningTest(DashTestFramework): 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 @@ class LLMQSigningTest(DashTestFramework): 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 @@ class LLMQSigningTest(DashTestFramework): # 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 @@ class LLMQSigningTest(DashTestFramework): # 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 @@ class LLMQSigningTest(DashTestFramework): # 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 @@ class LLMQSigningTest(DashTestFramework): 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 38eb7a7fb0..287641142d 100755 --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -168,7 +168,7 @@ class BlockchainTest(BitcoinTestFramework): 'dip0003': { 'type': 'buried', 'active': False, 'height': 432}, 'dip0008': { 'type': 'buried', 'active': True, 'height': 1}, 'dip0020': { 'type': 'buried', 'active': True, 'height': 1}, - 'dip0024': { 'type': 'buried', 'active': False, 'height': 900}, + 'dip0024': { 'type': 'buried', 'active': True, 'height': 1}, 'realloc': { 'type': 'buried', 'active': True, 'height': 1}, 'v19': { 'type': 'buried', 'active': False, 'height': 900}, 'v20': { 'type': 'buried', 'active': False, 'height': 900},