Skip to content

Commit 59c138d

Browse files
author
MarcoFalke
committed
Merge bitcoin#16898: test: Remove connect_nodes_bi
fadfd84 test: Remove unused connect_nodes_bi (MarcoFalke) fa3b9ee scripted-diff: test: Replace connect_nodes_bi with connect_nodes (MarcoFalke) faaee1e test: Use connect_nodes when connecting nodes in the test_framework (MarcoFalke) 1111bb9 test: Reformat python imports to aid scripted diff (MarcoFalke) Pull request description: By default all test nodes are connected in a chain. However, instead of just a single connection between each pair of nodes, we end up with up to four connections for a "middle" node (two outbound, two inbound, from each side). This is generally redundant (tx and block relay should succeed with just a single connection) and confusing. For example, test timeouts after a call to `sync_` may be racy and hard to reproduce. On top of that, the test `debug.log`s are hard to read because txs and block invs may be relayed on the same connection multiple times. Fix this by inlining `connect_nodes_bi` in the two tests that need it, and then replace it with a single `connect_nodes` in all other tests. Historic background: `connect_nodes_bi` has been introduced as a (temporary?) workaround for bug bitcoin#5113 and bitcoin#5138, which has long been fixed in bitcoin#5157 and bitcoin#5662. ACKs for top commit: laanwj: ACK fadfd84 jonasschnelli: utACK fadfd84 - more of less a cleanup PR. promag: Tested ACK fadfd84, ran extended tests. Tree-SHA512: 2d027a8fd150749c071b64438a0a78ec922178628a7dbb89fd1212b0fa34febd451798c940101155d3617c0426c2c4865174147709894f1f1bb6cfa336aa7e24
2 parents cfcaa97 + fadfd84 commit 59c138d

20 files changed

+108
-69
lines changed

test/functional/feature_notifications.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77

88
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE
99
from test_framework.test_framework import BitcoinTestFramework
10-
from test_framework.util import assert_equal, wait_until, connect_nodes_bi
10+
from test_framework.util import (
11+
assert_equal,
12+
wait_until,
13+
connect_nodes,
14+
)
1115

1216

1317
class NotificationsTest(BitcoinTestFramework):
@@ -58,7 +62,7 @@ def run_test(self):
5862
self.log.info("test -walletnotify after rescan")
5963
# restart node to rescan to force wallet notifications
6064
self.start_node(1)
61-
connect_nodes_bi(self.nodes, 0, 1)
65+
connect_nodes(self.nodes[0], 1)
6266

6367
wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
6468

test/functional/mining_basic.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from test_framework.util import (
2828
assert_equal,
2929
assert_raises_rpc_error,
30-
connect_nodes_bi,
30+
connect_nodes,
3131
)
3232
from test_framework.script import CScriptNum
3333

@@ -54,7 +54,7 @@ def mine_chain(self):
5454
assert_equal(mining_info['currentblocktx'], 0)
5555
assert_equal(mining_info['currentblockweight'], 4000)
5656
self.restart_node(0)
57-
connect_nodes_bi(self.nodes, 0, 1)
57+
connect_nodes(self.nodes[0], 1)
5858

5959
def run_test(self):
6060
self.mine_chain()

test/functional/p2p_disconnect_ban.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from test_framework.util import (
1010
assert_equal,
1111
assert_raises_rpc_error,
12-
connect_nodes_bi,
12+
connect_nodes,
1313
wait_until,
1414
)
1515

@@ -18,6 +18,10 @@ def set_test_params(self):
1818
self.num_nodes = 2
1919

2020
def run_test(self):
21+
self.log.info("Connect nodes both way")
22+
connect_nodes(self.nodes[0], 1)
23+
connect_nodes(self.nodes[1], 0)
24+
2125
self.log.info("Test setban and listbanned RPCs")
2226

2327
self.log.info("setban: successfully ban single IP address")
@@ -74,7 +78,9 @@ def run_test(self):
7478

7579
# Clear ban lists
7680
self.nodes[1].clearbanned()
77-
connect_nodes_bi(self.nodes, 0, 1)
81+
self.log.info("Connect nodes both way")
82+
connect_nodes(self.nodes[0], 1)
83+
connect_nodes(self.nodes[1], 0)
7884

7985
self.log.info("Test disconnectnode RPCs")
8086

@@ -93,7 +99,7 @@ def run_test(self):
9399
assert not [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1]
94100

95101
self.log.info("disconnectnode: successfully reconnect node")
96-
connect_nodes_bi(self.nodes, 0, 1) # reconnect the node
102+
connect_nodes(self.nodes[0], 1) # reconnect the node
97103
assert_equal(len(self.nodes[0].getpeerinfo()), 2)
98104
assert [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1]
99105

