Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc_p2p_avalanche_peer_discovery.py
- This file was added.
#!/usr/bin/env python3 | |||||
# Copyright (c) 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 avalanche peer discovery""" | |||||
from test_framework.key import ( | |||||
ECKey, | |||||
ECPubKey, | |||||
) | |||||
from test_framework.messages import ( | |||||
CInv, | |||||
MSG_AVALANCHE_PROOF, | |||||
NODE_AVALANCHE, | |||||
NODE_NETWORK, | |||||
) | |||||
from test_framework.mininode import P2PAvalancheTestNode | |||||
from test_framework.test_framework import BitcoinTestFramework | |||||
from test_framework.util import ( | |||||
assert_equal, | |||||
) | |||||
AVALANCHE_MAX_PROOF_STAKES = 1000 | |||||
BLOCK_ACCEPTED = 0 | |||||
BLOCK_INVALID = 1 | |||||
BLOCK_PARKED = 2 | |||||
BLOCK_FORK = 3 | |||||
BLOCK_UNKNOWN = -1 | |||||
BLOCK_MISSING = -2 | |||||
BLOCK_PENDING = -3 | |||||
QUORUM_NODE_COUNT = 16 | |||||
class AvalanchePeerDiscoveryTest(BitcoinTestFramework): | |||||
def set_test_params(self): | |||||
self.setup_clean_chain = True | |||||
self.num_nodes = 1 | |||||
self.extra_args = [['-enableavalanche=1', '-avacooldown=0']] | |||||
def run_test(self): | |||||
node = self.nodes[0] | |||||
# Get the key so we can verify signatures. | |||||
avakey = ECPubKey() | |||||
avakey.set(bytes.fromhex(node.getavalanchekey())) | |||||
self.log.info("Check the node is signalling the avalanche service.") | |||||
assert_equal( | |||||
int(node.getnetworkinfo()['localservices'], 16) & NODE_AVALANCHE, | |||||
NODE_AVALANCHE) | |||||
# Generate a block to have a stake for avalanche | |||||
addrkey = node.get_deterministic_priv_key() | |||||
coinbase_address = addrkey.address | |||||
coinbase_key = addrkey.key | |||||
blockhash = node.generatetoaddress(1, coinbase_address)[0] | |||||
block = node.getblock(blockhash, 2) | |||||
# Make a proof | |||||
privkey = ECKey() | |||||
privkey.set(bytes.fromhex( | |||||
"12b004fff7f4b69ef8650e767f18f11ede158148b425660723b9f9a66e61f747"), True) | |||||
proof_master = privkey.get_pubkey().get_bytes().hex() | |||||
proof_sequence = 11 | |||||
proof_expiration = 12 | |||||
proof = node.buildavalancheproof( | |||||
proof_sequence, proof_expiration, proof_master, | |||||
[{ | |||||
'txid': block['tx'][0]['txid'], | |||||
'vout': 0, | |||||
'amount': block['tx'][0]['vout'][0]['value'], | |||||
'height': block['height'], | |||||
'iscoinbase': True, | |||||
'privatekey': coinbase_key, | |||||
}]) | |||||
# Restart the main node with an avaproof specified | |||||
self.restart_node(0, self.extra_args[0] + [ | |||||
"-avaproof={}".format(proof), | |||||
"-avamasterkey=cND2ZvtabDbJ1gucx9GWH6XT9kgTAqfb6cotPt5Q5CyxVDhid2EN", | |||||
]) | |||||
# Create a peer | |||||
ava_mininode = P2PAvalancheTestNode() | |||||
node.add_p2p_connection( | |||||
ava_mininode, services=NODE_NETWORK | NODE_AVALANCHE) | |||||
ava_mininode.wait_for_verack() | |||||
# Check the handshake sequence | |||||
self.log.info("Test avahello sequence node -> ava_mininode") | |||||
avahello = ava_mininode.wait_for_avahello().hello | |||||
avakey.set(bytes.fromhex(node.getavalanchekey())) | |||||
assert avakey.verify_schnorr( | |||||
avahello.sig, avahello.get_sighash(ava_mininode)) | |||||
ava_mininode.send_getdata([CInv(MSG_AVALANCHE_PROOF, | |||||
avahello.delegation.proofid)]) | |||||
avaproof = ava_mininode.wait_for_avaproof().proof | |||||
assert_equal(proof, avaproof.serialize().hex()) | |||||
assert_equal(avaproof.proofid, avahello.delegation.proofid) | |||||
self.log.info( | |||||
"Test avahello sequence ava_mininode -> node") | |||||
# This is testing only the first couple of steps (for now) | |||||
# TODO: make a proper delegation and a valid signature for avahello, | |||||
# reply with a valid avaproof, test that the node adds us. | |||||
ava_mininode.send_avahello() | |||||
ava_mininode.wait_for_getdata([P2PAvalancheTestNode.DUMMY_PROOFID]) | |||||
if __name__ == '__main__': | |||||
AvalanchePeerDiscoveryTest().main() |