Changeset View
Changeset View
Standalone View
Standalone View
test/functional/p2p_inv_download.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2019 The Bitcoin Core developers | # Copyright (c) 2019 The Bitcoin Core 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 inventory download behavior | Test inventory download behavior | ||||
""" | """ | ||||
from test_framework.address import ADDRESS_BCHREG_UNSPENDABLE | from test_framework.address import ADDRESS_BCHREG_UNSPENDABLE | ||||
from test_framework.avatools import wait_for_proof | |||||
from test_framework.key import ECKey, bytes_to_wif | |||||
from test_framework.messages import ( | from test_framework.messages import ( | ||||
AvalancheProof, | |||||
CInv, | CInv, | ||||
CTransaction, | CTransaction, | ||||
FromHex, | FromHex, | ||||
MSG_AVA_PROOF, | MSG_AVA_PROOF, | ||||
MSG_TX, | MSG_TX, | ||||
MSG_TYPE_MASK, | MSG_TYPE_MASK, | ||||
msg_inv, | msg_inv, | ||||
msg_notfound, | msg_notfound, | ||||
▲ Show 20 Lines • Show All 338 Lines • ▼ Show 20 Lines | def test_large_inv_batch(self, context): | ||||
with p2p_lock: | with p2p_lock: | ||||
assert_equal(peer.getdata_count, max_peer_announcements) | assert_equal(peer.getdata_count, max_peer_announcements) | ||||
def test_spurious_notfound(self, context): | def test_spurious_notfound(self, context): | ||||
self.log.info('Check that spurious notfound is ignored') | self.log.info('Check that spurious notfound is ignored') | ||||
self.nodes[0].p2ps[0].send_message( | self.nodes[0].p2ps[0].send_message( | ||||
msg_notfound(vec=[CInv(context.inv_type, 1)])) | msg_notfound(vec=[CInv(context.inv_type, 1)])) | ||||
@skip(TX_TEST_CONTEXT) | |||||
def test_orphan_download(self, context): | |||||
node = self.nodes[0] | |||||
privkey = ECKey() | |||||
privkey.generate() | |||||
privkey_wif = bytes_to_wif(privkey.get_bytes()) | |||||
# Build a proof with missing utxos so it will be orphaned | |||||
orphan = node.buildavalancheproof( | |||||
42, 2000000000, privkey.get_pubkey().get_bytes().hex(), [{ | |||||
'txid': '0' * 64, | |||||
'vout': 0, | |||||
'amount': 10, | |||||
'height': 42, | |||||
'iscoinbase': False, | |||||
'privatekey': privkey_wif, | |||||
}] | |||||
) | |||||
proofid = FromHex(AvalancheProof(), orphan).proofid | |||||
proofid_hex = "{:064x}".format(proofid) | |||||
self.restart_node(0, extra_args=self.extra_args[0] + [ | |||||
"-avaproof={}".format(orphan), | |||||
"-avamasterkey={}".format(privkey_wif), | |||||
]) | |||||
node.generate(2) | |||||
wait_for_proof(node, proofid_hex) | |||||
assert_equal(node.getrawavalancheproof(proofid_hex)["orphan"], True) | |||||
peer = node.add_p2p_connection(context.p2p_conn()) | |||||
peer.send_message(msg_inv([CInv(t=context.inv_type, h=proofid)])) | |||||
# Give enough time for the node to eventually request the proof. | |||||
node.setmocktime(int(time.time()) + | |||||
context.constants.getdata_interval + 1) | |||||
peer.sync_with_ping() | |||||
assert_equal(peer.getdata_count, 0) | |||||
def run_test(self): | def run_test(self): | ||||
for context in [TX_TEST_CONTEXT, PROOF_TEST_CONTEXT]: | for context in [TX_TEST_CONTEXT, PROOF_TEST_CONTEXT]: | ||||
self.log.info( | self.log.info( | ||||
"Starting tests using " + | "Starting tests using " + | ||||
context.inv_name + | context.inv_name + | ||||
" inventory type") | " inventory type") | ||||
# Run tests without mocktime that only need one peer-connection first, | # Run tests without mocktime that only need one peer-connection first, | ||||
# to avoid restarting the nodes | # to avoid restarting the nodes | ||||
self.test_expiry_fallback(context) | self.test_expiry_fallback(context) | ||||
self.test_disconnect_fallback(context) | self.test_disconnect_fallback(context) | ||||
self.test_notfound_fallback(context) | self.test_notfound_fallback(context) | ||||
self.test_preferred_inv(context) | self.test_preferred_inv(context) | ||||
self.test_large_inv_batch(context) | self.test_large_inv_batch(context) | ||||
self.test_spurious_notfound(context) | self.test_spurious_notfound(context) | ||||
# Run each test against new bitcoind instances, as setting mocktimes has long-term effects on when | # Run each test against new bitcoind instances, as setting mocktimes has long-term effects on when | ||||
# the next trickle relay event happens. | # the next trickle relay event happens. | ||||
for test in [self.test_in_flight_max, | for test in [self.test_in_flight_max, | ||||
self.test_inv_block, self.test_data_requests]: | self.test_inv_block, self.test_data_requests, self.test_orphan_download]: | ||||
self.stop_nodes() | self.stop_nodes() | ||||
self.start_nodes() | self.start_nodes() | ||||
self.connect_nodes(1, 0) | self.connect_nodes(1, 0) | ||||
# Setup the p2p connections | # Setup the p2p connections | ||||
self.peers = [] | self.peers = [] | ||||
for node in self.nodes: | for node in self.nodes: | ||||
for _ in range(NUM_INBOUND): | for _ in range(NUM_INBOUND): | ||||
self.peers.append( | self.peers.append( | ||||
Show All 9 Lines |