test/functional/p2p_node_network_limited.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from test_framework.util import (
1515
assert_equal,
1616
disconnect_nodes,
17-
connect_nodes_bi,
17+
connect_nodes,
1818
wait_until,
1919
)
2020

@@ -64,7 +64,7 @@ def run_test(self):
6464
assert_equal(int(self.nodes[0].getnetworkinfo()['localservices'], 16), expected_services)
6565

6666
self.log.info("Mine enough blocks to reach the NODE_NETWORK_LIMITED range.")
67-
connect_nodes_bi(self.nodes, 0, 1)
67+
connect_nodes(self.nodes[0], 1)
6868
blocks = self.nodes[1].generatetoaddress(292, self.nodes[1].get_deterministic_priv_key().address)
6969
self.sync_blocks([self.nodes[0], self.nodes[1]])
7070

@@ -90,7 +90,7 @@ def run_test(self):
9090

9191
# connect unsynced node 2 with pruned NODE_NETWORK_LIMITED peer
9292
# because node 2 is in IBD and node 0 is a NODE_NETWORK_LIMITED peer, sync must not be possible
93-
connect_nodes_bi(self.nodes, 0, 2)
93+
connect_nodes(self.nodes[0], 2)
9494
try:
9595
self.sync_blocks([self.nodes[0], self.nodes[2]], timeout=5)
9696
except:
@@ -99,7 +99,7 @@ def run_test(self):
9999
assert_equal(self.nodes[2].getblockheader(self.nodes[2].getbestblockhash())['height'], 0)
100100

101101
# now connect also to node 1 (non pruned)
102-
connect_nodes_bi(self.nodes, 1, 2)
102+
connect_nodes(self.nodes[1], 2)
103103

104104
# sync must be possible
105105
self.sync_blocks()
@@ -111,7 +111,7 @@ def run_test(self):
111111
self.nodes[0].generatetoaddress(10, self.nodes[0].get_deterministic_priv_key().address)
112112

113113
# connect node1 (non pruned) with node0 (pruned) and check if the can sync
114-
connect_nodes_bi(self.nodes, 0, 1)
114+
connect_nodes(self.nodes[0], 1)
115115

116116
# sync must be possible, node 1 is no longer in IBD and should therefore connect to node 0 (NODE_NETWORK_LIMITED)
117117
self.sync_blocks([self.nodes[0], self.nodes[1]])

test/functional/p2p_tx_download.py

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def test_inv_block(self):
121121
# peer, plus
122122
# * the first time it is re-requested from the outbound peer, plus
123123
# * 2 seconds to avoid races
124+
assert self.nodes[1].getpeerinfo()[0]['inbound'] == False
124125
timeout = 2 + (MAX_GETDATA_RANDOM_DELAY + INBOUND_PEER_TX_DELAY) + (
125126
GETDATA_TX_INTERVAL + MAX_GETDATA_RANDOM_DELAY)
126127
self.log.info("Tx should be received at node 1 after {} seconds".format(timeout))

test/functional/rpc_fundrawtransaction.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
assert_greater_than,
1313
assert_greater_than_or_equal,
1414
assert_raises_rpc_error,
15-
connect_nodes_bi,
15+
connect_nodes,
1616
count_bytes,
1717
find_vout_for_address,
1818
)
@@ -35,10 +35,10 @@ def skip_test_if_missing_module(self):
3535
def setup_network(self):
3636
self.setup_nodes()
3737

38-
connect_nodes_bi(self.nodes, 0, 1)
39-
connect_nodes_bi(self.nodes, 1, 2)
40-
connect_nodes_bi(self.nodes, 0, 2)
41-
connect_nodes_bi(self.nodes, 0, 3)
38+
connect_nodes(self.nodes[0], 1)
39+
connect_nodes(self.nodes[1], 2)
40+
connect_nodes(self.nodes[0], 2)
41+
connect_nodes(self.nodes[0], 3)
4242

4343
def run_test(self):
4444
self.min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
@@ -508,10 +508,10 @@ def test_locked_wallet(self):
508508
for node in self.nodes:
509509
node.settxfee(self.min_relay_tx_fee)
510510

511-
connect_nodes_bi(self.nodes,0,1)
512-
connect_nodes_bi(self.nodes,1,2)
513-
connect_nodes_bi(self.nodes,0,2)
514-
connect_nodes_bi(self.nodes,0,3)
511+
connect_nodes(self.nodes[0], 1)
512+
connect_nodes(self.nodes[1], 2)
513+
connect_nodes(self.nodes[0], 2)
514+
connect_nodes(self.nodes[0], 3)
515515
# Again lock the watchonly UTXO or nodes[0] may spend it, because
516516
# lockunspent is memory-only and thus lost on restart
517517
self.nodes[0].lockunspent(False, [{"txid": self.watchonly_txid, "vout": self.watchonly_vout}])

