Instead of manually counting expected probes, rely on what dashd expects

And really only check inbound connections for recent probes. Also bump
mocktime by an hour in llmq-simplepose.py.

This fixes flakiness of llmq-simplepose.py.
This commit is contained in:
Alexander Block 2020-04-15 16:18:05 +02:00
parent 6c1262f1c8
commit 6467995178
2 changed files with 46 additions and 28 deletions

View File

@ -32,7 +32,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
def isolate_mn(mn):
mn.node.setnetworkactive(False)
wait_until(lambda: mn.node.getconnectioncount() == 0)
self.test_banning(isolate_mn, False, True, False)
self.test_banning(isolate_mn, True)
self.repair_masternodes(False)
@ -42,7 +42,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
self.reset_probe_timeouts()
# Make sure no banning happens with spork21 enabled
self.test_no_banning(expected_connections=4, expected_probes=4)
self.test_no_banning(expected_connections=4)
# Lets restart masternodes with closed ports and verify that they get banned even though they are connected to other MNs (via outbound connections)
def close_mn_port(mn):
@ -54,7 +54,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
if mn2 is not mn:
connect_nodes(mn.node, mn2.node.index)
self.reset_probe_timeouts()
self.test_banning(close_mn_port, True, False, True)
self.test_banning(close_mn_port, False)
self.repair_masternodes(True)
self.reset_probe_timeouts()
@ -64,15 +64,15 @@ class LLMQSimplePoSeTest(DashTestFramework):
self.start_masternode(mn, ["-pushversion=70216", "-mocktime=%d" % self.mocktime])
connect_nodes(mn.node, 0)
self.reset_probe_timeouts()
self.test_banning(force_old_mn_proto, True, False, False)
self.test_banning(force_old_mn_proto, False)
def test_no_banning(self, expected_connections=1, expected_probes=0):
def test_no_banning(self, expected_connections=1):
for i in range(3):
self.mine_quorum(expected_connections=expected_connections, expected_probes=expected_probes)
self.mine_quorum(expected_connections=expected_connections)
for mn in self.mninfo:
assert(not self.check_punished(mn) and not self.check_banned(mn))
def test_banning(self, invalidate_proc, check_probes, expect_contribution_to_fail, expect_probes_to_fail):
def test_banning(self, invalidate_proc, expect_contribution_to_fail):
online_mninfos = self.mninfo.copy()
for i in range(2):
mn = online_mninfos[len(online_mninfos) - 1]
@ -81,15 +81,12 @@ class LLMQSimplePoSeTest(DashTestFramework):
t = time.time()
while (not self.check_punished(mn) or not self.check_banned(mn)) and (time.time() - t) < 120:
expected_probes = 0
expected_contributors = len(online_mninfos) + 1
if check_probes:
expected_probes = len(online_mninfos)
if expect_probes_to_fail:
expected_probes -= 1
if expect_contribution_to_fail:
expected_contributors -= 1
self.mine_quorum(expected_connections=1, expected_probes=expected_probes, expected_members=len(online_mninfos), expected_contributions=expected_contributors, expected_complaints=expected_contributors-1, expected_commitments=expected_contributors, mninfos=online_mninfos)
# Make sure we do fresh probes
self.bump_mocktime(60 * 60)
self.mine_quorum(expected_connections=1, expected_members=len(online_mninfos), expected_contributions=expected_contributors, expected_complaints=expected_contributors-1, expected_commitments=expected_contributors, mninfos=online_mninfos)
assert(self.check_punished(mn) and self.check_banned(mn))

View File

