diff --git a/test/functional/feature_asset_locks.py b/test/functional/feature_asset_locks.py index fea54f4fa6b0..5a312167f2eb 100755 --- a/test/functional/feature_asset_locks.py +++ b/test/functional/feature_asset_locks.py @@ -624,7 +624,7 @@ def test_withdrawal_limits(self, node_wallet, node, pubkey): def test_mn_rr(self, node_wallet, node, pubkey): self.log.info("Activate mn_rr...") locked = self.get_credit_pool_balance() - self.activate_mn_rr(expected_activation_height=560) + self.activate_mn_rr() self.log.info(f'mn-rr height: {node.getblockcount()} credit: {self.get_credit_pool_balance()}') assert_equal(locked, self.get_credit_pool_balance()) diff --git a/test/functional/feature_llmq_chainlocks.py b/test/functional/feature_llmq_chainlocks.py index b96ab4cfaef3..ea070fb6e867 100755 --- a/test/functional/feature_llmq_chainlocks.py +++ b/test/functional/feature_llmq_chainlocks.py @@ -16,12 +16,22 @@ from test_framework.test_framework import DashTestFramework from test_framework.util import assert_equal, assert_raises_rpc_error, force_finish_mnsync +import time class LLMQChainLocksTest(DashTestFramework): def set_test_params(self): self.set_dash_test_params(5, 4) self.delay_v20_and_mn_rr(height=200) + def sleep_and_assert_no_cl(self, block_hash, sleep_time=5): + time.sleep(sleep_time) + + for node in self.nodes: + self.log.info(f"Expecting no ChainLock for {block_hash}") + block = node.getblock(block_hash) + #assert_equal(block["confirmations"], 0) + assert not block["chainlock"] + def run_test(self): # Connect all nodes to node1 so that we always have the whole network connected # Otherwise only masternode connections will be established between nodes, which won't propagate TXs/blocks @@ -84,7 +94,7 @@ def run_test(self): previous_block_hash = self.nodes[0].getbestblockhash() for _ in range(2): block_hash = self.generate(self.nodes[0], 1, sync_fun=self.no_op)[0] - self.wait_for_chainlocked_block_all_nodes(block_hash, timeout=5, expected=False) + self.sleep_and_assert_no_cl(block_hash) assert self.nodes[0].getblock(previous_block_hash)["chainlock"] self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 0) diff --git a/test/functional/feature_llmq_evo.py b/test/functional/feature_llmq_evo.py index bc272ee693eb..d4551f3ce8fc 100755 --- a/test/functional/feature_llmq_evo.py +++ b/test/functional/feature_llmq_evo.py @@ -49,9 +49,9 @@ def getmnlistdiff(self, baseBlockHash, blockHash): class LLMQEvoNodesTest(DashTestFramework): def set_test_params(self): - self.set_dash_test_params(5, 4, evo_count=5) - self.set_dash_llmq_test_params(4, 4) - self.mn_rr_height = 400 + # we just need a couple of regular nodes to be ensured that they are not included in platform quorum, 2 is enough + self.set_dash_test_params(3, 2, evo_count=4) + self.mn_rr_height = 320 def run_test(self): # Connect all nodes to node1 so that we always have the whole network connected @@ -62,18 +62,12 @@ def run_test(self): null_hash = format(0, "064x") self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0) - self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 1) - self.wait_for_sporks_same() expectedUpdated = [mn.proTxHash for mn in self.mninfo] b_0 = self.nodes[0].getbestblockhash() self.test_getmnlistdiff(null_hash, b_0, {}, [], expectedUpdated) - self.test_masternode_count(expected_mns_count=4, expected_evo_count=0) - - self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 0) - self.wait_for_sporks_same() - + self.test_masternode_count(expected_mns_count=2, expected_evo_count=0) evo_protxhash_list = list() for i in range(self.evo_count): evo_info: MasternodeInfo = self.dynamically_add_masternode(evo=True) @@ -84,7 +78,7 @@ def run_test(self): b_i = self.nodes[0].getbestblockhash() self.test_getmnlistdiff(null_hash, b_i, {}, [], expectedUpdated) - self.test_masternode_count(expected_mns_count=4, expected_evo_count=i+1) + self.test_masternode_count(expected_mns_count=2, expected_evo_count=i+1) self.dynamically_evo_update_service(evo_info) self.log.info("Test llmq_platform are formed only with EvoNodes") @@ -100,7 +94,7 @@ def run_test(self): self.test_masternode_winners() self.activate_mn_rr() - self.log.info("Activated MN RewardReallocation, current height:" + str(self.nodes[0].getblockcount())) + self.log.info(f"Activated MN RewardReallocation, current height: {self.nodes[0].getblockcount()}") # Generate a few blocks to make EvoNode/MN analysis on a pure MN RewardReallocation window self.bump_mocktime(1) @@ -110,10 +104,6 @@ def run_test(self): self.test_evo_payments(window_analysis=48, mnrr_active=True) self.test_masternode_winners(mn_rr_active=True) - self.log.info(self.nodes[0].masternodelist()) - - return - def test_evo_payments(self, window_analysis, mnrr_active): current_evo: MasternodeInfo = None consecutive_payments = 0 @@ -183,13 +173,21 @@ def test_quorum_members_are_evo_nodes(self, quorum_hash, llmq_type): def test_evo_protx_are_in_mnlist(self, evo_protx_list): mn_list = self.nodes[0].masternodelist() + mn_list_evo = self.nodes[0].masternodelist(mode="evo") for evo_protx in evo_protx_list: - found = False - for mn in mn_list: - if mn_list.get(mn)['proTxHash'] == evo_protx: - found = True - assert_equal(mn_list.get(mn)['type'], "Evo") - assert_equal(found, True) + found_in_mns = False + for _, mn in mn_list.items(): + if mn['proTxHash'] == evo_protx: + found_in_mns = True + assert_equal(mn['type'], "Evo") + assert_equal(found_in_mns, True) + + found_in_evos = False + for _, mn in mn_list_evo.items(): + assert_equal(mn['type'], "Evo") + if mn['proTxHash'] == evo_protx: + found_in_evos = True + assert_equal(found_in_evos, True) def test_masternode_count(self, expected_mns_count, expected_evo_count): mn_count = self.nodes[0].masternode('count') diff --git a/test/functional/feature_llmq_rotation.py b/test/functional/feature_llmq_rotation.py index 7b5790a04fd8..8ae7d7cddbba 100755 --- a/test/functional/feature_llmq_rotation.py +++ b/test/functional/feature_llmq_rotation.py @@ -51,9 +51,9 @@ def getmnlistdiff(self, baseBlockHash, blockHash): class LLMQQuorumRotationTest(DashTestFramework): def set_test_params(self): - self.set_dash_test_params(9, 8) + self.set_dash_test_params(9, 8, extra_args=[["-vbparams=testdummy:999999999999:999999999999"]] * 9) self.set_dash_llmq_test_params(4, 4) - self.delay_v20_and_mn_rr(height=900) + self.delay_v20_and_mn_rr(height=300) def run_test(self): llmq_type=103 @@ -106,14 +106,8 @@ def run_test(self): expectedNew = [h_100_0, h_100_1] quorumList = self.test_getmnlistdiff_quorums(b_h_0, b_h_1, {}, expectedDeleted, expectedNew, testQuorumsCLSigs=False) - projected_activation_height = 900 - - self.activate_v20(expected_activation_height=900) - self.log.info("Activated v20 at height:" + str(self.nodes[0].getblockcount())) - - softfork_info = self.nodes[0].getblockchaininfo()['softforks']['v20'] - assert_equal(softfork_info['active'], True) - assert_equal(projected_activation_height, softfork_info['height']) + self.activate_v20(expected_activation_height=self.mn_rr_height) + self.log.info(f"Activated v20 at height: {self.nodes[0].getblockcount()}") # v20 is active for the next block, not for the tip self.generate(self.nodes[0], 1) @@ -161,13 +155,12 @@ def run_test(self): self.log.info("Quorum #0_1 members: " + str(quorum_members_0_1)) q_100_0 = QuorumId(100, int(quorum_info_0_0["quorumHash"], 16)) - q_102_0 = QuorumId(102, int(quorum_info_0_0["quorumHash"], 16)) q_103_0_0 = QuorumId(103, int(quorum_info_0_0["quorumHash"], 16)) q_103_0_1 = QuorumId(103, int(quorum_info_0_1["quorumHash"], 16)) b_1 = self.nodes[0].getbestblockhash() expectedDeleted = [h_100_0] - expectedNew = [q_100_0, q_102_0, q_103_0_0, q_103_0_1] + expectedNew = [q_100_0, q_103_0_0, q_103_0_1] quorumList = self.test_getmnlistdiff_quorums(b_0, b_1, quorumList, expectedDeleted, expectedNew) self.log.info("Wait for chainlock") @@ -183,13 +176,12 @@ def run_test(self): self.log.info("Quorum #1_1 members: " + str(quorum_members_1_1)) q_100_1 = QuorumId(100, int(quorum_info_1_0["quorumHash"], 16)) - q_102_1 = QuorumId(102, int(quorum_info_1_0["quorumHash"], 16)) q_103_1_0 = QuorumId(103, int(quorum_info_1_0["quorumHash"], 16)) q_103_1_1 = QuorumId(103, int(quorum_info_1_1["quorumHash"], 16)) b_2 = self.nodes[0].getbestblockhash() expectedDeleted = [h_100_1, q_103_0_0, q_103_0_1] - expectedNew = [q_100_1, q_102_1, q_103_1_0, q_103_1_1] + expectedNew = [q_100_1, q_103_1_0, q_103_1_1] quorumList = self.test_getmnlistdiff_quorums(b_1, b_2, quorumList, expectedDeleted, expectedNew) mninfos_online = self.mninfo.copy() @@ -374,7 +366,6 @@ def compute_mn_score(self, mn, modifier): def get_llmq_size(self, llmq_type): return { 100: 4, # In this test size for llmqType 100 is overwritten to 4 - 102: 3, 103: 4, 106: 3 }.get(llmq_type, -1) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index db886de61a68..66976e4beb2e 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -1578,8 +1578,8 @@ def activate_by_name(self, name, expected_activation_height=None, slow_mode=True def activate_v20(self, expected_activation_height=None): self.activate_by_name('v20', expected_activation_height) - def activate_mn_rr(self, expected_activation_height=None): - self.activate_by_name('mn_rr', expected_activation_height) + def activate_mn_rr(self): + self.activate_by_name('mn_rr', self.mn_rr_height) def set_dash_llmq_test_params(self, llmq_size, llmq_threshold): self.llmq_size = llmq_size @@ -1953,9 +1953,9 @@ def check_chainlocked_block(): if self.wait_until(check_chainlocked_block, timeout=timeout, do_assert=expected) and not expected: raise AssertionError("waiting unexpectedly succeeded") - def wait_for_chainlocked_block_all_nodes(self, block_hash, timeout=15, expected=True): + def wait_for_chainlocked_block_all_nodes(self, block_hash, timeout=15): for node in self.nodes: - self.wait_for_chainlocked_block(node, block_hash, expected=expected, timeout=timeout) + self.wait_for_chainlocked_block(node, block_hash, timeout=timeout) def wait_for_best_chainlock(self, node, block_hash, timeout=15): self.wait_until(lambda: node.getbestchainlock()["blockhash"] == block_hash, timeout=timeout) @@ -2309,13 +2309,16 @@ def mine_cycle_quorum(self, is_first=True): self.log.info("New quorum: height=%d, quorumHash=%s, quorumIndex=%d, minedBlock=%s" % (quorum_info_0["height"], q_0, quorum_info_0["quorumIndex"], quorum_info_0["minedBlock"])) self.log.info("New quorum: height=%d, quorumHash=%s, quorumIndex=%d, minedBlock=%s" % (quorum_info_1["height"], q_1, quorum_info_1["quorumIndex"], quorum_info_1["minedBlock"])) - self.log.info("quorum_info_0:"+str(quorum_info_0)) - self.log.info("quorum_info_1:"+str(quorum_info_1)) + extra_debug_rotation_info = False + if extra_debug_rotation_info: + # these logs are useful to debug quorum rotation but it is not usefull for all other cases + self.log.info("quorum_info_0:"+str(quorum_info_0)) + self.log.info("quorum_info_1:"+str(quorum_info_1)) - best_block_hash = self.nodes[0].getbestblockhash() - block_height = self.nodes[0].getblockcount() - quorum_rotation_info = self.nodes[0].quorum("rotationinfo", best_block_hash) - self.log.info("h("+str(block_height)+"):"+str(quorum_rotation_info)) + best_block_hash = self.nodes[0].getbestblockhash() + block_height = self.nodes[0].getblockcount() + quorum_rotation_info = self.nodes[0].quorum("rotationinfo", best_block_hash) + self.log.info("h("+str(block_height)+"):"+str(quorum_rotation_info)) return (quorum_info_0, quorum_info_1)