test/functional/rpc_net.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
assert_greater_than_or_equal,
1616
assert_greater_than,
1717
assert_raises_rpc_error,
18-
connect_nodes_bi,
18+
connect_nodes,
1919
p2p_port,
2020
wait_until,
2121
)
@@ -54,6 +54,10 @@ def set_test_params(self):
5454
self.extra_args = [["-minrelaytxfee=0.00001000"],["-minrelaytxfee=0.00000500"]]
5555

5656
def run_test(self):
57+
self.log.info('Connect nodes both way')
58+
connect_nodes(self.nodes[0], 1)
59+
connect_nodes(self.nodes[1], 0)
60+
5761
self._test_connection_count()
5862
self._test_getnettotals()
5963
self._test_getnetworkinfo()
@@ -62,7 +66,7 @@ def run_test(self):
6266
self._test_getnodeaddresses()
6367

6468
def _test_connection_count(self):
65-
# connect_nodes_bi connects each node to the other
69+
# connect_nodes connects each node to the other
6670
assert_equal(self.nodes[0].getconnectioncount(), 2)
6771

6872
def _test_getnettotals(self):
@@ -105,7 +109,10 @@ def _test_getnetworkinfo(self):
105109
wait_until(lambda: self.nodes[0].getnetworkinfo()['connections'] == 0, timeout=3)
106110

107111
self.nodes[0].setnetworkactive(state=True)
108-
connect_nodes_bi(self.nodes, 0, 1)
112+
self.log.info('Connect nodes both way')
113+
connect_nodes(self.nodes[0], 1)
114+
connect_nodes(self.nodes[1], 0)
115+
109116
assert_equal(self.nodes[0].getnetworkinfo()['networkactive'], True)
110117
assert_equal(self.nodes[0].getnetworkinfo()['connections'], 2)
111118

test/functional/rpc_preciousblock.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from test_framework.test_framework import BitcoinTestFramework
88
from test_framework.util import (
99
assert_equal,
10-
connect_nodes_bi,
10+
connect_nodes,
1111
)
1212

1313
def unidirectional_node_sync_via_rpc(node_src, node_dest):
@@ -60,7 +60,7 @@ def run_test(self):
6060
self.log.info("Connect nodes and check no reorg occurs")
6161
# Submit competing blocks via RPC so any reorg should occur before we proceed (no way to wait on inaction for p2p sync)
6262
node_sync_via_rpc(self.nodes[0:2])
63-
connect_nodes_bi(self.nodes,0,1)
63+
connect_nodes(self.nodes[0], 1)
6464
assert_equal(self.nodes[0].getbestblockhash(), hashC)
6565
assert_equal(self.nodes[1].getbestblockhash(), hashG)
6666
self.log.info("Make Node0 prefer block G")
@@ -97,8 +97,8 @@ def run_test(self):
9797
hashL = self.nodes[2].getbestblockhash()
9898
self.log.info("Connect nodes and check no reorg occurs")
9999
node_sync_via_rpc(self.nodes[1:3])
100-
connect_nodes_bi(self.nodes,1,2)
101-
connect_nodes_bi(self.nodes,0,2)
100+
connect_nodes(self.nodes[1], 2)
101+
connect_nodes(self.nodes[0], 2)
102102
assert_equal(self.nodes[0].getbestblockhash(), hashH)
103103
assert_equal(self.nodes[1].getbestblockhash(), hashH)
104104
assert_equal(self.nodes[2].getbestblockhash(), hashL)

test/functional/rpc_psbt.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
assert_equal,
1212
assert_greater_than,
1313
assert_raises_rpc_error,
14-
connect_nodes_bi,
14+
connect_nodes,
1515
disconnect_nodes,
1616
find_output,
1717
)
@@ -72,8 +72,8 @@ def test_utxo_conversion(self):
7272
assert_equal(online_node.gettxout(txid,0)["confirmations"], 1)
7373

7474
# Reconnect
75-
connect_nodes_bi(self.nodes, 0, 1)
76-
connect_nodes_bi(self.nodes, 0, 2)
75+
connect_nodes(self.nodes[0], 1)
76+
connect_nodes(self.nodes[0], 2)
7777

7878
def run_test(self):
7979
# Create and fund a raw tx for sending 10 BTC

test/functional/rpc_rawtransaction.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@
1717
from io import BytesIO
1818
from test_framework.messages import CTransaction, ToHex
1919
from test_framework.test_framework import BitcoinTestFramework
20-
from test_framework.util import assert_equal, assert_raises_rpc_error, connect_nodes_bi, hex_str_to_bytes
20+
from test_framework.util import (
21+
assert_equal,
22+
assert_raises_rpc_error,
23+
connect_nodes,
24+
hex_str_to_bytes,
25+
)
26+
2127

