diff --git a/.arclint b/.arclint --- a/.arclint +++ b/.arclint @@ -23,7 +23,7 @@ "exclude": [ "(^contrib/gitian-builder/)", "(^contrib/apple-sdk-tools/)", - "(^test/functional/[a-mt].*\\.py$)" + "(^test/functional/[a-qt].*\\.py$)" ], "flags": [ "--aggressive", @@ -35,7 +35,7 @@ "type": "black", "version": ">=23.0.0", "include": [ - "(^test/functional/[a-mt].*\\.py$)" + "(^test/functional/[a-qt].*\\.py$)" ], "flags": [ "--preview" diff --git a/test/functional/p2p_add_connections.py b/test/functional/p2p_add_connections.py --- a/test/functional/p2p_add_connections.py +++ b/test/functional/p2p_add_connections.py @@ -35,9 +35,9 @@ self.extra_args = [ [ "-avaproofstakeutxoconfirmations=1", - f"-maxavalancheoutbound={MAX_AVALANCHE_OUTBOUND_CONNECTIONS}" + f"-maxavalancheoutbound={MAX_AVALANCHE_OUTBOUND_CONNECTIONS}", ], - [] + [], ] def setup_network(self): @@ -51,7 +51,8 @@ for _ in range(quantity): self.log.debug( - f"Node {node.index}, {conn_type}: {self.p2p_idx[node.index]}") + f"Node {node.index}, {conn_type}: {self.p2p_idx[node.index]}" + ) node.add_outbound_p2p_connection( P2PInterface(), p2p_idx=self.p2p_idx[node.index], @@ -61,30 +62,29 @@ self.p2p_idx[node.index] += 1 def simple_test(self): - self.log.info( - "Connect to various outbound peers in a predetermined way") + self.log.info("Connect to various outbound peers in a predetermined way") self.p2p_idx = [0] * self.num_nodes - self.log.info( - f"Add {MAX_OUTBOUND_FULL_RELAY_CONNECTIONS} outbounds to node 0") + self.log.info(f"Add {MAX_OUTBOUND_FULL_RELAY_CONNECTIONS} outbounds to node 0") self.add_outbounds( - self.nodes[0], - MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, - "outbound-full-relay") + self.nodes[0], MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, "outbound-full-relay" + ) self.log.info( - f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to node 0") + f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to" + " node 0" + ) self.add_outbounds( - self.nodes[0], - MAX_BLOCK_RELAY_ONLY_CONNECTIONS, - "block-relay-only") + self.nodes[0], MAX_BLOCK_RELAY_ONLY_CONNECTIONS, "block-relay-only" + ) self.log.info( - f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to node 1") + f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to" + " node 1" + ) self.add_outbounds( - self.nodes[1], - MAX_BLOCK_RELAY_ONLY_CONNECTIONS, - "block-relay-only") + self.nodes[1], MAX_BLOCK_RELAY_ONLY_CONNECTIONS, "block-relay-only" + ) self.log.info("Add 5 inbound connections to node 1") for i in range(5): @@ -98,73 +98,74 @@ check_node_connections( node=self.nodes[0], num_in=0, - num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + MAX_BLOCK_RELAY_ONLY_CONNECTIONS) + num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + + MAX_BLOCK_RELAY_ONLY_CONNECTIONS, + ) check_node_connections( - node=self.nodes[1], - num_in=5, - num_out=4 + MAX_BLOCK_RELAY_ONLY_CONNECTIONS) + node=self.nodes[1], num_in=5, num_out=4 + MAX_BLOCK_RELAY_ONLY_CONNECTIONS + ) self.log.info("Disconnect p2p connections & try to re-open") self.nodes[0].disconnect_p2ps() self.p2p_idx[0] = 0 check_node_connections(node=self.nodes[0], num_in=0, num_out=0) - self.log.info( - f"Add {MAX_OUTBOUND_FULL_RELAY_CONNECTIONS} outbounds to node 0") + self.log.info(f"Add {MAX_OUTBOUND_FULL_RELAY_CONNECTIONS} outbounds to node 0") self.add_outbounds( - self.nodes[0], - MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, - "outbound-full-relay") + self.nodes[0], MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, "outbound-full-relay" + ) check_node_connections( - node=self.nodes[0], - num_in=0, - num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS) + node=self.nodes[0], num_in=0, num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + ) self.log.info( - f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to node 0") + f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to" + " node 0" + ) self.add_outbounds( - self.nodes[0], - MAX_BLOCK_RELAY_ONLY_CONNECTIONS, - "block-relay-only") + self.nodes[0], MAX_BLOCK_RELAY_ONLY_CONNECTIONS, "block-relay-only" + ) check_node_connections( node=self.nodes[0], num_in=0, - num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + MAX_BLOCK_RELAY_ONLY_CONNECTIONS) + num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + + MAX_BLOCK_RELAY_ONLY_CONNECTIONS, + ) self.log.info("Restart node 0 and try to reconnect to p2ps") self.restart_node(0) self.p2p_idx[0] = 0 - self.log.info( - f"Add {MAX_OUTBOUND_FULL_RELAY_CONNECTIONS} outbounds to node 0") + self.log.info(f"Add {MAX_OUTBOUND_FULL_RELAY_CONNECTIONS} outbounds to node 0") self.add_outbounds( - self.nodes[0], - MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, - "outbound-full-relay") + self.nodes[0], MAX_OUTBOUND_FULL_RELAY_CONNECTIONS, "outbound-full-relay" + ) check_node_connections( - node=self.nodes[0], - num_in=0, - num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS) + node=self.nodes[0], num_in=0, num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + ) self.log.info( - f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to node 0") + f"Add {MAX_BLOCK_RELAY_ONLY_CONNECTIONS} block-relay-only connections to" + " node 0" + ) self.add_outbounds( - self.nodes[0], - MAX_BLOCK_RELAY_ONLY_CONNECTIONS, - "block-relay-only") + self.nodes[0], MAX_BLOCK_RELAY_ONLY_CONNECTIONS, "block-relay-only" + ) check_node_connections( node=self.nodes[0], num_in=0, - num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + MAX_BLOCK_RELAY_ONLY_CONNECTIONS) + num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + + MAX_BLOCK_RELAY_ONLY_CONNECTIONS, + ) check_node_connections( - node=self.nodes[1], - num_in=5, - num_out=4 + MAX_BLOCK_RELAY_ONLY_CONNECTIONS) + node=self.nodes[1], num_in=5, num_out=4 + MAX_BLOCK_RELAY_ONLY_CONNECTIONS + ) self.log.info("Add 1 feeler connection to node 0") feeler_conn = self.nodes[0].add_outbound_p2p_connection( - P2PFeelerReceiver(), p2p_idx=self.p2p_idx[0], connection_type="feeler") + P2PFeelerReceiver(), p2p_idx=self.p2p_idx[0], connection_type="feeler" + ) # Feeler connection is closed assert not feeler_conn.is_connected @@ -176,15 +177,15 @@ self.log.info("Connecting avalanche outbounds") self.add_outbounds( - self.nodes[0], - MAX_AVALANCHE_OUTBOUND_CONNECTIONS, - "avalanche") + self.nodes[0], MAX_AVALANCHE_OUTBOUND_CONNECTIONS, "avalanche" + ) check_node_connections( node=self.nodes[0], num_in=0, - num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + - MAX_BLOCK_RELAY_ONLY_CONNECTIONS + - MAX_AVALANCHE_OUTBOUND_CONNECTIONS) + num_out=MAX_OUTBOUND_FULL_RELAY_CONNECTIONS + + MAX_BLOCK_RELAY_ONLY_CONNECTIONS + + MAX_AVALANCHE_OUTBOUND_CONNECTIONS, + ) def random_test(self): for node in self.nodes: @@ -199,8 +200,7 @@ max_outbounds = sum(remaining_outbounds.values()) iterations = random.randint(1, 5 * max_outbounds) - self.log.info( - f"Randomly insert outbounds of various types {iterations} times") + self.log.info(f"Randomly insert outbounds of various types {iterations} times") for _ in range(iterations): conn_type = random.choice(list(remaining_outbounds)) @@ -213,12 +213,13 @@ check_node_connections( node=self.nodes[0], num_in=0, - num_out=max_outbounds - sum(remaining_outbounds.values())) + num_out=max_outbounds - sum(remaining_outbounds.values()), + ) def run_test(self): self.simple_test() self.random_test() -if __name__ == '__main__': +if __name__ == "__main__": P2PAddConnections().main() diff --git a/test/functional/p2p_addr_relay.py b/test/functional/p2p_addr_relay.py --- a/test/functional/p2p_addr_relay.py +++ b/test/functional/p2p_addr_relay.py @@ -41,8 +41,9 @@ assert_equal(addr.nServices, NODE_NETWORK) if not 8333 <= addr.port < 8343: raise AssertionError( - f"Invalid addr.port of {addr.port} (8333-8342 expected)") - assert addr.ip.startswith('123.123.123.') + f"Invalid addr.port of {addr.port} (8333-8342 expected)" + ) + assert addr.ip.startswith("123.123.123.") def on_getaddr(self, message): # When the node sends us a getaddr, it increments the addr relay tokens @@ -65,11 +66,11 @@ def on_version(self, message): self.send_message(msg_verack()) - if (self.send_getaddr): + if self.send_getaddr: self.send_message(msg_getaddr()) def getaddr_received(self): - return self.message_count['getaddr'] > 0 + return self.message_count["getaddr"] > 0 class AddrTest(BitcoinTestFramework): @@ -131,27 +132,25 @@ peer.sync_send_with_ping() def oversized_addr_test(self): - self.log.info('Send an addr message that is too large') + self.log.info("Send an addr message that is too large") addr_source = self.nodes[0].add_p2p_connection(P2PInterface()) msg = self.setup_addr_msg(1010) - with self.nodes[0].assert_debug_log(['addr message size = 1010']): + with self.nodes[0].assert_debug_log(["addr message size = 1010"]): addr_source.send_and_ping(msg) self.nodes[0].disconnect_p2ps() def relay_tests(self): - self.log.info('Test address relay') - self.log.info( - 'Check that addr message content is relayed and added to addrman') + self.log.info("Test address relay") + self.log.info("Check that addr message content is relayed and added to addrman") addr_source = self.nodes[0].add_p2p_connection(P2PInterface()) num_receivers = 7 receivers = [] for _ in range(num_receivers): receivers.append( - self.nodes[0].add_p2p_connection( - AddrReceiver( - test_addr_contents=True))) + self.nodes[0].add_p2p_connection(AddrReceiver(test_addr_contents=True)) + ) # Keep this with length <= 10. Addresses from larger messages are not # relayed. @@ -159,8 +158,8 @@ msg = self.setup_addr_msg(num_ipv4_addrs) with self.nodes[0].assert_debug_log( [ - f'Added {num_ipv4_addrs} addresses from 127.0.0.1: 0 tried', - 'received: addr (301 bytes) peer=1', + f"Added {num_ipv4_addrs} addresses from 127.0.0.1: 0 tried", + "received: addr (301 bytes) peer=1", ] ): self.send_addr_msg(addr_source, msg, receivers) @@ -170,22 +169,23 @@ # Every IPv4 address must be relayed to two peers, other than the # originating node (addr_source). ipv4_branching_factor = 2 - assert_equal( - total_ipv4_received, - num_ipv4_addrs * - ipv4_branching_factor) + assert_equal(total_ipv4_received, num_ipv4_addrs * ipv4_branching_factor) self.nodes[0].disconnect_p2ps() - self.log.info('Check relay of addresses received from outbound peers') + self.log.info("Check relay of addresses received from outbound peers") inbound_peer = self.nodes[0].add_p2p_connection( - AddrReceiver(test_addr_contents=True, send_getaddr=False)) + AddrReceiver(test_addr_contents=True, send_getaddr=False) + ) full_outbound_peer = self.nodes[0].add_outbound_p2p_connection( - AddrReceiver(), p2p_idx=0, connection_type="outbound-full-relay") + AddrReceiver(), p2p_idx=0, connection_type="outbound-full-relay" + ) msg = self.setup_addr_msg(2) self.send_addr_msg(full_outbound_peer, msg, [inbound_peer]) self.log.info( - 'Check that the first addr message received from an outbound peer is not relayed') + "Check that the first addr message received from an outbound peer is not" + " relayed" + ) # Currently, there is a flag that prevents the first addr message # received from a new outbound peer to be relayed to others. Originally # meant to prevent large GETADDR responses from being relayed, it now @@ -198,48 +198,52 @@ inbound_peer.send_and_ping(msg_addr()) self.log.info( - 'Check that subsequent addr messages sent from an outbound peer are relayed') + "Check that subsequent addr messages sent from an outbound peer are relayed" + ) msg2 = self.setup_addr_msg(2) self.send_addr_msg(full_outbound_peer, msg2, [inbound_peer]) assert_equal(inbound_peer.num_ipv4_received, 2) - self.log.info('Check address relay to outbound peers') + self.log.info("Check address relay to outbound peers") block_relay_peer = self.nodes[0].add_outbound_p2p_connection( - AddrReceiver(), p2p_idx=1, connection_type="block-relay-only") + AddrReceiver(), p2p_idx=1, connection_type="block-relay-only" + ) msg3 = self.setup_addr_msg(2) - self.send_addr_msg( - inbound_peer, msg3, - [full_outbound_peer, block_relay_peer]) + self.send_addr_msg(inbound_peer, msg3, [full_outbound_peer, block_relay_peer]) - self.log.info( - 'Check that addresses are relayed to full outbound peers') + self.log.info("Check that addresses are relayed to full outbound peers") assert_equal(full_outbound_peer.num_ipv4_received, 2) self.log.info( - 'Check that addresses are not relayed to block-relay-only outbound peers') + "Check that addresses are not relayed to block-relay-only outbound peers" + ) assert_equal(block_relay_peer.num_ipv4_received, 0) self.nodes[0].disconnect_p2ps() def sum_addr_messages(self, msgs_dict): - return sum(bytes_received for (msg, bytes_received) - in msgs_dict.items() if msg in ['addr', 'addrv2', 'getaddr']) + return sum( + bytes_received + for (msg, bytes_received) in msgs_dict.items() + if msg in ["addr", "addrv2", "getaddr"] + ) def inbound_blackhole_tests(self): self.log.info( - 'Check that we only relay addresses to inbound peers who have previously sent us addr related messages') + "Check that we only relay addresses to inbound peers who have previously" + " sent us addr related messages" + ) addr_source = self.nodes[0].add_p2p_connection(P2PInterface()) receiver_peer = self.nodes[0].add_p2p_connection(AddrReceiver()) blackhole_peer = self.nodes[0].add_p2p_connection( - AddrReceiver(send_getaddr=False)) + AddrReceiver(send_getaddr=False) + ) initial_addrs_received = receiver_peer.num_ipv4_received peerinfo = self.nodes[0].getpeerinfo() - assert_equal(peerinfo[0]['addr_relay_enabled'], True) # addr_source - assert_equal(peerinfo[1]['addr_relay_enabled'], True) # receiver_peer - assert_equal( - peerinfo[2]['addr_relay_enabled'], - False) # blackhole_peer + assert_equal(peerinfo[0]["addr_relay_enabled"], True) # addr_source + assert_equal(peerinfo[1]["addr_relay_enabled"], True) # receiver_peer + assert_equal(peerinfo[2]["addr_relay_enabled"], False) # blackhole_peer # addr_source sends 2 addresses to node0 msg = self.setup_addr_msg(2) @@ -252,34 +256,26 @@ peerinfo = self.nodes[0].getpeerinfo() # Confirm node received addr-related messages from receiver peer - assert_greater_than( - self.sum_addr_messages( - peerinfo[1]['bytesrecv_per_msg']), 0) + assert_greater_than(self.sum_addr_messages(peerinfo[1]["bytesrecv_per_msg"]), 0) # And that peer received addresses - assert_equal( - receiver_peer.num_ipv4_received - - initial_addrs_received, - 2) + assert_equal(receiver_peer.num_ipv4_received - initial_addrs_received, 2) # Confirm node has not received addr-related messages from blackhole # peer - assert_equal( - self.sum_addr_messages( - peerinfo[2]['bytesrecv_per_msg']), 0) + assert_equal(self.sum_addr_messages(peerinfo[2]["bytesrecv_per_msg"]), 0) # And that peer did not receive addresses assert_equal(blackhole_peer.num_ipv4_received, 0) self.log.info( - "After blackhole peer sends addr message, it becomes eligible for addr gossip") + "After blackhole peer sends addr message, it becomes eligible for addr" + " gossip" + ) blackhole_peer.send_and_ping(msg_addr()) # Confirm node has now received addr-related messages from blackhole # peer - assert_greater_than( - self.sum_addr_messages( - peerinfo[1]['bytesrecv_per_msg']), 0) - assert_equal(self.nodes[0].getpeerinfo()[2] - ['addr_relay_enabled'], True) + assert_greater_than(self.sum_addr_messages(peerinfo[1]["bytesrecv_per_msg"]), 0) + assert_equal(self.nodes[0].getpeerinfo()[2]["addr_relay_enabled"], True) msg = self.setup_addr_msg(2) self.send_addr_msg(addr_source, msg, [receiver_peer, blackhole_peer]) @@ -296,25 +292,31 @@ # in response until enough time has passed or the node is restarted. self.restart_node(0) - self.log.info('Test getaddr behavior') + self.log.info("Test getaddr behavior") self.log.info( - 'Check that we send a getaddr message upon connecting to an outbound-full-relay peer') + "Check that we send a getaddr message upon connecting to an" + " outbound-full-relay peer" + ) full_outbound_peer = self.nodes[0].add_outbound_p2p_connection( - AddrReceiver(), p2p_idx=0, connection_type="outbound-full-relay") + AddrReceiver(), p2p_idx=0, connection_type="outbound-full-relay" + ) full_outbound_peer.sync_with_ping() assert full_outbound_peer.getaddr_received() self.log.info( - 'Check that we do not send a getaddr message upon connecting to a block-relay-only peer') + "Check that we do not send a getaddr message upon connecting to a" + " block-relay-only peer" + ) block_relay_peer = self.nodes[0].add_outbound_p2p_connection( - AddrReceiver(), p2p_idx=1, connection_type="block-relay-only") + AddrReceiver(), p2p_idx=1, connection_type="block-relay-only" + ) block_relay_peer.sync_with_ping() assert_equal(block_relay_peer.getaddr_received(), False) - self.log.info( - 'Check that we answer getaddr messages only from inbound peers') + self.log.info("Check that we answer getaddr messages only from inbound peers") inbound_peer = self.nodes[0].add_p2p_connection( - AddrReceiver(send_getaddr=False)) + AddrReceiver(send_getaddr=False) + ) inbound_peer.sync_with_ping() # Add some addresses to addrman @@ -339,17 +341,18 @@ self.nodes[0].disconnect_p2ps() def blocksonly_mode_tests(self): - self.log.info('Test addr relay in -blocksonly mode') + self.log.info("Test addr relay in -blocksonly mode") self.restart_node(0, ["-blocksonly", "-whitelist=addr@127.0.0.1"]) self.mocktime = int(time.time()) - self.log.info('Check that we send getaddr messages') + self.log.info("Check that we send getaddr messages") full_outbound_peer = self.nodes[0].add_outbound_p2p_connection( - AddrReceiver(), p2p_idx=0, connection_type="outbound-full-relay") + AddrReceiver(), p2p_idx=0, connection_type="outbound-full-relay" + ) full_outbound_peer.sync_with_ping() assert full_outbound_peer.getaddr_received() - self.log.info('Check that we relay address messages') + self.log.info("Check that we relay address messages") addr_source = self.nodes[0].add_p2p_connection(P2PInterface()) msg = self.setup_addr_msg(2) self.send_addr_msg(addr_source, msg, [full_outbound_peer]) @@ -357,18 +360,21 @@ self.nodes[0].disconnect_p2ps() - def send_addrs_and_test_rate_limiting(self, peer, no_relay, *, new_addrs, - total_addrs): + def send_addrs_and_test_rate_limiting( + self, peer, no_relay, *, new_addrs, total_addrs + ): """Send an addr message and check that the number of addresses processed - and rate-limited is as expected + and rate-limited is as expected """ peer.send_and_ping(self.setup_rand_addr_msg(new_addrs)) peerinfo = self.nodes[0].getpeerinfo()[0] - addrs_processed = peerinfo['addr_processed'] - addrs_rate_limited = peerinfo['addr_rate_limited'] - self.log.debug(f"addrs_processed = {addrs_processed}, " - f"addrs_rate_limited = {addrs_rate_limited}") + addrs_processed = peerinfo["addr_processed"] + addrs_rate_limited = peerinfo["addr_rate_limited"] + self.log.debug( + f"addrs_processed = {addrs_processed}, " + f"addrs_rate_limited = {addrs_rate_limited}" + ) if no_relay: assert_equal(addrs_processed, 0) @@ -385,31 +391,36 @@ for conn_type, no_relay in [ ("outbound-full-relay", False), ("block-relay-only", True), - ("inbound", False) + ("inbound", False), ]: self.log.info( - f'Test rate limiting of addr processing for {conn_type} peers') + f"Test rate limiting of addr processing for {conn_type} peers" + ) if conn_type == "inbound": peer = self.nodes[0].add_p2p_connection(AddrReceiver()) else: peer = self.nodes[0].add_outbound_p2p_connection( - AddrReceiver(), p2p_idx=0, connection_type=conn_type) + AddrReceiver(), p2p_idx=0, connection_type=conn_type + ) # Send 600 addresses. For all but the block-relay-only peer this # should result in addresses being processed. self.send_addrs_and_test_rate_limiting( - peer, no_relay, new_addrs=600, total_addrs=600) + peer, no_relay, new_addrs=600, total_addrs=600 + ) # Send 600 more addresses. For the outbound-full-relay peer (which # we send a GETADDR, and thus will process up to 1001 incoming # addresses), this means more addresses will be processed. self.send_addrs_and_test_rate_limiting( - peer, no_relay, new_addrs=600, total_addrs=1200) + peer, no_relay, new_addrs=600, total_addrs=1200 + ) # Send 10 more. As we reached the processing limit for all nodes, # no more addresses should be procesesd. self.send_addrs_and_test_rate_limiting( - peer, no_relay, new_addrs=10, total_addrs=1210) + peer, no_relay, new_addrs=10, total_addrs=1210 + ) # Advance the time by 100 seconds, permitting the processing of 10 # more addresses. @@ -419,7 +430,8 @@ peer.increment_tokens(10) self.send_addrs_and_test_rate_limiting( - peer, no_relay, new_addrs=200, total_addrs=1410) + peer, no_relay, new_addrs=200, total_addrs=1410 + ) # Advance the time by 1000 seconds, permitting the processing of 100 # more addresses. @@ -429,10 +441,11 @@ peer.increment_tokens(100) self.send_addrs_and_test_rate_limiting( - peer, no_relay, new_addrs=200, total_addrs=1610) + peer, no_relay, new_addrs=200, total_addrs=1610 + ) self.nodes[0].disconnect_p2ps() -if __name__ == '__main__': +if __name__ == "__main__": AddrTest().main() diff --git a/test/functional/p2p_addrfetch.py b/test/functional/p2p_addrfetch.py --- a/test/functional/p2p_addrfetch.py +++ b/test/functional/p2p_addrfetch.py @@ -30,26 +30,31 @@ info = self.nodes[0].getpeerinfo() assert_equal(len(info), num_peers) for n in range(0, num_peers): - assert_equal(info[n]['id'], peer_ids[n]) - assert_equal(info[n]['connection_type'], 'addr-fetch') + assert_equal(info[n]["id"], peer_ids[n]) + assert_equal(info[n]["connection_type"], "addr-fetch") def run_test(self): node = self.nodes[0] self.log.info("Connect to an addr-fetch peer") peer_id = 0 peer = node.add_outbound_p2p_connection( - P2PInterface(), p2p_idx=peer_id, connection_type="addr-fetch") + P2PInterface(), p2p_idx=peer_id, connection_type="addr-fetch" + ) self.assert_getpeerinfo(peer_ids=[peer_id]) self.log.info( - "Check that we send getaddr but don't try to sync headers with the addr-fetch peer") + "Check that we send getaddr but don't try to sync headers with the" + " addr-fetch peer" + ) peer.sync_send_with_ping() with p2p_lock: - assert peer.message_count['getaddr'] == 1 - assert peer.message_count['getheaders'] == 0 + assert peer.message_count["getaddr"] == 1 + assert peer.message_count["getheaders"] == 0 self.log.info( - "Check that answering the getaddr with a single address does not lead to disconnect") + "Check that answering the getaddr with a single address does not lead to" + " disconnect" + ) # This prevents disconnecting on self-announcements msg = msg_addr() msg.addrs = [ADDR] @@ -57,16 +62,17 @@ self.assert_getpeerinfo(peer_ids=[peer_id]) self.log.info( - "Check that answering with larger addr messages leads to disconnect") + "Check that answering with larger addr messages leads to disconnect" + ) msg.addrs = [ADDR] * 2 peer.send_message(msg) peer.wait_for_disconnect(timeout=5) - self.log.info( - "Check timeout for addr-fetch peer that does not send addrs") + self.log.info("Check timeout for addr-fetch peer that does not send addrs") peer_id = 1 peer = node.add_outbound_p2p_connection( - P2PInterface(), p2p_idx=peer_id, connection_type="addr-fetch") + P2PInterface(), p2p_idx=peer_id, connection_type="addr-fetch" + ) time_now = int(time.time()) self.assert_getpeerinfo(peer_ids=[peer_id]) @@ -81,5 +87,5 @@ self.assert_getpeerinfo(peer_ids=[]) -if __name__ == '__main__': +if __name__ == "__main__": P2PAddrFetch().main() diff --git a/test/functional/p2p_addrv2_relay.py b/test/functional/p2p_addrv2_relay.py --- a/test/functional/p2p_addrv2_relay.py +++ b/test/functional/p2p_addrv2_relay.py @@ -45,24 +45,27 @@ self.extra_args = [["-whitelist=addr@127.0.0.1"]] def run_test(self): - self.log.info('Create connection that sends addrv2 messages') + self.log.info("Create connection that sends addrv2 messages") addr_source = self.nodes[0].add_p2p_connection(P2PInterface()) msg = msg_addrv2() - self.log.info('Send too-large addrv2 message') + self.log.info("Send too-large addrv2 message") msg.addrs = ADDRS * 101 - with self.nodes[0].assert_debug_log(['addrv2 message size = 1010']): + with self.nodes[0].assert_debug_log(["addrv2 message size = 1010"]): addr_source.send_and_ping(msg) self.log.info( - 'Check that addrv2 message content is relayed and added to addrman') + "Check that addrv2 message content is relayed and added to addrman" + ) addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver()) msg.addrs = ADDRS - with self.nodes[0].assert_debug_log([ - 'Added 10 addresses from 127.0.0.1: 0 tried', - 'received: addrv2 (131 bytes) peer=0', - 'sending addrv2 (131 bytes) peer=1', - ]): + with self.nodes[0].assert_debug_log( + [ + "Added 10 addresses from 127.0.0.1: 0 tried", + "received: addrv2 (131 bytes) peer=0", + "sending addrv2 (131 bytes) peer=1", + ] + ): addr_source.send_and_ping(msg) self.nodes[0].setmocktime(int(time.time()) + 30 * 60) addr_receiver.wait_for_addrv2() @@ -70,5 +73,5 @@ assert addr_receiver.addrv2_received_and_checked -if __name__ == '__main__': +if __name__ == "__main__": AddrTest().main() diff --git a/test/functional/p2p_blockfilters.py b/test/functional/p2p_blockfilters.py --- a/test/functional/p2p_blockfilters.py +++ b/test/functional/p2p_blockfilters.py @@ -63,8 +63,7 @@ # Stale blocks by disconnecting nodes 0 & 1, mining, then reconnecting self.disconnect_nodes(0, 1) - stale_block_hash = self.generate( - self.nodes[0], 1, sync_fun=self.no_op)[0] + stale_block_hash = self.generate(self.nodes[0], 1, sync_fun=self.no_op)[0] self.nodes[0].syncwithvalidationinterfacequeue() assert_equal(self.nodes[0].getblockcount(), 1000) @@ -76,12 +75,16 @@ assert peer_1.nServices & NODE_COMPACT_FILTERS == 0 # Check that the localservices is as expected. - assert int( - self.nodes[0].getnetworkinfo()['localservices'], - 16) & NODE_COMPACT_FILTERS != 0 - assert int( - self.nodes[1].getnetworkinfo()['localservices'], - 16) & NODE_COMPACT_FILTERS == 0 + assert ( + int(self.nodes[0].getnetworkinfo()["localservices"], 16) + & NODE_COMPACT_FILTERS + != 0 + ) + assert ( + int(self.nodes[1].getnetworkinfo()["localservices"], 16) + & NODE_COMPACT_FILTERS + == 0 + ) self.log.info("get cfcheckpt on chain to be re-orged out.") request = msg_getcfcheckpt( @@ -89,7 +92,7 @@ stop_hash=int(stale_block_hash, 16), ) peer_0.send_and_ping(message=request) - response = peer_0.last_message['cfcheckpt'] + response = peer_0.last_message["cfcheckpt"] assert_equal(response.filter_type, request.filter_type) assert_equal(response.stop_hash, request.stop_hash) assert_equal(len(response.headers), 1) @@ -109,14 +112,14 @@ stop_hash=int(tip_hash, 16), ) peer_0.send_and_ping(request) - response = peer_0.last_message['cfcheckpt'] + response = peer_0.last_message["cfcheckpt"] assert_equal(response.filter_type, request.filter_type) assert_equal(response.stop_hash, request.stop_hash) - main_cfcheckpt = self.nodes[0].getblockfilter( - main_block_hash, 'basic')['header'] - tip_cfcheckpt = self.nodes[0].getblockfilter(tip_hash, 'basic')[ - 'header'] + main_cfcheckpt = self.nodes[0].getblockfilter(main_block_hash, "basic")[ + "header" + ] + tip_cfcheckpt = self.nodes[0].getblockfilter(tip_hash, "basic")["header"] assert_equal( response.headers, [int(header, 16) for header in (main_cfcheckpt, tip_cfcheckpt)], @@ -128,13 +131,14 @@ stop_hash=int(stale_block_hash, 16), ) peer_0.send_and_ping(request) - response = peer_0.last_message['cfcheckpt'] + response = peer_0.last_message["cfcheckpt"] - stale_cfcheckpt = self.nodes[0].getblockfilter( - stale_block_hash, 'basic')['header'] + stale_cfcheckpt = self.nodes[0].getblockfilter(stale_block_hash, "basic")[ + "header" + ] assert_equal( response.headers, - [int(header, 16) for header in (stale_cfcheckpt, )], + [int(header, 16) for header in (stale_cfcheckpt,)], ) self.log.info("Check that peers can fetch cfheaders on active chain.") @@ -144,7 +148,7 @@ stop_hash=int(main_block_hash, 16), ) peer_0.send_and_ping(request) - response = peer_0.last_message['cfheaders'] + response = peer_0.last_message["cfheaders"] main_cfhashes = response.hashes assert_equal(len(main_cfhashes), 1000) assert_equal( @@ -159,7 +163,7 @@ stop_hash=int(stale_block_hash, 16), ) peer_0.send_and_ping(request) - response = peer_0.last_message['cfheaders'] + response = peer_0.last_message["cfheaders"] stale_cfhashes = response.hashes assert_equal(len(stale_cfhashes), 1000) assert_equal( @@ -179,8 +183,7 @@ assert_equal(len(response), 10) self.log.info("Check that cfilter responses are correct.") - for cfilter, cfhash, height in zip( - response, main_cfhashes, range(1, 11)): + for cfilter, cfhash, height in zip(response, main_cfhashes, range(1, 11)): block_hash = self.nodes[0].getblockhash(height) assert_equal(cfilter.filter_type, FILTER_TYPE_BASIC) assert_equal(cfilter.block_hash, int(block_hash, 16)) @@ -204,7 +207,8 @@ assert_equal(computed_cfhash, stale_cfhashes[999]) self.log.info( - "Requests to node 1 without NODE_COMPACT_FILTERS results in disconnection.") + "Requests to node 1 without NODE_COMPACT_FILTERS results in disconnection." + ) requests = [ msg_getcfcheckpt( filter_type=FILTER_TYPE_BASIC, @@ -265,5 +269,5 @@ return uint256_from_str(header) -if __name__ == '__main__': +if __name__ == "__main__": CompactFiltersTest().main() diff --git a/test/functional/p2p_blocksonly.py b/test/functional/p2p_blocksonly.py --- a/test/functional/p2p_blocksonly.py +++ b/test/functional/p2p_blocksonly.py @@ -29,51 +29,58 @@ def blocksonly_mode_tests(self): self.log.info("Tests with node running in -blocksonly mode") - assert_equal(self.nodes[0].getnetworkinfo()['localrelay'], False) + assert_equal(self.nodes[0].getnetworkinfo()["localrelay"], False) self.nodes[0].add_p2p_connection(P2PInterface()) tx, txid, tx_hex = self.check_p2p_tx_violation() - self.log.info('Check that tx invs also violate the protocol') + self.log.info("Check that tx invs also violate the protocol") self.nodes[0].add_p2p_connection(P2PInterface()) - with self.nodes[0].assert_debug_log(['transaction (0000000000000000000000000000000000000000000000000000000000001234) inv sent in violation of protocol, disconnecting peer']): - self.nodes[0].p2ps[0].send_message( - msg_inv([CInv(t=MSG_TX, h=0x1234)])) + with self.nodes[0].assert_debug_log( + [ + "transaction" + " (0000000000000000000000000000000000000000000000000000000000001234)" + " inv sent in violation of protocol, disconnecting peer" + ] + ): + self.nodes[0].p2ps[0].send_message(msg_inv([CInv(t=MSG_TX, h=0x1234)])) self.nodes[0].p2ps[0].wait_for_disconnect() del self.nodes[0].p2ps[0] self.log.info( - 'Check that txs from rpc are not rejected and relayed to other peers') + "Check that txs from rpc are not rejected and relayed to other peers" + ) tx_relay_peer = self.nodes[0].add_p2p_connection(P2PInterface()) - assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], True) - assert_equal( - self.nodes[0].testmempoolaccept( - [tx_hex])[0]['allowed'], True) - with self.nodes[0].assert_debug_log([f'received getdata for: tx {txid} peer']): + assert_equal(self.nodes[0].getpeerinfo()[0]["relaytxes"], True) + assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]["allowed"], True) + with self.nodes[0].assert_debug_log([f"received getdata for: tx {txid} peer"]): self.nodes[0].sendrawtransaction(tx_hex) tx_relay_peer.wait_for_tx(txid) - assert_equal(self.nodes[0].getmempoolinfo()['size'], 1) + assert_equal(self.nodes[0].getmempoolinfo()["size"], 1) self.log.info("Restarting node 0 with relay permission and blocksonly") - self.restart_node(0, - ["-persistmempool=0", - "-whitelist=relay@127.0.0.1", - "-blocksonly", - '-deprecatedrpc=whitelisted']) + self.restart_node( + 0, + [ + "-persistmempool=0", + "-whitelist=relay@127.0.0.1", + "-blocksonly", + "-deprecatedrpc=whitelisted", + ], + ) assert_equal(self.nodes[0].getrawmempool(), []) first_peer = self.nodes[0].add_p2p_connection(P2PInterface()) second_peer = self.nodes[0].add_p2p_connection(P2PInterface()) peer_1_info = self.nodes[0].getpeerinfo()[0] - assert_equal(peer_1_info['permissions'], ['relay']) + assert_equal(peer_1_info["permissions"], ["relay"]) peer_2_info = self.nodes[0].getpeerinfo()[1] - assert_equal(peer_2_info['permissions'], ['relay']) - assert_equal( - self.nodes[0].testmempoolaccept( - [tx_hex])[0]['allowed'], True) + assert_equal(peer_2_info["permissions"], ["relay"]) + assert_equal(self.nodes[0].testmempoolaccept([tx_hex])[0]["allowed"], True) self.log.info( - 'Check that the tx from first_peer with relay-permission is ' - 'relayed to others (ie.second_peer)') + "Check that the tx from first_peer with relay-permission is " + "relayed to others (ie.second_peer)" + ) with self.nodes[0].assert_debug_log(["received getdata"]): # Note that normally, first_peer would never send us transactions # since we're a blocksonly node. By activating blocksonly, we @@ -86,35 +93,37 @@ # See https://github.com/bitcoin/bitcoin/issues/19943 for details. first_peer.send_message(msg_tx(tx)) self.log.info( - 'Check that the peer with relay-permission is still connected' - ' after sending the transaction') + "Check that the peer with relay-permission is still connected" + " after sending the transaction" + ) assert_equal(first_peer.is_connected, True) second_peer.wait_for_tx(txid) - assert_equal(self.nodes[0].getmempoolinfo()['size'], 1) - self.log.info( - "Relay-permission peer's transaction is accepted and relayed") + assert_equal(self.nodes[0].getmempoolinfo()["size"], 1) + self.log.info("Relay-permission peer's transaction is accepted and relayed") self.nodes[0].disconnect_p2ps() self.generate(self.nodes[0], 1) def blocks_relay_conn_tests(self): self.log.info( - 'Tests with node in normal mode with block-relay-only connections') + "Tests with node in normal mode with block-relay-only connections" + ) # disables blocks only mode self.restart_node(0, ["-noblocksonly"]) - assert_equal(self.nodes[0].getnetworkinfo()['localrelay'], True) + assert_equal(self.nodes[0].getnetworkinfo()["localrelay"], True) # Ensure we disconnect if a block-relay-only connection sends us a # transaction self.nodes[0].add_outbound_p2p_connection( - P2PInterface(), p2p_idx=0, connection_type="block-relay-only") - assert_equal(self.nodes[0].getpeerinfo()[0]['relaytxes'], False) + P2PInterface(), p2p_idx=0, connection_type="block-relay-only" + ) + assert_equal(self.nodes[0].getpeerinfo()[0]["relaytxes"], False) _, txid, tx_hex = self.check_p2p_tx_violation() - self.log.info( - "Check that txs from RPC are not sent to blockrelay connection") + self.log.info("Check that txs from RPC are not sent to blockrelay connection") conn = self.nodes[0].add_outbound_p2p_connection( - P2PTxInvStore(), p2p_idx=1, connection_type="block-relay-only") + P2PTxInvStore(), p2p_idx=1, connection_type="block-relay-only" + ) self.nodes[0].sendrawtransaction(tx_hex) @@ -125,20 +134,21 @@ assert int(txid, 16) not in conn.get_invs() def check_p2p_tx_violation(self): - self.log.info( - 'Check that txs from P2P are rejected and result in disconnect') + self.log.info("Check that txs from P2P are rejected and result in disconnect") spendtx = self.miniwallet.create_self_transfer(from_node=self.nodes[0]) - with self.nodes[0].assert_debug_log(['transaction sent in violation of protocol peer=0']): - self.nodes[0].p2ps[0].send_message(msg_tx(spendtx['tx'])) + with self.nodes[0].assert_debug_log( + ["transaction sent in violation of protocol peer=0"] + ): + self.nodes[0].p2ps[0].send_message(msg_tx(spendtx["tx"])) self.nodes[0].p2ps[0].wait_for_disconnect() - assert_equal(self.nodes[0].getmempoolinfo()['size'], 0) + assert_equal(self.nodes[0].getmempoolinfo()["size"], 0) # Remove the disconnected peer del self.nodes[0].p2ps[0] - return spendtx['tx'], spendtx['txid'], spendtx['hex'] + return spendtx["tx"], spendtx["txid"], spendtx["hex"] -if __name__ == '__main__': +if __name__ == "__main__": P2PBlocksOnly().main() diff --git a/test/functional/p2p_compactblocks.py b/test/functional/p2p_compactblocks.py --- a/test/functional/p2p_compactblocks.py +++ b/test/functional/p2p_compactblocks.py @@ -68,7 +68,8 @@ self.block_announced = True self.last_message["cmpctblock"].header_and_shortids.header.calc_sha256() self.announced_blockhashes.add( - self.last_message["cmpctblock"].header_and_shortids.header.sha256) + self.last_message["cmpctblock"].header_and_shortids.header.sha256 + ) def on_headers(self, message): self.block_announced = True @@ -114,7 +115,8 @@ # received. def wait_for_block_announcement(self, block_hash, timeout=30): def received_hash(): - return (block_hash in self.announced_blockhashes) + return block_hash in self.announced_blockhashes + self.wait_until(received_hash, timeout=timeout) def send_await_disconnect(self, message, timeout=30): @@ -130,8 +132,7 @@ def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 - self.extra_args = [["-acceptnonstdtxn=1"], - ["-txindex", "-acceptnonstdtxn=1"]] + self.extra_args = [["-acceptnonstdtxn=1"], ["-txindex", "-acceptnonstdtxn=1"]] self.utxos = [] def skip_test_if_missing_module(self): @@ -153,7 +154,7 @@ total_value = block.vtx[0].vout[0].nValue out_value = total_value // 10 tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(block.vtx[0].sha256, 0), b'')) + tx.vin.append(CTxIn(COutPoint(block.vtx[0].sha256, 0), b"")) for _ in range(10): tx.vout.append(CTxOut(out_value, CScript([OP_TRUE]))) tx.rehash() @@ -176,16 +177,15 @@ # are made with compact blocks. # If old_node is passed in, request compact blocks with version=preferred-1 # and verify that it receives block announcements via compact block. - def test_sendcmpct(self, node, test_node, - preferred_version, old_node=None): + def test_sendcmpct(self, node, test_node, preferred_version, old_node=None): # Make sure we get a SENDCMPCT message from our peer def received_sendcmpct(): - return (len(test_node.last_sendcmpct) > 0) + return len(test_node.last_sendcmpct) > 0 + test_node.wait_until(received_sendcmpct, timeout=30) with p2p_lock: # Check that the first version received is the preferred one - assert_equal( - test_node.last_sendcmpct[0].version, preferred_version) + assert_equal(test_node.last_sendcmpct[0].version, preferred_version) # And that we receive versions down to 1. assert_equal(test_node.last_sendcmpct[-1].version, 1) test_node.last_sendcmpct = [] @@ -207,12 +207,16 @@ # We shouldn't get any block announcements via cmpctblock yet. check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" not in p.last_message) + node, test_node, lambda p: "cmpctblock" not in p.last_message + ) # Try one more time, this time after requesting headers. test_node.request_headers_and_sync(locator=[tip]) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" not in p.last_message and "inv" in p.last_message) + node, + test_node, + lambda p: "cmpctblock" not in p.last_message and "inv" in p.last_message, + ) # Test a few ways of using sendcmpct that should NOT # result in compact block announcements. @@ -222,46 +226,58 @@ # Now try a SENDCMPCT message with too-high version test_node.send_and_ping(msg_sendcmpct(announce=True, version=999)) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" not in p.last_message) + node, test_node, lambda p: "cmpctblock" not in p.last_message + ) # Headers sync before next test. test_node.request_headers_and_sync(locator=[tip]) # Now try a SENDCMPCT message with valid version, but announce=False - test_node.send_and_ping(msg_sendcmpct(announce=False, - version=preferred_version)) + test_node.send_and_ping( + msg_sendcmpct(announce=False, version=preferred_version) + ) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" not in p.last_message) + node, test_node, lambda p: "cmpctblock" not in p.last_message + ) # Headers sync before next test. test_node.request_headers_and_sync(locator=[tip]) # Finally, try a SENDCMPCT message with announce=True - test_node.send_and_ping(msg_sendcmpct(announce=True, - version=preferred_version)) + test_node.send_and_ping(msg_sendcmpct(announce=True, version=preferred_version)) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" in p.last_message) + node, test_node, lambda p: "cmpctblock" in p.last_message + ) # Try one more time (no headers sync should be needed!) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" in p.last_message) + node, test_node, lambda p: "cmpctblock" in p.last_message + ) # Try one more time, after turning on sendheaders test_node.send_and_ping(msg_sendheaders()) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" in p.last_message) + node, test_node, lambda p: "cmpctblock" in p.last_message + ) # Try one more time, after sending a version-1, announce=false message. - test_node.send_and_ping(msg_sendcmpct(announce=False, - version=preferred_version - 1)) + test_node.send_and_ping( + msg_sendcmpct(announce=False, version=preferred_version - 1) + ) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" in p.last_message) + node, test_node, lambda p: "cmpctblock" in p.last_message + ) # Now turn off announcements - test_node.send_and_ping(msg_sendcmpct(announce=False, - version=preferred_version)) + test_node.send_and_ping( + msg_sendcmpct(announce=False, version=preferred_version) + ) check_announcement_of_new_block( - node, test_node, lambda p: "cmpctblock" not in p.last_message and "headers" in p.last_message) + node, + test_node, + lambda p: "cmpctblock" not in p.last_message + and "headers" in p.last_message, + ) if old_node is not None: # Verify that a peer using an older protocol version can receive @@ -270,7 +286,8 @@ # Header sync old_node.request_headers_and_sync(locator=[tip]) check_announcement_of_new_block( - node, old_node, lambda p: "cmpctblock" in p.last_message) + node, old_node, lambda p: "cmpctblock" in p.last_message + ) # This test actually causes bitcoind to (reasonably!) disconnect us, so do # this last. @@ -285,8 +302,7 @@ prefilled_txn = PrefilledTransaction(1, block.vtx[0]) cmpct_block.prefilled_txn = [prefilled_txn] self.test_node.send_await_disconnect(msg_cmpctblock(cmpct_block)) - assert_equal( - int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock) # Compare the generated shortids to what we expect based on BIP 152, given # bitcoind's choice of nonce. @@ -313,44 +329,46 @@ block_hash = int(self.generate(node, 1)[0], 16) # Store the raw block in our internal format. - block = FromHex(CBlock(), - node.getblock(uint256_hex(block_hash), False)) + block = FromHex(CBlock(), node.getblock(uint256_hex(block_hash), False)) for tx in block.vtx: tx.calc_sha256() block.rehash() # Wait until the block was announced (via compact blocks) - test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, - timeout=30) + test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30) # Now fetch and check the compact block header_and_shortids = None with p2p_lock: # Convert the on-the-wire representation to absolute indexes header_and_shortids = HeaderAndShortIDs( - test_node.last_message["cmpctblock"].header_and_shortids) + test_node.last_message["cmpctblock"].header_and_shortids + ) self.check_compactblock_construction_from_block( - header_and_shortids, block_hash, block) + header_and_shortids, block_hash, block + ) # Now fetch the compact block using a normal non-announce getdata test_node.clear_block_announcement() inv = CInv(MSG_CMPCT_BLOCK, block_hash) test_node.send_message(msg_getdata([inv])) - test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, - timeout=30) + test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30) # Now fetch and check the compact block header_and_shortids = None with p2p_lock: # Convert the on-the-wire representation to absolute indexes header_and_shortids = HeaderAndShortIDs( - test_node.last_message["cmpctblock"].header_and_shortids) + test_node.last_message["cmpctblock"].header_and_shortids + ) self.check_compactblock_construction_from_block( - header_and_shortids, block_hash, block) + header_and_shortids, block_hash, block + ) def check_compactblock_construction_from_block( - self, header_and_shortids, block_hash, block): + self, header_and_shortids, block_hash, block + ): # Check that we got the right block! header_and_shortids.header.calc_sha256() assert_equal(header_and_shortids.header.sha256, block_hash) @@ -366,8 +384,10 @@ assert_equal(entry.tx.sha256, block.vtx[entry.index].sha256) # Check that the cmpctblock message announced all the transactions. - assert_equal(len(header_and_shortids.prefilled_txn) - + len(header_and_shortids.shortids), len(block.vtx)) + assert_equal( + len(header_and_shortids.prefilled_txn) + len(header_and_shortids.shortids), + len(block.vtx), + ) # And now check that all the shortids are as expected as well. # Determine the siphash keys to use. @@ -375,8 +395,10 @@ index = 0 while index < len(block.vtx): - if (len(header_and_shortids.prefilled_txn) > 0 and - header_and_shortids.prefilled_txn[0].index == index): + if ( + len(header_and_shortids.prefilled_txn) > 0 + and header_and_shortids.prefilled_txn[0].index == index + ): # Already checked prefilled transactions above header_and_shortids.prefilled_txn.pop(0) else: @@ -396,10 +418,10 @@ block = self.build_block_on_tip(node) if announce == "inv": - test_node.send_message( - msg_inv([CInv(MSG_BLOCK, block.sha256)])) - self.wait_until(lambda: "getheaders" in test_node.last_message, - timeout=30) + test_node.send_message(msg_inv([CInv(MSG_BLOCK, block.sha256)])) + self.wait_until( + lambda: "getheaders" in test_node.last_message, timeout=30 + ) test_node.send_header_for_blocks([block]) else: test_node.send_header_for_blocks([block]) @@ -412,15 +434,15 @@ comp_block.nonce = 0 [k0, k1] = comp_block.get_siphash_keys() coinbase_hash = block.vtx[0].sha256 - comp_block.shortids = [ - calculate_shortid(k0, k1, coinbase_hash)] + comp_block.shortids = [calculate_shortid(k0, k1, coinbase_hash)] test_node.send_and_ping(msg_cmpctblock(comp_block.to_p2p())) assert_equal(int(node.getbestblockhash(), 16), block.hashPrevBlock) # Expect a getblocktxn message. with p2p_lock: assert "getblocktxn" in test_node.last_message - absolute_indexes = test_node.last_message["getblocktxn"].block_txn_request.to_absolute( - ) + absolute_indexes = test_node.last_message[ + "getblocktxn" + ].block_txn_request.to_absolute() assert_equal(absolute_indexes, [0]) # should be a coinbase request # Send the coinbase, and verify that the tip advances. @@ -438,7 +460,7 @@ for _ in range(num_transactions): tx = CTransaction() - tx.vin.append(CTxIn(COutPoint(utxo[0], utxo[1]), b'')) + tx.vin.append(CTxIn(COutPoint(utxo[0], utxo[1]), b"")) tx.vout.append(CTxOut(utxo[2] - 1000, CScript([OP_TRUE]))) pad_tx(tx) tx.rehash() @@ -446,8 +468,7 @@ block.vtx.append(tx) ordered_txs = block.vtx - block.vtx = [block.vtx[0]] + \ - sorted(block.vtx[1:], key=lambda tx: tx.get_id()) + block.vtx = [block.vtx[0]] + sorted(block.vtx[1:], key=lambda tx: tx.get_id()) block.hashMerkleRoot = block.calc_merkle_root() block.solve() return block, ordered_txs @@ -461,8 +482,9 @@ peer.send_and_ping(msg) with p2p_lock: assert "getblocktxn" in peer.last_message - absolute_indexes = peer.last_message["getblocktxn"].block_txn_request.to_absolute( - ) + absolute_indexes = peer.last_message[ + "getblocktxn" + ].block_txn_request.to_absolute() assert_equal(absolute_indexes, expected_result) def test_tip_after_message(node, peer, msg, tip): @@ -474,36 +496,30 @@ utxo = self.utxos.pop(0) block, ordered_txs = self.build_block_with_transactions(node, utxo, 5) - self.utxos.append( - [ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) + self.utxos.append([ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) comp_block = HeaderAndShortIDs() comp_block.initialize_from_block(block) test_getblocktxn_response(comp_block, test_node, [1, 2, 3, 4, 5]) msg_bt = msg_blocktxn() - msg_bt.block_transactions = BlockTransactions( - block.sha256, block.vtx[1:]) + msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[1:]) test_tip_after_message(node, test_node, msg_bt, block.sha256) utxo = self.utxos.pop(0) block, ordered_txs = self.build_block_with_transactions(node, utxo, 5) - self.utxos.append( - [ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) + self.utxos.append([ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) # Now try interspersing the prefilled transactions - comp_block.initialize_from_block( - block, prefill_list=[0, 1, 5]) + comp_block.initialize_from_block(block, prefill_list=[0, 1, 5]) test_getblocktxn_response(comp_block, test_node, [2, 3, 4]) - msg_bt.block_transactions = BlockTransactions( - block.sha256, block.vtx[2:5]) + msg_bt.block_transactions = BlockTransactions(block.sha256, block.vtx[2:5]) test_tip_after_message(node, test_node, msg_bt, block.sha256) # Now try giving one transaction ahead of time. utxo = self.utxos.pop(0) block, ordered_txs = self.build_block_with_transactions(node, utxo, 5) - self.utxos.append( - [ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) + self.utxos.append([ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) test_node.send_and_ping(msg_tx(ordered_txs[1])) assert ordered_txs[1].hash in node.getrawmempool() test_node.send_and_ping(msg_tx(ordered_txs[1])) @@ -517,16 +533,14 @@ comp_block.initialize_from_block(block, prefill_list=prefill_list) test_getblocktxn_response(comp_block, test_node, [expected_index]) - msg_bt.block_transactions = BlockTransactions( - block.sha256, [ordered_txs[5]]) + msg_bt.block_transactions = BlockTransactions(block.sha256, [ordered_txs[5]]) test_tip_after_message(node, test_node, msg_bt, block.sha256) # Now provide all transactions to the node before the block is # announced and verify reconstruction happens immediately. utxo = self.utxos.pop(0) block, ordered_txs = self.build_block_with_transactions(node, utxo, 10) - self.utxos.append( - [ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) + self.utxos.append([ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) for tx in ordered_txs[1:]: test_node.send_message(msg_tx(tx)) test_node.sync_with_ping() @@ -542,7 +556,8 @@ # Send compact block comp_block.initialize_from_block(block, prefill_list=[0]) test_tip_after_message( - node, test_node, msg_cmpctblock(comp_block.to_p2p()), block.sha256) + node, test_node, msg_cmpctblock(comp_block.to_p2p()), block.sha256 + ) with p2p_lock: # Shouldn't have gotten a request for any transaction assert "getblocktxn" not in test_node.last_message @@ -550,13 +565,12 @@ # Incorrectly responding to a getblocktxn shouldn't cause the block to be # permanently failed. def test_incorrect_blocktxn_response(self, node, test_node, version): - if (len(self.utxos) == 0): + if len(self.utxos) == 0: self.make_utxos() utxo = self.utxos.pop(0) block, ordered_txs = self.build_block_with_transactions(node, utxo, 10) - self.utxos.append( - [ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) + self.utxos.append([ordered_txs[-1].sha256, 0, ordered_txs[-1].vout[0].nValue]) # Relay the first 5 transactions from the block in advance for tx in ordered_txs[1:6]: test_node.send_message(msg_tx(tx)) @@ -573,8 +587,9 @@ absolute_indices = [] with p2p_lock: assert "getblocktxn" in test_node.last_message - absolute_indices = test_node.last_message["getblocktxn"].block_txn_request.to_absolute( - ) + absolute_indices = test_node.last_message[ + "getblocktxn" + ].block_txn_request.to_absolute() expected_indices = [] for i in [6, 7, 8, 9, 10]: expected_indices.append(block.vtx.index(ordered_txs[i])) @@ -590,7 +605,8 @@ # enough for now. msg = msg_blocktxn() msg.block_transactions = BlockTransactions( - block.sha256, [ordered_txs[5]] + ordered_txs[7:]) + block.sha256, [ordered_txs[5]] + ordered_txs[7:] + ) test_node.send_and_ping(msg) # Tip should not have updated @@ -610,28 +626,32 @@ MAX_GETBLOCKTXN_DEPTH = 10 chain_height = node.getblockcount() current_height = chain_height - while (current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH): + while current_height >= chain_height - MAX_GETBLOCKTXN_DEPTH: block_hash = node.getblockhash(current_height) block = FromHex(CBlock(), node.getblock(block_hash, False)) msg = msg_getblocktxn() - msg.block_txn_request = BlockTransactionsRequest( - int(block_hash, 16), []) + msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), []) num_to_request = random.randint(1, len(block.vtx)) msg.block_txn_request.from_absolute( - sorted(random.sample(range(len(block.vtx)), num_to_request))) + sorted(random.sample(range(len(block.vtx)), num_to_request)) + ) test_node.send_message(msg) - test_node.wait_until(lambda: "blocktxn" in test_node.last_message, - timeout=10) + test_node.wait_until( + lambda: "blocktxn" in test_node.last_message, timeout=10 + ) [tx.calc_sha256() for tx in block.vtx] with p2p_lock: - assert_equal(test_node.last_message["blocktxn"].block_transactions.blockhash, int( - block_hash, 16)) + assert_equal( + test_node.last_message["blocktxn"].block_transactions.blockhash, + int(block_hash, 16), + ) all_indices = msg.block_txn_request.to_absolute() for index in all_indices: - tx = test_node.last_message["blocktxn"].block_transactions.transactions.pop( - 0) + tx = test_node.last_message[ + "blocktxn" + ].block_transactions.transactions.pop(0) tx.calc_sha256() assert_equal(tx.sha256, block.vtx[index].sha256) test_node.last_message.pop("blocktxn", None) @@ -640,8 +660,7 @@ # Next request should send a full block response, as we're past the # allowed depth for a blocktxn response. block_hash = node.getblockhash(current_height) - msg.block_txn_request = BlockTransactionsRequest( - int(block_hash, 16), [0]) + msg.block_txn_request = BlockTransactionsRequest(int(block_hash, 16), [0]) with p2p_lock: test_node.last_message.pop("block", None) test_node.last_message.pop("blocktxn", None) @@ -649,7 +668,8 @@ with p2p_lock: test_node.last_message["block"].block.calc_sha256() assert_equal( - test_node.last_message["block"].block.sha256, int(block_hash, 16)) + test_node.last_message["block"].block.sha256, int(block_hash, 16) + ) assert "blocktxn" not in test_node.last_message def test_compactblocks_not_at_tip(self, node, test_node): @@ -659,30 +679,29 @@ for _ in range(MAX_CMPCTBLOCK_DEPTH + 1): test_node.clear_block_announcement() new_blocks.append(self.generate(node, 1)[0]) - test_node.wait_until(test_node.received_block_announcement, - timeout=30) + test_node.wait_until(test_node.received_block_announcement, timeout=30) test_node.clear_block_announcement() - test_node.send_message(msg_getdata( - [CInv(MSG_CMPCT_BLOCK, int(new_blocks[0], 16))])) - test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, - timeout=30) + test_node.send_message( + msg_getdata([CInv(MSG_CMPCT_BLOCK, int(new_blocks[0], 16))]) + ) + test_node.wait_until(lambda: "cmpctblock" in test_node.last_message, timeout=30) test_node.clear_block_announcement() self.generate(node, 1) - test_node.wait_until(test_node.received_block_announcement, - timeout=30) + test_node.wait_until(test_node.received_block_announcement, timeout=30) test_node.clear_block_announcement() with p2p_lock: test_node.last_message.pop("block", None) - test_node.send_message(msg_getdata( - [CInv(MSG_CMPCT_BLOCK, int(new_blocks[0], 16))])) - test_node.wait_until(lambda: "block" in test_node.last_message, - timeout=30) + test_node.send_message( + msg_getdata([CInv(MSG_CMPCT_BLOCK, int(new_blocks[0], 16))]) + ) + test_node.wait_until(lambda: "block" in test_node.last_message, timeout=30) with p2p_lock: test_node.last_message["block"].block.calc_sha256() assert_equal( - test_node.last_message["block"].block.sha256, int(new_blocks[0], 16)) + test_node.last_message["block"].block.sha256, int(new_blocks[0], 16) + ) # Generate an old compactblock, and verify that it's not accepted. cur_height = node.getblockcount() @@ -724,14 +743,20 @@ node.submitblock(ToHex(block)) for listener in listeners: - listener.wait_until(lambda: "cmpctblock" in listener.last_message, - timeout=30) + listener.wait_until( + lambda: "cmpctblock" in listener.last_message, timeout=30 + ) with p2p_lock: for listener in listeners: - listener.last_message["cmpctblock"].header_and_shortids.header.calc_sha256( - ) + listener.last_message[ + "cmpctblock" + ].header_and_shortids.header.calc_sha256() assert_equal( - listener.last_message["cmpctblock"].header_and_shortids.header.sha256, block.sha256) + listener.last_message[ + "cmpctblock" + ].header_and_shortids.header.sha256, + block.sha256, + ) # Test that we don't get disconnected if we relay a compact block with valid header, # but invalid transactions. @@ -763,7 +788,8 @@ peer.send_and_ping(msg_sendcmpct(announce=True, version=version)) def test_compactblock_reconstruction_multiple_peers( - self, node, stalling_peer, delivery_peer): + self, node, stalling_peer, delivery_peer + ): assert len(self.utxos) def announce_cmpct_block(node, peer): @@ -790,8 +816,7 @@ delivery_peer.send_and_ping(msg_cmpctblock(cmpct_block.to_p2p())) assert_equal(int(node.getbestblockhash(), 16), block.sha256) - self.utxos.append( - [block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) + self.utxos.append([block.vtx[-1].sha256, 0, block.vtx[-1].vout[0].nValue]) # Now test that delivering an invalid compact block won't break relay block, cmpct_block = announce_cmpct_block(node, stalling_peer) @@ -819,8 +844,8 @@ # match the given parameters for the last peer of a given node def assert_highbandwidth_states(node, hb_to, hb_from): peerinfo = node.getpeerinfo()[-1] - assert_equal(peerinfo['bip152_hb_to'], hb_to) - assert_equal(peerinfo['bip152_hb_from'], hb_from) + assert_equal(peerinfo["bip152_hb_to"], hb_to) + assert_equal(peerinfo["bip152_hb_from"], hb_from) # initially, neither node has selected the other peer as high-bandwidth # yet @@ -848,9 +873,11 @@ # Setup the p2p connections self.test_node = self.nodes[0].add_p2p_connection(TestP2PConn()) self.ex_softfork_node = self.nodes[1].add_p2p_connection( - TestP2PConn(), services=NODE_NETWORK) + TestP2PConn(), services=NODE_NETWORK + ) self.old_node = self.nodes[1].add_p2p_connection( - TestP2PConn(), services=NODE_NETWORK) + TestP2PConn(), services=NODE_NETWORK + ) # We will need UTXOs to construct transactions in later tests. self.make_utxos() @@ -861,21 +888,20 @@ self.test_sendcmpct(self.nodes[0], self.test_node, 1) self.sync_blocks() self.test_sendcmpct( - self.nodes[1], self.ex_softfork_node, 1, old_node=self.old_node) + self.nodes[1], self.ex_softfork_node, 1, old_node=self.old_node + ) self.sync_blocks() self.log.info("\tTesting compactblock construction...") self.test_compactblock_construction(self.nodes[0], self.test_node) self.sync_blocks() - self.test_compactblock_construction( - self.nodes[1], self.ex_softfork_node) + self.test_compactblock_construction(self.nodes[1], self.ex_softfork_node) self.sync_blocks() self.log.info("\tTesting compactblock requests... ") self.test_compactblock_requests(self.nodes[0], self.test_node, 1) self.sync_blocks() - self.test_compactblock_requests( - self.nodes[1], self.ex_softfork_node, 2) + self.test_compactblock_requests(self.nodes[1], self.ex_softfork_node, 2) self.sync_blocks() self.log.info("\tTesting getblocktxn requests...") @@ -892,42 +918,41 @@ self.sync_blocks() self.log.info( - "\tTesting compactblock requests/announcements not at chain tip...") + "\tTesting compactblock requests/announcements not at chain tip..." + ) self.test_compactblocks_not_at_tip(self.nodes[0], self.test_node) self.sync_blocks() - self.test_compactblocks_not_at_tip( - self.nodes[1], self.ex_softfork_node) + self.test_compactblocks_not_at_tip(self.nodes[1], self.ex_softfork_node) self.test_compactblocks_not_at_tip(self.nodes[1], self.old_node) self.sync_blocks() self.log.info("\tTesting handling of incorrect blocktxn responses...") self.test_incorrect_blocktxn_response(self.nodes[0], self.test_node, 1) self.sync_blocks() - self.test_incorrect_blocktxn_response( - self.nodes[1], self.ex_softfork_node, 2) + self.test_incorrect_blocktxn_response(self.nodes[1], self.ex_softfork_node, 2) self.sync_blocks() # End-to-end block relay tests self.log.info("\tTesting end-to-end block relay...") self.request_cb_announcements(self.test_node, self.nodes[0]) self.request_cb_announcements(self.old_node, self.nodes[1]) - self.request_cb_announcements( - self.ex_softfork_node, self.nodes[1], version=2) + self.request_cb_announcements(self.ex_softfork_node, self.nodes[1], version=2) self.test_end_to_end_block_relay( - self.nodes[0], [self.ex_softfork_node, self.test_node, self.old_node]) + self.nodes[0], [self.ex_softfork_node, self.test_node, self.old_node] + ) self.test_end_to_end_block_relay( - self.nodes[1], [self.ex_softfork_node, self.test_node, self.old_node]) + self.nodes[1], [self.ex_softfork_node, self.test_node, self.old_node] + ) self.log.info("\tTesting handling of invalid compact blocks...") self.test_invalid_tx_in_compactblock(self.nodes[0], self.test_node) - self.test_invalid_tx_in_compactblock( - self.nodes[1], self.ex_softfork_node) + self.test_invalid_tx_in_compactblock(self.nodes[1], self.ex_softfork_node) self.test_invalid_tx_in_compactblock(self.nodes[1], self.old_node) - self.log.info( - "\tTesting reconstructing compact blocks from all peers...") + self.log.info("\tTesting reconstructing compact blocks from all peers...") self.test_compactblock_reconstruction_multiple_peers( - self.nodes[1], self.ex_softfork_node, self.old_node) + self.nodes[1], self.ex_softfork_node, self.old_node + ) self.sync_blocks() self.log.info("\tTesting invalid index in cmpctblock message...") @@ -937,5 +962,5 @@ self.test_highbandwidth_mode_states_via_getpeerinfo() -if __name__ == '__main__': +if __name__ == "__main__": CompactBlocksTest().main() diff --git a/test/functional/p2p_compactblocks_hb.py b/test/functional/p2p_compactblocks_hb.py --- a/test/functional/p2p_compactblocks_hb.py +++ b/test/functional/p2p_compactblocks_hb.py @@ -18,7 +18,7 @@ def peer_info(self, from_node, to_node): """Query from_node for its getpeerinfo about to_node.""" for peerinfo in self.nodes[from_node].getpeerinfo(): - if f"testnode-{to_node}" in peerinfo['subver']: + if f"testnode-{to_node}" in peerinfo["subver"]: return peerinfo return None @@ -33,8 +33,8 @@ self.connect_nodes(peer, 0) self.generate(self.nodes[0], 1, sync_fun=self.sync_blocks) self.disconnect_nodes(peer, 0) - status_to = [self.peer_info(1, i)['bip152_hb_to'] for i in range(2, 6)] - status_from = [self.peer_info(i, 1)['bip152_hb_from'] for i in range(2, 6)] + status_to = [self.peer_info(1, i)["bip152_hb_to"] for i in range(2, 6)] + status_from = [self.peer_info(i, 1)["bip152_hb_from"] for i in range(2, 6)] assert_equal(status_to, status_from) return status_to @@ -92,5 +92,5 @@ assert_equal(status, [False, True, True, True]) -if __name__ == '__main__': +if __name__ == "__main__": CompactBlocksConnectionTest().main() diff --git a/test/functional/p2p_disconnect_ban.py b/test/functional/p2p_disconnect_ban.py --- a/test/functional/p2p_disconnect_ban.py +++ b/test/functional/p2p_disconnect_ban.py @@ -25,8 +25,7 @@ # node1 should have 2 connections to node0 at this point assert_equal(len(self.nodes[1].getpeerinfo()), 2) self.nodes[1].setban(subnet="127.0.0.1", command="add") - self.wait_until(lambda: len(self.nodes[1].getpeerinfo()) == 0, - timeout=10) + self.wait_until(lambda: len(self.nodes[1].getpeerinfo()) == 0, timeout=10) # all nodes must be disconnected at this point assert_equal(len(self.nodes[1].getpeerinfo()), 0) assert_equal(len(self.nodes[1].listbanned()), 1) @@ -39,18 +38,21 @@ self.log.info("setban: fail to ban an already banned subnet") assert_equal(len(self.nodes[1].listbanned()), 1) assert_raises_rpc_error( - -23, "IP/Subnet already banned", self.nodes[1].setban, "127.0.0.1", "add") + -23, "IP/Subnet already banned", self.nodes[1].setban, "127.0.0.1", "add" + ) self.log.info("setban: fail to ban an invalid subnet") assert_raises_rpc_error( - -30, "Error: Invalid IP/Subnet", self.nodes[1].setban, "127.0.0.1/42", "add") + -30, "Error: Invalid IP/Subnet", self.nodes[1].setban, "127.0.0.1/42", "add" + ) # still only one banned ip because 127.0.0.1 is within the range of # 127.0.0.0/24 assert_equal(len(self.nodes[1].listbanned()), 1) self.log.info("setban remove: fail to unban a non-banned subnet") assert_raises_rpc_error( - -30, "Error: Unban failed", self.nodes[1].setban, "127.0.0.1", "remove") + -30, "Error: Unban failed", self.nodes[1].setban, "127.0.0.1", "remove" + ) assert_equal(len(self.nodes[1].listbanned()), 1) self.log.info("setban remove: successfully unban subnet") @@ -68,10 +70,9 @@ # ban for 1 seconds self.nodes[1].setban("192.168.0.1", "add", 1) # ban for 1000 seconds - self.nodes[1].setban( - "2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) + self.nodes[1].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) listBeforeShutdown = self.nodes[1].listbanned() - assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) + assert_equal("192.168.0.1/32", listBeforeShutdown[2]["address"]) # Move time forward by 3 seconds so the third ban has expired self.nodes[1].setmocktime(old_time + 3) assert_equal(len(self.nodes[1].listbanned()), 3) @@ -79,9 +80,9 @@ self.restart_node(1) listAfterShutdown = self.nodes[1].listbanned() - assert_equal("127.0.0.0/24", listAfterShutdown[0]['address']) - assert_equal("127.0.0.0/32", listAfterShutdown[1]['address']) - assert_equal("/19" in listAfterShutdown[2]['address'], True) + assert_equal("127.0.0.0/24", listAfterShutdown[0]["address"]) + assert_equal("127.0.0.0/32", listAfterShutdown[1]["address"]) + assert_equal("/19" in listAfterShutdown[2]["address"], True) # Clear ban lists self.nodes[1].clearbanned() @@ -92,43 +93,50 @@ self.log.info("Test disconnectnode RPCs") self.log.info( - "disconnectnode: fail to disconnect when calling with address and nodeid") - address1 = self.nodes[0].getpeerinfo()[0]['addr'] - node1 = self.nodes[0].getpeerinfo()[0]['addr'] + "disconnectnode: fail to disconnect when calling with address and nodeid" + ) + address1 = self.nodes[0].getpeerinfo()[0]["addr"] + node1 = self.nodes[0].getpeerinfo()[0]["addr"] assert_raises_rpc_error( - -32602, "Only one of address and nodeid should be provided.", - self.nodes[0].disconnectnode, address=address1, nodeid=node1) + -32602, + "Only one of address and nodeid should be provided.", + self.nodes[0].disconnectnode, + address=address1, + nodeid=node1, + ) self.log.info( - "disconnectnode: fail to disconnect when calling with junk address") - assert_raises_rpc_error(-29, "Node not found in connected nodes", - self.nodes[0].disconnectnode, address="221B Baker Street") - - self.log.info( - "disconnectnode: successfully disconnect node by address") - address1 = self.nodes[0].getpeerinfo()[0]['addr'] + "disconnectnode: fail to disconnect when calling with junk address" + ) + assert_raises_rpc_error( + -29, + "Node not found in connected nodes", + self.nodes[0].disconnectnode, + address="221B Baker Street", + ) + + self.log.info("disconnectnode: successfully disconnect node by address") + address1 = self.nodes[0].getpeerinfo()[0]["addr"] self.nodes[0].disconnectnode(address=address1) - self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, - timeout=10) - assert not [node for node in self.nodes[0].getpeerinfo() - if node['addr'] == address1] + self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, timeout=10) + assert not [ + node for node in self.nodes[0].getpeerinfo() if node["addr"] == address1 + ] self.log.info("disconnectnode: successfully reconnect node") # reconnect the node self.connect_nodes(0, 1) assert_equal(len(self.nodes[0].getpeerinfo()), 2) - assert [node for node in self.nodes[0] - .getpeerinfo() if node['addr'] == address1] + assert [ + node for node in self.nodes[0].getpeerinfo() if node["addr"] == address1 + ] - self.log.info( - "disconnectnode: successfully disconnect node by node id") - id1 = self.nodes[0].getpeerinfo()[0]['id'] + self.log.info("disconnectnode: successfully disconnect node by node id") + id1 = self.nodes[0].getpeerinfo()[0]["id"] self.nodes[0].disconnectnode(nodeid=id1) - self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, - timeout=10) - assert not [node for node in self.nodes[0].getpeerinfo() - if node['id'] == id1] + self.wait_until(lambda: len(self.nodes[0].getpeerinfo()) == 1, timeout=10) + assert not [node for node in self.nodes[0].getpeerinfo() if node["id"] == id1] -if __name__ == '__main__': +if __name__ == "__main__": DisconnectBanTest().main() diff --git a/test/functional/p2p_dos_header_tree.py b/test/functional/p2p_dos_header_tree.py --- a/test/functional/p2p_dos_header_tree.py +++ b/test/functional/p2p_dos_header_tree.py @@ -14,57 +14,56 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework): def set_test_params(self): self.setup_clean_chain = True - self.chain = 'testnet3' # Use testnet chain because it has an early checkpoint + self.chain = "testnet3" # Use testnet chain because it has an early checkpoint self.num_nodes = 2 def add_options(self, parser): parser.add_argument( - '--datafile', - default='data/blockheader_testnet3.hex', - help='Test data file (default: %(default)s)', + "--datafile", + default="data/blockheader_testnet3.hex", + help="Test data file (default: %(default)s)", ) def run_test(self): self.log.info("Read headers data") self.headers_file_path = os.path.join( - os.path.dirname( - os.path.realpath(__file__)), - self.options.datafile) - with open(self.headers_file_path, encoding='utf-8') as headers_data: + os.path.dirname(os.path.realpath(__file__)), self.options.datafile + ) + with open(self.headers_file_path, encoding="utf-8") as headers_data: h_lines = [line.strip() for line in headers_data.readlines()] # The headers data is taken from testnet3 for early blocks from genesis until the first checkpoint. There are # two headers with valid POW at height 1 and 2, forking off from # genesis. They are indicated by the FORK_PREFIX. - FORK_PREFIX = 'fork:' - self.headers = [ - line for line in h_lines if not line.startswith(FORK_PREFIX)] - self.headers_fork = [line[len(FORK_PREFIX):] - for line in h_lines if line.startswith(FORK_PREFIX)] + FORK_PREFIX = "fork:" + self.headers = [line for line in h_lines if not line.startswith(FORK_PREFIX)] + self.headers_fork = [ + line[len(FORK_PREFIX) :] for line in h_lines if line.startswith(FORK_PREFIX) + ] self.headers = [FromHex(CBlockHeader(), h) for h in self.headers] - self.headers_fork = [FromHex(CBlockHeader(), h) - for h in self.headers_fork] + self.headers_fork = [FromHex(CBlockHeader(), h) for h in self.headers_fork] self.log.info( - "Feed all non-fork headers, including and up to the first checkpoint") + "Feed all non-fork headers, including and up to the first checkpoint" + ) peer_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface()) peer_checkpoint.send_and_ping(msg_headers(self.headers)) assert { - 'height': 546, - 'hash': '000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70', - 'branchlen': 546, - 'status': 'headers-only', + "height": 546, + "hash": "000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70", + "branchlen": 546, + "status": "headers-only", } in self.nodes[0].getchaintips() self.log.info("Feed all fork headers (fails due to checkpoint)") - with self.nodes[0].assert_debug_log(['bad-fork-prior-to-checkpoint']): + with self.nodes[0].assert_debug_log(["bad-fork-prior-to-checkpoint"]): peer_checkpoint.send_message(msg_headers(self.headers_fork)) peer_checkpoint.wait_for_disconnect() self.log.info("Feed all fork headers (succeeds without checkpoint)") # On node 0 it succeeds because checkpoints are disabled - self.restart_node(0, ['-nocheckpoints']) + self.restart_node(0, ["-nocheckpoints"]) peer_no_checkpoint = self.nodes[0].add_p2p_connection(P2PInterface()) peer_no_checkpoint.send_and_ping(msg_headers(self.headers_fork)) assert { @@ -76,10 +75,8 @@ # On node 1 it succeeds because no checkpoint has been reached yet by a # chain tip - peer_before_checkpoint = self.nodes[1].add_p2p_connection( - P2PInterface()) - peer_before_checkpoint.send_and_ping( - msg_headers(self.headers_fork)) + peer_before_checkpoint = self.nodes[1].add_p2p_connection(P2PInterface()) + peer_before_checkpoint.send_and_ping(msg_headers(self.headers_fork)) assert { "height": 2, "hash": "00000000b0494bd6c3d5ff79c497cfce40831871cbf39b1bc28bd1dac817dc39", @@ -88,5 +85,5 @@ } in self.nodes[1].getchaintips() -if __name__ == '__main__': +if __name__ == "__main__": RejectLowDifficultyHeadersTest().main() diff --git a/test/functional/p2p_eviction.py b/test/functional/p2p_eviction.py --- a/test/functional/p2p_eviction.py +++ b/test/functional/p2p_eviction.py @@ -64,101 +64,111 @@ # 4 by netgroup, 4 that sent us blocks, 4 that sent us proofs, 4 that # sent us transactions, 8 via lowest ping time, 128 with the best # avalanche availability score - self.extra_args = [["-maxconnections=188", - "-avaproofstakeutxodustthreshold=1000000", - "-avaproofstakeutxoconfirmations=1", - "-maxavalancheoutbound=16"]] + self.extra_args = [ + [ + "-maxconnections=188", + "-avaproofstakeutxodustthreshold=1000000", + "-avaproofstakeutxoconfirmations=1", + "-maxavalancheoutbound=16", + ] + ] def run_test(self): # peers that we expect to be protected from eviction protected_peers = set() current_peer = -1 node = self.nodes[0] - blocks = self.generatetoaddress(node, - 101, node.get_deterministic_priv_key().address) + blocks = self.generatetoaddress( + node, 101, node.get_deterministic_priv_key().address + ) self.log.info( - "Create 4 peers and protect them from eviction by sending us a block") + "Create 4 peers and protect them from eviction by sending us a block" + ) for _ in range(4): block_peer = node.add_p2p_connection(SlowP2PDataStore()) current_peer += 1 block_peer.sync_with_ping() best_block = node.getbestblockhash() tip = int(best_block, 16) - best_block_time = node.getblock(best_block)['time'] + best_block_time = node.getblock(best_block)["time"] block = create_block( - tip, - create_coinbase( - node.getblockcount() + 1), - best_block_time + 1) + tip, create_coinbase(node.getblockcount() + 1), best_block_time + 1 + ) block.solve() block_peer.send_blocks_and_test([block], node, success=True) protected_peers.add(current_peer) self.log.info( - "Create 4 peers and protect them from eviction by sending us a proof") + "Create 4 peers and protect them from eviction by sending us a proof" + ) privkey = ECKey() privkey.generate() wif_privkey = bytes_to_wif(privkey.get_bytes()) stakes = create_coinbase_stakes( - node, blocks, node.get_deterministic_priv_key().key) + node, blocks, node.get_deterministic_priv_key().key + ) for i in range(4): proof_peer = node.add_p2p_connection(SlowP2PDataStore()) current_peer += 1 proof_peer.sync_with_ping() - proof = node.buildavalancheproof( - 42, 2000000000, wif_privkey, [stakes[i]]) + proof = node.buildavalancheproof(42, 2000000000, wif_privkey, [stakes[i]]) avaproof_msg = msg_avaproof() avaproof_msg.proof = avalanche_proof_from_hex(proof) proof_peer.send_message(avaproof_msg) protected_peers.add(current_peer) - self.log.info( - "Create 5 slow-pinging peers, making them eviction candidates") + self.log.info("Create 5 slow-pinging peers, making them eviction candidates") for _ in range(5): node.add_p2p_connection(SlowP2PInterface()) current_peer += 1 self.log.info( - "Create 4 peers and protect them from eviction by sending us a tx") + "Create 4 peers and protect them from eviction by sending us a tx" + ) for i in range(4): txpeer = node.add_p2p_connection(SlowP2PInterface()) current_peer += 1 txpeer.sync_with_ping() - prevtx = node.getblock(node.getblockhash(i + 1), 2)['tx'][0] + prevtx = node.getblock(node.getblockhash(i + 1), 2)["tx"][0] rawtx = node.createrawtransaction( - inputs=[{'txid': prevtx['txid'], 'vout': 0}], + inputs=[{"txid": prevtx["txid"], "vout": 0}], outputs=[ - {node.get_deterministic_priv_key().address: 50000000 - 1250.00}], + {node.get_deterministic_priv_key().address: 50000000 - 1250.00} + ], ) sigtx = node.signrawtransactionwithkey( hexstring=rawtx, privkeys=[node.get_deterministic_priv_key().key], - prevtxs=[{ - 'txid': prevtx['txid'], - 'vout': 0, - 'amount': prevtx['vout'][0]['value'], - 'scriptPubKey': prevtx['vout'][0]['scriptPubKey']['hex'], - }], - )['hex'] + prevtxs=[ + { + "txid": prevtx["txid"], + "vout": 0, + "amount": prevtx["vout"][0]["value"], + "scriptPubKey": prevtx["vout"][0]["scriptPubKey"]["hex"], + } + ], + )["hex"] txpeer.send_message(msg_tx(FromHex(CTransaction(), sigtx))) protected_peers.add(current_peer) self.log.info( - "Create 8 peers and protect them from eviction by having faster pings") + "Create 8 peers and protect them from eviction by having faster pings" + ) for _ in range(8): fastpeer = node.add_p2p_connection(P2PInterface()) current_peer += 1 - self.wait_until(lambda: "ping" in fastpeer.last_message, - timeout=10) + self.wait_until(lambda: "ping" in fastpeer.last_message, timeout=10) self.log.info( - "Create 128 peers and protect them from eviction by sending an avahello message") + "Create 128 peers and protect them from eviction by sending an avahello" + " message" + ) for _ in range(128): node.add_p2p_connection(SlowAvaP2PInterface()) @@ -168,7 +178,7 @@ peerinfo = node.getpeerinfo() pings = {} for i in range(len(peerinfo)): - pings[i] = peerinfo[i]['minping'] if 'minping' in peerinfo[i] else 1000000 + pings[i] = peerinfo[i]["minping"] if "minping" in peerinfo[i] else 1000000 sorted_pings = sorted(pings.items(), key=lambda x: x[1]) # Usually the 8 fast peers are protected. In rare case of unreliable pings, @@ -189,15 +199,13 @@ evicted_peers.append(i) self.log.info("Test that one peer was evicted") - self.log.debug( - f"{len(evicted_peers)} evicted peer: {set(evicted_peers)}") + self.log.debug(f"{len(evicted_peers)} evicted peer: {set(evicted_peers)}") assert_equal(len(evicted_peers), 1) self.log.info("Test that no peer expected to be protected was evicted") - self.log.debug( - f"{len(protected_peers)} protected peers: {protected_peers}") + self.log.debug(f"{len(protected_peers)} protected peers: {protected_peers}") assert evicted_peers[0] not in protected_peers -if __name__ == '__main__': +if __name__ == "__main__": P2PEvict().main() diff --git a/test/functional/p2p_feefilter.py b/test/functional/p2p_feefilter.py --- a/test/functional/p2p_feefilter.py +++ b/test/functional/p2p_feefilter.py @@ -31,7 +31,7 @@ def on_inv(self, message): for i in message.inv: - if (i.type == MSG_TX): + if i.type == MSG_TX: self.txinvs.append(uint256_hex(i.hash)) def wait_for_invs_to_match(self, invs_expected): @@ -53,11 +53,13 @@ # See issue #16499 # grant noban permission to all peers to speed up tx relay / mempool # sync - self.extra_args = [[ - "-minrelaytxfee=1", - "-mintxfee=1", - "-whitelist=noban@127.0.0.1", - ]] * self.num_nodes + self.extra_args = [ + [ + "-minrelaytxfee=1", + "-mintxfee=1", + "-whitelist=noban@127.0.0.1", + ] + ] * self.num_nodes def run_test(self): self.test_feefilter_forcerelay() @@ -66,15 +68,20 @@ def test_feefilter_forcerelay(self): self.log.info( - 'Check that peers without forcerelay permission (default) get a feefilter message') - self.nodes[0].add_p2p_connection( - FeefilterConn()).assert_feefilter_received(True) + "Check that peers without forcerelay permission (default) get a feefilter" + " message" + ) + self.nodes[0].add_p2p_connection(FeefilterConn()).assert_feefilter_received( + True + ) self.log.info( - 'Check that peers with forcerelay permission do not get a feefilter message') - self.restart_node(0, extra_args=['-whitelist=forcerelay@127.0.0.1']) - self.nodes[0].add_p2p_connection( - FeefilterConn()).assert_feefilter_received(False) + "Check that peers with forcerelay permission do not get a feefilter message" + ) + self.restart_node(0, extra_args=["-whitelist=forcerelay@127.0.0.1"]) + self.nodes[0].add_p2p_connection(FeefilterConn()).assert_feefilter_received( + False + ) # Restart to disconnect peers and load default extra_args self.restart_node(0) @@ -91,30 +98,38 @@ conn = self.nodes[0].add_p2p_connection(TestP2PConn()) - self.log.info( - "Test txs paying 0.2 sat/byte are received by test connection") - txids = [miniwallet.send_self_transfer(fee_rate=Decimal('2.00'), - from_node=node1)['txid'] - for _ in range(3)] + self.log.info("Test txs paying 0.2 sat/byte are received by test connection") + txids = [ + miniwallet.send_self_transfer(fee_rate=Decimal("2.00"), from_node=node1)[ + "txid" + ] + for _ in range(3) + ] conn.wait_for_invs_to_match(txids) conn.clear_invs() # Set a fee filter of 0.15 sat/byte on test connection conn.send_and_ping(msg_feefilter(150)) - self.log.info( - "Test txs paying 0.15 sat/byte are received by test connection") - txids = [miniwallet.send_self_transfer(fee_rate=Decimal('1.50'), - from_node=node1)['txid'] - for _ in range(3)] + self.log.info("Test txs paying 0.15 sat/byte are received by test connection") + txids = [ + miniwallet.send_self_transfer(fee_rate=Decimal("1.50"), from_node=node1)[ + "txid" + ] + for _ in range(3) + ] conn.wait_for_invs_to_match(txids) conn.clear_invs() self.log.info( - "Test txs paying 0.1 sat/byte are no longer received by test connection") - txids = [miniwallet.send_self_transfer(fee_rate=Decimal('1.00'), - from_node=node1)['txid'] - for _ in range(3)] + "Test txs paying 0.1 sat/byte are no longer received by test connection" + ) + txids = [ + miniwallet.send_self_transfer(fee_rate=Decimal("1.00"), from_node=node1)[ + "txid" + ] + for _ in range(3) + ] self.sync_mempools() # must be sure node 0 has received all txs # Send one transaction from node0 that should be received, so that we @@ -124,8 +139,11 @@ # to 35 entries in an inv, which means that when this next transaction # is eligible for relay, the prior transactions from node1 are eligible # as well. - txids = [miniwallet.send_self_transfer(fee_rate=Decimal('200.00'), - from_node=node0)['txid']] + txids = [ + miniwallet.send_self_transfer(fee_rate=Decimal("200.00"), from_node=node0)[ + "txid" + ] + ] conn.wait_for_invs_to_match(txids) conn.clear_invs() # must be sure node 1 has received all txs @@ -133,29 +151,31 @@ self.log.info("Remove fee filter and check txs are received again") conn.send_and_ping(msg_feefilter(0)) - txids = [miniwallet.send_self_transfer(fee_rate=Decimal('200.00'), - from_node=node1)['txid'] - for _ in range(3)] + txids = [ + miniwallet.send_self_transfer(fee_rate=Decimal("200.00"), from_node=node1)[ + "txid" + ] + for _ in range(3) + ] conn.wait_for_invs_to_match(txids) conn.clear_invs() def test_feefilter_blocksonly(self): """Test that we don't send fee filters to block-relay-only peers and when we're in blocksonly mode.""" - self.log.info( - "Check that we don't send fee filters to block-relay-only peers.") + self.log.info("Check that we don't send fee filters to block-relay-only peers.") feefilter_peer = self.nodes[0].add_outbound_p2p_connection( - FeefilterConn(), p2p_idx=0, connection_type="block-relay-only") + FeefilterConn(), p2p_idx=0, connection_type="block-relay-only" + ) feefilter_peer.sync_with_ping() feefilter_peer.assert_feefilter_received(False) - self.log.info( - "Check that we don't send fee filters when in blocksonly mode.") + self.log.info("Check that we don't send fee filters when in blocksonly mode.") self.restart_node(0, ["-blocksonly"]) feefilter_peer = self.nodes[0].add_p2p_connection(FeefilterConn()) feefilter_peer.sync_with_ping() feefilter_peer.assert_feefilter_received(False) -if __name__ == '__main__': +if __name__ == "__main__": FeeFilterTest().main() diff --git a/test/functional/p2p_filter.py b/test/functional/p2p_filter.py --- a/test/functional/p2p_filter.py +++ b/test/functional/p2p_filter.py @@ -35,11 +35,15 @@ class P2PBloomFilter(P2PInterface): # This is a P2SH watch-only wallet watch_script_pubkey = bytes.fromhex( - 'a914ffffffffffffffffffffffffffffffffffffffff87') + "a914ffffffffffffffffffffffffffffffffffffffff87" + ) # The initial filter (n=10, fp=0.000001) with just the above scriptPubKey # added watch_filter_init = msg_filterload( - data=b'@\x00\x08\x00\x80\x00\x00 \x00\xc0\x00 \x04\x00\x08$\x00\x04\x80\x00\x00 \x00\x00\x00\x00\x80\x00\x00@\x00\x02@ \x00', + data=( + b"@\x00\x08\x00\x80\x00\x00 \x00\xc0\x00 \x04\x00\x08$\x00\x04\x80\x00\x00" + b" \x00\x00\x00\x00\x80\x00\x00@\x00\x02@ \x00" + ), nHashFuncs=19, nTweak=0, nFlags=1, @@ -92,73 +96,80 @@ class FilterTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 - self.extra_args = [[ - '-peerbloomfilters', - '-whitelist=noban@127.0.0.1', # immediate tx relay - ]] + self.extra_args = [ + [ + "-peerbloomfilters", + "-whitelist=noban@127.0.0.1", # immediate tx relay + ] + ] def generatetoscriptpubkey(self, scriptpubkey): """Helper to generate a single block to the given scriptPubKey.""" return self.generatetodescriptor( - self.nodes[0], 1, f'raw({scriptpubkey.hex()})')[0] + self.nodes[0], 1, f"raw({scriptpubkey.hex()})" + )[0] def test_size_limits(self, filter_peer): - self.log.info('Check that too large filter is rejected') - with self.nodes[0].assert_debug_log(['Misbehaving']): - filter_peer.send_and_ping(msg_filterload( - data=b'\xbb' * (MAX_BLOOM_FILTER_SIZE + 1))) + self.log.info("Check that too large filter is rejected") + with self.nodes[0].assert_debug_log(["Misbehaving"]): + filter_peer.send_and_ping( + msg_filterload(data=b"\xbb" * (MAX_BLOOM_FILTER_SIZE + 1)) + ) - self.log.info('Check that max size filter is accepted') - with self.nodes[0].assert_debug_log([""], unexpected_msgs=['Misbehaving']): + self.log.info("Check that max size filter is accepted") + with self.nodes[0].assert_debug_log([""], unexpected_msgs=["Misbehaving"]): filter_peer.send_and_ping( - msg_filterload( - data=b'\xbb' * - (MAX_BLOOM_FILTER_SIZE))) + msg_filterload(data=b"\xbb" * (MAX_BLOOM_FILTER_SIZE)) + ) filter_peer.send_and_ping(msg_filterclear()) - self.log.info( - 'Check that filter with too many hash functions is rejected') - with self.nodes[0].assert_debug_log(['Misbehaving']): + self.log.info("Check that filter with too many hash functions is rejected") + with self.nodes[0].assert_debug_log(["Misbehaving"]): filter_peer.send_and_ping( - msg_filterload( - data=b'\xaa', - nHashFuncs=MAX_BLOOM_HASH_FUNCS + 1)) + msg_filterload(data=b"\xaa", nHashFuncs=MAX_BLOOM_HASH_FUNCS + 1) + ) - self.log.info('Check that filter with max hash functions is accepted') - with self.nodes[0].assert_debug_log([""], unexpected_msgs=['Misbehaving']): + self.log.info("Check that filter with max hash functions is accepted") + with self.nodes[0].assert_debug_log([""], unexpected_msgs=["Misbehaving"]): filter_peer.send_and_ping( - msg_filterload( - data=b'\xaa', - nHashFuncs=MAX_BLOOM_HASH_FUNCS)) + msg_filterload(data=b"\xaa", nHashFuncs=MAX_BLOOM_HASH_FUNCS) + ) # Don't send filterclear until next two filteradd checks are done self.log.info( - 'Check that max size data element to add to the filter is accepted') - with self.nodes[0].assert_debug_log([""], unexpected_msgs=['Misbehaving']): + "Check that max size data element to add to the filter is accepted" + ) + with self.nodes[0].assert_debug_log([""], unexpected_msgs=["Misbehaving"]): filter_peer.send_and_ping( - msg_filteradd( - data=b'\xcc' * - (MAX_SCRIPT_ELEMENT_SIZE))) + msg_filteradd(data=b"\xcc" * (MAX_SCRIPT_ELEMENT_SIZE)) + ) self.log.info( - 'Check that too large data element to add to the filter is rejected') - with self.nodes[0].assert_debug_log(['Misbehaving']): - filter_peer.send_and_ping(msg_filteradd( - data=b'\xcc' * (MAX_SCRIPT_ELEMENT_SIZE + 1))) + "Check that too large data element to add to the filter is rejected" + ) + with self.nodes[0].assert_debug_log(["Misbehaving"]): + filter_peer.send_and_ping( + msg_filteradd(data=b"\xcc" * (MAX_SCRIPT_ELEMENT_SIZE + 1)) + ) filter_peer.send_and_ping(msg_filterclear()) def test_msg_mempool(self): self.log.info( - "Check that a node with bloom filters enabled services p2p mempool messages") + "Check that a node with bloom filters enabled services p2p mempool messages" + ) filter_peer = P2PBloomFilter() self.log.debug("Create a tx relevant to the peer before connecting") txid, _ = self.wallet.send_to( - from_node=self.nodes[0], scriptPubKey=filter_peer.watch_script_pubkey, amount=9 * COIN) + from_node=self.nodes[0], + scriptPubKey=filter_peer.watch_script_pubkey, + amount=9 * COIN, + ) self.log.debug( - "Send a mempool msg after connecting and check that the tx is received") + "Send a mempool msg after connecting and check that the tx is received" + ) self.nodes[0].add_p2p_connection(filter_peer) filter_peer.send_and_ping(filter_peer.watch_filter_init) filter_peer.send_message(msg_mempool()) @@ -166,12 +177,15 @@ def test_frelay_false(self, filter_peer): self.log.info( - "Check that a node with fRelay set to false does not receive invs until the filter is set") + "Check that a node with fRelay set to false does not receive invs until the" + " filter is set" + ) filter_peer.tx_received = False self.wallet.send_to( from_node=self.nodes[0], scriptPubKey=filter_peer.watch_script_pubkey, - amount=9 * COIN) + amount=9 * COIN, + ) # Sync to make sure the reason filter_peer doesn't receive the tx is # not p2p delays filter_peer.sync_with_ping() @@ -185,58 +199,67 @@ # Set the bloomfilter using filterload filter_peer.send_and_ping(filter_peer.watch_filter_init) # If fRelay is not already True, sending filterload sets it to True - assert self.nodes[0].getpeerinfo()[0]['relaytxes'] + assert self.nodes[0].getpeerinfo()[0]["relaytxes"] self.log.info( - 'Check that we receive merkleblock and tx if the filter matches a tx in a block') - block_hash = self.generatetoscriptpubkey( - filter_peer.watch_script_pubkey) - txid = self.nodes[0].getblock(block_hash)['tx'][0] + "Check that we receive merkleblock and tx if the filter matches a tx in a" + " block" + ) + block_hash = self.generatetoscriptpubkey(filter_peer.watch_script_pubkey) + txid = self.nodes[0].getblock(block_hash)["tx"][0] filter_peer.wait_for_merkleblock(block_hash) filter_peer.wait_for_tx(txid) self.log.info( - 'Check that we only receive a merkleblock if the filter does not match a tx in a block') + "Check that we only receive a merkleblock if the filter does not match a tx" + " in a block" + ) filter_peer.tx_received = False block_hash = self.generatetoscriptpubkey(getnewdestination()[1]) filter_peer.wait_for_merkleblock(block_hash) assert not filter_peer.tx_received self.log.info( - 'Check that we not receive a tx if the filter does not match a mempool tx') + "Check that we not receive a tx if the filter does not match a mempool tx" + ) filter_peer.merkleblock_received = False filter_peer.tx_received = False self.wallet.send_to( from_node=self.nodes[0], scriptPubKey=getnewdestination()[1], - amount=7 * COIN) + amount=7 * COIN, + ) filter_peer.sync_send_with_ping() assert not filter_peer.merkleblock_received assert not filter_peer.tx_received - self.log.info( - 'Check that we receive a tx if the filter matches a mempool tx') + self.log.info("Check that we receive a tx if the filter matches a mempool tx") filter_peer.merkleblock_received = False txid, _ = self.wallet.send_to( - from_node=self.nodes[0], scriptPubKey=filter_peer.watch_script_pubkey, amount=9 * COIN) + from_node=self.nodes[0], + scriptPubKey=filter_peer.watch_script_pubkey, + amount=9 * COIN, + ) filter_peer.wait_for_tx(txid) assert not filter_peer.merkleblock_received - self.log.info( - 'Check that after deleting filter all txs get relayed again') + self.log.info("Check that after deleting filter all txs get relayed again") filter_peer.send_and_ping(msg_filterclear()) for _ in range(5): txid, _ = self.wallet.send_to( - from_node=self.nodes[0], scriptPubKey=getnewdestination()[1], amount=7 * COIN) + from_node=self.nodes[0], + scriptPubKey=getnewdestination()[1], + amount=7 * COIN, + ) filter_peer.wait_for_tx(txid) self.log.info( - 'Check that request for filtered blocks is ignored if no filter' - ' is set') + "Check that request for filtered blocks is ignored if no filter is set" + ) filter_peer.merkleblock_received = False filter_peer.tx_received = False - with self.nodes[0].assert_debug_log(expected_msgs=['received getdata']): + with self.nodes[0].assert_debug_log(expected_msgs=["received getdata"]): block_hash = self.generatetoscriptpubkey(getnewdestination()[1]) filter_peer.wait_for_inv([CInv(MSG_BLOCK, int(block_hash, 16))]) filter_peer.sync_with_ping() @@ -245,16 +268,16 @@ self.log.info( 'Check that sending "filteradd" if no filter is set is treated as ' - 'misbehavior') - with self.nodes[0].assert_debug_log(['Misbehaving']): - filter_peer.send_and_ping(msg_filteradd(data=b'letsmisbehave')) + "misbehavior" + ) + with self.nodes[0].assert_debug_log(["Misbehaving"]): + filter_peer.send_and_ping(msg_filteradd(data=b"letsmisbehave")) self.log.info( - "Check that division-by-zero remote crash bug [CVE-2013-5700] is fixed") - filter_peer.send_and_ping(msg_filterload(data=b'', nHashFuncs=1)) - filter_peer.send_and_ping( - msg_filteradd( - data=b'letstrytocrashthisnode')) + "Check that division-by-zero remote crash bug [CVE-2013-5700] is fixed" + ) + filter_peer.send_and_ping(msg_filterload(data=b"", nHashFuncs=1)) + filter_peer.send_and_ping(msg_filteradd(data=b"letstrytocrashthisnode")) self.nodes[0].disconnect_p2ps() def run_test(self): @@ -262,17 +285,18 @@ self.wallet.rescan_utxos() filter_peer = self.nodes[0].add_p2p_connection(P2PBloomFilter()) - self.log.info('Test filter size limits') + self.log.info("Test filter size limits") self.test_size_limits(filter_peer) - self.log.info('Test BIP 37 for a node with fRelay = True (default)') + self.log.info("Test BIP 37 for a node with fRelay = True (default)") self.test_filter(filter_peer) self.nodes[0].disconnect_p2ps() - self.log.info('Test BIP 37 for a node with fRelay = False') + self.log.info("Test BIP 37 for a node with fRelay = False") # Add peer but do not send version yet filter_peer_without_nrelay = self.nodes[0].add_p2p_connection( - P2PBloomFilter(), send_version=False, wait_for_verack=False) + P2PBloomFilter(), send_version=False, wait_for_verack=False + ) # Send version with relay=False version_without_fRelay = msg_version() version_without_fRelay.nVersion = P2P_VERSION @@ -281,12 +305,12 @@ version_without_fRelay.relay = 0 filter_peer_without_nrelay.send_message(version_without_fRelay) filter_peer_without_nrelay.wait_for_verack() - assert not self.nodes[0].getpeerinfo()[0]['relaytxes'] + assert not self.nodes[0].getpeerinfo()[0]["relaytxes"] self.test_frelay_false(filter_peer_without_nrelay) self.test_filter(filter_peer_without_nrelay) self.test_msg_mempool() -if __name__ == '__main__': +if __name__ == "__main__": FilterTest().main() diff --git a/test/functional/p2p_fingerprint.py b/test/functional/p2p_fingerprint.py --- a/test/functional/p2p_fingerprint.py +++ b/test/functional/p2p_fingerprint.py @@ -67,8 +67,9 @@ self.nodes[0].setmocktime(int(time.time()) - 60 * 24 * 60 * 60) # Generating a chain of 10 blocks - block_hashes = self.generatetoaddress(self.nodes[0], - 10, self.nodes[0].get_deterministic_priv_key().address) + block_hashes = self.generatetoaddress( + self.nodes[0], 10, self.nodes[0].get_deterministic_priv_key().address + ) # Create longer chain starting 2 blocks before current tip height = len(block_hashes) - 2 @@ -98,8 +99,12 @@ # Longest chain is extended so stale is much older than chain tip self.nodes[0].setmocktime(0) - block_hash = int(self.generatetoaddress(self.nodes[0], - 1, self.nodes[0].get_deterministic_priv_key().address)[-1], 16) + block_hash = int( + self.generatetoaddress( + self.nodes[0], 1, self.nodes[0].get_deterministic_priv_key().address + )[-1], + 16, + ) assert_equal(self.nodes[0].getblockcount(), 14) node0.wait_for_block(block_hash, timeout=3) @@ -130,5 +135,5 @@ node0.wait_for_header(hex(block_hash), timeout=3) -if __name__ == '__main__': +if __name__ == "__main__": P2PFingerprintTest().main() diff --git a/test/functional/p2p_getaddr_caching.py b/test/functional/p2p_getaddr_caching.py --- a/test/functional/p2p_getaddr_caching.py +++ b/test/functional/p2p_getaddr_caching.py @@ -17,7 +17,6 @@ class AddrReceiver(P2PInterface): - def __init__(self): super().__init__() self.received_addrs = None @@ -43,7 +42,7 @@ # - core#25333 def run_test(self): - self.log.info('Fill peer AddrMan with a lot of records') + self.log.info("Fill peer AddrMan with a lot of records") for i in range(10000): first_octet = i >> 8 second_octet = i % 256 @@ -54,10 +53,11 @@ # response later because only a fraction of all known addresses # can be cached and returned. assert len(self.nodes[0].getnodeaddresses(0)) > int( - MAX_ADDR_TO_SEND / (MAX_PCT_ADDR_TO_SEND / 100)) + MAX_ADDR_TO_SEND / (MAX_PCT_ADDR_TO_SEND / 100) + ) responses = [] - self.log.info('Send many addr requests within short time to receive') + self.log.info("Send many addr requests within short time to receive") N = 5 cur_mock_time = int(time.time()) @@ -76,7 +76,7 @@ cur_mock_time += 3 * 24 * 60 * 60 self.nodes[0].setmocktime(cur_mock_time) - self.log.info('After time passed, see a new response to addr request') + self.log.info("After time passed, see a new response to addr request") last_addr_receiver = self.nodes[0].add_p2p_connection(AddrReceiver()) last_addr_receiver.send_and_ping(msg_getaddr()) # Trigger response @@ -84,9 +84,8 @@ self.nodes[0].setmocktime(cur_mock_time) last_addr_receiver.wait_until(last_addr_receiver.addr_received) # new response is different - assert (set(responses[0]) != set( - last_addr_receiver.get_received_addrs())) + assert set(responses[0]) != set(last_addr_receiver.get_received_addrs()) -if __name__ == '__main__': +if __name__ == "__main__": AddrTest().main() diff --git a/test/functional/p2p_getdata.py b/test/functional/p2p_getdata.py --- a/test/functional/p2p_getdata.py +++ b/test/functional/p2p_getdata.py @@ -28,7 +28,8 @@ p2p_block_store = self.nodes[0].add_p2p_connection(P2PStoreBlock()) self.log.info( - "test that an invalid GETDATA doesn't prevent processing of future messages") + "test that an invalid GETDATA doesn't prevent processing of future messages" + ) # Send invalid message and verify that node responds to later ping invalid_getdata = msg_getdata() @@ -40,9 +41,8 @@ good_getdata = msg_getdata() good_getdata.inv.append(CInv(t=2, h=best_block)) p2p_block_store.send_and_ping(good_getdata) - p2p_block_store.wait_until( - lambda: p2p_block_store.blocks[best_block] == 1) + p2p_block_store.wait_until(lambda: p2p_block_store.blocks[best_block] == 1) -if __name__ == '__main__': +if __name__ == "__main__": GetdataTest().main() diff --git a/test/functional/p2p_i2p_ports.py b/test/functional/p2p_i2p_ports.py --- a/test/functional/p2p_i2p_ports.py +++ b/test/functional/p2p_i2p_ports.py @@ -24,26 +24,28 @@ addr = "zsxwyo6qcn3chqzwxnseusqgsnuw3maqnztkiypyfxtya4snkoka.b32.i2p:8333" raised = False try: - with node.assert_debug_log( - expected_msgs=[f"Error connecting to {addr}"]): + with node.assert_debug_log(expected_msgs=[f"Error connecting to {addr}"]): node.addnode(node=addr, command="onetry") except AssertionError as e: raised = True if not re.search( - r"Expected messages .* does not partially match log", - str(e)): + r"Expected messages .* does not partially match log", str(e) + ): raise AssertionError( - f"Assertion raised as expected, but with an unexpected message: {str(e)}") + "Assertion raised as expected, but with an unexpected message:" + f" {str(e)}" + ) if not raised: raise AssertionError("Assertion should have been raised") self.log.info( - "Ensure we try to connect if port=0 and get an error due to missing I2P proxy") + "Ensure we try to connect if port=0 and get an error due to missing I2P" + " proxy" + ) addr = "h3r6bkn46qxftwja53pxiykntegfyfjqtnzbm6iv6r5mungmqgmq.b32.i2p:0" - with node.assert_debug_log( - expected_msgs=[f"Error connecting to {addr}"]): + with node.assert_debug_log(expected_msgs=[f"Error connecting to {addr}"]): node.addnode(node=addr, command="onetry") -if __name__ == '__main__': +if __name__ == "__main__": I2PPorts().main() diff --git a/test/functional/p2p_ibd_txrelay.py b/test/functional/p2p_ibd_txrelay.py --- a/test/functional/p2p_ibd_txrelay.py +++ b/test/functional/p2p_ibd_txrelay.py @@ -23,24 +23,29 @@ ] def run_test(self): - self.log.info( - "Check that nodes set minfilter to MAX_MONEY while still in IBD") + self.log.info("Check that nodes set minfilter to MAX_MONEY while still in IBD") for node in self.nodes: - assert node.getblockchaininfo()['initialblockdownload'] - self.wait_until(lambda: all(peer['minfeefilter'] == MAX_FEE_FILTER - for peer in node.getpeerinfo())) + assert node.getblockchaininfo()["initialblockdownload"] + self.wait_until( + lambda: all( + peer["minfeefilter"] == MAX_FEE_FILTER + for peer in node.getpeerinfo() + ) + ) # Come out of IBD by generating a block self.generate(self.nodes[0], 1) - self.log.info( - "Check that nodes reset minfilter after coming out of IBD") + self.log.info("Check that nodes reset minfilter after coming out of IBD") for node in self.nodes: - assert not node.getblockchaininfo()['initialblockdownload'] + assert not node.getblockchaininfo()["initialblockdownload"] self.wait_until( - lambda: all(peer['minfeefilter'] == NORMAL_FEE_FILTER - for peer in node.getpeerinfo())) + lambda: all( + peer["minfeefilter"] == NORMAL_FEE_FILTER + for peer in node.getpeerinfo() + ) + ) -if __name__ == '__main__': +if __name__ == "__main__": P2PIBDTxRelayTest().main() diff --git a/test/functional/p2p_inv_download.py b/test/functional/p2p_inv_download.py --- a/test/functional/p2p_inv_download.py +++ b/test/functional/p2p_inv_download.py @@ -44,21 +44,24 @@ class NetConstants: """Constants from net_processing""" - def __init__(self, - getdata_interval, - inbound_peer_delay, - overloaded_peer_delay, - max_getdata_in_flight, - max_peer_announcements, - bypass_request_limits_permission_flags, - ): + def __init__( + self, + getdata_interval, + inbound_peer_delay, + overloaded_peer_delay, + max_getdata_in_flight, + max_peer_announcements, + bypass_request_limits_permission_flags, + ): self.getdata_interval = getdata_interval self.inbound_peer_delay = inbound_peer_delay self.overloaded_peer_delay = overloaded_peer_delay self.max_getdata_in_flight = max_getdata_in_flight self.max_peer_announcements = max_peer_announcements self.max_getdata_inbound_wait = self.getdata_interval + self.inbound_peer_delay - self.bypass_request_limits_permission_flags = bypass_request_limits_permission_flags + self.bypass_request_limits_permission_flags = ( + bypass_request_limits_permission_flags + ) class TestContext: @@ -114,22 +117,27 @@ if call_context == context: return lambda *args, **kwargs: None return test(*args, **kwargs) + return wrapper + return decorator class InventoryDownloadTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 - self.extra_args = [['-avaproofstakeutxodustthreshold=1000000', - '-avaproofstakeutxoconfirmations=1', - '-avacooldown=0']] * self.num_nodes + self.extra_args = [ + [ + "-avaproofstakeutxodustthreshold=1000000", + "-avaproofstakeutxoconfirmations=1", + "-avacooldown=0", + ] + ] * self.num_nodes def test_data_requests(self, context): - self.log.info( - "Test that we request data from all our peers, eventually") + self.log.info("Test that we request data from all our peers, eventually") - invid = 0xdeadbeef + invid = 0xDEADBEEF self.log.info("Announce the invid from each incoming peer to node 0") msg = msg_inv([CInv(t=context.inv_type, h=invid)]) @@ -141,15 +149,18 @@ def getdata_found(peer_index): p = self.nodes[0].p2ps[peer_index] with p2p_lock: - return p.last_message.get( - "getdata") and p.last_message["getdata"].inv[-1].hash == invid + return ( + p.last_message.get("getdata") + and p.last_message["getdata"].inv[-1].hash == invid + ) node_0_mocktime = int(time.time()) while outstanding_peer_index: node_0_mocktime += context.constants.max_getdata_inbound_wait self.nodes[0].setmocktime(node_0_mocktime) - self.wait_until(lambda: any(getdata_found(i) - for i in outstanding_peer_index)) + self.wait_until( + lambda: any(getdata_found(i) for i in outstanding_peer_index) + ) for i in outstanding_peer_index: if getdata_found(i): outstanding_peer_index.remove(i) @@ -161,23 +172,28 @@ def test_inv_tx(self, context): self.log.info("Generate a transaction on node 0") tx = self.nodes[0].createrawtransaction( - inputs=[{ - # coinbase - "txid": self.nodes[0].getblock(self.nodes[0].getblockhash(1))['tx'][0], - "vout": 0 - }], + inputs=[ + { + # coinbase + "txid": self.nodes[0].getblock(self.nodes[0].getblockhash(1))["tx"][ + 0 + ], + "vout": 0, + } + ], outputs={ADDRESS_ECREG_UNSPENDABLE: 50000000 - 250.00}, ) tx = self.nodes[0].signrawtransactionwithkey( hexstring=tx, privkeys=[self.nodes[0].get_deterministic_priv_key().key], - )['hex'] + )["hex"] ctx = FromHex(CTransaction(), tx) txid = int(ctx.rehash(), 16) self.log.info( f"Announce the transaction to all nodes from all {NUM_INBOUND} incoming " - "peers, but never send it") + "peers, but never send it" + ) msg = msg_inv([CInv(t=context.inv_type, h=txid)]) for p in self.peers: p.send_and_ping(msg) @@ -191,9 +207,9 @@ # forward, which has the added side effect that the tx can be # unconditionally requested. with self.nodes[1].assert_debug_log( - [f"got inv: tx {uint256_hex(txid)} new peer=0"]): - self.nodes[0].setmocktime( - int(time.time()) + UNCONDITIONAL_RELAY_DELAY) + [f"got inv: tx {uint256_hex(txid)} new peer=0"] + ): + self.nodes[0].setmocktime(int(time.time()) + UNCONDITIONAL_RELAY_DELAY) # Since node 1 is connected outbound to an honest peer (node 0), it # should get the tx within a timeout. @@ -202,23 +218,28 @@ # peer, plus # * the first time it is re-requested from the outbound peer, plus # * 2 seconds to avoid races - assert self.nodes[1].getpeerinfo()[0]['inbound'] is False - max_delay = context.constants.inbound_peer_delay + \ - context.constants.getdata_interval + assert self.nodes[1].getpeerinfo()[0]["inbound"] is False + max_delay = ( + context.constants.inbound_peer_delay + context.constants.getdata_interval + ) margin = 2 self.log.info( - f"Tx should be received at node 1 after {max_delay + margin} seconds") + f"Tx should be received at node 1 after {max_delay + margin} seconds" + ) self.nodes[1].setmocktime(int(time.time()) + max_delay) self.sync_mempools(timeout=margin) def test_in_flight_max(self, context): max_getdata_in_flight = context.constants.max_getdata_in_flight - max_inbound_delay = context.constants.inbound_peer_delay + \ - context.constants.overloaded_peer_delay + max_inbound_delay = ( + context.constants.inbound_peer_delay + + context.constants.overloaded_peer_delay + ) self.log.info( f"Test that we don't load peers with more than {max_getdata_in_flight} " - "getdata requests immediately") + "getdata requests immediately" + ) invids = list(range(max_getdata_in_flight + 2)) p = self.nodes[0].p2ps[0] @@ -239,106 +260,89 @@ p.sync_with_ping() self.log.info( f"No more than {max_getdata_in_flight} requests should be seen within " - f"{max_inbound_delay - 1} seconds after announcement") - self.nodes[0].setmocktime( - mock_time + - max_inbound_delay - 1) + f"{max_inbound_delay - 1} seconds after announcement" + ) + self.nodes[0].setmocktime(mock_time + max_inbound_delay - 1) p.sync_with_ping() with p2p_lock: assert_equal(p.getdata_count, max_getdata_in_flight) self.log.info( f"If we wait {max_inbound_delay} seconds after announcement, we should " - f"eventually get more requests") - self.nodes[0].setmocktime( - mock_time + - max_inbound_delay) + "eventually get more requests" + ) + self.nodes[0].setmocktime(mock_time + max_inbound_delay) p.wait_until(lambda: p.getdata_count == len(invids)) def test_expiry_fallback(self, context): - self.log.info( - 'Check that expiry will select another peer for download') + self.log.info("Check that expiry will select another peer for download") peer1 = self.nodes[0].add_p2p_connection(context.p2p_conn()) peer2 = self.nodes[0].add_p2p_connection(context.p2p_conn()) for p in [peer1, peer2]: - p.send_message(msg_inv([CInv(t=context.inv_type, h=0xffaa)])) + p.send_message(msg_inv([CInv(t=context.inv_type, h=0xFFAA)])) # One of the peers is asked for the data - peer2.wait_until( - lambda: sum( - p.getdata_count for p in [ - peer1, peer2]) == 1) + peer2.wait_until(lambda: sum(p.getdata_count for p in [peer1, peer2]) == 1) with p2p_lock: peer_expiry, peer_fallback = ( - peer1, peer2) if peer1.getdata_count == 1 else ( - peer2, peer1) + (peer1, peer2) if peer1.getdata_count == 1 else (peer2, peer1) + ) assert_equal(peer_fallback.getdata_count, 0) # Wait for request to peer_expiry to expire self.nodes[0].setmocktime( - int(time.time()) + context.constants.getdata_interval + 1) - peer_fallback.wait_until( - lambda: peer_fallback.getdata_count >= 1) + int(time.time()) + context.constants.getdata_interval + 1 + ) + peer_fallback.wait_until(lambda: peer_fallback.getdata_count >= 1) with p2p_lock: assert_equal(peer_fallback.getdata_count, 1) # reset mocktime self.restart_node(0) def test_disconnect_fallback(self, context): - self.log.info( - 'Check that disconnect will select another peer for download') + self.log.info("Check that disconnect will select another peer for download") peer1 = self.nodes[0].add_p2p_connection(context.p2p_conn()) peer2 = self.nodes[0].add_p2p_connection(context.p2p_conn()) for p in [peer1, peer2]: - p.send_message(msg_inv([CInv(t=context.inv_type, h=0xffbb)])) + p.send_message(msg_inv([CInv(t=context.inv_type, h=0xFFBB)])) # One of the peers is asked for the data - peer2.wait_until( - lambda: sum( - p.getdata_count for p in [ - peer1, peer2]) == 1) + peer2.wait_until(lambda: sum(p.getdata_count for p in [peer1, peer2]) == 1) with p2p_lock: peer_disconnect, peer_fallback = ( - peer1, peer2) if peer1.getdata_count == 1 else ( - peer2, peer1) + (peer1, peer2) if peer1.getdata_count == 1 else (peer2, peer1) + ) assert_equal(peer_fallback.getdata_count, 0) peer_disconnect.peer_disconnect() peer_disconnect.wait_for_disconnect() - peer_fallback.wait_until( - lambda: peer_fallback.getdata_count >= 1) + peer_fallback.wait_until(lambda: peer_fallback.getdata_count >= 1) with p2p_lock: assert_equal(peer_fallback.getdata_count, 1) def test_notfound_fallback(self, context): self.log.info( - 'Check that notfounds will select another peer for download immediately') + "Check that notfounds will select another peer for download immediately" + ) peer1 = self.nodes[0].add_p2p_connection(context.p2p_conn()) peer2 = self.nodes[0].add_p2p_connection(context.p2p_conn()) for p in [peer1, peer2]: - p.send_message(msg_inv([CInv(t=context.inv_type, h=0xffdd)])) + p.send_message(msg_inv([CInv(t=context.inv_type, h=0xFFDD)])) # One of the peers is asked for the data - peer2.wait_until( - lambda: sum( - p.getdata_count for p in [ - peer1, peer2]) == 1) + peer2.wait_until(lambda: sum(p.getdata_count for p in [peer1, peer2]) == 1) with p2p_lock: peer_notfound, peer_fallback = ( - peer1, peer2) if peer1.getdata_count == 1 else ( - peer2, peer1) + (peer1, peer2) if peer1.getdata_count == 1 else (peer2, peer1) + ) assert_equal(peer_fallback.getdata_count, 0) # Send notfound, so that fallback peer is selected - peer_notfound.send_and_ping(msg_notfound( - vec=[CInv(context.inv_type, 0xffdd)])) - peer_fallback.wait_until( - lambda: peer_fallback.getdata_count >= 1) + peer_notfound.send_and_ping(msg_notfound(vec=[CInv(context.inv_type, 0xFFDD)])) + peer_fallback.wait_until(lambda: peer_fallback.getdata_count >= 1) with p2p_lock: assert_equal(peer_fallback.getdata_count, 1) def test_preferred_inv(self, context): - self.log.info( - 'Check that invs from preferred peers are downloaded immediately') + self.log.info("Check that invs from preferred peers are downloaded immediately") self.restart_node( - 0, - extra_args=self.extra_args[0] + - ['-whitelist=noban@127.0.0.1']) + 0, extra_args=self.extra_args[0] + ["-whitelist=noban@127.0.0.1"] + ) peer = self.nodes[0].add_p2p_connection(context.p2p_conn()) - peer.send_message(msg_inv([CInv(t=context.inv_type, h=0xff00ff00)])) + peer.send_message(msg_inv([CInv(t=context.inv_type, h=0xFF00FF00)])) peer.wait_until(lambda: peer.getdata_count >= 1) with p2p_lock: assert_equal(peer.getdata_count, 1) @@ -347,33 +351,47 @@ max_peer_announcements = context.constants.max_peer_announcements net_permissions = context.constants.bypass_request_limits_permission_flags self.log.info( - f'Test how large inv batches are handled with {net_permissions} permission') + f"Test how large inv batches are handled with {net_permissions} permission" + ) self.restart_node( 0, - extra_args=self.extra_args[0] + - [f'-whitelist={net_permissions}@127.0.0.1']) + extra_args=self.extra_args[0] + [f"-whitelist={net_permissions}@127.0.0.1"], + ) peer = self.nodes[0].add_p2p_connection(context.p2p_conn()) - peer.send_message(msg_inv([CInv(t=context.inv_type, h=invid) - for invid in range(max_peer_announcements + 1)])) - peer.wait_until(lambda: peer.getdata_count == - max_peer_announcements + 1) + peer.send_message( + msg_inv( + [ + CInv(t=context.inv_type, h=invid) + for invid in range(max_peer_announcements + 1) + ] + ) + ) + peer.wait_until(lambda: peer.getdata_count == max_peer_announcements + 1) self.log.info( - f'Test how large inv batches are handled without {net_permissions} permission') + "Test how large inv batches are handled without" + f" {net_permissions} permission" + ) self.restart_node(0) peer = self.nodes[0].add_p2p_connection(context.p2p_conn()) - peer.send_message(msg_inv([CInv(t=context.inv_type, h=invid) - for invid in range(max_peer_announcements + 1)])) - peer.wait_until(lambda: peer.getdata_count == - max_peer_announcements) + peer.send_message( + msg_inv( + [ + CInv(t=context.inv_type, h=invid) + for invid in range(max_peer_announcements + 1) + ] + ) + ) + peer.wait_until(lambda: peer.getdata_count == max_peer_announcements) peer.sync_with_ping() with p2p_lock: assert_equal(peer.getdata_count, max_peer_announcements) 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( - msg_notfound(vec=[CInv(context.inv_type, 1)])) + msg_notfound(vec=[CInv(context.inv_type, 1)]) + ) @skip(TX_TEST_CONTEXT) def test_immature_download(self, context): @@ -383,23 +401,25 @@ privkey, immature = gen_proof(self, node) proofid_hex = uint256_hex(immature.proofid) - self.restart_node(0, extra_args=self.extra_args[0] + [ - "-avaproofstakeutxoconfirmations=3", - f"-avaproof={immature.serialize().hex()}", - f"-avamasterkey={bytes_to_wif(privkey.get_bytes())}", - ]) + self.restart_node( + 0, + extra_args=self.extra_args[0] + + [ + "-avaproofstakeutxoconfirmations=3", + f"-avaproof={immature.serialize().hex()}", + f"-avamasterkey={bytes_to_wif(privkey.get_bytes())}", + ], + ) # Add an inbound so the node proof can be registered and advertised node.add_p2p_connection(P2PInterface()) self.generate(node, 1, sync_fun=self.no_op) wait_for_proof(node, proofid_hex, expect_status="immature") peer = node.add_p2p_connection(context.p2p_conn()) - peer.send_message( - msg_inv([CInv(t=context.inv_type, h=immature.proofid)])) + peer.send_message(msg_inv([CInv(t=context.inv_type, h=immature.proofid)])) # 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) peer.sync_with_ping() assert_equal(peer.getdata_count, 0) @@ -415,10 +435,12 @@ 42, 2000000000, bytes_to_wif(privkey.get_bytes()), [] ) no_stake = avalanche_proof_from_hex(no_stake_hex) - assert_raises_rpc_error(-8, - "The proof is invalid: no-stake", - node.verifyavalancheproof, - no_stake_hex) + assert_raises_rpc_error( + -8, + "The proof is invalid: no-stake", + node.verifyavalancheproof, + no_stake_hex, + ) # Send the proof msg = msg_avaproof() @@ -431,19 +453,18 @@ # Now that the node knows the proof is invalid, it should not be # requested anymore node.p2ps[1].send_message( - msg_inv([CInv(t=context.inv_type, h=no_stake.proofid)])) + msg_inv([CInv(t=context.inv_type, h=no_stake.proofid)]) + ) # 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() assert all(p.getdata_count == 0 for p in node.p2ps[1:]) def run_test(self): 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, # to avoid restarting the nodes @@ -456,8 +477,13 @@ # Run each test against new bitcoind instances, as setting mocktimes has long-term effects on when # the next trickle relay event happens. - for test in [self.test_in_flight_max, self.test_inv_tx, - self.test_data_requests, self.test_immature_download, self.test_request_invalid_once]: + for test in [ + self.test_in_flight_max, + self.test_inv_tx, + self.test_data_requests, + self.test_immature_download, + self.test_request_invalid_once, + ]: self.stop_nodes() self.start_nodes() self.connect_nodes(1, 0) @@ -465,13 +491,12 @@ self.peers = [] for node in self.nodes: for _ in range(NUM_INBOUND): - self.peers.append( - node.add_p2p_connection( - context.p2p_conn())) + self.peers.append(node.add_p2p_connection(context.p2p_conn())) self.log.info( - f"Nodes are setup with {NUM_INBOUND} incoming connections each") + f"Nodes are setup with {NUM_INBOUND} incoming connections each" + ) test(context) -if __name__ == '__main__': +if __name__ == "__main__": InventoryDownloadTest().main() diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -56,8 +56,7 @@ peer.send_blocks_and_test([block1], node, success=True) self.log.info("Mature the block.") - self.generatetoaddress( - node, 100, node.get_deterministic_priv_key().address) + self.generatetoaddress(node, 100, node.get_deterministic_priv_key().address) best_block = node.getblock(node.getbestblockhash()) tip = int(node.getbestblockhash(), 16) @@ -77,14 +76,13 @@ block_time += 1 # b'0x51' is OP_TRUE - tx1 = create_tx_with_script( - block1.vtx[0], 0, script_sig=b'', amount=50 * COIN) - tx2 = create_tx_with_script( - tx1, 0, script_sig=b'\x51', amount=50 * COIN) + tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b"", amount=50 * COIN) + tx2 = create_tx_with_script(tx1, 0, script_sig=b"\x51", amount=50 * COIN) block2.vtx.extend([tx1, tx2]) - block2.vtx = [block2.vtx[0]] + \ - sorted(block2.vtx[1:], key=lambda tx: tx.get_id()) + block2.vtx = [block2.vtx[0]] + sorted( + block2.vtx[1:], key=lambda tx: tx.get_id() + ) block2.hashMerkleRoot = block2.calc_merkle_root() block2.rehash() block2.solve() @@ -98,7 +96,8 @@ assert block2_orig.vtx != block2.vtx peer.send_blocks_and_test( - [block2], node, success=False, reject_reason='bad-txns-duplicate') + [block2], node, success=False, reject_reason="bad-txns-duplicate" + ) # Check transactions for duplicate inputs (CVE-2018-17144) self.log.info("Test duplicate input block.") @@ -111,8 +110,8 @@ block2_dup.rehash() block2_dup.solve() peer.send_blocks_and_test( - [block2_dup], node, success=False, - reject_reason='bad-txns-inputs-duplicate') + [block2_dup], node, success=False, reject_reason="bad-txns-inputs-duplicate" + ) self.log.info("Test very broken block.") @@ -126,16 +125,17 @@ block3.solve() peer.send_blocks_and_test( - [block3], node, success=False, reject_reason='bad-cb-amount') + [block3], node, success=False, reject_reason="bad-cb-amount" + ) # Complete testing of CVE-2012-2459 by sending the original block. # It should be accepted even though it has the same hash as the mutated # one. - self.log.info("Test accepting original block after rejecting its" - " mutated version.") - peer.send_blocks_and_test([block2_orig], node, success=True, - timeout=5) + self.log.info( + "Test accepting original block after rejecting its mutated version." + ) + peer.send_blocks_and_test([block2_orig], node, success=True, timeout=5) # Update tip info height += 1 @@ -145,8 +145,7 @@ # Complete testing of CVE-2018-17144, by checking for the inflation bug. # Create a block that spends the output of a tx in a previous block. block4 = create_block(tip, create_coinbase(height), block_time) - tx3 = create_tx_with_script(tx2, 0, script_sig=b'\x51', - amount=50 * COIN) + tx3 = create_tx_with_script(tx2, 0, script_sig=b"\x51", amount=50 * COIN) # Duplicates input tx3.vin.append(tx3.vin[0]) @@ -157,29 +156,30 @@ block4.rehash() block4.solve() self.log.info("Test inflation by duplicating input") - peer.send_blocks_and_test([block4], node, success=False, - reject_reason='bad-txns-inputs-duplicate') + peer.send_blocks_and_test( + [block4], node, success=False, reject_reason="bad-txns-inputs-duplicate" + ) self.log.info( - "Test accepting identical block after rejecting it due to a future timestamp.") + "Test accepting identical block after rejecting it due to a future" + " timestamp." + ) t = int(time.time()) node.setmocktime(t) # Set block time +1 second past max future validity - block = create_block(tip, create_coinbase( - height), t + MAX_FUTURE_BLOCK_TIME + 1) + block = create_block( + tip, create_coinbase(height), t + MAX_FUTURE_BLOCK_TIME + 1 + ) block.hashMerkleRoot = block.calc_merkle_root() block.solve() # Need force_send because the block will get rejected without a getdata # otherwise peer.send_blocks_and_test( - [block], - node, - force_send=True, - success=False, - reject_reason='time-too-new') + [block], node, force_send=True, success=False, reject_reason="time-too-new" + ) node.setmocktime(t + 1) peer.send_blocks_and_test([block], node, success=True) -if __name__ == '__main__': +if __name__ == "__main__": InvalidBlockRequestTest().main() diff --git a/test/functional/p2p_invalid_locator.py b/test/functional/p2p_invalid_locator.py --- a/test/functional/p2p_invalid_locator.py +++ b/test/functional/p2p_invalid_locator.py @@ -18,33 +18,37 @@ # Convenience reference to the node node = self.nodes[0] # Get node out of IBD - self.generatetoaddress( - node, 1, node.get_deterministic_priv_key().address) + self.generatetoaddress(node, 1, node.get_deterministic_priv_key().address) - self.log.info('Test max locator size') + self.log.info("Test max locator size") block_count = node.getblockcount() for msg in [msg_getheaders(), msg_getblocks()]: self.log.info( - f'Wait for disconnect when sending {MAX_LOCATOR_SZ + 1} hashes in ' - f'locator') + f"Wait for disconnect when sending {MAX_LOCATOR_SZ + 1} hashes in " + "locator" + ) exceed_max_peer = node.add_p2p_connection(P2PInterface()) - msg.locator.vHave = [int(node.getblockhash( - i - 1), 16) for i in range(block_count, block_count - (MAX_LOCATOR_SZ + 1), -1)] + msg.locator.vHave = [ + int(node.getblockhash(i - 1), 16) + for i in range(block_count, block_count - (MAX_LOCATOR_SZ + 1), -1) + ] exceed_max_peer.send_message(msg) exceed_max_peer.wait_for_disconnect() self.log.info( - f'Wait for response when sending {MAX_LOCATOR_SZ} hashes in locator') + f"Wait for response when sending {MAX_LOCATOR_SZ} hashes in locator" + ) within_max_peer = node.add_p2p_connection(P2PInterface()) - msg.locator.vHave = [int(node.getblockhash( - i - 1), 16) for i in range(block_count, block_count - (MAX_LOCATOR_SZ), -1)] + msg.locator.vHave = [ + int(node.getblockhash(i - 1), 16) + for i in range(block_count, block_count - (MAX_LOCATOR_SZ), -1) + ] within_max_peer.send_message(msg) if isinstance(msg, msg_getheaders): within_max_peer.wait_for_header(node.getbestblockhash()) else: - within_max_peer.wait_for_block( - int(node.getbestblockhash(), 16)) + within_max_peer.wait_for_block(int(node.getbestblockhash(), 16)) -if __name__ == '__main__': +if __name__ == "__main__": InvalidLocatorTest().main() diff --git a/test/functional/p2p_invalid_messages.py b/test/functional/p2p_invalid_messages.py --- a/test/functional/p2p_invalid_messages.py +++ b/test/functional/p2p_invalid_messages.py @@ -30,10 +30,12 @@ class msg_unrecognized: """Nonsensical message. Modeled after similar types in test_framework.messages.""" - msgtype = b'badmsg' + msgtype = b"badmsg" def __init__(self, *, str_data): - self.str_data = str_data.encode() if not isinstance(str_data, bytes) else str_data + self.str_data = ( + str_data.encode() if not isinstance(str_data, bytes) else str_data + ) def serialize(self): return ser_string(self.str_data) @@ -44,7 +46,7 @@ class SenderOfAddrV2(P2PInterface): def wait_for_sendaddrv2(self): - self.wait_until(lambda: 'sendaddrv2' in self.last_message) + self.wait_until(lambda: "sendaddrv2" in self.last_message) class InvalidMessagesTest(BitcoinTestFramework): @@ -69,20 +71,20 @@ self.test_resource_exhaustion() def test_buffer(self): - self.log.info( - "Test message with header split across two buffers is received") + self.log.info("Test message with header split across two buffers is received") conn = self.nodes[0].add_p2p_connection(P2PDataStore()) # Create valid message msg = conn.build_message(msg_ping(nonce=12345)) # Chosen at an arbitrary position within the header cut_pos = 12 # Send message in two pieces - before = self.nodes[0].getnettotals()['totalbytesrecv'] + before = self.nodes[0].getnettotals()["totalbytesrecv"] conn.send_raw_message(msg[:cut_pos]) # Wait until node has processed the first half of the message self.wait_until( - lambda: self.nodes[0].getnettotals()['totalbytesrecv'] != before) - middle = self.nodes[0].getnettotals()['totalbytesrecv'] + lambda: self.nodes[0].getnettotals()["totalbytesrecv"] != before + ) + middle = self.nodes[0].getnettotals()["totalbytesrecv"] # If this assert fails, we've hit an unlikely race # where the test framework sent a message in between the two halves assert_equal(middle, before + cut_pos) @@ -93,10 +95,12 @@ def test_magic_bytes(self): self.log.info("Test message with invalid magic bytes disconnects peer") conn = self.nodes[0].add_p2p_connection(P2PDataStore()) - with self.nodes[0].assert_debug_log(['PROCESSMESSAGE: INVALID MESSAGESTART badmsg']): + with self.nodes[0].assert_debug_log( + ["PROCESSMESSAGE: INVALID MESSAGESTART badmsg"] + ): msg = conn.build_message(msg_unrecognized(str_data="d")) # modify magic bytes - msg = b'\xff' * 4 + msg[4:] + msg = b"\xff" * 4 + msg[4:] conn.send_raw_message(msg) conn.wait_for_disconnect(timeout=1) self.nodes[0].disconnect_p2ps() @@ -104,12 +108,14 @@ def test_checksum(self): self.log.info("Test message with invalid checksum logs an error") conn = self.nodes[0].add_p2p_connection(P2PDataStore()) - with self.nodes[0].assert_debug_log(['CHECKSUM ERROR (badmsg, 2 bytes), expected 78df0a04 was ffffffff']): + with self.nodes[0].assert_debug_log( + ["CHECKSUM ERROR (badmsg, 2 bytes), expected 78df0a04 was ffffffff"] + ): msg = conn.build_message(msg_unrecognized(str_data="d")) # Checksum is after start bytes (4B), message type (12B), len (4B) cut_len = 4 + 12 + 4 # modify checksum - msg = msg[:cut_len] + b'\xff' * 4 + msg[cut_len + 4:] + msg = msg[:cut_len] + b"\xff" * 4 + msg[cut_len + 4 :] conn.send_raw_message(msg) conn.wait_for_disconnect() self.nodes[0].disconnect_p2ps() @@ -117,7 +123,7 @@ def test_size(self): self.log.info("Test message with oversized payload disconnects peer") conn = self.nodes[0].add_p2p_connection(P2PDataStore()) - with self.nodes[0].assert_debug_log(['']): + with self.nodes[0].assert_debug_log([""]): msg = msg_unrecognized(str_data="d" * (VALID_DATA_LIMIT + 1)) msg = conn.build_message(msg) conn.send_raw_message(msg) @@ -127,18 +133,17 @@ def test_msgtype(self): self.log.info("Test message with invalid message type logs an error") conn = self.nodes[0].add_p2p_connection(P2PDataStore()) - with self.nodes[0].assert_debug_log(['PROCESSMESSAGE: ERRORS IN HEADER']): + with self.nodes[0].assert_debug_log(["PROCESSMESSAGE: ERRORS IN HEADER"]): msg = msg_unrecognized(str_data="d") - msg.msgtype = b'\xff' * 12 + msg.msgtype = b"\xff" * 12 msg = conn.build_message(msg) # Modify msgtype - msg = msg[:7] + b'\x00' + msg[7 + 1:] + msg = msg[:7] + b"\x00" + msg[7 + 1 :] conn.send_raw_message(msg) conn.sync_with_ping(timeout=1) # Check that traffic is accounted for (24 bytes header + 2 bytes # payload) - assert_equal( - self.nodes[0].getpeerinfo()[0]['bytesrecv_per_msg']['*other*'], 26) + assert_equal(self.nodes[0].getpeerinfo()[0]["bytesrecv_per_msg"]["*other*"], 26) self.nodes[0].disconnect_p2ps() def test_addrv2(self, label, required_log_messages, raw_addrv2): @@ -152,8 +157,8 @@ self.log.info(f"Test addrv2: {label}") - msg = msg_unrecognized(str_data=b'') - msg.msgtype = b'addrv2' + msg = msg_unrecognized(str_data=b"") + msg.msgtype = b"addrv2" with node.assert_debug_log(required_log_messages): # override serialize() which would include the length of the data msg.serialize = lambda: raw_addrv2 @@ -163,92 +168,113 @@ node.disconnect_p2ps() def test_addrv2_empty(self): - self.test_addrv2('empty', - [ - 'received: addrv2 (0 bytes)', - 'ProcessMessages(addrv2, 0 bytes): Exception', - 'end of data', - ], - b'') + self.test_addrv2( + "empty", + [ + "received: addrv2 (0 bytes)", + "ProcessMessages(addrv2, 0 bytes): Exception", + "end of data", + ], + b"", + ) def test_addrv2_no_addresses(self): - self.test_addrv2('no addresses', - [ - 'received: addrv2 (1 bytes)', - ], - bytes.fromhex('00')) + self.test_addrv2( + "no addresses", + [ + "received: addrv2 (1 bytes)", + ], + bytes.fromhex("00"), + ) def test_addrv2_too_long_address(self): - self.test_addrv2('too long address', - [ - 'received: addrv2 (525 bytes)', - 'ProcessMessages(addrv2, 525 bytes): Exception', - 'Address too long: 513 > 512', - ], - bytes.fromhex( - # number of entries - '01' - # time, Fri Jan 9 02:54:25 UTC 2009 - '61bc6649' - # service flags, COMPACTSIZE(NODE_NONE) - '00' - # network type (IPv4) - '01' - # address length (COMPACTSIZE(513)) - 'fd0102' - # address - f'{"ab" * 513}' - # port - '208d')) + self.test_addrv2( + "too long address", + [ + "received: addrv2 (525 bytes)", + "ProcessMessages(addrv2, 525 bytes): Exception", + "Address too long: 513 > 512", + ], + bytes.fromhex( + # number of entries + "01" + # time, Fri Jan 9 02:54:25 UTC 2009 + "61bc6649" + # service flags, COMPACTSIZE(NODE_NONE) + "00" + # network type (IPv4) + "01" + # address length (COMPACTSIZE(513)) + "fd0102" + # address + f'{"ab" * 513}' + # port + "208d" + ), + ) def test_addrv2_unrecognized_network(self): - now_hex = struct.pack('= TIME_SIZE + \ - LENGTH_SIZE + MSGTYPE_SIZE + assert os.fstat(f_in.fileno()).st_size >= TIME_SIZE + LENGTH_SIZE + MSGTYPE_SIZE while True: tmp_header_raw = f_in.read(TIME_SIZE + LENGTH_SIZE + MSGTYPE_SIZE) if not tmp_header_raw: @@ -48,8 +47,8 @@ tmp_header = BytesIO(tmp_header_raw) int.from_bytes(tmp_header.read(TIME_SIZE), "little") raw_msgtype = tmp_header.read(MSGTYPE_SIZE) - msgtype = raw_msgtype.split(b'\x00', 1)[0] - remainder = raw_msgtype.split(b'\x00', 1)[1] + msgtype = raw_msgtype.split(b"\x00", 1)[0] + remainder = raw_msgtype.split(b"\x00", 1)[1] assert len(msgtype) > 0 assert msgtype in MESSAGEMAP assert len(remainder) == 0 or not remainder.decode().isprintable() @@ -65,9 +64,7 @@ self.setup_clean_chain = True def run_test(self): - capturedir = os.path.join( - self.nodes[0].datadir, - "regtest/message_capture") + capturedir = os.path.join(self.nodes[0].datadir, "regtest/message_capture") # Connect a node so that the handshake occurs self.nodes[0].add_p2p_connection(P2PDataStore()) self.nodes[0].disconnect_p2ps() @@ -77,5 +74,5 @@ mini_parser(sent_file) -if __name__ == '__main__': +if __name__ == "__main__": MessageCaptureTest().main() diff --git a/test/functional/p2p_nobloomfilter_messages.py b/test/functional/p2p_nobloomfilter_messages.py --- a/test/functional/p2p_nobloomfilter_messages.py +++ b/test/functional/p2p_nobloomfilter_messages.py @@ -36,22 +36,20 @@ assert_equal(self.nodes[0].getconnectioncount(), 0) def run_test(self): - self.log.info( - "Test that peer is disconnected if it sends mempool message") + self.log.info("Test that peer is disconnected if it sends mempool message") self.test_message_causes_disconnect(msg_mempool()) - self.log.info( - "Test that peer is disconnected if it sends filterload message") + self.log.info("Test that peer is disconnected if it sends filterload message") self.test_message_causes_disconnect(msg_filterload()) - self.log.info( - "Test that peer is disconnected if it sends filteradd message") - self.test_message_causes_disconnect(msg_filteradd(data=b'\xcc')) + self.log.info("Test that peer is disconnected if it sends filteradd message") + self.test_message_causes_disconnect(msg_filteradd(data=b"\xcc")) self.log.info( - "Test that peer is disconnected if it sends a filterclear message") + "Test that peer is disconnected if it sends a filterclear message" + ) self.test_message_causes_disconnect(msg_filterclear()) -if __name__ == '__main__': +if __name__ == "__main__": P2PNoBloomFilterMessages().main() diff --git a/test/functional/p2p_node_network_limited.py b/test/functional/p2p_node_network_limited.py --- a/test/functional/p2p_node_network_limited.py +++ b/test/functional/p2p_node_network_limited.py @@ -32,7 +32,9 @@ self.firstAddrnServices = message.addrs[0].nServices def wait_for_addr(self, timeout=5): - def test_function(): return self.last_message.get("addr") + def test_function(): + return self.last_message.get("addr") + self.wait_until(test_function, timeout=timeout) def send_getdata_for_block(self, blockhash): @@ -45,7 +47,7 @@ def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 3 - self.extra_args = [['-prune=550', '-addrmantest'], [], []] + self.extra_args = [["-prune=550", "-addrmantest"], [], []] def disconnect_all(self): self.disconnect_nodes(0, 1) @@ -65,22 +67,24 @@ assert_equal(node.nServices, expected_services) self.log.info("Check that the localservices is as expected.") - assert_equal(int(self.nodes[0].getnetworkinfo()[ - 'localservices'], 16), expected_services) + assert_equal( + int(self.nodes[0].getnetworkinfo()["localservices"], 16), expected_services + ) - self.log.info( - "Mine enough blocks to reach the NODE_NETWORK_LIMITED range.") + self.log.info("Mine enough blocks to reach the NODE_NETWORK_LIMITED range.") self.connect_nodes(0, 1) - blocks = self.generate(self.nodes[1], 292, sync_fun=lambda: self.sync_blocks( - [self.nodes[0], self.nodes[1]])) + blocks = self.generate( + self.nodes[1], + 292, + sync_fun=lambda: self.sync_blocks([self.nodes[0], self.nodes[1]]), + ) self.log.info("Make sure we can max retrieve block at tip-288.") # last block in valid range node.send_getdata_for_block(blocks[1]) node.wait_for_block(int(blocks[1], 16), timeout=3) - self.log.info( - "Requesting block at height 2 (tip-289) must fail (ignored).") + self.log.info("Requesting block at height 2 (tip-289) must fail (ignored).") # first block outside of the 288+2 limit node.send_getdata_for_block(blocks[0]) node.wait_for_disconnect(5) @@ -105,8 +109,9 @@ except Exception: pass # node2 must remain at heigh 0 - assert_equal(self.nodes[2].getblockheader( - self.nodes[2].getbestblockhash())['height'], 0) + assert_equal( + self.nodes[2].getblockheader(self.nodes[2].getbestblockhash())["height"], 0 + ) # now connect also to node 1 (non pruned) self.connect_nodes(1, 2) @@ -129,5 +134,5 @@ self.sync_blocks([self.nodes[0], self.nodes[1]]) -if __name__ == '__main__': +if __name__ == "__main__": NodeNetworkLimitedTest().main() diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py --- a/test/functional/p2p_permissions.py +++ b/test/functional/p2p_permissions.py @@ -65,18 +65,16 @@ # by modifying the configuration file. ip_port = f"127.0.0.1:{p2p_port(1)}" self.replaceinconfig( - 1, - "bind=127.0.0.1", - f"whitebind=bloomfilter,forcerelay@{ip_port}") + 1, "bind=127.0.0.1", f"whitebind=bloomfilter,forcerelay@{ip_port}" + ) self.checkpermission( ["-whitelist=noban@127.0.0.1"], # Check parameter interaction forcerelay should activate relay ["noban", "bloomfilter", "forcerelay", "relay", "download"], ) self.replaceinconfig( - 1, - f"whitebind=bloomfilter,forcerelay@{ip_port}", - "bind=127.0.0.1") + 1, f"whitebind=bloomfilter,forcerelay@{ip_port}", "bind=127.0.0.1" + ) self.checkpermission( # legacy whitelistrelay should be ignored @@ -105,8 +103,16 @@ self.checkpermission( # all permission added ["-whitelist=all@127.0.0.1"], - ["forcerelay", "noban", "mempool", "bloomfilter", - "relay", "download", "bypass_proof_request_limits", "addr"], + [ + "forcerelay", + "noban", + "mempool", + "bloomfilter", + "relay", + "download", + "bypass_proof_request_limits", + "addr", + ], ) self.checkpermission( @@ -119,35 +125,42 @@ self.nodes[1].assert_start_raises_init_error( ["-whitelist=oopsie@127.0.0.1"], "Invalid P2P permission", - match=ErrorMatch.PARTIAL_REGEX) + match=ErrorMatch.PARTIAL_REGEX, + ) self.nodes[1].assert_start_raises_init_error( ["-whitelist=noban@127.0.0.1:230"], "Invalid netmask specified in", - match=ErrorMatch.PARTIAL_REGEX) + match=ErrorMatch.PARTIAL_REGEX, + ) self.nodes[1].assert_start_raises_init_error( ["-whitebind=noban@127.0.0.1/10"], "Cannot resolve -whitebind address", - match=ErrorMatch.PARTIAL_REGEX) + match=ErrorMatch.PARTIAL_REGEX, + ) def check_tx_relay(self): block_op_true = self.nodes[0].getblock( - self.generatetoaddress(self.nodes[0], 100, ADDRESS_ECREG_P2SH_OP_TRUE)[0]) + self.generatetoaddress(self.nodes[0], 100, ADDRESS_ECREG_P2SH_OP_TRUE)[0] + ) self.log.debug( - "Create a connection from a forcerelay peer that rebroadcasts raw txs") + "Create a connection from a forcerelay peer that rebroadcasts raw txs" + ) # A python mininode is needed to send the raw transaction directly. # If a full node was used, it could only rebroadcast via the inv-getdata # mechanism. However, even for forcerelay connections, a full node would # currently not request a txid that is already in the mempool. self.restart_node(1, extra_args=["-whitelist=forcerelay@127.0.0.1"]) - p2p_rebroadcast_wallet = self.nodes[1].add_p2p_connection( - P2PDataStore()) + p2p_rebroadcast_wallet = self.nodes[1].add_p2p_connection(P2PDataStore()) self.log.debug("Send a tx from the wallet initially") - tx = FromHex(CTransaction(), - self.nodes[0].createrawtransaction( - inputs=[{'txid': block_op_true['tx'][0], 'vout': 0}], - outputs=[{ADDRESS_ECREG_P2SH_OP_TRUE: 50}])) + tx = FromHex( + CTransaction(), + self.nodes[0].createrawtransaction( + inputs=[{"txid": block_op_true["tx"][0], "vout": 0}], + outputs=[{ADDRESS_ECREG_P2SH_OP_TRUE: 50}], + ), + ) # push the one byte script to the stack tx.vin[0].scriptSig = SCRIPTSIG_OP_TRUE pad_tx(tx) @@ -158,15 +171,14 @@ self.log.debug( "Check that node[1] will send the tx to node[0] even though it" - " is already in the mempool") + " is already in the mempool" + ) self.connect_nodes(1, 0) - with self.nodes[1].assert_debug_log( - [f"Force relaying tx {txid} from peer=0"]): + with self.nodes[1].assert_debug_log([f"Force relaying tx {txid} from peer=0"]): p2p_rebroadcast_wallet.send_txs_and_test([tx], self.nodes[1]) self.wait_until(lambda: txid in self.nodes[0].getrawmempool()) - self.log.debug( - "Check that node[1] will not send an invalid tx to node[0]") + self.log.debug("Check that node[1] will not send an invalid tx to node[0]") tx.vout[0].nValue += 1 txid = tx.rehash() # Send the transaction twice. The first time, it'll be rejected by ATMP @@ -176,33 +188,32 @@ [tx], self.nodes[1], success=False, - reject_reason=f'{txid} from peer=0 was not accepted: ' - f'txn-mempool-conflict', + reject_reason=f"{txid} from peer=0 was not accepted: txn-mempool-conflict", ) p2p_rebroadcast_wallet.send_txs_and_test( [tx], self.nodes[1], success=False, - reject_reason=f'Not relaying non-mempool transaction {txid} from ' - f'forcerelay peer=0', + reject_reason=( + f"Not relaying non-mempool transaction {txid} from forcerelay peer=0" + ), ) def checkpermission(self, args, expectedPermissions): self.restart_node(1, args) self.connect_nodes(0, 1) peerinfo = self.nodes[1].getpeerinfo()[0] - assert_equal(len(expectedPermissions), len(peerinfo['permissions'])) + assert_equal(len(expectedPermissions), len(peerinfo["permissions"])) for p in expectedPermissions: - if p not in peerinfo['permissions']: - raise AssertionError( - f"Expected permissions {p!r} is not granted.") + if p not in peerinfo["permissions"]: + raise AssertionError(f"Expected permissions {p!r} is not granted.") def replaceinconfig(self, nodeid, old, new): with open(self.nodes[nodeid].bitcoinconf, encoding="utf8") as f: newText = f.read().replace(old, new) - with open(self.nodes[nodeid].bitcoinconf, 'w', encoding="utf8") as f: + with open(self.nodes[nodeid].bitcoinconf, "w", encoding="utf8") as f: f.write(newText) -if __name__ == '__main__': +if __name__ == "__main__": P2PPermissionsTests().main() diff --git a/test/functional/p2p_ping.py b/test/functional/p2p_ping.py --- a/test/functional/p2p_ping.py +++ b/test/functional/p2p_ping.py @@ -39,13 +39,13 @@ self.num_nodes = 1 # Set the peer connection timeout low. It does not matter for this # test, as long as it is less than TIMEOUT_INTERVAL. - self.extra_args = [['-peertimeout=1']] + self.extra_args = [["-peertimeout=1"]] def check_peer_info(self, *, pingtime, minping, pingwait): stats = self.nodes[0].getpeerinfo()[0] - assert_equal(stats.pop('pingtime', None), pingtime) - assert_equal(stats.pop('minping', None), minping) - assert_equal(stats.pop('pingwait', None), pingwait) + assert_equal(stats.pop("pingtime", None), pingtime) + assert_equal(stats.pop("minping", None), minping) + assert_equal(stats.pop("pingwait", None), pingwait) def mock_forward(self, delta): self.mock_time += delta @@ -55,77 +55,77 @@ self.mock_time = int(time.time()) self.mock_forward(0) - self.log.info( - 'Check that ping is sent after connection is established') + self.log.info("Check that ping is sent after connection is established") no_pong_node = self.nodes[0].add_p2p_connection(NodeNoPong()) self.mock_forward(3) - assert no_pong_node.last_message.pop('ping').nonce != 0 + assert no_pong_node.last_message.pop("ping").nonce != 0 self.check_peer_info(pingtime=None, minping=None, pingwait=3) - self.log.info('Reply without nonce cancels ping') - with self.nodes[0].assert_debug_log(['pong peer=0: Short payload']): + self.log.info("Reply without nonce cancels ping") + with self.nodes[0].assert_debug_log(["pong peer=0: Short payload"]): no_pong_node.send_and_ping(msg_pong_corrupt()) self.check_peer_info(pingtime=None, minping=None, pingwait=None) - self.log.info('Reply without ping') - with self.nodes[0].assert_debug_log([ - 'pong peer=0: Unsolicited pong without ping, 0 expected, 0 received, 8 bytes', - ]): + self.log.info("Reply without ping") + with self.nodes[0].assert_debug_log( + [ + ( + "pong peer=0: Unsolicited pong without ping, 0 expected, 0" + " received, 8 bytes" + ), + ] + ): no_pong_node.send_and_ping(msg_pong()) self.check_peer_info(pingtime=None, minping=None, pingwait=None) - self.log.info('Reply with wrong nonce does not cancel ping') - assert 'ping' not in no_pong_node.last_message - with self.nodes[0].assert_debug_log(['pong peer=0: Nonce mismatch']): + self.log.info("Reply with wrong nonce does not cancel ping") + assert "ping" not in no_pong_node.last_message + with self.nodes[0].assert_debug_log(["pong peer=0: Nonce mismatch"]): # mock time PING_INTERVAL ahead to trigger node into sending a ping self.mock_forward(PING_INTERVAL + 1) - no_pong_node.wait_until( - lambda: 'ping' in no_pong_node.last_message) + no_pong_node.wait_until(lambda: "ping" in no_pong_node.last_message) self.mock_forward(9) # Send the wrong pong no_pong_node.send_and_ping( - msg_pong(no_pong_node.last_message.pop('ping').nonce - 1)) + msg_pong(no_pong_node.last_message.pop("ping").nonce - 1) + ) self.check_peer_info(pingtime=None, minping=None, pingwait=9) - self.log.info('Reply with zero nonce does cancel ping') - with self.nodes[0].assert_debug_log(['pong peer=0: Nonce zero']): + self.log.info("Reply with zero nonce does cancel ping") + with self.nodes[0].assert_debug_log(["pong peer=0: Nonce zero"]): no_pong_node.send_and_ping(msg_pong(0)) self.check_peer_info(pingtime=None, minping=None, pingwait=None) - self.log.info('Check that ping is properly reported on RPC') - assert 'ping' not in no_pong_node.last_message + self.log.info("Check that ping is properly reported on RPC") + assert "ping" not in no_pong_node.last_message # mock time PING_INTERVAL ahead to trigger node into sending a ping self.mock_forward(PING_INTERVAL + 1) - no_pong_node.wait_until(lambda: 'ping' in no_pong_node.last_message) + no_pong_node.wait_until(lambda: "ping" in no_pong_node.last_message) ping_delay = 29 self.mock_forward(ping_delay) - no_pong_node.wait_until(lambda: 'ping' in no_pong_node.last_message) + no_pong_node.wait_until(lambda: "ping" in no_pong_node.last_message) no_pong_node.send_and_ping( - msg_pong(no_pong_node.last_message.pop('ping').nonce)) - self.check_peer_info( - pingtime=ping_delay, - minping=ping_delay, - pingwait=None) + msg_pong(no_pong_node.last_message.pop("ping").nonce) + ) + self.check_peer_info(pingtime=ping_delay, minping=ping_delay, pingwait=None) - self.log.info('Check that minping is decreased after a fast roundtrip') + self.log.info("Check that minping is decreased after a fast roundtrip") # mock time PING_INTERVAL ahead to trigger node into sending a ping self.mock_forward(PING_INTERVAL + 1) - no_pong_node.wait_until(lambda: 'ping' in no_pong_node.last_message) + no_pong_node.wait_until(lambda: "ping" in no_pong_node.last_message) ping_delay = 9 self.mock_forward(ping_delay) - no_pong_node.wait_until(lambda: 'ping' in no_pong_node.last_message) + no_pong_node.wait_until(lambda: "ping" in no_pong_node.last_message) no_pong_node.send_and_ping( - msg_pong(no_pong_node.last_message.pop('ping').nonce)) - self.check_peer_info( - pingtime=ping_delay, - minping=ping_delay, - pingwait=None) - - self.log.info('Check that peer is disconnected after ping timeout') - assert 'ping' not in no_pong_node.last_message + msg_pong(no_pong_node.last_message.pop("ping").nonce) + ) + self.check_peer_info(pingtime=ping_delay, minping=ping_delay, pingwait=None) + + self.log.info("Check that peer is disconnected after ping timeout") + assert "ping" not in no_pong_node.last_message self.nodes[0].ping() - no_pong_node.wait_until(lambda: 'ping' in no_pong_node.last_message) - with self.nodes[0].assert_debug_log(['ping timeout: 1201.000000s']): + no_pong_node.wait_until(lambda: "ping" in no_pong_node.last_message) + with self.nodes[0].assert_debug_log(["ping timeout: 1201.000000s"]): self.mock_forward(TIMEOUT_INTERVAL // 2) # Check that sending a ping does not prevent the disconnect no_pong_node.sync_with_ping() @@ -133,5 +133,5 @@ no_pong_node.wait_for_disconnect() -if __name__ == '__main__': +if __name__ == "__main__": PingPongTest().main() diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py --- a/test/functional/p2p_sendheaders.py +++ b/test/functional/p2p_sendheaders.py @@ -141,7 +141,9 @@ self.send_message(getblocks_message) def wait_for_block_announcement(self, block_hash, timeout=60): - def test_function(): return self.last_blockhash_announced == block_hash + def test_function(): + return self.last_blockhash_announced == block_hash + self.wait_until(test_function, timeout=timeout) def on_inv(self, message): @@ -167,9 +169,11 @@ def check_last_headers_announcement(self, headers): """Test whether the last headers announcements received are right. - Headers may be announced across more than one message.""" + Headers may be announced across more than one message.""" + + def test_function(): + return len(self.recent_headers_announced) >= len(headers) - def test_function(): return (len(self.recent_headers_announced) >= len(headers)) self.wait_until(test_function) with p2p_lock: assert_equal(self.recent_headers_announced, headers) @@ -181,7 +185,9 @@ """Test whether the last announcement received had the right inv. inv should be a list of block hashes.""" - def test_function(): return self.block_announced + def test_function(): + return self.block_announced + self.wait_until(test_function) with p2p_lock: @@ -204,8 +210,9 @@ # Clear out block announcements from each p2p listener [x.clear_block_announcements() for x in self.nodes[0].p2ps] - self.generatetoaddress(self.nodes[0], - count, self.nodes[0].get_deterministic_priv_key().address) + self.generatetoaddress( + self.nodes[0], count, self.nodes[0].get_deterministic_priv_key().address + ) return int(self.nodes[0].getbestblockhash(), 16) def mine_reorg(self, length): @@ -216,20 +223,22 @@ return the list of block hashes newly mined.""" # make sure all invalidated blocks are node0's - self.generatetoaddress(self.nodes[0], - length, self.nodes[0].get_deterministic_priv_key().address) + self.generatetoaddress( + self.nodes[0], length, self.nodes[0].get_deterministic_priv_key().address + ) for x in self.nodes[0].p2ps: - x.wait_for_block_announcement( - int(self.nodes[0].getbestblockhash(), 16)) + x.wait_for_block_announcement(int(self.nodes[0].getbestblockhash(), 16)) x.clear_block_announcements() tip_height = self.nodes[1].getblockcount() - hash_to_invalidate = self.nodes[1].getblockhash( - tip_height - (length - 1)) + hash_to_invalidate = self.nodes[1].getblockhash(tip_height - (length - 1)) self.nodes[1].invalidateblock(hash_to_invalidate) # Must be longer than the orig chain - all_hashes = self.generatetoaddress(self.nodes[1], - length + 1, self.nodes[1].get_deterministic_priv_key().address) + all_hashes = self.generatetoaddress( + self.nodes[1], + length + 1, + self.nodes[1].get_deterministic_priv_key().address, + ) return [int(x, 16) for x in all_hashes] def run_test(self): @@ -243,23 +252,32 @@ self.test_nonnull_locators(test_node, inv_node) def test_null_locators(self, test_node, inv_node): - tip = self.nodes[0].getblockheader(self.generatetoaddress(self.nodes[0], - 1, self.nodes[0].get_deterministic_priv_key().address)[0]) + tip = self.nodes[0].getblockheader( + self.generatetoaddress( + self.nodes[0], 1, self.nodes[0].get_deterministic_priv_key().address + )[0] + ) tip_hash = int(tip["hash"], 16) inv_node.check_last_inv_announcement(inv=[tip_hash]) test_node.check_last_inv_announcement(inv=[tip_hash]) self.log.info( - "Verify getheaders with null locator and valid hashstop returns headers.") + "Verify getheaders with null locator and valid hashstop returns headers." + ) test_node.clear_block_announcements() test_node.send_get_headers(locator=[], hashstop=tip_hash) test_node.check_last_headers_announcement(headers=[tip_hash]) self.log.info( - "Verify getheaders with null locator and invalid hashstop does not return headers.") - block = create_block(int(tip["hash"], 16), create_coinbase( - tip["height"] + 1), tip["mediantime"] + 1) + "Verify getheaders with null locator and invalid hashstop does not return" + " headers." + ) + block = create_block( + int(tip["hash"], 16), + create_coinbase(tip["height"] + 1), + tip["mediantime"] + 1, + ) block.solve() test_node.send_header_for_blocks([block]) test_node.clear_block_announcements() @@ -275,8 +293,7 @@ # PART 1 # 1. Mine a block; expect inv announcements each time - self.log.info( - "Part 1: headers don't start before sendheaders message...") + self.log.info("Part 1: headers don't start before sendheaders message...") for i in range(4): self.log.debug(f"Part 1.{i}: starting...") old_tip = tip @@ -300,11 +317,11 @@ # this time announce own block via headers inv_node.clear_block_announcements() height = self.nodes[0].getblockcount() - last_time = self.nodes[0].getblock( - self.nodes[0].getbestblockhash())['time'] + last_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())[ + "time" + ] block_time = last_time + 1 - new_block = create_block( - tip, create_coinbase(height + 1), block_time) + new_block = create_block(tip, create_coinbase(height + 1), block_time) new_block.solve() test_node.send_header_for_blocks([new_block]) test_node.wait_for_getdata([new_block.sha256]) @@ -316,7 +333,8 @@ self.log.info("Part 1: success!") self.log.info( - "Part 2: announce blocks with headers after sendheaders message...") + "Part 2: announce blocks with headers after sendheaders message..." + ) # PART 2 # 2. Send a sendheaders message and test that headers announcements # commence and keep working. @@ -342,8 +360,9 @@ self.log.debug(f"Part 2.{i}.{j}: starting...") blocks = [] for _ in range(i + 1): - blocks.append(create_block( - tip, create_coinbase(height), block_time)) + blocks.append( + create_block(tip, create_coinbase(height), block_time) + ) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -383,7 +402,9 @@ self.log.info("Part 2: success!") self.log.info( - "Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer...") + "Part 3: headers announcements can stop after large reorg, and resume after" + " headers/inv from peer..." + ) # PART 3. Headers announcements can stop after large reorg, and resume after # getheaders or inv from peer. @@ -407,8 +428,9 @@ block_time += 9 - fork_point = self.nodes[0].getblock( - uint256_hex(new_block_hashes[0]))["previousblockhash"] + fork_point = self.nodes[0].getblock(uint256_hex(new_block_hashes[0]))[ + "previousblockhash" + ] fork_point = int(fork_point, 16) # Use getblocks/getdata @@ -433,7 +455,8 @@ # Send a getheaders message that shouldn't trigger headers announcements # to resume (best header sent will be too old) test_node.send_get_headers( - locator=[fork_point], hashstop=new_block_hashes[1]) + locator=[fork_point], hashstop=new_block_hashes[1] + ) test_node.send_get_data([tip]) test_node.wait_for_block(tip) elif i == 2: @@ -458,15 +481,13 @@ self.log.info("Part 4: Testing direct fetch behavior...") tip = self.mine_blocks(1) height = self.nodes[0].getblockcount() + 1 - last_time = self.nodes[0].getblock( - self.nodes[0].getbestblockhash())['time'] + last_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())["time"] block_time = last_time + 1 # Create 2 blocks. Send the blocks, then send the headers. blocks = [] for _ in range(2): - blocks.append(create_block( - tip, create_coinbase(height), block_time)) + blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -484,8 +505,7 @@ # This time, direct fetch should work blocks = [] for _ in range(3): - blocks.append(create_block( - tip, create_coinbase(height), block_time)) + blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -494,7 +514,8 @@ test_node.send_header_for_blocks(blocks) test_node.sync_with_ping() test_node.wait_for_getdata( - [x.sha256 for x in blocks], timeout=DIRECT_FETCH_RESPONSE_TIME) + [x.sha256 for x in blocks], timeout=DIRECT_FETCH_RESPONSE_TIME + ) [test_node.send_message(msg_block(x)) for x in blocks] @@ -507,8 +528,7 @@ # Create extra blocks for later for _ in range(20): - blocks.append(create_block( - tip, create_coinbase(height), block_time)) + blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -527,14 +547,16 @@ test_node.send_header_for_blocks(blocks[1:2]) test_node.sync_with_ping() test_node.wait_for_getdata( - [x.sha256 for x in blocks[0:2]], timeout=DIRECT_FETCH_RESPONSE_TIME) + [x.sha256 for x in blocks[0:2]], timeout=DIRECT_FETCH_RESPONSE_TIME + ) # Announcing 16 more headers should trigger direct fetch for 14 more # blocks test_node.send_header_for_blocks(blocks[2:18]) test_node.sync_with_ping() test_node.wait_for_getdata( - [x.sha256 for x in blocks[2:16]], timeout=DIRECT_FETCH_RESPONSE_TIME) + [x.sha256 for x in blocks[2:16]], timeout=DIRECT_FETCH_RESPONSE_TIME + ) # Announcing 1 more header should not trigger any response test_node.last_message.pop("getdata", None) @@ -557,8 +579,7 @@ blocks = [] # Create two more blocks. for _ in range(2): - blocks.append(create_block( - tip, create_coinbase(height), block_time)) + blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -572,16 +593,14 @@ test_node.wait_for_getdata([x.sha256 for x in blocks]) [test_node.send_message(msg_block(x)) for x in blocks] test_node.sync_with_ping() - assert_equal( - int(self.nodes[0].getbestblockhash(), 16), blocks[1].sha256) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), blocks[1].sha256) blocks = [] # Now we test that if we repeatedly don't send connecting headers, we # don't go into an infinite loop trying to get them to connect. MAX_UNCONNECTING_HEADERS = 10 for _ in range(MAX_UNCONNECTING_HEADERS + 1): - blocks.append(create_block( - tip, create_coinbase(height), block_time)) + blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -624,5 +643,5 @@ assert "getdata" not in inv_node.last_message -if __name__ == '__main__': +if __name__ == "__main__": SendHeadersTest().main() diff --git a/test/functional/p2p_timeouts.py b/test/functional/p2p_timeouts.py --- a/test/functional/p2p_timeouts.py +++ b/test/functional/p2p_timeouts.py @@ -50,11 +50,14 @@ # Setup the p2p connections no_verack_node = self.nodes[0].add_p2p_connection( - TestP2PConn(), wait_for_verack=False) + TestP2PConn(), wait_for_verack=False + ) no_version_node = self.nodes[0].add_p2p_connection( - TestP2PConn(), send_version=False, wait_for_verack=False) + TestP2PConn(), send_version=False, wait_for_verack=False + ) no_send_node = self.nodes[0].add_p2p_connection( - TestP2PConn(), send_version=False, wait_for_verack=False) + TestP2PConn(), send_version=False, wait_for_verack=False + ) # Wait until we got the verack in response to the version. Though, don't wait for the other node to receive the # verack, since we never sent one @@ -93,5 +96,5 @@ no_send_node.wait_for_disconnect(timeout=1) -if __name__ == '__main__': +if __name__ == "__main__": TimeoutsTest().main() diff --git a/test/functional/p2p_unrequested_blocks.py b/test/functional/p2p_unrequested_blocks.py --- a/test/functional/p2p_unrequested_blocks.py +++ b/test/functional/p2p_unrequested_blocks.py @@ -72,12 +72,10 @@ class AcceptBlockTest(BitcoinTestFramework): - def set_test_params(self): self.setup_clean_chain = True self.num_nodes = 2 - self.extra_args = [["-noparkdeepreorg"], - ["-minimumchainwork=0x10"]] + self.extra_args = [["-noparkdeepreorg"], ["-minimumchainwork=0x10"]] def setup_network(self): self.setup_nodes() @@ -95,8 +93,7 @@ blocks_h2 = [] # the height 2 blocks on each node's chain block_time = int(time.time()) + 1 for i in range(2): - blocks_h2.append(create_block( - tips[i], create_coinbase(2), block_time)) + blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time)) blocks_h2[i].solve() block_time += 1 test_node.send_and_ping(msg_block(blocks_h2[0])) @@ -105,27 +102,29 @@ assert_equal(self.nodes[0].getblockcount(), 2) assert_equal(self.nodes[1].getblockcount(), 1) self.log.info( - "First height 2 block accepted by node0; correctly rejected by node1") + "First height 2 block accepted by node0; correctly rejected by node1" + ) # 3. Send another block that builds on genesis. block_h1f = create_block( - int(self.nodes[0].getblockhash(0), 16), create_coinbase(1), block_time) + int(self.nodes[0].getblockhash(0), 16), create_coinbase(1), block_time + ) block_time += 1 block_h1f.solve() test_node.send_and_ping(msg_block(block_h1f)) tip_entry_found = False for x in self.nodes[0].getchaintips(): - if x['hash'] == block_h1f.hash: - assert_equal(x['status'], "headers-only") + if x["hash"] == block_h1f.hash: + assert_equal(x["status"], "headers-only") tip_entry_found = True assert tip_entry_found - assert_raises_rpc_error(-1, "Block not found on disk", - self.nodes[0].getblock, block_h1f.hash) + assert_raises_rpc_error( + -1, "Block not found on disk", self.nodes[0].getblock, block_h1f.hash + ) # 4. Send another two block that build on the fork. - block_h2f = create_block( - block_h1f.sha256, create_coinbase(2), block_time) + block_h2f = create_block(block_h1f.sha256, create_coinbase(2), block_time) block_time += 1 block_h2f.solve() test_node.send_and_ping(msg_block(block_h2f)) @@ -134,8 +133,8 @@ # can't be fully validated. tip_entry_found = False for x in self.nodes[0].getchaintips(): - if x['hash'] == block_h2f.hash: - assert_equal(x['status'], "headers-only") + if x["hash"] == block_h2f.hash: + assert_equal(x["status"], "headers-only") tip_entry_found = True assert tip_entry_found @@ -145,7 +144,8 @@ # 4b. Now send another block that builds on the forking chain. block_h3 = create_block( - block_h2f.sha256, create_coinbase(3), block_h2f.nTime + 1) + block_h2f.sha256, create_coinbase(3), block_h2f.nTime + 1 + ) block_h3.solve() test_node.send_and_ping(msg_block(block_h3)) @@ -153,8 +153,8 @@ # can't be fully validated. tip_entry_found = False for x in self.nodes[0].getchaintips(): - if x['hash'] == block_h3.hash: - assert_equal(x['status'], "headers-only") + if x["hash"] == block_h3.hash: + assert_equal(x["status"], "headers-only") tip_entry_found = True assert tip_entry_found self.nodes[0].getblock(block_h3.hash) @@ -169,8 +169,7 @@ tip = block_h3 all_blocks = [] for i in range(288): - next_block = create_block( - tip.sha256, create_coinbase(i + 4), tip.nTime + 1) + next_block = create_block(tip.sha256, create_coinbase(i + 4), tip.nTime + 1) next_block.solve() all_blocks.append(next_block) tip = next_block @@ -178,10 +177,12 @@ # Now send the block at height 5 and check that it wasn't accepted # (missing header) test_node.send_and_ping(msg_block(all_blocks[1])) - assert_raises_rpc_error(-5, "Block not found", - self.nodes[0].getblock, all_blocks[1].hash) - assert_raises_rpc_error(-5, "Block not found", - self.nodes[0].getblockheader, all_blocks[1].hash) + assert_raises_rpc_error( + -5, "Block not found", self.nodes[0].getblock, all_blocks[1].hash + ) + assert_raises_rpc_error( + -5, "Block not found", self.nodes[0].getblockheader, all_blocks[1].hash + ) # The block at height 5 should be accepted if we provide the missing # header, though @@ -201,7 +202,8 @@ for x in all_blocks[:-1]: self.nodes[0].getblock(x.hash) assert_raises_rpc_error( - -1, "Block not found on disk", self.nodes[0].getblock, all_blocks[-1].hash) + -1, "Block not found on disk", self.nodes[0].getblock, all_blocks[-1].hash + ) # 5. Test handling of unrequested block on the node that didn't process # Should still not be processed (even though it has a child that has more @@ -217,7 +219,8 @@ test_node.send_and_ping(msg_block(block_h1f)) assert_equal(self.nodes[0].getblockcount(), 2) self.log.info( - "Unrequested block that would complete more-work chain was ignored") + "Unrequested block that would complete more-work chain was ignored" + ) # 6. Try to get node to request the missing block. # Poke the node with an inv for block at height 3 and see if that @@ -240,27 +243,33 @@ assert_equal(self.nodes[0].getblockcount(), 290) self.nodes[0].getblock(all_blocks[286].hash) assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash) - assert_raises_rpc_error(-1, "Block not found on disk", - self.nodes[0].getblock, all_blocks[287].hash) + assert_raises_rpc_error( + -1, "Block not found on disk", self.nodes[0].getblock, all_blocks[287].hash + ) self.log.info("Successfully reorged to longer chain") # 8. Create a chain which is invalid at a height longer than the # current chain, but which has more blocks on top of that block_289f = create_block( - all_blocks[284].sha256, create_coinbase(289), all_blocks[284].nTime + 1) + all_blocks[284].sha256, create_coinbase(289), all_blocks[284].nTime + 1 + ) block_289f.solve() block_290f = create_block( - block_289f.sha256, create_coinbase(290), block_289f.nTime + 1) + block_289f.sha256, create_coinbase(290), block_289f.nTime + 1 + ) block_290f.solve() block_291 = create_block( - block_290f.sha256, create_coinbase(291), block_290f.nTime + 1) + block_290f.sha256, create_coinbase(291), block_290f.nTime + 1 + ) # block_291 spends a coinbase below maturity! - block_291.vtx.append(create_tx_with_script( - block_290f.vtx[0], 0, script_sig=b"42", amount=1)) + block_291.vtx.append( + create_tx_with_script(block_290f.vtx[0], 0, script_sig=b"42", amount=1) + ) block_291.hashMerkleRoot = block_291.calc_merkle_root() block_291.solve() block_292 = create_block( - block_291.sha256, create_coinbase(292), block_291.nTime + 1) + block_291.sha256, create_coinbase(292), block_291.nTime + 1 + ) block_292.solve() # Now send all the headers on the chain and enough blocks to trigger @@ -274,12 +283,13 @@ tip_entry_found = False for x in self.nodes[0].getchaintips(): - if x['hash'] == block_292.hash: - assert_equal(x['status'], "headers-only") + if x["hash"] == block_292.hash: + assert_equal(x["status"], "headers-only") tip_entry_found = True assert tip_entry_found - assert_raises_rpc_error(-1, "Block not found on disk", - self.nodes[0].getblock, block_292.hash) + assert_raises_rpc_error( + -1, "Block not found on disk", self.nodes[0].getblock, block_292.hash + ) test_node.send_message(msg_block(block_289f)) test_node.send_and_ping(msg_block(block_290f)) @@ -305,13 +315,13 @@ # 291) assert_equal(self.nodes[0].getblockcount(), 290) assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash) - assert_equal(self.nodes[0].getblock( - block_291.hash)["confirmations"], -1) + assert_equal(self.nodes[0].getblock(block_291.hash)["confirmations"], -1) # Now send a new header on the invalid chain, indicating we're forked # off, and expect to get disconnected block_293 = create_block( - block_292.sha256, create_coinbase(293), block_292.nTime + 1) + block_292.sha256, create_coinbase(293), block_292.nTime + 1 + ) block_293.solve() headers_message = msg_headers() headers_message.headers.append(CBlockHeader(block_293)) @@ -324,5 +334,5 @@ self.log.info("Successfully synced nodes 1 and 0") -if __name__ == '__main__': +if __name__ == "__main__": AcceptBlockTest().main()