Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_rpc_addavalanchenode.py
Show All 19 Lines | |||||
def add_interface_node(test_node) -> int: | def add_interface_node(test_node) -> int: | ||||
"""Create a peer, connect it to test_node, return the nodeid of the peer as | """Create a peer, connect it to test_node, return the nodeid of the peer as | ||||
registered by test_node. | 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"] | ||||
class AddAvalancheNodeTest(BitcoinTestFramework): | class AddAvalancheNodeTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
self.extra_args = [['-avaproofstakeutxodustthreshold=1000000', | self.extra_args = [ | ||||
'-avaproofstakeutxoconfirmations=1', | [ | ||||
'-avacooldown=0']] | "-avaproofstakeutxodustthreshold=1000000", | ||||
"-avaproofstakeutxoconfirmations=1", | |||||
"-avacooldown=0", | |||||
] | |||||
] | |||||
def run_test(self): | def run_test(self): | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
addrkey0 = node.get_deterministic_priv_key() | addrkey0 = node.get_deterministic_priv_key() | ||||
blockhashes = self.generatetoaddress( | blockhashes = self.generatetoaddress( | ||||
node, 2, addrkey0.address, sync_fun=self.no_op) | node, 2, addrkey0.address, sync_fun=self.no_op | ||||
) | |||||
stakes = create_coinbase_stakes(node, [blockhashes[0]], addrkey0.key) | stakes = create_coinbase_stakes(node, [blockhashes[0]], addrkey0.key) | ||||
privkey = ECKey() | privkey = ECKey() | ||||
privkey.generate() | privkey.generate() | ||||
wif_privkey = bytes_to_wif(privkey.get_bytes()) | wif_privkey = bytes_to_wif(privkey.get_bytes()) | ||||
proof_master = privkey.get_pubkey().get_bytes().hex() | proof_master = privkey.get_pubkey().get_bytes().hex() | ||||
proof_sequence = 42 | proof_sequence = 42 | ||||
proof_expiration = 2000000000 | proof_expiration = 2000000000 | ||||
proof = node.buildavalancheproof( | proof = node.buildavalancheproof( | ||||
proof_sequence, proof_expiration, wif_privkey, stakes) | proof_sequence, proof_expiration, wif_privkey, stakes | ||||
) | |||||
nodeid = add_interface_node(node) | nodeid = add_interface_node(node) | ||||
def check_addavalanchenode_error( | def check_addavalanchenode_error( | ||||
error_code, error_message, nodeid=nodeid, proof=proof, pubkey=proof_master, delegation=None): | error_code, | ||||
error_message, | |||||
nodeid=nodeid, | |||||
proof=proof, | |||||
pubkey=proof_master, | |||||
delegation=None, | |||||
): | |||||
assert_raises_rpc_error( | assert_raises_rpc_error( | ||||
error_code, | error_code, | ||||
error_message, | error_message, | ||||
node.addavalanchenode, | node.addavalanchenode, | ||||
nodeid, | nodeid, | ||||
pubkey, | pubkey, | ||||
proof, | proof, | ||||
delegation, | delegation, | ||||
) | ) | ||||
self.log.info("Invalid proof") | self.log.info("Invalid proof") | ||||
check_addavalanchenode_error(-22, | check_addavalanchenode_error( | ||||
"Proof must be an hexadecimal string", | -22, "Proof must be an hexadecimal string", proof="not a proof" | ||||
proof="not a proof") | ) | ||||
check_addavalanchenode_error(-22, | check_addavalanchenode_error(-22, "Proof has invalid format", proof="f000") | ||||
"Proof has invalid format", | |||||
proof="f000") | |||||
no_stake = node.buildavalancheproof( | no_stake = node.buildavalancheproof( | ||||
proof_sequence, proof_expiration, wif_privkey, []) | proof_sequence, proof_expiration, wif_privkey, [] | ||||
check_addavalanchenode_error(-8, | ) | ||||
"The proof is invalid: no-stake", | check_addavalanchenode_error( | ||||
proof=no_stake) | -8, "The proof is invalid: no-stake", proof=no_stake | ||||
) | |||||
self.log.info("Node doesn't exist") | self.log.info("Node doesn't exist") | ||||
check_addavalanchenode_error(-8, | check_addavalanchenode_error( | ||||
f"The node does not exist: {nodeid + 1}", | -8, f"The node does not exist: {nodeid + 1}", nodeid=nodeid + 1 | ||||
nodeid=nodeid + 1) | ) | ||||
self.log.info("Invalid delegation") | self.log.info("Invalid delegation") | ||||
dg_privkey = ECKey() | dg_privkey = ECKey() | ||||
dg_privkey.generate() | dg_privkey.generate() | ||||
dg_pubkey = dg_privkey.get_pubkey().get_bytes() | dg_pubkey = dg_privkey.get_pubkey().get_bytes() | ||||
check_addavalanchenode_error(-22, | check_addavalanchenode_error( | ||||
-22, | |||||
"Delegation must be an hexadecimal string", | "Delegation must be an hexadecimal string", | ||||
pubkey=dg_pubkey.hex(), | pubkey=dg_pubkey.hex(), | ||||
delegation="not a delegation") | delegation="not a delegation", | ||||
check_addavalanchenode_error(-22, | ) | ||||
check_addavalanchenode_error( | |||||
-22, | |||||
"Delegation has invalid format", | "Delegation has invalid format", | ||||
pubkey=dg_pubkey.hex(), | pubkey=dg_pubkey.hex(), | ||||
delegation="f000") | delegation="f000", | ||||
) | |||||
self.log.info("Delegation mismatch with the proof") | self.log.info("Delegation mismatch with the proof") | ||||
delegation_wrong_proofid = AvalancheDelegation() | delegation_wrong_proofid = AvalancheDelegation() | ||||
check_addavalanchenode_error(-8, | check_addavalanchenode_error( | ||||
-8, | |||||
"The delegation does not match the proof", | "The delegation does not match the proof", | ||||
pubkey=dg_pubkey.hex(), | pubkey=dg_pubkey.hex(), | ||||
delegation=delegation_wrong_proofid.serialize().hex()) | delegation=delegation_wrong_proofid.serialize().hex(), | ||||
) | |||||
proofobj = avalanche_proof_from_hex(proof) | proofobj = avalanche_proof_from_hex(proof) | ||||
delegation = AvalancheDelegation( | delegation = AvalancheDelegation( | ||||
limited_proofid=proofobj.limited_proofid, | limited_proofid=proofobj.limited_proofid, | ||||
proof_master=proofobj.master, | proof_master=proofobj.master, | ||||
) | ) | ||||
self.log.info("Delegation with bad signature") | self.log.info("Delegation with bad signature") | ||||
bad_level = AvalancheDelegationLevel( | bad_level = AvalancheDelegationLevel( | ||||
pubkey=dg_pubkey, | pubkey=dg_pubkey, | ||||
) | ) | ||||
delegation.levels.append(bad_level) | delegation.levels.append(bad_level) | ||||
check_addavalanchenode_error(-8, | check_addavalanchenode_error( | ||||
-8, | |||||
"The delegation is invalid", | "The delegation is invalid", | ||||
pubkey=dg_pubkey.hex(), | pubkey=dg_pubkey.hex(), | ||||
delegation=delegation.serialize().hex()) | delegation=delegation.serialize().hex(), | ||||
) | |||||
delegation.levels = [] | delegation.levels = [] | ||||
level = AvalancheDelegationLevel( | level = AvalancheDelegationLevel( | ||||
pubkey=dg_pubkey, | pubkey=dg_pubkey, | ||||
sig=privkey.sign_schnorr( | sig=privkey.sign_schnorr( | ||||
hash256( | hash256(delegation.getid() + ser_string(dg_pubkey)) | ||||
delegation.getid() + | ), | ||||
ser_string(dg_pubkey) | |||||
) | |||||
) | |||||
) | ) | ||||
delegation.levels.append(level) | delegation.levels.append(level) | ||||
self.log.info("Key mismatch with the proof") | self.log.info("Key mismatch with the proof") | ||||
check_addavalanchenode_error( | check_addavalanchenode_error( | ||||
-5, | -5, | ||||
"The public key does not match the proof", | "The public key does not match the proof", | ||||
pubkey=dg_pubkey.hex(), | pubkey=dg_pubkey.hex(), | ||||
Show All 23 Lines | def run_test(self): | ||||
delegation.serialize().hex(), | delegation.serialize().hex(), | ||||
) | ) | ||||
self.log.info("Several nodes can share a proof") | self.log.info("Several nodes can share a proof") | ||||
nodeid2 = add_interface_node(node) | nodeid2 = add_interface_node(node) | ||||
assert node.addavalanchenode(nodeid2, proof_master, proof) | assert node.addavalanchenode(nodeid2, proof_master, proof) | ||||
if __name__ == '__main__': | if __name__ == "__main__": | ||||
AddAvalancheNodeTest().main() | AddAvalancheNodeTest().main() |