2228
class multidict(dict):
2329
"""Dictionary that allows duplicate keys.
@@ -53,7 +59,7 @@ def skip_test_if_missing_module(self):
5359

5460
def setup_network(self):
5561
super().setup_network()
56-
connect_nodes_bi(self.nodes, 0, 2)
62+
connect_nodes(self.nodes[0], 2)
5763

5864
def run_test(self):
5965
self.log.info('prepare some coins for multiple *rawtransaction commands')

test/functional/test_framework/test_framework.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
PortSeed,
2626
assert_equal,
2727
check_json_precision,
28-
connect_nodes_bi,
28+
connect_nodes,
2929
disconnect_nodes,
3030
get_datadir_path,
3131
initialize_datadir,
@@ -281,8 +281,18 @@ def setup_network(self):
281281
# Connect the nodes as a "chain". This allows us
282282
# to split the network between nodes 1 and 2 to get
283283
# two halves that can work on competing chains.
284+
#
285+
# Topology looks like this:
286+
# node0 <-- node1 <-- node2 <-- node3
287+
#
288+
# If all nodes are in IBD (clean chain from genesis), node0 is assumed to be the source of blocks (miner). To
289+
# ensure block propagation, all nodes will establish outgoing connections toward node0.
290+
# See fPreferredDownload in net_processing.
291+
#
292+
# If further outbound connections are needed, they can be added at the beginning of the test with e.g.
293+
# connect_nodes(self.nodes[1], 2)
284294
for i in range(self.num_nodes - 1):
285-
connect_nodes_bi(self.nodes, i, i + 1)
295+
connect_nodes(self.nodes[i + 1], i)
286296
self.sync_all()
287297

288298
def setup_nodes(self):
@@ -423,7 +433,7 @@ def join_network(self):
423433
"""
424434
Join the (previously split) network halves together.
425435
"""
426-
connect_nodes_bi(self.nodes, 1, 2)
436+
connect_nodes(self.nodes[1], 2)
427437
self.sync_all()
428438

429439
def sync_blocks(self, nodes=None, **kwargs):

test/functional/test_framework/util.py

-4
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,6 @@ def connect_nodes(from_connection, node_num):
377377
# with transaction relaying
378378
wait_until(lambda: all(peer['version'] != 0 for peer in from_connection.getpeerinfo()))
379379

380-
def connect_nodes_bi(nodes, a, b):
381-
connect_nodes(nodes[a], b)
382-
connect_nodes(nodes[b], a)
383-
384380
def sync_blocks(rpc_connections, *, wait=1, timeout=60):
385381
"""
386382
Wait until everybody has the same tip.

test/functional/wallet_address_types.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
assert_equal,
6363
assert_greater_than,
6464
assert_raises_rpc_error,
65-
connect_nodes_bi,
65+
connect_nodes,
6666
)
6767
from test_framework.segwit_addr import (
6868
encode,
@@ -90,7 +90,7 @@ def setup_network(self):
9090
# Fully mesh-connect nodes for faster mempool sync
9191
for i, j in itertools.product(range(self.num_nodes), repeat=2):
9292
if i > j:
93-
connect_nodes_bi(self.nodes, i, j)
93+
connect_nodes(self.nodes[i], j)
9494
self.sync_all()
9595

9696
def get_balances(self, confirmed=True):

test/functional/wallet_avoidreuse.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from test_framework.util import (
99
assert_equal,
1010
assert_raises_rpc_error,
11-
connect_nodes_bi,
11+
connect_nodes,
1212
)
1313

1414
# TODO: Copied from wallet_groups.py -- should perhaps move into util.py
@@ -103,7 +103,7 @@ def test_persistence(self):
103103
# Stop and restart node 1
104104
self.stop_node(1)
105105
self.start_node(1)
106-
connect_nodes_bi(self.nodes, 0, 1)
106+
connect_nodes(self.nodes[0], 1)
107107

108108
# Flags should still be node1.avoid_reuse=false, node2.avoid_reuse=true
109109
assert_equal(self.nodes[0].getwalletinfo()["avoid_reuse"], False)

test/functional/wallet_balance.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from test_framework.util import (
1212
assert_equal,
1313
assert_raises_rpc_error,
14-
connect_nodes_bi,
14+
connect_nodes,
1515
sync_blocks,
1616
)
1717

@@ -211,7 +211,7 @@ def test_balances(*, fee_node_1=0):
211211

212212
# Now confirm tx_orig
213213
self.restart_node(1, ['-persistmempool=0'])
214-
connect_nodes_bi(self.nodes, 0, 1)
214+
connect_nodes(self.nodes[0], 1)
215215
sync_blocks(self.nodes)
216216
self.nodes[1].sendrawtransaction(tx_orig)
217217
self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)

0 commit comments

Comments
 (0)