Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_p2p_avalanche_proof_voting.py
- This file was added.
Property | Old Value | New Value |
---|---|---|
File Mode | null | 100755 |
#!/usr/bin/env python3 | |||||
# Copyright (c) 2020-2021 The Bitcoin developers | |||||
# Distributed under the MIT software license, see the accompanying | |||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | |||||
"""Test the conflicting proofs voting.""" | |||||
from test_framework.avatools import ( | |||||
create_coinbase_stakes, | |||||
gen_proof, | |||||
get_ava_p2p_interface, | |||||
get_proof_ids, | |||||
) | |||||
from test_framework.key import ( | |||||
ECKey, | |||||
) | |||||
from test_framework.messages import ( | |||||
AvalancheProof, | |||||
CInv, | |||||
FromHex, | |||||
MSG_AVA_PROOF, | |||||
) | |||||
from test_framework.p2p import p2p_lock | |||||
from test_framework.test_framework import BitcoinTestFramework | |||||
from test_framework.util import ( | |||||
assert_equal, | |||||
assert_raises_rpc_error, | |||||
wait_until, | |||||
) | |||||
QUORUM_NODE_COUNT = 16 | |||||
class AvalancheProofVotingTest(BitcoinTestFramework): | |||||
def set_test_params(self): | |||||
self.setup_clean_chain = True | |||||
self.num_nodes = 1 | |||||
self.extra_args = [[ | |||||
'-enableavalanche=1', | |||||
'-enableavalancheproofvoting=1', | |||||
'-avacooldown=0', | |||||
]] | |||||
def run_test(self): | |||||
node = self.nodes[0] | |||||
# Build a fake quorum of nodes. | |||||
def get_quorum(): | |||||
nodes = [] | |||||
for i in range(QUORUM_NODE_COUNT): | |||||
n = get_ava_p2p_interface(node) | |||||
key, proof = gen_proof(node) | |||||
assert node.addavalanchenode( | |||||
n.nodeid, | |||||
key.get_pubkey().get_bytes().hex(), | |||||
proof.serialize().hex(), | |||||
) | |||||
nodes.append(n) | |||||
return nodes | |||||
# Pick on node from the quorum for polling. | |||||
quorum = get_quorum() | |||||
assert_equal(len(node.getavalanchepeerinfo()), QUORUM_NODE_COUNT) | |||||
privkey = ECKey() | |||||
privkey.generate() | |||||
pubkey = privkey.get_pubkey() | |||||
addrkey0 = node.get_deterministic_priv_key() | |||||
blockhashes = node.generatetoaddress(1, addrkey0.address) | |||||
stakes = create_coinbase_stakes(node, blockhashes, addrkey0.key) | |||||
def get_proof_with_sequence_number(sequence_number): | |||||
proof = node.buildavalancheproof( | |||||
sequence_number, 2000000000, pubkey.get_bytes().hex(), stakes) | |||||
proofid = FromHex(AvalancheProof(), proof).proofid | |||||
return proofid, proof | |||||
proofid_seq10, proof_seq10 = get_proof_with_sequence_number(10) | |||||
proofid_seq20, proof_seq20 = get_proof_with_sequence_number(20) | |||||
proofid_seq30, proof_seq30 = get_proof_with_sequence_number(30) | |||||
node.sendavalancheproof(proof_seq20) | |||||
assert proofid_seq20 in get_proof_ids(node) | |||||
def avapoll_found(proofid): | |||||
inv = CInv(t=MSG_AVA_PROOF, h=proofid) | |||||
with p2p_lock: | |||||
return any(peer.last_message.get( | |||||
"avapoll") and inv in peer.last_message["avapoll"].poll.invs for peer in quorum) | |||||
def check_proof_is_polled(proofid, proof): | |||||
assert_raises_rpc_error(-8, "The proof has conflicting utxo with an existing proof", | |||||
node.sendavalancheproof, proof) | |||||
wait_until(lambda: avapoll_found(proofid)) | |||||
assert proofid not in get_proof_ids(node) | |||||
self.log.info("Check the node is polling for conflicting proofs") | |||||
# Conflicting proof with higher sequence number | |||||
check_proof_is_polled(proofid_seq30, proof_seq30) | |||||
# Conflicting proof with lower sequence number | |||||
check_proof_is_polled(proofid_seq10, proof_seq10) | |||||
if __name__ == '__main__': | |||||
AvalancheProofVotingTest().main() |