Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_rpc_avalancheproof.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 building avalanche proofs and using them to add avalanche peers.""" | """Test building avalanche proofs and using them to add avalanche peers.""" | ||||
from test_framework.avatools import get_stakes | from test_framework.avatools import get_stakes | ||||
from test_framework.key import ECKey | from test_framework.key import ECKey | ||||
from test_framework.mininode import P2PInterface | from test_framework.mininode import P2PInterface | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.test_node import ErrorMatch | |||||
from test_framework.util import ( | from test_framework.util import ( | ||||
append_config, | |||||
assert_equal, | assert_equal, | ||||
assert_raises_rpc_error, | |||||
) | ) | ||||
AVALANCHE_MAX_PROOF_STAKES = 1000 | AVALANCHE_MAX_PROOF_STAKES = 1000 | ||||
def add_interface_node(test_node) -> str: | def add_interface_node(test_node) -> str: | ||||
"""Create a mininode, connect it to test_node, return the nodeid | """Create a mininode, connect it to test_node, return the nodeid | ||||
PiRK: this function is now unused | |||||
of the mininode as registered by test_node. | of the mininode as registered by test_node. | ||||
""" | """ | ||||
n = P2PInterface() | n = P2PInterface() | ||||
test_node.add_p2p_connection(n) | test_node.add_p2p_connection(n) | ||||
n.wait_for_verack() | n.wait_for_verack() | ||||
return test_node.getpeerinfo()[-1]['id'] | return test_node.getpeerinfo()[-1]['id'] | ||||
Show All 36 Lines | def run_test(self): | ||||
# Our proof cannot be verified during IBD, so we should have no peer | # Our proof cannot be verified during IBD, so we should have no peer | ||||
assert not node.getavalanchepeerinfo() | assert not node.getavalanchepeerinfo() | ||||
# Mining a few more blocks should cause us to leave IBD | # Mining a few more blocks should cause us to leave IBD | ||||
node.generate(2) | node.generate(2) | ||||
# Our proof is now verified and our node is added as a peer | # Our proof is now verified and our node is added as a peer | ||||
assert node.getblockchaininfo()["initialblockdownload"] is False | assert node.getblockchaininfo()["initialblockdownload"] is False | ||||
assert_equal(len(node.getavalanchepeerinfo()), 1) | assert_equal(len(node.getavalanchepeerinfo()), 1) | ||||
self.log.info( | |||||
"A proof using the maximum number of stakes is accepted...") | |||||
blockhashes = node.generatetoaddress(AVALANCHE_MAX_PROOF_STAKES + 1, | |||||
addrkey0.address) | |||||
too_many_stakes = get_stakes(node, blockhashes, addrkey0.key) | |||||
maximum_stakes = get_stakes(node, blockhashes[:-1], addrkey0.key) | |||||
good_proof = node.buildavalancheproof( | |||||
proof_sequence, proof_expiration, | |||||
proof_master, maximum_stakes) | |||||
peerid1 = add_interface_node(node) | |||||
node.addavalanchenode( | |||||
PiRKUnsubmitted Not Done Inline ActionsI think this removes the only functional test we currently have adding a node with a good multiple UTXOs proof . PiRK: I think this removes the only functional test we currently have adding a node with a good… | |||||
PiRKUnsubmitted Not Done Inline ActionsThe test wasn't good anyway, because it was missing an assert to check that addavalanchenode returns True. But we have to remember to add another one in a future diff. PiRK: The test wasn't good anyway, because it was missing an assert to check that addavalanchenode… | |||||
peerid1, proof_master, good_proof) | |||||
self.log.info("A proof using too many stakes should be rejected...") | |||||
bad_proof = node.buildavalancheproof( | |||||
proof_sequence, proof_expiration, | |||||
proof_master, too_many_stakes) | |||||
peerid2 = add_interface_node(node) | |||||
assert_raises_rpc_error(-32602, "Avalanche proof has too many UTXOs", | |||||
node.addavalanchenode, | |||||
peerid2, proof_master, bad_proof) | |||||
# Test invalid proofs | # Test invalid proofs | ||||
self.log.info("Bad proof should be rejected at startup") | self.log.info("Bad proof should be rejected at startup") | ||||
no_stake = node.buildavalancheproof( | no_stake = node.buildavalancheproof( | ||||
proof_sequence, proof_expiration, proof_master, []) | proof_sequence, proof_expiration, proof_master, []) | ||||
blockhashes = node.generatetoaddress(AVALANCHE_MAX_PROOF_STAKES + 1, | |||||
addrkey0.address) | |||||
dust = node.buildavalancheproof( | dust = node.buildavalancheproof( | ||||
proof_sequence, proof_expiration, proof_master, | proof_sequence, proof_expiration, proof_master, | ||||
get_stakes(node, [blockhashes[0]], addrkey0.key, amount="0")) | get_stakes(node, [blockhashes[0]], addrkey0.key, amount="0")) | ||||
duplicate_stake = node.buildavalancheproof( | duplicate_stake = node.buildavalancheproof( | ||||
proof_sequence, proof_expiration, proof_master, | proof_sequence, proof_expiration, proof_master, | ||||
get_stakes(node, [blockhashes[0]] * 2, addrkey0.key)) | get_stakes(node, [blockhashes[0]] * 2, addrkey0.key)) | ||||
bad_sig = ("0b000000000000000c0000000000000021030b4c866585dd868a9d62348" | bad_sig = ("0b000000000000000c0000000000000021030b4c866585dd868a9d62348" | ||||
"a9cd008d6a312937048fff31670e7e920cfc7a7440105c5f72f5d6da3085" | "a9cd008d6a312937048fff31670e7e920cfc7a7440105c5f72f5d6da3085" | ||||
"583e75ee79340eb4eff208c89988e7ed0efb30b87298fa30000000000f20" | "583e75ee79340eb4eff208c89988e7ed0efb30b87298fa30000000000f20" | ||||
"52a0100000003000000210227d85ba011276cf25b51df6a188b75e604b3" | "52a0100000003000000210227d85ba011276cf25b51df6a188b75e604b3" | ||||
"8770a462b2d0e9fb2fc839ef5d3faf07f001dd38e9b4a43d07d5d449cc0" | "8770a462b2d0e9fb2fc839ef5d3faf07f001dd38e9b4a43d07d5d449cc0" | ||||
"f7d2888d96b82962b3ce516d1083c0e031773487fc3c4f2e38acd1db974" | "f7d2888d96b82962b3ce516d1083c0e031773487fc3c4f2e38acd1db974" | ||||
"1321b91a79b82d1c2cfd47793261e4ba003cf5") | "1321b91a79b82d1c2cfd47793261e4ba003cf5") | ||||
too_many_utxos = node.buildavalancheproof( | |||||
proof_sequence, proof_expiration, | |||||
proof_master, get_stakes(node, blockhashes, addrkey0.key)) | |||||
self.stop_node(0) | self.stop_node(0) | ||||
def check_proof_init_error(proof, message): | def check_proof_init_error(proof, message): | ||||
node.assert_start_raises_init_error( | node.assert_start_raises_init_error( | ||||
self.extra_args[0] + [ | self.extra_args[0] + [ | ||||
"-avaproof={}".format(proof), | "-avaproof={}".format(proof), | ||||
"-avamasterkey=cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN", | "-avamasterkey=cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN", | ||||
], | ], | ||||
expected_msg="Error: " + message, | expected_msg="Error: " + message, | ||||
) | ) | ||||
check_proof_init_error(no_stake, | check_proof_init_error(no_stake, | ||||
"the avalanche proof has no stake") | "the avalanche proof has no stake") | ||||
check_proof_init_error(dust, | check_proof_init_error(dust, | ||||
"the avalanche proof stake is too low") | "the avalanche proof stake is too low") | ||||
check_proof_init_error(duplicate_stake, | check_proof_init_error(duplicate_stake, | ||||
"the avalanche proof has duplicated stake") | "the avalanche proof has duplicated stake") | ||||
check_proof_init_error(bad_sig, | check_proof_init_error(bad_sig, | ||||
"the avalanche proof has invalid stake signatures") | "the avalanche proof has invalid stake signatures") | ||||
# The too many utxos case creates a proof which is that large that it | |||||
# cannot fit on the command line | |||||
append_config(node.datadir, ["avaproof={}".format(too_many_utxos)]) | |||||
node.assert_start_raises_init_error( | |||||
self.extra_args[0] + [ | |||||
"-avamasterkey=cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN", | |||||
], | |||||
expected_msg="Error: the avalanche proof has too many utxos", | |||||
match=ErrorMatch.PARTIAL_REGEX, | |||||
) | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
AvalancheProofTest().main() | AvalancheProofTest().main() |
this function is now unused