Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_p2p_proof_inventory.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2021 The Bitcoin developers | # Copyright (c) 2021 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 proof inventory relaying | Test proof inventory relaying | ||||
""" | """ | ||||
from test_framework.avatools import ( | from test_framework.avatools import ( | ||||
create_coinbase_stakes, | gen_proof, | ||||
get_proof_ids, | get_proof_ids, | ||||
wait_for_proof, | wait_for_proof, | ||||
) | ) | ||||
from test_framework.address import ADDRESS_ECREG_UNSPENDABLE | from test_framework.address import ADDRESS_ECREG_UNSPENDABLE | ||||
from test_framework.key import ECKey | from test_framework.key import ECKey | ||||
from test_framework.messages import ( | from test_framework.messages import ( | ||||
AvalancheProof, | AvalancheProof, | ||||
CInv, | CInv, | ||||
Show All 36 Lines | |||||
class ProofInventoryTest(BitcoinTestFramework): | class ProofInventoryTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 5 | self.num_nodes = 5 | ||||
self.extra_args = [['-enableavalanche=1', | self.extra_args = [['-enableavalanche=1', | ||||
'-avacooldown=0']] * self.num_nodes | '-avacooldown=0']] * self.num_nodes | ||||
def gen_proof(self, node): | |||||
blockhashes = node.generate(10) | |||||
privkey = ECKey() | |||||
privkey.generate() | |||||
pubkey = privkey.get_pubkey() | |||||
stakes = create_coinbase_stakes( | |||||
node, blockhashes, node.get_deterministic_priv_key().key) | |||||
proof_hex = node.buildavalancheproof( | |||||
42, 2000000000, pubkey.get_bytes().hex(), stakes) | |||||
return bytes_to_wif(privkey.get_bytes()), FromHex( | |||||
AvalancheProof(), proof_hex) | |||||
def test_send_proof_inv(self): | def test_send_proof_inv(self): | ||||
self.log.info("Test sending a proof to our peers") | self.log.info("Test sending a proof to our peers") | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
for i in range(10): | for i in range(10): | ||||
node.add_p2p_connection(ProofInvStoreP2PInterface()) | node.add_p2p_connection(ProofInvStoreP2PInterface()) | ||||
_, proof = self.gen_proof(node) | _, proof = gen_proof(node) | ||||
assert node.sendavalancheproof(proof.serialize().hex()) | assert node.sendavalancheproof(proof.serialize().hex()) | ||||
def proof_inv_found(peer): | def proof_inv_found(peer): | ||||
with p2p_lock: | with p2p_lock: | ||||
return peer.last_message.get( | return peer.last_message.get( | ||||
"inv") and peer.last_message["inv"].inv[-1].hash == proof.proofid | "inv") and peer.last_message["inv"].inv[-1].hash == proof.proofid | ||||
wait_until(lambda: all(proof_inv_found(i) for i in node.p2ps)) | wait_until(lambda: all(proof_inv_found(i) for i in node.p2ps)) | ||||
Show All 16 Lines | def test_send_proof_inv(self): | ||||
peer.sync_with_ping() | peer.sync_with_ping() | ||||
assert all(p.proof_invs_counter == 1 for p in node.p2ps) | assert all(p.proof_invs_counter == 1 for p in node.p2ps) | ||||
def test_receive_proof(self): | def test_receive_proof(self): | ||||
self.log.info("Test a peer is created on proof reception") | self.log.info("Test a peer is created on proof reception") | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
_, proof = self.gen_proof(node) | _, proof = gen_proof(node) | ||||
peer = node.add_p2p_connection(P2PInterface()) | peer = node.add_p2p_connection(P2PInterface()) | ||||
msg = msg_avaproof() | msg = msg_avaproof() | ||||
msg.proof = proof | msg.proof = proof | ||||
peer.send_message(msg) | peer.send_message(msg) | ||||
wait_until(lambda: proof.proofid in get_proof_ids(node)) | wait_until(lambda: proof.proofid in get_proof_ids(node)) | ||||
Show All 19 Lines | def test_receive_proof(self): | ||||
msg = msg_avaproof() | msg = msg_avaproof() | ||||
msg.proof = orphan | msg.proof = orphan | ||||
peer.send_message(msg) | peer.send_message(msg) | ||||
wait_for_proof(node, orphan_proofid, expect_orphan=True) | wait_for_proof(node, orphan_proofid, expect_orphan=True) | ||||
def test_ban_invalid_proof(self): | def test_ban_invalid_proof(self): | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
_, bad_proof = self.gen_proof(node) | _, bad_proof = gen_proof(node) | ||||
bad_proof.stakes = [] | bad_proof.stakes = [] | ||||
peer = node.add_p2p_connection(P2PInterface()) | peer = node.add_p2p_connection(P2PInterface()) | ||||
msg = msg_avaproof() | msg = msg_avaproof() | ||||
msg.proof = bad_proof | msg.proof = bad_proof | ||||
with node.assert_debug_log([ | with node.assert_debug_log([ | ||||
'Misbehaving', | 'Misbehaving', | ||||
'invalid-avaproof', | 'invalid-avaproof', | ||||
]): | ]): | ||||
peer.send_message(msg) | peer.send_message(msg) | ||||
peer.wait_for_disconnect() | peer.wait_for_disconnect() | ||||
def test_proof_relay(self): | def test_proof_relay(self): | ||||
# This test makes no sense with a single node ! | # This test makes no sense with a single node ! | ||||
assert_greater_than(self.num_nodes, 1) | assert_greater_than(self.num_nodes, 1) | ||||
def restart_nodes_with_proof(nodes=self.nodes): | def restart_nodes_with_proof(nodes=self.nodes): | ||||
proofids = set() | proofids = set() | ||||
for i, node in enumerate(nodes): | for i, node in enumerate(nodes): | ||||
privkey, proof = self.gen_proof(node) | privkey, proof = gen_proof(node) | ||||
proofids.add(proof.proofid) | proofids.add(proof.proofid) | ||||
self.restart_node(node.index, self.extra_args[node.index] + [ | self.restart_node(node.index, self.extra_args[node.index] + [ | ||||
"-avaproof={}".format(proof.serialize().hex()), | "-avaproof={}".format(proof.serialize().hex()), | ||||
"-avamasterkey={}".format(privkey) | "-avamasterkey={}".format(privkey) | ||||
]) | ]) | ||||
# Connect a block to make the proof be added to our pool | # Connect a block to make the proof be added to our pool | ||||
Show All 9 Lines | def test_proof_relay(self): | ||||
self.log.info("Nodes should eventually get the proof from their peer") | self.log.info("Nodes should eventually get the proof from their peer") | ||||
self.sync_proofs() | self.sync_proofs() | ||||
for node in self.nodes: | for node in self.nodes: | ||||
assert_equal(set(get_proof_ids(node)), proofids) | assert_equal(set(get_proof_ids(node)), proofids) | ||||
def test_manually_sent_proof(self): | def test_manually_sent_proof(self): | ||||
node0 = self.nodes[0] | node0 = self.nodes[0] | ||||
_, proof = self.gen_proof(node0) | _, proof = gen_proof(node0) | ||||
self.log.info( | self.log.info( | ||||
"Send a proof via RPC and check all the nodes download it") | "Send a proof via RPC and check all the nodes download it") | ||||
node0.sendavalancheproof(proof.serialize().hex()) | node0.sendavalancheproof(proof.serialize().hex()) | ||||
self.sync_proofs() | self.sync_proofs() | ||||
def test_unbroadcast(self): | def test_unbroadcast(self): | ||||
self.log.info("Test broadcasting proofs") | self.log.info("Test broadcasting proofs") | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
# Disconnect the other nodes, or they will request the proof and | # Disconnect the other nodes, or they will request the proof and | ||||
# invalidate the test | # invalidate the test | ||||
[node.stop_node() for node in self.nodes[1:]] | [node.stop_node() for node in self.nodes[1:]] | ||||
def add_peers(count): | def add_peers(count): | ||||
peers = [] | peers = [] | ||||
for i in range(count): | for i in range(count): | ||||
peer = node.add_p2p_connection(ProofInvStoreP2PInterface()) | peer = node.add_p2p_connection(ProofInvStoreP2PInterface()) | ||||
peer.wait_for_verack() | peer.wait_for_verack() | ||||
peers.append(peer) | peers.append(peer) | ||||
return peers | return peers | ||||
_, proof = self.gen_proof(node) | _, proof = gen_proof(node) | ||||
proofid_hex = "{:064x}".format(proof.proofid) | proofid_hex = "{:064x}".format(proof.proofid) | ||||
# Broadcast the proof | # Broadcast the proof | ||||
peers = add_peers(3) | peers = add_peers(3) | ||||
assert node.sendavalancheproof(proof.serialize().hex()) | assert node.sendavalancheproof(proof.serialize().hex()) | ||||
wait_for_proof(node, proofid_hex) | wait_for_proof(node, proofid_hex) | ||||
def proof_inv_received(peers): | def proof_inv_received(peers): | ||||
▲ Show 20 Lines • Show All 84 Lines • Show Last 20 Lines |