diff --git a/test/functional/abc-finalize-block.py b/test/functional/abc-finalize-block.py --- a/test/functional/abc-finalize-block.py +++ b/test/functional/abc-finalize-block.py @@ -27,7 +27,7 @@ self.finalization_delay = 2 * 60 * 60 def run_test(self): - node = self.nodes[0] + node = self.nodes[1] self.mocktime = int(time.time()) @@ -43,7 +43,7 @@ return node.getbestblockhash() == tip wait_until(check_tip) - alt_node = self.nodes[1] + alt_node = self.nodes[0] wait_for_tip(alt_node, tip) alt_node.invalidateblock(tip) diff --git a/test/functional/abc-parkedchain.py b/test/functional/abc-parkedchain.py --- a/test/functional/abc-parkedchain.py +++ b/test/functional/abc-parkedchain.py @@ -5,14 +5,19 @@ """Test the parckblock and unparkblock RPC calls.""" from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, connect_nodes_bi, wait_until +from test_framework.util import ( + assert_equal, + connect_nodes, + wait_until +) class ParkedChainTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 2 self.extra_args = [["-noparkdeepreorg", - "-noautomaticunparking"], ["-maxreorgdepth=-1"]] + "-noautomaticunparking", "-whitelist=noban@127.0.0.1"], + ["-maxreorgdepth=-1", "-whitelist=noban@127.0.0.1"]] def skip_test_if_missing_module(self): self.skip_if_no_wallet() @@ -229,7 +234,7 @@ # Restart the parking node without parkdeepreorg. self.restart_node(1, ["-parkdeepreorg=0"]) parking_node = self.nodes[1] - connect_nodes_bi(node, parking_node) + connect_nodes(node, parking_node) # The other chain should still be marked 'parked'. wait_for_parked_block(node.getbestblockhash()) # Three more blocks is not enough to unpark. Even though its PoW is diff --git a/test/functional/abc_p2p_compactblocks.py b/test/functional/abc_p2p_compactblocks.py --- a/test/functional/abc_p2p_compactblocks.py +++ b/test/functional/abc_p2p_compactblocks.py @@ -40,7 +40,10 @@ from test_framework.script import CScript, OP_RETURN, OP_TRUE from test_framework.test_framework import BitcoinTestFramework from test_framework.txtools import pad_tx -from test_framework.util import assert_equal, wait_until +from test_framework.util import ( + assert_equal, + wait_until +) class PreviousSpendableOutput(): diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py --- a/test/functional/feature_notifications.py +++ b/test/functional/feature_notifications.py @@ -8,7 +8,11 @@ from test_framework.address import ADDRESS_BCHREG_UNSPENDABLE from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, connect_nodes_bi, wait_until +from test_framework.util import ( + assert_equal, + connect_nodes, + wait_until +) FORK_WARNING_MESSAGE = "Warning: Large-work fork detected, forking after block {}" @@ -79,7 +83,7 @@ self.log.info("test -walletnotify after rescan") # restart node to rescan to force wallet notifications self.restart_node(1) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) wait_until( lambda: len( diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py --- a/test/functional/mining_basic.py +++ b/test/functional/mining_basic.py @@ -26,7 +26,7 @@ from test_framework.util import ( assert_equal, assert_raises_rpc_error, - connect_nodes_bi, + connect_nodes, ) @@ -58,7 +58,7 @@ assert_equal(mining_info['currentblocktx'], 0) assert_equal(mining_info['currentblocksize'], 1000) self.restart_node(0) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) def run_test(self): self.mine_chain() 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 @@ -9,7 +9,7 @@ from test_framework.util import ( assert_equal, assert_raises_rpc_error, - connect_nodes_bi, + connect_nodes, wait_until, ) @@ -19,6 +19,10 @@ self.num_nodes = 2 def run_test(self): + self.log.info("Connect nodes both way") + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[0]) + self.log.info("Test setban and listbanned RPCs") self.log.info("setban: successfully ban single IP address") @@ -85,7 +89,9 @@ # Clear ban lists self.nodes[1].clearbanned() - connect_nodes_bi(self.nodes[0], self.nodes[1]) + self.log.info("Connect nodes both way") + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[0]) self.log.info("Test disconnectnode RPCs") @@ -112,7 +118,7 @@ self.log.info("disconnectnode: successfully reconnect node") # reconnect the node - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) assert_equal(len(self.nodes[0].getpeerinfo()), 2) assert [node for node in self.nodes[0] .getpeerinfo() if node['addr'] == address1] 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 @@ -23,7 +23,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, - connect_nodes_bi, + connect_nodes, disconnect_nodes, wait_until, ) @@ -81,7 +81,7 @@ self.log.info( "Mine enough blocks to reach the NODE_NETWORK_LIMITED range.") - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) blocks = self.nodes[1].generatetoaddress( 292, self.nodes[1].get_deterministic_priv_key().address) self.sync_blocks([self.nodes[0], self.nodes[1]]) @@ -112,7 +112,7 @@ # connect unsynced node 2 with pruned NODE_NETWORK_LIMITED peer # because node 2 is in IBD and node 0 is a NODE_NETWORK_LIMITED peer, # sync must not be possible - connect_nodes_bi(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) try: self.sync_blocks([self.nodes[0], self.nodes[2]], timeout=5) except Exception: @@ -122,7 +122,7 @@ self.nodes[2].getbestblockhash())['height'], 0) # now connect also to node 1 (non pruned) - connect_nodes_bi(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[1], self.nodes[2]) # sync must be possible self.sync_blocks() @@ -136,7 +136,7 @@ # connect node1 (non pruned) with node0 (pruned) and check if the can # sync - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) # sync must be possible, node 1 is no longer in IBD and should # therefore connect to node 0 (NODE_NETWORK_LIMITED) diff --git a/test/functional/p2p_tx_download.py b/test/functional/p2p_tx_download.py --- a/test/functional/p2p_tx_download.py +++ b/test/functional/p2p_tx_download.py @@ -126,6 +126,7 @@ # peer, plus # * the first time it is re-requested from the outbound peer, plus # * 2 seconds to avoid races + assert not self.nodes[1].getpeerinfo()[0]['inbound'] timeout = 2 + (MAX_GETDATA_RANDOM_DELAY + INBOUND_PEER_TX_DELAY) + ( GETDATA_TX_INTERVAL + MAX_GETDATA_RANDOM_DELAY) self.log.info( diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -13,7 +13,7 @@ assert_greater_than, assert_greater_than_or_equal, assert_raises_rpc_error, - connect_nodes_bi, + connect_nodes, find_vout_for_address, ) @@ -38,10 +38,10 @@ def setup_network(self): self.setup_nodes() - connect_nodes_bi(self.nodes[0], self.nodes[1]) - connect_nodes_bi(self.nodes[1], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[3]) + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[3]) def run_test(self): min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee'] @@ -496,10 +496,10 @@ for node in self.nodes: node.settxfee(min_relay_tx_fee) - connect_nodes_bi(self.nodes[0], self.nodes[1]) - connect_nodes_bi(self.nodes[1], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[3]) + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[3]) # Again lock the watchonly UTXO or nodes[0] may spend it, because # lockunspent is memory-only and thus lost on restart self.nodes[0].lockunspent( diff --git a/test/functional/rpc_invalidateblock.py b/test/functional/rpc_invalidateblock.py --- a/test/functional/rpc_invalidateblock.py +++ b/test/functional/rpc_invalidateblock.py @@ -9,7 +9,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, - connect_nodes_bi, + connect_nodes, ) @@ -37,7 +37,7 @@ assert self.nodes[1].getblockcount() == 6 self.log.info("Connect nodes to force a reorg") - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) self.sync_blocks(self.nodes[0:2]) assert self.nodes[0].getblockcount() == 6 badhash = self.nodes[1].getblockhash(2) @@ -52,7 +52,7 @@ "Wrong tip for node0, hash {}, height {}".format(newhash, newheight)) self.log.info("\nMake sure we won't reorg to a lower work chain:") - connect_nodes_bi(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[1], self.nodes[2]) self.log.info("Sync node 2 to node 1 so both have 6 blocks") self.sync_blocks(self.nodes[1:3]) assert self.nodes[2].getblockcount() == 6 diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py --- a/test/functional/rpc_net.py +++ b/test/functional/rpc_net.py @@ -15,7 +15,7 @@ assert_greater_than_or_equal, assert_greater_than, assert_raises_rpc_error, - connect_nodes_bi, + connect_nodes, p2p_port, wait_until, ) @@ -31,6 +31,10 @@ ["-minrelaytxfee=0.00000500"]] def run_test(self): + self.log.info('Connect nodes both way') + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[0]) + self._test_connection_count() self._test_getnettotals() self._test_getnetworkinginfo() @@ -39,7 +43,7 @@ self._test_getnodeaddresses() def _test_connection_count(self): - # connect_nodes_bi connects each node to the other + # connect_nodes connects each node to the other assert_equal(self.nodes[0].getconnectioncount(), 2) def _test_getnettotals(self): @@ -95,7 +99,10 @@ 'connections'] == 0, timeout=3) self.nodes[0].setnetworkactive(state=True) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + self.log.info('Connect nodes both way') + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[0]) + assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True) assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2) diff --git a/test/functional/rpc_preciousblock.py b/test/functional/rpc_preciousblock.py --- a/test/functional/rpc_preciousblock.py +++ b/test/functional/rpc_preciousblock.py @@ -7,7 +7,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, - connect_nodes_bi, + connect_nodes, ) @@ -71,7 +71,7 @@ # Submit competing blocks via RPC so any reorg should occur before we # proceed (no way to wait on inaction for p2p sync) node_sync_via_rpc(self.nodes[0:2]) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) assert_equal(self.nodes[0].getbestblockhash(), hashC) assert_equal(self.nodes[1].getbestblockhash(), hashG) self.log.info("Make Node0 prefer block G") @@ -110,8 +110,8 @@ hashL = self.nodes[2].getbestblockhash() self.log.info("Connect nodes and check no reorg occurs") node_sync_via_rpc(self.nodes[1:3]) - connect_nodes_bi(self.nodes[1], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) assert_equal(self.nodes[0].getbestblockhash(), hashH) assert_equal(self.nodes[1].getbestblockhash(), hashH) assert_equal(self.nodes[2].getbestblockhash(), hashL) diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py --- a/test/functional/rpc_rawtransaction.py +++ b/test/functional/rpc_rawtransaction.py @@ -30,7 +30,7 @@ assert_equal, assert_greater_than, assert_raises_rpc_error, - connect_nodes_bi, + connect_nodes, hex_str_to_bytes, ) @@ -63,7 +63,7 @@ def setup_network(self): super().setup_network() - connect_nodes_bi(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) def run_test(self): self.log.info( diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -22,7 +22,7 @@ from .util import ( assert_equal, check_json_precision, - connect_nodes_bi, + connect_nodes, disconnect_nodes, get_datadir_path, initialize_datadir, @@ -265,8 +265,18 @@ # Connect the nodes as a "chain". This allows us # to split the network between nodes 1 and 2 to get # two halves that can work on competing chains. + # + # Topology looks like this: + # node0 <-- node1 <-- node2 <-- node3 + # + # If all nodes are in IBD (clean chain from genesis), node0 is assumed to be the source of blocks (miner). To + # ensure block propagation, all nodes will establish outgoing connections toward node0. + # See fPreferredDownload in net_processing. + # + # If further outbound connections are needed, they can be added at the beginning of the test with e.g. + # connect_nodes(self.nodes[1], 2) for i in range(self.num_nodes - 1): - connect_nodes_bi(self.nodes[i], self.nodes[i + 1]) + connect_nodes(self.nodes[i + 1], self.nodes[i]) self.sync_all() def setup_nodes(self): @@ -416,7 +426,7 @@ """ Join the (previously split) network halves together. """ - connect_nodes_bi(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[1], self.nodes[2]) self.sync_all() def sync_blocks(self, nodes=None, **kwargs): diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -426,11 +426,6 @@ != 0 for peer in from_node.getpeerinfo())) -def connect_nodes_bi(a, b): - connect_nodes(a, b) - connect_nodes(b, a) - - def sync_blocks(rpc_connections, *, wait=1, timeout=60): """ Wait until everybody has the same tip. diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py --- a/test/functional/wallet_address_types.py +++ b/test/functional/wallet_address_types.py @@ -39,7 +39,7 @@ from test_framework.util import ( assert_equal, assert_greater_than, - connect_nodes_bi, + connect_nodes, ) @@ -58,7 +58,7 @@ # Fully mesh-connect nodes for faster mempool sync for i, j in itertools.product(range(self.num_nodes), repeat=2): if i > j: - connect_nodes_bi(self.nodes[i], self.nodes[j]) + connect_nodes(self.nodes[i], self.nodes[j]) self.sync_all() def get_balances(self, confirmed=True): diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py --- a/test/functional/wallet_basic.py +++ b/test/functional/wallet_basic.py @@ -13,7 +13,7 @@ assert_equal, assert_fee_amount, assert_raises_rpc_error, - connect_nodes_bi, + connect_nodes, count_bytes, wait_until, ) @@ -34,9 +34,9 @@ self.setup_nodes() # Only need nodes 0-2 running at start of test self.stop_node(3) - connect_nodes_bi(self.nodes[0], self.nodes[1]) - connect_nodes_bi(self.nodes[1], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) self.sync_all(self.nodes[0:3]) def check_fee_amount(self, curr_balance, @@ -240,7 +240,7 @@ ), node_0_bal + Decimal('10'), fee_per_byte, ctx.billable_size()) self.start_node(3, self.extra_args[3]) - connect_nodes_bi(self.nodes[0], self.nodes[3]) + connect_nodes(self.nodes[0], self.nodes[3]) self.sync_all() # check if we can list zero value tx as available coins @@ -280,9 +280,9 @@ self.start_node(0, self.extra_args[0] + ["-walletbroadcast=0"]) self.start_node(1, self.extra_args[1] + ["-walletbroadcast=0"]) self.start_node(2, self.extra_args[2] + ["-walletbroadcast=0"]) - connect_nodes_bi(self.nodes[0], self.nodes[1]) - connect_nodes_bi(self.nodes[1], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) self.sync_all(self.nodes[0:3]) txIdNotBroadcasted = self.nodes[0].sendtoaddress( @@ -311,9 +311,9 @@ self.start_node(0, self.extra_args[0]) self.start_node(1, self.extra_args[1]) self.start_node(2, self.extra_args[2]) - connect_nodes_bi(self.nodes[0], self.nodes[1]) - connect_nodes_bi(self.nodes[1], self.nodes[2]) - connect_nodes_bi(self.nodes[0], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[1], self.nodes[2]) + connect_nodes(self.nodes[0], self.nodes[2]) self.sync_blocks(self.nodes[0:3]) self.nodes[0].generate(1) diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py --- a/test/functional/wallet_hd.py +++ b/test/functional/wallet_hd.py @@ -10,7 +10,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, - connect_nodes_bi, + connect_nodes, assert_raises_rpc_error ) @@ -88,7 +88,7 @@ assert_equal(hd_info_2["hdkeypath"], "m/0'/0'/" + str(i) + "'") assert_equal(hd_info_2["hdseedid"], masterkeyid) assert_equal(hd_add, hd_add_2) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) self.sync_all() # Needs rescan @@ -104,7 +104,7 @@ shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join( self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")) self.start_node(1, extra_args=self.extra_args[1]) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) self.sync_all() # Wallet automatically scans blocks older than key on startup assert_equal(self.nodes[1].getbalance(), NUM_HD_ADDS + 1) diff --git a/test/functional/wallet_keypool_topup.py b/test/functional/wallet_keypool_topup.py --- a/test/functional/wallet_keypool_topup.py +++ b/test/functional/wallet_keypool_topup.py @@ -16,7 +16,7 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, - connect_nodes_bi, + connect_nodes, ) @@ -39,7 +39,7 @@ self.stop_node(1) shutil.copyfile(wallet_path, wallet_backup_path) self.start_node(1, self.extra_args[1]) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) self.log.info("Generate keys for wallet") for _ in range(90): @@ -58,7 +58,7 @@ self.stop_node(1) shutil.copyfile(wallet_backup_path, wallet_path) self.start_node(1, self.extra_args[1]) - connect_nodes_bi(self.nodes[0], self.nodes[1]) + connect_nodes(self.nodes[0], self.nodes[1]) self.sync_all() self.log.info("Verify keypool is restored and balance is correct") diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py --- a/test/functional/wallet_listsinceblock.py +++ b/test/functional/wallet_listsinceblock.py @@ -4,10 +4,15 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. """Test the listsincelast RPC.""" from test_framework.test_framework import BitcoinTestFramework -from test_framework.util import assert_equal, assert_array_result, assert_raises_rpc_error +from test_framework.util import ( + assert_array_result, + assert_equal, + assert_raises_rpc_error, + connect_nodes, +) -class ListSinceBlockTest (BitcoinTestFramework): +class ListSinceBlockTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 4 self.setup_clean_chain = True @@ -17,6 +22,9 @@ self.skip_if_no_wallet() def run_test(self): + # All nodes are in IBD from genesis, so they'll need the miner (node2) to be an outbound connection, or have + # only one connection. (See fPreferredDownload in net_processing) + connect_nodes(self.nodes[1], self.nodes[2]) self.nodes[2].generate(101) self.sync_all()