@ -807,19 +807,39 @@ class DashTestFramework(BitcoinTestFramework):
return all_ok
wait_until(check_quorum_connections, timeout=timeout, sleep=1)
def wait_for_masternode_probes(self, expected_probes, mninfos, timeout = 30, wait_proc=None):
def wait_for_masternode_probes(self, mninfos, timeout = 30, wait_proc=None):
def check_probes():
def ret():
if wait_proc is not None:
wait_proc()
return False
for mn in mninfos:
l = mn.node.protx('list', 'registered', 1)
cnt = 0
for mn2 in l:
if mn2['proTxHash'] != mn.proTxHash:
if mn2['metaInfo']['lastOutboundSuccessElapsed'] <= 60:
cnt += 1
if cnt < expected_probes:
if wait_proc is not None:
wait_proc()
return False
s = mn.node.quorum('dkgstatus')
if s["session"] == {}:
continue
if "quorumConnections" not in s:
return ret()
s = s["quorumConnections"]
if "llmq_test" not in s:
return ret()
for c in s["llmq_test"]:
if c["proTxHash"] == mn.proTxHash:
continue
if not c["outbound"]:
mn2 = mn.node.protx('info', c["proTxHash"])
if [m for m in mninfos if c["proTxHash"] == m.proTxHash]:
# MN is expected to be online and functioning, so let's verify that the last successful
# probe is not too old. Probes are retried after 50 minutes, while DKGs consider a probe
# as failed after 60 minutes
if mn2['metaInfo']['lastOutboundSuccessElapsed'] > 55 * 60:
return ret()
else:
# MN is expected to be offline, so let's only check that the last probe is not too long ago
if mn2['metaInfo']['lastOutboundAttemptElapsed'] > 55 * 60 and mn2['metaInfo']['lastOutboundSuccessElapsed'] > 55 * 60:
return ret()
return True
wait_until(check_probes, timeout=timeout, sleep=1)
@ -870,7 +890,7 @@ class DashTestFramework(BitcoinTestFramework):
return all_ok
wait_until(check_dkg_comitments, timeout=timeout, sleep=0.1)
def mine_quorum(self, expected_members=None, expected_connections=2, expected_probes=0, expected_contributions=None, expected_complaints=0, expected_justifications=0, expected_commitments=None, mninfos=None):
def mine_quorum(self, expected_members=None, expected_connections=2, expected_contributions=None, expected_complaints=0, expected_justifications=0, expected_commitments=None, mninfos=None):
if expected_members is None:
expected_members = self.llmq_size
if expected_contributions is None:
@ -880,8 +900,8 @@ class DashTestFramework(BitcoinTestFramework):
if mninfos is None:
mninfos = self.mninfo
self.log.info("Mining quorum: expected_members=%d, expected_connections=%d, expected_probes=%d, expected_contributions=%d, expected_complaints=%d, expected_justifications=%d, "
"expected_commitments=%d" % (expected_members, expected_connections, expected_probes, expected_contributions, expected_complaints,
self.log.info("Mining quorum: expected_members=%d, expected_connections=%d, expected_contributions=%d, expected_complaints=%d, expected_justifications=%d, "
"expected_commitments=%d" % (expected_members, expected_connections, expected_contributions, expected_complaints,
expected_justifications, expected_commitments))
nodes = [self.nodes[0]] + [mn.node for mn in mninfos]
@ -900,7 +920,8 @@ class DashTestFramework(BitcoinTestFramework):
self.log.info("Waiting for phase 1 (init)")
self.wait_for_quorum_phase(q, 1, expected_members, None, 0, mninfos)
self.wait_for_quorum_connections(expected_connections, nodes, wait_proc=lambda: self.bump_mocktime(1, nodes=nodes))
self.wait_for_masternode_probes(expected_probes, mninfos, wait_proc=lambda: self.bump_mocktime(1, nodes=nodes))
if self.nodes[0].spork('show')['SPORK_21_QUORUM_ALL_CONNECTED'] == 0:
self.wait_for_masternode_probes(mninfos, wait_proc=lambda: self.bump_mocktime(1, nodes=nodes))
self.bump_mocktime(1, nodes=nodes)
self.nodes[0].generate(2)
sync_blocks(nodes)