Changeset View
Changeset View
Standalone View
Standalone View
test/functional/p2p_inv_download.py
| # 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 | ||||
| """ | """ | ||||
| import functools | import functools | ||||
| import random | |||||
| import time | import time | ||||
| from test_framework.address import ADDRESS_ECREG_UNSPENDABLE | from test_framework.address import ADDRESS_ECREG_UNSPENDABLE | ||||
| from test_framework.avatools import avalanche_proof_from_hex, gen_proof, wait_for_proof | from test_framework.avatools import avalanche_proof_from_hex, gen_proof, wait_for_proof | ||||
| from test_framework.key import ECKey | from test_framework.key import ECKey | ||||
| from test_framework.messages import ( | from test_framework.messages import ( | ||||
| MSG_AVA_PROOF, | MSG_AVA_PROOF, | ||||
| MSG_AVA_STAKE_CONTENDER, | |||||
| MSG_TX, | MSG_TX, | ||||
| MSG_TYPE_MASK, | MSG_TYPE_MASK, | ||||
| CInv, | CInv, | ||||
| CTransaction, | CTransaction, | ||||
| FromHex, | FromHex, | ||||
| msg_avaproof, | msg_avaproof, | ||||
| msg_getdata, | |||||
| msg_inv, | msg_inv, | ||||
| msg_notfound, | msg_notfound, | ||||
| ) | ) | ||||
| from test_framework.p2p import P2PInterface, p2p_lock | from test_framework.p2p import P2PInterface, p2p_lock | ||||
| from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
| from test_framework.util import assert_equal, assert_raises_rpc_error, uint256_hex | from test_framework.util import assert_equal, assert_raises_rpc_error, uint256_hex | ||||
| from test_framework.wallet_util import bytes_to_wif | from test_framework.wallet_util import bytes_to_wif | ||||
| ▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | NetConstants( | ||||
| inbound_peer_delay=2, # seconds | inbound_peer_delay=2, # seconds | ||||
| overloaded_peer_delay=2, # seconds | overloaded_peer_delay=2, # seconds | ||||
| max_getdata_in_flight=100, | max_getdata_in_flight=100, | ||||
| max_peer_announcements=5000, | max_peer_announcements=5000, | ||||
| bypass_request_limits_permission_flags="bypass_proof_request_limits", | bypass_request_limits_permission_flags="bypass_proof_request_limits", | ||||
| ), | ), | ||||
| ) | ) | ||||
| STAKE_CONTENDER_TEST_CONTEXT = TestContext( | |||||
| MSG_AVA_STAKE_CONTENDER, | |||||
| "avalanche stake contender", | |||||
| NetConstants( | |||||
| getdata_interval=60, # seconds | |||||
| inbound_peer_delay=2, # seconds | |||||
| overloaded_peer_delay=2, # seconds | |||||
| max_getdata_in_flight=100, | |||||
| max_peer_announcements=5000, | |||||
| bypass_request_limits_permission_flags=None, | |||||
| ), | |||||
| ) | |||||
| TX_TEST_CONTEXT = TestContext( | TX_TEST_CONTEXT = TestContext( | ||||
| MSG_TX, | MSG_TX, | ||||
| "transaction", | "transaction", | ||||
| NetConstants( | NetConstants( | ||||
| getdata_interval=60, # seconds | getdata_interval=60, # seconds | ||||
| inbound_peer_delay=2, # seconds | inbound_peer_delay=2, # seconds | ||||
| overloaded_peer_delay=2, # seconds | overloaded_peer_delay=2, # seconds | ||||
| max_getdata_in_flight=100, | max_getdata_in_flight=100, | ||||
| ▲ Show 20 Lines • Show All 359 Lines • ▼ Show 20 Lines | def test_request_invalid_once(self, context): | ||||
| ) | ) | ||||
| # Give enough time for the node to eventually request the proof | # Give enough time for the node to eventually request the proof | ||||
| node.setmocktime(int(time.time()) + context.constants.getdata_interval + 1) | node.setmocktime(int(time.time()) + context.constants.getdata_interval + 1) | ||||
| node.p2ps[1].sync_with_ping() | node.p2ps[1].sync_with_ping() | ||||
| assert all(p.getdata_count == 0 for p in node.p2ps[1:]) | assert all(p.getdata_count == 0 for p in node.p2ps[1:]) | ||||
| def test_inv_ignore(self, context): | |||||
| self.log.info( | |||||
| f"Announce an item of type {context.inv_name} that is expected to be ignored" | |||||
| ) | |||||
| peer = self.nodes[0].add_p2p_connection(context.p2p_conn()) | |||||
| # Send an inv message to the node. It should not log the inv since this type is ignored. | |||||
| itemid = random.randint(0, 2**256 - 1) | |||||
| inv = CInv(t=context.inv_type, h=itemid) | |||||
| with self.nodes[0].assert_debug_log( | |||||
| ["received: inv (37 bytes)"], | |||||
| unexpected_msgs=["got inv:"], | |||||
| ): | |||||
| peer.send_and_ping(msg_inv([inv])) | |||||
| # No getdata request should be made by the node | |||||
| assert peer.getdata_count == 0 | |||||
| # If we craft a getdata message, it is also ignored by the node | |||||
| with self.nodes[0].assert_debug_log( | |||||
| [ | |||||
| "received getdata (1 invsz)", | |||||
| f"received getdata for: 0x{context.inv_type:x} {itemid:x}", | |||||
| ], | |||||
| ): | |||||
| msg = msg_getdata() | |||||
| msg.inv.append(inv) | |||||
| peer.send_and_ping(msg) | |||||
| # There should be no notfound message sent in response to the getdata message | |||||
| with p2p_lock: | |||||
| assert "notfound" not in peer.last_message | |||||
| def run_test(self): | def run_test(self): | ||||
| for context in [STAKE_CONTENDER_TEST_CONTEXT]: | |||||
| self.test_inv_ignore(context) | |||||
| for context in [TX_TEST_CONTEXT, PROOF_TEST_CONTEXT]: | for context in [TX_TEST_CONTEXT, PROOF_TEST_CONTEXT]: | ||||
| self.log.info(f"Starting tests using {context.inv_name} inventory type") | self.log.info(f"Starting tests using {context.inv_name} 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) | ||||
| Show All 29 Lines | |||||