Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_p2p_avalanche_voting.py
Show First 20 Lines • Show All 212 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
can_find_block_in_poll(hash_to_find, AvalancheVoteError.PARKED) | can_find_block_in_poll(hash_to_find, AvalancheVoteError.PARKED) | ||||
return node.getbestblockhash() == fork_tip | return node.getbestblockhash() == fork_tip | ||||
# Because everybody answers no, the node will park that block. | # Because everybody answers no, the node will park that block. | ||||
with node.assert_debug_log([f"Avalanche invalidated block {hash_to_find:0{64}x}"]): | with node.assert_debug_log([f"Avalanche invalidated block {hash_to_find:0{64}x}"]): | ||||
self.wait_until(has_parked_new_tip, timeout=15) | self.wait_until(has_parked_new_tip, timeout=15) | ||||
assert_equal(node.getbestblockhash(), fork_tip) | assert_equal(node.getbestblockhash(), fork_tip) | ||||
# Trigger polling again | |||||
fork_node.generatetoaddress(2, fork_address) | |||||
fork_tip = fork_node.getbestblockhash() | |||||
self.wait_until(lambda: parked_block(fork_tip), timeout=15) | |||||
def reciprocate_poll(hash_to_find, pollResponse, expected): | |||||
can_find_block_in_poll(hash_to_find, resp=pollResponse) | |||||
poll_node.send_poll([hash_to_find]) | |||||
response = poll_node.wait_for_avaresponse() | |||||
r = response.response | |||||
return repr(r.votes[0]) == repr( | |||||
AvalancheVote(expected, hash_to_find)) | |||||
hash_to_find = int(fork_tip, 16) | |||||
self.wait_until( | |||||
lambda: reciprocate_poll( | |||||
hash_to_find, | |||||
AvalancheVoteError.UNKNOWN, | |||||
AvalancheVoteError.INCONCLUSIVE), | |||||
timeout=30) | |||||
# Wait until the block becomes invalidated due to inconclusive voting | |||||
with node.assert_debug_log([f"Avalanche invalidated block {hash_to_find:0{64}x}"]): | |||||
self.wait_until( | |||||
lambda: not can_find_block_in_poll( | |||||
hash_to_find, | |||||
resp=AvalancheVoteError.INCONCLUSIVE), | |||||
timeout=15) | |||||
# Trigger polling again | |||||
fork_node.generatetoaddress(2, fork_address) | |||||
fork_tip = fork_node.getbestblockhash() | |||||
self.wait_until(lambda: parked_block(fork_tip), timeout=15) | |||||
hash_to_find = int(fork_tip, 16) | |||||
self.wait_until( | |||||
lambda: reciprocate_poll( | |||||
hash_to_find, | |||||
AvalancheVoteError.UNKNOWN, | |||||
AvalancheVoteError.INCONCLUSIVE), | |||||
timeout=30) | |||||
# Wait until the block becomes finalized, despite node being | |||||
# inconclusive | |||||
with node.assert_debug_log([f"Avalanche finalized block {hash_to_find:0{64}x}"]): | |||||
self.wait_until( | |||||
lambda: not can_find_block_in_poll( | |||||
hash_to_find, | |||||
resp=AvalancheVoteError.ACCEPTED), | |||||
timeout=15) | |||||
self.log.info( | self.log.info( | ||||
"Check the node is discouraging unexpected avaresponses.") | "Check the node is discouraging unexpected avaresponses.") | ||||
with node.assert_debug_log( | with node.assert_debug_log( | ||||
['Misbehaving', 'peer=1 (0 -> 2): unexpected-ava-response']): | ['Misbehaving', 'peer=1 (0 -> 2): unexpected-ava-response']): | ||||
# unknown voting round | # unknown voting round | ||||
poll_node.send_avaresponse( | poll_node.send_avaresponse( | ||||
round=2**32 - 1, votes=[], privkey=privkey) | round=2**32 - 1, votes=[], privkey=privkey) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
AvalancheTest().main() | AvalancheTest().main() |