Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_feature_proof_cleanup.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2022 The Bitcoin developers | # Copyright (c) 2022 The Bitcoin developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
""" | """ | ||||
Test the dangling proofs cleanup | Test the dangling proofs cleanup | ||||
""" | """ | ||||
import time | import time | ||||
from test_framework.avatools import ( | from test_framework.avatools import ( | ||||
gen_proof, | gen_proof, | ||||
get_ava_p2p_interface, | get_ava_p2p_interface, | ||||
get_proof_ids, | get_proof_ids, | ||||
) | ) | ||||
from test_framework.key import ECKey | |||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import assert_equal | from test_framework.util import assert_equal | ||||
from test_framework.wallet_util import bytes_to_wif | |||||
# Interval between 2 proof cleanups | # Interval between 2 proof cleanups | ||||
AVALANCHE_CLEANUP_INTERVAL = 5 * 60 | AVALANCHE_CLEANUP_INTERVAL = 5 * 60 | ||||
# Dangling proof timeout | # Dangling proof timeout | ||||
AVALANCHE_DANGLING_PROOF_TIMEOUT = 15 * 60 | AVALANCHE_DANGLING_PROOF_TIMEOUT = 15 * 60 | ||||
class ProofsCleanupTest(BitcoinTestFramework): | class ProofsCleanupTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
self.extra_args = [[ | self.extra_args = [[ | ||||
'-enableavalanche=1', | '-enableavalanche=1', | ||||
'-avaproofstakeutxoconfirmations=1', | '-avaproofstakeutxoconfirmations=1', | ||||
'-enableavalanchepeerdiscovery=1', | |||||
# Get rid of the getdata delay penalty for inbounds | |||||
'-whitelist=noban@127.0.0.1', | |||||
]] * self.num_nodes | ]] * self.num_nodes | ||||
def run_test(self): | def run_test(self): | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
mocktime = int(time.time()) | mocktime = int(time.time()) | ||||
node.setmocktime(mocktime) | node.setmocktime(mocktime) | ||||
proofs = [] | proofs = [] | ||||
keys = [] | |||||
peers = [] | peers = [] | ||||
# The first 5 peers have a node attached | # The first 5 peers have a node attached | ||||
for _ in range(5): | for _ in range(5): | ||||
key, proof = gen_proof(node) | key, proof = gen_proof(node) | ||||
peer = get_ava_p2p_interface(node) | peer = get_ava_p2p_interface(node) | ||||
node.addavalanchenode( | node.addavalanchenode( | ||||
peer.nodeid, | peer.nodeid, | ||||
key.get_pubkey().get_bytes().hex(), | key.get_pubkey().get_bytes().hex(), | ||||
proof.serialize().hex()) | proof.serialize().hex()) | ||||
proofs.append(proof) | proofs.append(proof) | ||||
keys.append(key) | |||||
peers.append(peer) | peers.append(peer) | ||||
# The last 5 peers have no node attached | # The last 5 peers have no node attached | ||||
for _ in range(5): | for _ in range(5): | ||||
_, proof = gen_proof(node) | _, proof = gen_proof(node) | ||||
node.sendavalancheproof(proof.serialize().hex()) | node.sendavalancheproof(proof.serialize().hex()) | ||||
proofs.append(proof) | proofs.append(proof) | ||||
Show All 26 Lines | def run_test(self): | ||||
for peer in peers: | for peer in peers: | ||||
peer.peer_disconnect() | peer.peer_disconnect() | ||||
peer.wait_for_disconnect() | peer.wait_for_disconnect() | ||||
node.mockscheduler(AVALANCHE_CLEANUP_INTERVAL) | node.mockscheduler(AVALANCHE_CLEANUP_INTERVAL) | ||||
self.wait_until(lambda: get_proof_ids(node) == []) | self.wait_until(lambda: get_proof_ids(node) == []) | ||||
self.log.info("Check the cleaned up proofs are no longer accepted...") | |||||
sender = get_ava_p2p_interface(node) | |||||
for proof in proofs: | |||||
with node.assert_debug_log(["dangling-proof"]): | |||||
sender.send_avaproof(proof) | |||||
assert_equal(get_proof_ids(node), []) | |||||
self.log.info("...until there is a node to attach") | |||||
node.disconnect_p2ps() | |||||
assert_equal(len(node.p2ps), 0) | |||||
avanode = get_ava_p2p_interface(node) | |||||
avanode_key = keys[0] | |||||
avanode_proof = proofs[0] | |||||
delegated_key = ECKey() | |||||
delegated_key.generate() | |||||
delegation = node.delegateavalancheproof( | |||||
f"{avanode_proof.limited_proofid:064x}", | |||||
bytes_to_wif(avanode_key.get_bytes()), | |||||
delegated_key.get_pubkey().get_bytes().hex(), | |||||
) | |||||
avanode.send_avahello(delegation, delegated_key) | |||||
avanode.sync_with_ping() | |||||
avanode.wait_until(lambda: avanode.last_message.get( | |||||
"getdata") and avanode.last_message["getdata"].inv[-1].hash == avanode_proof.proofid) | |||||
avanode.send_avaproof(avanode_proof) | |||||
self.wait_until(lambda: avanode_proof.proofid in get_proof_ids(node)) | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
ProofsCleanupTest().main() | ProofsCleanupTest().main() |