From 206962575988c80f9254aa045293bf7a490090ab Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Mon, 16 Sep 2024 14:38:59 +0300 Subject: [PATCH 1/7] fix: calculate expected_complaints correctly --- test/functional/feature_llmq_simplepose.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index 6ca819968a..f3e48ff48e 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -161,6 +161,7 @@ class LLMQSimplePoSeTest(DashTestFramework): for _ in range(2): mn = mninfos_valid.pop() went_offline, instant_ban = invalidate_proc(mn) + expected_complaints = expected_contributors - 1 if went_offline: mninfos_online.remove(mn) expected_contributors -= 1 @@ -169,7 +170,7 @@ class LLMQSimplePoSeTest(DashTestFramework): # so nodes are PoSe-banned in the same DKG they misbehave without being PoSe-punished first. if instant_ban: self.reset_probe_timeouts() - self.mine_quorum(expected_connections=expected_connections, expected_members=expected_contributors, expected_contributions=expected_contributors, expected_complaints=expected_contributors-1, expected_commitments=expected_contributors, mninfos_online=mninfos_online, mninfos_valid=mninfos_valid) + self.mine_quorum(expected_connections=expected_connections, expected_members=expected_contributors, expected_contributions=expected_contributors, expected_complaints=expected_complaints, expected_commitments=expected_contributors, mninfos_online=mninfos_online, mninfos_valid=mninfos_valid) else: # It's ok to miss probes/quorum connections up to 5 times. # 6th time is when it should be banned for sure. From 8597acd0dcd2ee4e6e8476611130879d9ab3dd7e Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 24 Sep 2024 01:19:51 +0300 Subject: [PATCH 2/7] fix: remember mns that don't listen and avoid them --- test/functional/feature_llmq_simplepose.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index f3e48ff48e..d359d41f56 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -23,6 +23,7 @@ class LLMQSimplePoSeTest(DashTestFramework): def run_test(self): + self.deaf_mns = [] self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0) self.wait_for_sporks_same() @@ -45,6 +46,7 @@ class LLMQSimplePoSeTest(DashTestFramework): # Lets restart masternodes with closed ports and verify that they get banned even though they are connected to other MNs (via outbound connections) self.test_banning(self.close_mn_port, 3) + self.deaf_mns.clear() self.repair_masternodes(True) self.reset_probe_timeouts() @@ -61,6 +63,7 @@ class LLMQSimplePoSeTest(DashTestFramework): self.repair_masternodes(True) self.close_mn_port(self.mninfo[0]) + self.deaf_mns.clear() self.test_no_banning(3) def isolate_mn(self, mn): @@ -69,12 +72,13 @@ class LLMQSimplePoSeTest(DashTestFramework): return True, True def close_mn_port(self, mn): + self.deaf_mns.append(mn) self.stop_node(mn.node.index) self.start_masternode(mn, ["-listen=0", "-nobind"]) self.connect_nodes(mn.node.index, 0) # Make sure the to-be-banned node is still connected well via outbound connections for mn2 in self.mninfo: - if mn2 is not mn: + if self.deaf_mns.count(mn2) == 0: self.connect_nodes(mn.node.index, mn2.node.index) self.reset_probe_timeouts() return False, False From 793f4b739f1a44b0408c36980f85e06f607333aa Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Tue, 24 Sep 2024 01:20:54 +0300 Subject: [PATCH 3/7] fix: connect repaired mns only --- test/functional/feature_llmq_simplepose.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index d359d41f56..2ba6543cb1 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -200,7 +200,7 @@ class LLMQSimplePoSeTest(DashTestFramework): self.start_masternode(mn) else: mn.node.setnetworkactive(True) - self.connect_nodes(mn.node.index, 0) + self.connect_nodes(mn.node.index, 0) # syncing blocks only since node 0 has txes waiting to be mined self.sync_blocks() From cce87a662a04844b37fe4963325af5868f66fb0f Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 25 Sep 2024 16:22:33 +0300 Subject: [PATCH 4/7] fix: should have at least 2 connections when testing isolate_mn --- test/functional/feature_llmq_simplepose.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index 2ba6543cb1..d2d5c81ca6 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -31,7 +31,7 @@ class LLMQSimplePoSeTest(DashTestFramework): self.test_no_banning() # Now lets isolate MNs one by one and verify that punishment/banning happens - self.test_banning(self.isolate_mn, 1) + self.test_banning(self.isolate_mn, 2) self.repair_masternodes(False) From fd2fbe06a324ef4e119d7a36432524b5cd2fa438 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 25 Sep 2024 16:18:29 +0300 Subject: [PATCH 5/7] fix: check mn state after each mined quorum --- test/functional/feature_llmq_simplepose.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index d2d5c81ca6..f4cab59429 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -93,8 +93,8 @@ class LLMQSimplePoSeTest(DashTestFramework): def test_no_banning(self, expected_connections=None): for _ in range(3): self.mine_quorum(expected_connections=expected_connections) - for mn in self.mninfo: - assert not self.check_punished(mn) and not self.check_banned(mn) + for mn in self.mninfo: + assert not self.check_punished(mn) and not self.check_banned(mn) def mine_quorum_less_checks(self, expected_good_nodes, mninfos_online): # Unlike in mine_quorum we skip most of the checks and only care about From cedd3d52be677f4c145504c35b919ee8bd109908 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 25 Sep 2024 16:21:15 +0300 Subject: [PATCH 6/7] refactor: make expected_connections optional --- test/functional/feature_llmq_simplepose.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index f4cab59429..44da01d7c0 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -45,7 +45,7 @@ class LLMQSimplePoSeTest(DashTestFramework): self.test_no_banning() # Lets restart masternodes with closed ports and verify that they get banned even though they are connected to other MNs (via outbound connections) - self.test_banning(self.close_mn_port, 3) + self.test_banning(self.close_mn_port) self.deaf_mns.clear() self.repair_masternodes(True) @@ -158,7 +158,7 @@ class LLMQSimplePoSeTest(DashTestFramework): return new_quorum - def test_banning(self, invalidate_proc, expected_connections): + def test_banning(self, invalidate_proc, expected_connections=None): mninfos_online = self.mninfo.copy() mninfos_valid = self.mninfo.copy() expected_contributors = len(mninfos_online) @@ -173,11 +173,13 @@ class LLMQSimplePoSeTest(DashTestFramework): # NOTE: Min PoSe penalty is 100 (see CDeterministicMNList::CalcMaxPoSePenalty()), # so nodes are PoSe-banned in the same DKG they misbehave without being PoSe-punished first. if instant_ban: + assert expected_connections is not None self.reset_probe_timeouts() self.mine_quorum(expected_connections=expected_connections, expected_members=expected_contributors, expected_contributions=expected_contributors, expected_complaints=expected_complaints, expected_commitments=expected_contributors, mninfos_online=mninfos_online, mninfos_valid=mninfos_valid) else: # It's ok to miss probes/quorum connections up to 5 times. # 6th time is when it should be banned for sure. + assert expected_connections is None for _ in range(6): self.reset_probe_timeouts() self.mine_quorum_less_checks(expected_contributors - 1, mninfos_online) From a656d2f14f7f44609787b9ee10ae069a9b8dac97 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 25 Sep 2024 16:17:44 +0300 Subject: [PATCH 7/7] feat: more logging --- test/functional/feature_llmq_simplepose.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/functional/feature_llmq_simplepose.py b/test/functional/feature_llmq_simplepose.py index 44da01d7c0..5a7cb1ea6a 100755 --- a/test/functional/feature_llmq_simplepose.py +++ b/test/functional/feature_llmq_simplepose.py @@ -91,7 +91,8 @@ class LLMQSimplePoSeTest(DashTestFramework): return False, True def test_no_banning(self, expected_connections=None): - for _ in range(3): + for i in range(3): + self.log.info(f"Testing no PoSe banning in normal conditions {i + 1}/3") self.mine_quorum(expected_connections=expected_connections) for mn in self.mninfo: assert not self.check_punished(mn) and not self.check_banned(mn) @@ -162,7 +163,8 @@ class LLMQSimplePoSeTest(DashTestFramework): mninfos_online = self.mninfo.copy() mninfos_valid = self.mninfo.copy() expected_contributors = len(mninfos_online) - for _ in range(2): + for i in range(2): + self.log.info(f"Testing PoSe banning due to {invalidate_proc.__name__} {i + 1}/2") mn = mninfos_valid.pop() went_offline, instant_ban = invalidate_proc(mn) expected_complaints = expected_contributors - 1 @@ -174,13 +176,15 @@ class LLMQSimplePoSeTest(DashTestFramework): # so nodes are PoSe-banned in the same DKG they misbehave without being PoSe-punished first. if instant_ban: assert expected_connections is not None + self.log.info("Expecting instant PoSe banning") self.reset_probe_timeouts() self.mine_quorum(expected_connections=expected_connections, expected_members=expected_contributors, expected_contributions=expected_contributors, expected_complaints=expected_complaints, expected_commitments=expected_contributors, mninfos_online=mninfos_online, mninfos_valid=mninfos_valid) else: # It's ok to miss probes/quorum connections up to 5 times. # 6th time is when it should be banned for sure. assert expected_connections is None - for _ in range(6): + for j in range(6): + self.log.info(f"Accumulating PoSe penalty {j + 1}/6") self.reset_probe_timeouts() self.mine_quorum_less_checks(expected_contributors - 1, mninfos_online) @@ -191,7 +195,7 @@ class LLMQSimplePoSeTest(DashTestFramework): expected_contributors -= 1 def repair_masternodes(self, restart): - # Repair all nodes + self.log.info("Repairing all banned and punished masternodes") for mn in self.mninfo: if self.check_banned(mn) or self.check_punished(mn): addr = self.nodes[0].getnewaddress()