aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/data/invalid_txs.py56
-rw-r--r--test/functional/data/wallets/high_minversion/GENERATE.md8
-rwxr-xr-xtest/functional/feature_assumevalid.py4
-rwxr-xr-xtest/functional/feature_block.py8
-rwxr-xr-xtest/functional/feature_dbcrash.py2
-rwxr-xr-xtest/functional/feature_notifications.py8
-rwxr-xr-xtest/functional/feature_pruning.py1
-rwxr-xr-xtest/functional/feature_segwit.py2
-rwxr-xr-xtest/functional/mempool_accept.py2
-rwxr-xr-xtest/functional/mining_basic.py4
-rwxr-xr-xtest/functional/p2p_disconnect_ban.py12
-rwxr-xr-xtest/functional/p2p_invalid_block.py44
-rwxr-xr-xtest/functional/p2p_invalid_messages.py2
-rwxr-xr-xtest/functional/p2p_node_network_limited.py10
-rwxr-xr-xtest/functional/p2p_tx_download.py1
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py18
-rwxr-xr-xtest/functional/rpc_net.py13
-rwxr-xr-xtest/functional/rpc_preciousblock.py8
-rwxr-xr-xtest/functional/rpc_psbt.py16
-rwxr-xr-xtest/functional/rpc_rawtransaction.py42
-rwxr-xr-xtest/functional/test_framework/test_framework.py16
-rw-r--r--test/functional/test_framework/util.py4
-rwxr-xr-xtest/functional/tool_wallet.py1
-rwxr-xr-xtest/functional/wallet_address_types.py18
-rwxr-xr-xtest/functional/wallet_avoidreuse.py4
-rwxr-xr-xtest/functional/wallet_backup.py1
-rwxr-xr-xtest/functional/wallet_balance.py4
-rwxr-xr-xtest/functional/wallet_basic.py24
-rwxr-xr-xtest/functional/wallet_bumpfee.py4
-rwxr-xr-xtest/functional/wallet_hd.py6
-rwxr-xr-xtest/functional/wallet_keypool_topup.py10
-rwxr-xr-xtest/functional/wallet_listsinceblock.py13
32 files changed, 273 insertions, 93 deletions
diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py
index a21a613986..fd69bbd2c7 100644
--- a/test/functional/data/invalid_txs.py
+++ b/test/functional/data/invalid_txs.py
@@ -24,7 +24,24 @@ import abc
from test_framework.messages import CTransaction, CTxIn, CTxOut, COutPoint
from test_framework import script as sc
from test_framework.blocktools import create_tx_with_script, MAX_BLOCK_SIGOPS
-
+from test_framework.script import (
+ CScript,
+ OP_CAT,
+ OP_SUBSTR,
+ OP_LEFT,
+ OP_RIGHT,
+ OP_INVERT,
+ OP_AND,
+ OP_OR,
+ OP_XOR,
+ OP_2MUL,
+ OP_2DIV,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_LSHIFT,
+ OP_RSHIFT
+)
basic_p2sh = sc.CScript([sc.OP_HASH160, sc.hash160(sc.CScript([sc.OP_0])), sc.OP_EQUAL])
@@ -180,7 +197,44 @@ class TooManySigops(BadTxTemplate):
script_pub_key=lotsa_checksigs,
amount=1)
+def getDisabledOpcodeTemplate(opcode):
+ """ Creates disabled opcode tx template class"""
+ def get_tx(self):
+ tx = CTransaction()
+ vin = self.valid_txin
+ vin.scriptSig = CScript([opcode])
+ tx.vin.append(vin)
+ tx.vout.append(CTxOut(1, basic_p2sh))
+ tx.calc_sha256()
+ return tx
+
+ return type('DisabledOpcode_' + str(opcode), (BadTxTemplate,), {
+ 'reject_reason': "disabled opcode",
+ 'expect_disconnect': True,
+ 'get_tx': get_tx,
+ 'valid_in_block' : True
+ })
+
+# Disabled opcode tx templates (CVE-2010-5137)
+DisabledOpcodeTemplates = [getDisabledOpcodeTemplate(opcode) for opcode in [
+ OP_CAT,
+ OP_SUBSTR,
+ OP_LEFT,
+ OP_RIGHT,
+ OP_INVERT,
+ OP_AND,
+ OP_OR,
+ OP_XOR,
+ OP_2MUL,
+ OP_2DIV,
+ OP_MUL,
+ OP_DIV,
+ OP_MOD,
+ OP_LSHIFT,
+ OP_RSHIFT]]
+
def iter_all_templates():
"""Iterate through all bad transaction template types."""
return BadTxTemplate.__subclasses__()
+
diff --git a/test/functional/data/wallets/high_minversion/GENERATE.md b/test/functional/data/wallets/high_minversion/GENERATE.md
new file mode 100644
index 0000000000..e55c4557ca
--- /dev/null
+++ b/test/functional/data/wallets/high_minversion/GENERATE.md
@@ -0,0 +1,8 @@
+The wallet has been created by starting Bitcoin Core with the options
+`-regtest -datadir=/tmp -nowallet -walletdir=$(pwd)/test/functional/data/wallets/`.
+
+In the source code, `WalletFeature::FEATURE_LATEST` has been modified to be large, so that the minversion is too high
+for a current build of the wallet.
+
+The wallet has then been created with the RPC `createwallet high_minversion true true`, so that a blank wallet with
+private keys disabled is created.
diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py
index 420a3a7688..1b434c4485 100755
--- a/test/functional/feature_assumevalid.py
+++ b/test/functional/feature_assumevalid.py
@@ -40,7 +40,7 @@ from test_framework.messages import (
CTxIn,
CTxOut,
msg_block,
- msg_headers
+ msg_headers,
)
from test_framework.mininode import P2PInterface
from test_framework.script import (CScript, OP_TRUE)
@@ -180,7 +180,7 @@ class AssumeValidTest(BitcoinTestFramework):
for i in range(2202):
p2p1.send_message(msg_block(self.blocks[i]))
# Syncing 2200 blocks can take a while on slow systems. Give it plenty of time to sync.
- p2p1.sync_with_ping(200)
+ p2p1.sync_with_ping(960)
assert_equal(self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'], 2202)
# Send blocks to node2. Block 102 will be rejected.
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 12a52935ef..c74270febc 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -806,7 +806,7 @@ class FullBlockTest(BitcoinTestFramework):
#
# Blocks are not allowed to contain a transaction whose id matches that of an earlier,
# not-fully-spent transaction in the same chain. To test, make identical coinbases;
- # the second one should be rejected.
+ # the second one should be rejected. See also CVE-2012-1909.
#
self.log.info("Reject a block with a transaction with a duplicate hash of a previous transaction (BIP30)")
self.move_tip(60)
@@ -1261,7 +1261,7 @@ class FullBlockTest(BitcoinTestFramework):
self.save_spendable_output()
spend = self.get_spendable_output()
- self.send_blocks(blocks, True, timeout=480)
+ self.send_blocks(blocks, True, timeout=960)
chain1_tip = i
# now create alt chain of same length
@@ -1273,14 +1273,14 @@ class FullBlockTest(BitcoinTestFramework):
# extend alt chain to trigger re-org
block = self.next_block("alt" + str(chain1_tip + 1), version=4)
- self.send_blocks([block], True, timeout=480)
+ self.send_blocks([block], True, timeout=960)
# ... and re-org back to the first chain
self.move_tip(chain1_tip)
block = self.next_block(chain1_tip + 1, version=4)
self.send_blocks([block], False, force_send=True)
block = self.next_block(chain1_tip + 2, version=4)
- self.send_blocks([block], True, timeout=480)
+ self.send_blocks([block], True, timeout=960)
self.log.info("Reject a block with an invalid block header version")
b_v1 = self.next_block('b_v1', version=1)
diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py
index b86f6af4ca..6bd6bb5b8c 100755
--- a/test/functional/feature_dbcrash.py
+++ b/test/functional/feature_dbcrash.py
@@ -50,7 +50,7 @@ class ChainstateWriteCrashTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
self.setup_clean_chain = False
- self.rpc_timeout = 180
+ self.rpc_timeout = 480
# Set -maxmempool=0 to turn off mempool memory sharing with dbcache
# Set -rpcservertimeout=900 to reduce socket disconnects in this
diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py
index 13cf951550..da00b773ad 100755
--- a/test/functional/feature_notifications.py
+++ b/test/functional/feature_notifications.py
@@ -7,7 +7,11 @@ import os
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal, wait_until, connect_nodes_bi
+from test_framework.util import (
+ assert_equal,
+ wait_until,
+ connect_nodes,
+)
class NotificationsTest(BitcoinTestFramework):
@@ -58,7 +62,7 @@ class NotificationsTest(BitcoinTestFramework):
self.log.info("test -walletnotify after rescan")
# restart node to rescan to force wallet notifications
self.start_node(1)
- connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes(self.nodes[0], 1)
wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
index 727f4b9589..51523f13e7 100755
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -92,6 +92,7 @@ class PruneTest(BitcoinTestFramework):
["-maxreceivebuffer=20000"],
["-prune=550"],
]
+ self.rpc_timeout = 120
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index b9db618575..d2826dd1b7 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -257,7 +257,7 @@ class SegWitTest(BitcoinTestFramework):
tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b""))
tx.vout.append(CTxOut(int(49.95 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) # Huge fee
tx.calc_sha256()
- txid3 = self.nodes[0].sendrawtransaction(ToHex(tx))
+ txid3 = self.nodes[0].sendrawtransaction(ToHex(tx), 0)
assert tx.wit.is_null()
assert txid3 in self.nodes[0].getrawmempool()
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index 209a222004..dee7a04516 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -183,6 +183,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
self.check_mempool_result(
result_expected=[{'txid': tx.rehash(), 'allowed': True}],
rawtxs=[tx.serialize().hex()],
+ maxfeerate=0,
)
self.log.info('A transaction with no outputs')
@@ -211,6 +212,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
rawtxs=[tx.serialize().hex()],
)
+ # The following two validations prevent overflow of the output amounts (see CVE-2010-5139).
self.log.info('A transaction with too large output value')
tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference)))
tx.vout[0].nValue = 21000000 * COIN + 1
diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py
index 788aabc192..f9231614ce 100755
--- a/test/functional/mining_basic.py
+++ b/test/functional/mining_basic.py
@@ -27,7 +27,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
)
from test_framework.script import CScriptNum
@@ -54,7 +54,7 @@ class MiningTest(BitcoinTestFramework):
assert_equal(mining_info['currentblocktx'], 0)
assert_equal(mining_info['currentblockweight'], 4000)
self.restart_node(0)
- connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes(self.nodes[0], 1)
def run_test(self):
self.mine_chain()
diff --git a/test/functional/p2p_disconnect_ban.py b/test/functional/p2p_disconnect_ban.py
index 1b11a2a294..23dea4b729 100755
--- a/test/functional/p2p_disconnect_ban.py
+++ b/test/functional/p2p_disconnect_ban.py
@@ -9,7 +9,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
wait_until,
)
@@ -18,6 +18,10 @@ class DisconnectBanTest(BitcoinTestFramework):
self.num_nodes = 2
def run_test(self):
+ self.log.info("Connect nodes both way")
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 0)
+
self.log.info("Test setban and listbanned RPCs")
self.log.info("setban: successfully ban single IP address")
@@ -74,7 +78,9 @@ class DisconnectBanTest(BitcoinTestFramework):
# Clear ban lists
self.nodes[1].clearbanned()
- connect_nodes_bi(self.nodes, 0, 1)
+ self.log.info("Connect nodes both way")
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 0)
self.log.info("Test disconnectnode RPCs")
@@ -93,7 +99,7 @@ class DisconnectBanTest(BitcoinTestFramework):
assert not [node for node in self.nodes[0].getpeerinfo() if node['addr'] == address1]
self.log.info("disconnectnode: successfully reconnect node")
- connect_nodes_bi(self.nodes, 0, 1) # reconnect the node
+ connect_nodes(self.nodes[0], 1) # reconnect the node
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_invalid_block.py b/test/functional/p2p_invalid_block.py
index 1e0b876593..905534b862 100755
--- a/test/functional/p2p_invalid_block.py
+++ b/test/functional/p2p_invalid_block.py
@@ -53,10 +53,11 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
block_time = best_block["time"] + 1
# Use merkle-root malleability to generate an invalid block with
- # same blockheader.
+ # same blockheader (CVE-2012-2459).
# Manufacture a block with 3 transactions (coinbase, spend of prior
# coinbase, spend of that spend). Duplicate the 3rd transaction to
# leave merkle root and blockheader unchanged but invalidate the block.
+ # For more information on merkle-root malleability see src/consensus/merkle.cpp.
self.log.info("Test merkle root malleability.")
block2 = create_block(tip, create_coinbase(height), block_time)
@@ -81,15 +82,16 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
node.p2p.send_blocks_and_test([block2], node, success=False, reject_reason='bad-txns-duplicate')
- # Check transactions for duplicate inputs
+ # Check transactions for duplicate inputs (CVE-2018-17144)
self.log.info("Test duplicate input block.")
- block2_orig.vtx[2].vin.append(block2_orig.vtx[2].vin[0])
- block2_orig.vtx[2].rehash()
- block2_orig.hashMerkleRoot = block2_orig.calc_merkle_root()
- block2_orig.rehash()
- block2_orig.solve()
- node.p2p.send_blocks_and_test([block2_orig], node, success=False, reject_reason='bad-txns-inputs-duplicate')
+ block2_dup = copy.deepcopy(block2_orig)
+ block2_dup.vtx[2].vin.append(block2_dup.vtx[2].vin[0])
+ block2_dup.vtx[2].rehash()
+ block2_dup.hashMerkleRoot = block2_dup.calc_merkle_root()
+ block2_dup.rehash()
+ block2_dup.solve()
+ node.p2p.send_blocks_and_test([block2_dup], node, success=False, reject_reason='bad-txns-inputs-duplicate')
self.log.info("Test very broken block.")
@@ -105,5 +107,31 @@ class InvalidBlockRequestTest(BitcoinTestFramework):
node.p2p.send_blocks_and_test([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.")
+ node.p2p.send_blocks_and_test([block2_orig], node, success=True, timeout=5)
+
+ # Update tip info
+ height += 1
+ block_time += 1
+ tip = int(block2_orig.hash, 16)
+
+ # 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)
+
+ # Duplicates input
+ tx3.vin.append(tx3.vin[0])
+ tx3.rehash()
+ block4.vtx.append(tx3)
+ block4.hashMerkleRoot = block4.calc_merkle_root()
+ block4.rehash()
+ block4.solve()
+ self.log.info("Test inflation by duplicating input")
+ node.p2p.send_blocks_and_test([block4], node, success=False, reject_reason='bad-txns-inputs-duplicate')
+
if __name__ == '__main__':
InvalidBlockRequestTest().main()
diff --git a/test/functional/p2p_invalid_messages.py b/test/functional/p2p_invalid_messages.py
index d5c68e622b..58c72f89d8 100755
--- a/test/functional/p2p_invalid_messages.py
+++ b/test/functional/p2p_invalid_messages.py
@@ -85,7 +85,7 @@ class InvalidMessagesTest(BitcoinTestFramework):
# Peer 1, despite serving up a bunch of nonsense, should still be connected.
self.log.info("Waiting for node to drop junk messages.")
- node.p2p.sync_with_ping(timeout=120)
+ node.p2p.sync_with_ping(timeout=320)
assert node.p2p.is_connected
#
diff --git a/test/functional/p2p_node_network_limited.py b/test/functional/p2p_node_network_limited.py
index a4650df8ee..e6451d9f18 100755
--- a/test/functional/p2p_node_network_limited.py
+++ b/test/functional/p2p_node_network_limited.py
@@ -14,7 +14,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
disconnect_nodes,
- connect_nodes_bi,
+ connect_nodes,
wait_until,
)
@@ -64,7 +64,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
assert_equal(int(self.nodes[0].getnetworkinfo()['localservices'], 16), expected_services)
self.log.info("Mine enough blocks to reach the NODE_NETWORK_LIMITED range.")
- connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes(self.nodes[0], 1)
blocks = self.nodes[1].generatetoaddress(292, self.nodes[1].get_deterministic_priv_key().address)
self.sync_blocks([self.nodes[0], self.nodes[1]])
@@ -90,7 +90,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
# 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, 2)
+ connect_nodes(self.nodes[0], 2)
try:
self.sync_blocks([self.nodes[0], self.nodes[2]], timeout=5)
except:
@@ -99,7 +99,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
assert_equal(self.nodes[2].getblockheader(self.nodes[2].getbestblockhash())['height'], 0)
# now connect also to node 1 (non pruned)
- connect_nodes_bi(self.nodes, 1, 2)
+ connect_nodes(self.nodes[1], 2)
# sync must be possible
self.sync_blocks()
@@ -111,7 +111,7 @@ class NodeNetworkLimitedTest(BitcoinTestFramework):
self.nodes[0].generatetoaddress(10, self.nodes[0].get_deterministic_priv_key().address)
# connect node1 (non pruned) with node0 (pruned) and check if the can sync
- connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes(self.nodes[0], 1)
# sync must be possible, node 1 is no longer in IBD and should therefore connect to node 0 (NODE_NETWORK_LIMITED)
self.sync_blocks([self.nodes[0], self.nodes[1]])
diff --git a/test/functional/p2p_tx_download.py b/test/functional/p2p_tx_download.py
index 19d78ff303..aada04f66f 100755
--- a/test/functional/p2p_tx_download.py
+++ b/test/functional/p2p_tx_download.py
@@ -121,6 +121,7 @@ class TxDownloadTest(BitcoinTestFramework):
# 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'] == False
timeout = 2 + (MAX_GETDATA_RANDOM_DELAY + INBOUND_PEER_TX_DELAY) + (
GETDATA_TX_INTERVAL + MAX_GETDATA_RANDOM_DELAY)
self.log.info("Tx should be received at node 1 after {} seconds".format(timeout))
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index b621081752..c956af1cbe 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -12,7 +12,7 @@ from test_framework.util import (
assert_greater_than,
assert_greater_than_or_equal,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
count_bytes,
find_vout_for_address,
)
@@ -35,10 +35,10 @@ class RawTransactionsTest(BitcoinTestFramework):
def setup_network(self):
self.setup_nodes()
- connect_nodes_bi(self.nodes, 0, 1)
- connect_nodes_bi(self.nodes, 1, 2)
- connect_nodes_bi(self.nodes, 0, 2)
- connect_nodes_bi(self.nodes, 0, 3)
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 2)
+ connect_nodes(self.nodes[0], 2)
+ connect_nodes(self.nodes[0], 3)
def run_test(self):
self.min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
@@ -508,10 +508,10 @@ class RawTransactionsTest(BitcoinTestFramework):
for node in self.nodes:
node.settxfee(self.min_relay_tx_fee)
- connect_nodes_bi(self.nodes,0,1)
- connect_nodes_bi(self.nodes,1,2)
- connect_nodes_bi(self.nodes,0,2)
- connect_nodes_bi(self.nodes,0,3)
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 2)
+ connect_nodes(self.nodes[0], 2)
+ connect_nodes(self.nodes[0], 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(False, [{"txid": self.watchonly_txid, "vout": self.watchonly_vout}])
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index 104c66aaa7..e24bf3111b 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -15,7 +15,7 @@ from test_framework.util import (
assert_greater_than_or_equal,
assert_greater_than,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
p2p_port,
wait_until,
)
@@ -54,6 +54,10 @@ class NetTest(BitcoinTestFramework):
self.extra_args = [["-minrelaytxfee=0.00001000"],["-minrelaytxfee=0.00000500"]]
def run_test(self):
+ self.log.info('Connect nodes both way')
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 0)
+
self._test_connection_count()
self._test_getnettotals()
self._test_getnetworkinfo()
@@ -62,7 +66,7 @@ class NetTest(BitcoinTestFramework):
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):
@@ -105,7 +109,10 @@ class NetTest(BitcoinTestFramework):
wait_until(lambda: self.nodes[0].getnetworkinfo()['connections'] == 0, timeout=3)
self.nodes[0].setnetworkactive(state=True)
- connect_nodes_bi(self.nodes, 0, 1)
+ self.log.info('Connect nodes both way')
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 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
index 2d5631bb27..0663ffdf5b 100755
--- 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,
)
def unidirectional_node_sync_via_rpc(node_src, node_dest):
@@ -60,7 +60,7 @@ class PreciousTest(BitcoinTestFramework):
self.log.info("Connect nodes and check no reorg occurs")
# 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,1)
+ connect_nodes(self.nodes[0], 1)
assert_equal(self.nodes[0].getbestblockhash(), hashC)
assert_equal(self.nodes[1].getbestblockhash(), hashG)
self.log.info("Make Node0 prefer block G")
@@ -97,8 +97,8 @@ class PreciousTest(BitcoinTestFramework):
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,2)
- connect_nodes_bi(self.nodes,0,2)
+ connect_nodes(self.nodes[1], 2)
+ connect_nodes(self.nodes[0], 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_psbt.py b/test/functional/rpc_psbt.py
index 5a04e0c8d8..61572654e0 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -11,7 +11,7 @@ from test_framework.util import (
assert_equal,
assert_greater_than,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
disconnect_nodes,
find_output,
)
@@ -72,8 +72,8 @@ class PSBTTest(BitcoinTestFramework):
assert_equal(online_node.gettxout(txid,0)["confirmations"], 1)
# Reconnect
- connect_nodes_bi(self.nodes, 0, 1)
- connect_nodes_bi(self.nodes, 0, 2)
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[0], 2)
def run_test(self):
# Create and fund a raw tx for sending 10 BTC
@@ -382,6 +382,16 @@ class PSBTTest(BitcoinTestFramework):
joined_decoded = self.nodes[0].decodepsbt(joined)
assert len(joined_decoded['inputs']) == 4 and len(joined_decoded['outputs']) == 2 and "final_scriptwitness" not in joined_decoded['inputs'][3] and "final_scriptSig" not in joined_decoded['inputs'][3]
+ # Check that joining shuffles the inputs and outputs
+ # 10 attempts should be enough to get a shuffled join
+ shuffled = False
+ for i in range(0, 10):
+ shuffled_joined = self.nodes[0].joinpsbts([psbt, psbt2])
+ shuffled |= joined != shuffled_joined
+ if shuffled:
+ break
+ assert shuffled
+
# Newly created PSBT needs UTXOs and updating
addr = self.nodes[1].getnewaddress("", "p2sh-segwit")
txid = self.nodes[0].sendtoaddress(addr, 7)
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index 4338675270..eb98334988 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -17,7 +17,13 @@ from decimal import Decimal
from io import BytesIO
from test_framework.messages import CTransaction, ToHex
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal, assert_raises_rpc_error, connect_nodes_bi, hex_str_to_bytes
+from test_framework.util import (
+ assert_equal,
+ assert_raises_rpc_error,
+ connect_nodes,
+ hex_str_to_bytes,
+)
+
class multidict(dict):
"""Dictionary that allows duplicate keys.
@@ -53,7 +59,7 @@ class RawTransactionsTest(BitcoinTestFramework):
def setup_network(self):
super().setup_network()
- connect_nodes_bi(self.nodes, 0, 2)
+ connect_nodes(self.nodes[0], 2)
def run_test(self):
self.log.info('prepare some coins for multiple *rawtransaction commands')
@@ -432,17 +438,18 @@ class RawTransactionsTest(BitcoinTestFramework):
self.log.info('sendrawtransaction/testmempoolaccept with maxfeerate')
+ # Test a transaction with small fee
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
rawTx = self.nodes[0].getrawtransaction(txId, True)
vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('1.00000000'))
self.sync_all()
inputs = [{ "txid" : txId, "vout" : vout['n'] }]
- outputs = { self.nodes[0].getnewaddress() : Decimal("0.99999000") } # 1000 sat fee
+ outputs = { self.nodes[0].getnewaddress() : Decimal("0.999990000") } # 10000 sat fee
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx)
assert_equal(rawTxSigned['complete'], True)
- # 1000 sat fee, ~100 b transaction, fee rate should land around 10 sat/b = 0.00010000 BTC/kB
+ # 10000 sat fee, ~100 b transaction, fee rate should land around 100 sat/b = 0.00100000 BTC/kB
# Thus, testmempoolaccept should reject
testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']], 0.00001000)[0]
assert_equal(testres['allowed'], False)
@@ -450,9 +457,32 @@ class RawTransactionsTest(BitcoinTestFramework):
# and sendrawtransaction should throw
assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'], 0.00001000)
# And below calls should both succeed
- testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']], maxfeerate='0.00070000')[0]
+ testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']])[0]
+ assert_equal(testres['allowed'], True)
+ self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'])
+
+ # Test a transaction with large fee
+ txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
+ rawTx = self.nodes[0].getrawtransaction(txId, True)
+ vout = next(o for o in rawTx['vout'] if o['value'] == Decimal('1.00000000'))
+
+ self.sync_all()
+ inputs = [{ "txid" : txId, "vout" : vout['n'] }]
+ outputs = { self.nodes[0].getnewaddress() : Decimal("0.98000000") } # 2000000 sat fee
+ rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
+ rawTxSigned = self.nodes[2].signrawtransactionwithwallet(rawTx)
+ assert_equal(rawTxSigned['complete'], True)
+ # 2000000 sat fee, ~100 b transaction, fee rate should land around 20000 sat/b = 0.20000000 BTC/kB
+ # Thus, testmempoolaccept should reject
+ testres = self.nodes[2].testmempoolaccept([rawTxSigned['hex']])[0]
+ assert_equal(testres['allowed'], False)
+ assert_equal(testres['reject-reason'], '256: absurdly-high-fee')
+ # and sendrawtransaction should throw
+ assert_raises_rpc_error(-26, "absurdly-high-fee", self.nodes[2].sendrawtransaction, rawTxSigned['hex'])
+ # And below calls should both succeed
+ testres = self.nodes[2].testmempoolaccept(rawtxs=[rawTxSigned['hex']], maxfeerate='0.20000000')[0]
assert_equal(testres['allowed'], True)
- self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'], maxfeerate='0.00070000')
+ self.nodes[2].sendrawtransaction(hexstring=rawTxSigned['hex'], maxfeerate='0.20000000')
if __name__ == '__main__':
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index 9aff08fdc7..780aa5fe03 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -25,7 +25,7 @@ from .util import (
PortSeed,
assert_equal,
check_json_precision,
- connect_nodes_bi,
+ connect_nodes,
disconnect_nodes,
get_datadir_path,
initialize_datadir,
@@ -281,8 +281,18 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# 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, i + 1)
+ connect_nodes(self.nodes[i + 1], i)
self.sync_all()
def setup_nodes(self):
@@ -423,7 +433,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
"""
Join the (previously split) network halves together.
"""
- connect_nodes_bi(self.nodes, 1, 2)
+ connect_nodes(self.nodes[1], 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
index f9f5fe553e..3175872b00 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -377,10 +377,6 @@ def connect_nodes(from_connection, node_num):
# with transaction relaying
wait_until(lambda: all(peer['version'] != 0 for peer in from_connection.getpeerinfo()))
-def connect_nodes_bi(nodes, a, b):
- connect_nodes(nodes[a], b)
- connect_nodes(nodes[b], a)
-
def sync_blocks(rpc_connections, *, wait=1, timeout=60):
"""
Wait until everybody has the same tip.
diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py
index 28a65f7823..355cd7af75 100755
--- a/test/functional/tool_wallet.py
+++ b/test/functional/tool_wallet.py
@@ -19,6 +19,7 @@ class ToolWalletTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
+ self.rpc_timeout = 120
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py
index 4e4ed8f26b..c41b31e2e1 100755
--- a/test/functional/wallet_address_types.py
+++ b/test/functional/wallet_address_types.py
@@ -62,9 +62,12 @@ from test_framework.util import (
assert_equal,
assert_greater_than,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
+)
+from test_framework.segwit_addr import (
+ encode,
+ decode,
)
-
class AddressTypeTest(BitcoinTestFramework):
def set_test_params(self):
@@ -87,7 +90,7 @@ class AddressTypeTest(BitcoinTestFramework):
# 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, j)
+ connect_nodes(self.nodes[i], j)
self.sync_all()
def get_balances(self, confirmed=True):
@@ -97,6 +100,13 @@ class AddressTypeTest(BitcoinTestFramework):
else:
return [self.nodes[i].getunconfirmedbalance() for i in range(4)]
+ # Quick test of python bech32 implementation
+ def test_python_bech32(self, addr):
+ hrp = addr[:4]
+ assert_equal(hrp, "bcrt")
+ (witver, witprog) = decode(hrp, addr)
+ assert_equal(encode(hrp, witver, witprog), addr)
+
def test_address(self, node, address, multisig, typ):
"""Run sanity checks on an address."""
info = self.nodes[node].getaddressinfo(address)
@@ -121,6 +131,7 @@ class AddressTypeTest(BitcoinTestFramework):
assert_equal(info['witness_version'], 0)
assert_equal(len(info['witness_program']), 40)
assert 'pubkey' in info
+ self.test_python_bech32(info["address"])
elif typ == 'legacy':
# P2SH-multisig
assert info['isscript']
@@ -146,6 +157,7 @@ class AddressTypeTest(BitcoinTestFramework):
assert_equal(info['witness_version'], 0)
assert_equal(len(info['witness_program']), 64)
assert 'pubkeys' in info
+ self.test_python_bech32(info["address"])
else:
# Unknown type
assert False
diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py
index 58ad835d39..e3aa6705e5 100755
--- a/test/functional/wallet_avoidreuse.py
+++ b/test/functional/wallet_avoidreuse.py
@@ -8,7 +8,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
)
# TODO: Copied from wallet_groups.py -- should perhaps move into util.py
@@ -103,7 +103,7 @@ class AvoidReuseTest(BitcoinTestFramework):
# Stop and restart node 1
self.stop_node(1)
self.start_node(1)
- connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes(self.nodes[0], 1)
# Flags should still be node1.avoid_reuse=false, node2.avoid_reuse=true
assert_equal(self.nodes[0].getwalletinfo()["avoid_reuse"], False)
diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py
index 55c517e92f..93178c5ab2 100755
--- a/test/functional/wallet_backup.py
+++ b/test/functional/wallet_backup.py
@@ -49,6 +49,7 @@ class WalletBackupTest(BitcoinTestFramework):
self.setup_clean_chain = True
# nodes 1, 2,3 are spenders, let's give them a keypool=100
self.extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
+ self.rpc_timeout = 120
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py
index 137c77a51e..c50dcd987a 100755
--- a/test/functional/wallet_balance.py
+++ b/test/functional/wallet_balance.py
@@ -11,7 +11,7 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
sync_blocks,
)
@@ -211,7 +211,7 @@ class WalletTest(BitcoinTestFramework):
# Now confirm tx_orig
self.restart_node(1, ['-persistmempool=0'])
- connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes(self.nodes[0], 1)
sync_blocks(self.nodes)
self.nodes[1].sendrawtransaction(tx_orig)
self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY)
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index ce04110240..5b1c672a48 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -12,7 +12,7 @@ from test_framework.util import (
assert_equal,
assert_fee_amount,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
wait_until,
)
@@ -32,9 +32,9 @@ class WalletTest(BitcoinTestFramework):
self.setup_nodes()
# Only need nodes 0-2 running at start of test
self.stop_node(3)
- connect_nodes_bi(self.nodes, 0, 1)
- connect_nodes_bi(self.nodes, 1, 2)
- connect_nodes_bi(self.nodes, 0, 2)
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 2)
+ connect_nodes(self.nodes[0], 2)
self.sync_all(self.nodes[0:3])
def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size):
@@ -218,7 +218,7 @@ class WalletTest(BitcoinTestFramework):
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance(), node_0_bal + Decimal('10'), fee_per_byte, self.get_vsize(self.nodes[2].gettransaction(txid)['hex']))
self.start_node(3)
- connect_nodes_bi(self.nodes, 0, 3)
+ connect_nodes(self.nodes[0], 3)
self.sync_all()
# check if we can list zero value tx as available coins
@@ -253,9 +253,9 @@ class WalletTest(BitcoinTestFramework):
self.start_node(0, ["-walletbroadcast=0"])
self.start_node(1, ["-walletbroadcast=0"])
self.start_node(2, ["-walletbroadcast=0"])
- connect_nodes_bi(self.nodes, 0, 1)
- connect_nodes_bi(self.nodes, 1, 2)
- connect_nodes_bi(self.nodes, 0, 2)
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 2)
+ connect_nodes(self.nodes[0], 2)
self.sync_all(self.nodes[0:3])
txid_not_broadcast = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
@@ -280,9 +280,9 @@ class WalletTest(BitcoinTestFramework):
self.start_node(0)
self.start_node(1)
self.start_node(2)
- connect_nodes_bi(self.nodes, 0, 1)
- connect_nodes_bi(self.nodes, 1, 2)
- connect_nodes_bi(self.nodes, 0, 2)
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[1], 2)
+ connect_nodes(self.nodes[0], 2)
self.sync_blocks(self.nodes[0:3])
self.nodes[0].generate(1)
@@ -433,7 +433,7 @@ class WalletTest(BitcoinTestFramework):
# Split into two chains
rawtx = self.nodes[0].createrawtransaction([{"txid": singletxid, "vout": 0}], {chain_addrs[0]: node0_balance / 2 - Decimal('0.01'), chain_addrs[1]: node0_balance / 2 - Decimal('0.01')})
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
- singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"])
+ singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"], 0)
self.nodes[0].generate(1)
# Make a long chain of unconfirmed payments without hitting mempool limit
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index bfc01e3f5e..a7c79ec916 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -23,7 +23,7 @@ from test_framework.util import (
assert_equal,
assert_greater_than,
assert_raises_rpc_error,
- connect_nodes_bi,
+ connect_nodes,
hex_str_to_bytes,
)
@@ -48,7 +48,7 @@ class BumpFeeTest(BitcoinTestFramework):
self.nodes[1].encryptwallet(WALLET_PASSPHRASE)
self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
- connect_nodes_bi(self.nodes, 0, 1)
+ connect_nodes(self.nodes[0], 1)
self.sync_all()
peer_node, rbf_node = self.nodes
diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py
index 97172d8b82..fa5d5a8878 100755
--- a/test/functional/wallet_hd.py
+++ b/test/functional/wallet_hd.py
@@ -10,7 +10,7 @@ import shutil
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
- connect_nodes_bi,
+ connect_nodes,
assert_raises_rpc_error
)
@@ -82,7 +82,7 @@ class WalletHDTest(BitcoinTestFramework):
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, 1)
+ connect_nodes(self.nodes[0], 1)
self.sync_all()
# Needs rescan
@@ -96,7 +96,7 @@ class WalletHDTest(BitcoinTestFramework):
shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "chainstate"))
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, 1)
+ connect_nodes(self.nodes[0], 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
index 0014555ade..2e70a9e0a5 100755
--- a/test/functional/wallet_keypool_topup.py
+++ b/test/functional/wallet_keypool_topup.py
@@ -16,7 +16,7 @@ import shutil
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
- connect_nodes_bi,
+ connect_nodes,
)
@@ -38,9 +38,9 @@ class KeypoolRestoreTest(BitcoinTestFramework):
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, 1)
- connect_nodes_bi(self.nodes, 0, 2)
- connect_nodes_bi(self.nodes, 0, 3)
+ connect_nodes(self.nodes[0], 1)
+ connect_nodes(self.nodes[0], 2)
+ connect_nodes(self.nodes[0], 3)
for i, output_type in enumerate(["legacy", "p2sh-segwit", "bech32"]):
@@ -72,7 +72,7 @@ class KeypoolRestoreTest(BitcoinTestFramework):
self.stop_node(idx)
shutil.copyfile(wallet_backup_path, wallet_path)
self.start_node(idx, self.extra_args[idx])
- connect_nodes_bi(self.nodes, 0, idx)
+ connect_nodes(self.nodes[0], idx)
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
index 021a29d4ac..4aeb393255 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -5,9 +5,15 @@
"""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
@@ -16,6 +22,9 @@ class ListSinceBlockTest (BitcoinTestFramework):
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], 2)
self.nodes[2].generate(101)
self.sync_all()