aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/combine_logs.py3
-rwxr-xr-xtest/functional/feature_abortnode.py4
-rwxr-xr-xtest/functional/feature_block.py2
-rwxr-xr-xtest/functional/feature_cltv.py2
-rwxr-xr-xtest/functional/feature_config_args.py46
-rwxr-xr-xtest/functional/feature_dersig.py2
-rwxr-xr-xtest/functional/feature_filelock.py2
-rwxr-xr-xtest/functional/feature_help.py2
-rwxr-xr-xtest/functional/feature_loadblock.py2
-rwxr-xr-xtest/functional/feature_logging.py2
-rwxr-xr-xtest/functional/feature_pruning.py4
-rwxr-xr-xtest/functional/interface_rpc.py2
-rwxr-xr-xtest/functional/interface_zmq.py4
-rwxr-xr-xtest/functional/mempool_accept.py15
-rwxr-xr-xtest/functional/mempool_persist.py4
-rwxr-xr-xtest/functional/mempool_reorg.py4
-rwxr-xr-xtest/functional/mining_basic.py2
-rwxr-xr-xtest/functional/p2p_invalid_messages.py6
-rwxr-xr-xtest/functional/p2p_permissions.py58
-rwxr-xr-xtest/functional/p2p_segwit.py9
-rwxr-xr-xtest/functional/rpc_dumptxoutset.py2
-rwxr-xr-xtest/functional/rpc_getaddressinfo_label_deprecation.py43
-rwxr-xr-xtest/functional/rpc_getaddressinfo_labels_purpose_deprecation.py48
-rwxr-xr-xtest/functional/rpc_psbt.py15
-rwxr-xr-xtest/functional/rpc_scantxoutset.py2
-rwxr-xr-xtest/functional/rpc_setban.py2
-rw-r--r--test/functional/test_framework/address.py2
-rwxr-xr-xtest/functional/test_framework/messages.py6
-rwxr-xr-xtest/functional/test_framework/test_node.py7
-rwxr-xr-xtest/functional/test_framework/wallet_util.py7
-rwxr-xr-xtest/functional/test_runner.py2
-rwxr-xr-xtest/functional/tool_wallet.py4
-rwxr-xr-xtest/functional/wallet_avoidreuse.py58
-rwxr-xr-xtest/functional/wallet_backup.py28
-rwxr-xr-xtest/functional/wallet_basic.py7
-rwxr-xr-xtest/functional/wallet_bumpfee.py82
-rwxr-xr-xtest/functional/wallet_dump.py2
-rwxr-xr-xtest/functional/wallet_groups.py2
-rwxr-xr-xtest/functional/wallet_hd.py14
-rwxr-xr-xtest/functional/wallet_import_with_label.py45
-rwxr-xr-xtest/functional/wallet_importmulti.py7
-rwxr-xr-xtest/functional/wallet_keypool_topup.py2
-rwxr-xr-xtest/functional/wallet_labels.py15
-rwxr-xr-xtest/functional/wallet_listreceivedby.py7
-rwxr-xr-xtest/functional/wallet_multiwallet.py4
-rwxr-xr-xtest/functional/wallet_reorgsrestore.py2
-rwxr-xr-xtest/fuzz/test_runner.py3
-rwxr-xr-xtest/lint/extended-lint-all.sh2
-rwxr-xr-xtest/lint/extended-lint-cppcheck.sh2
-rwxr-xr-xtest/lint/lint-circular-dependencies.sh5
-rwxr-xr-xtest/lint/lint-format-strings.py5
-rwxr-xr-xtest/lint/lint-format-strings.sh2
-rwxr-xr-xtest/lint/lint-locale-dependence.sh20
-rwxr-xr-xtest/lint/lint-shebang.sh4
-rw-r--r--test/sanitizer_suppressions/tsan8
55 files changed, 487 insertions, 154 deletions
diff --git a/test/functional/combine_logs.py b/test/functional/combine_logs.py
index a70d9c4ac1..00f2833f55 100755
--- a/test/functional/combine_logs.py
+++ b/test/functional/combine_logs.py
@@ -1,4 +1,7 @@
#!/usr/bin/env python3
+# Copyright (c) 2017-2019 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Combine logs from multiple bitcoin nodes as well as the test_framework log.
This streams the combined log output to stdout. Use combine_logs.py > outputfile
diff --git a/test/functional/feature_abortnode.py b/test/functional/feature_abortnode.py
index 62c3eca07d..9b878e8bf8 100755
--- a/test/functional/feature_abortnode.py
+++ b/test/functional/feature_abortnode.py
@@ -29,7 +29,7 @@ class AbortNodeTest(BitcoinTestFramework):
datadir = get_datadir_path(self.options.tmpdir, 0)
# Deleting the undo file will result in reorg failure
- os.unlink(os.path.join(datadir, 'regtest', 'blocks', 'rev00000.dat'))
+ os.unlink(os.path.join(datadir, self.chain, 'blocks', 'rev00000.dat'))
# Connecting to a node with a more work chain will trigger a reorg
# attempt.
@@ -40,7 +40,7 @@ class AbortNodeTest(BitcoinTestFramework):
# Check that node0 aborted
self.log.info("Waiting for crash")
- wait_until(lambda: self.nodes[0].is_node_stopped(), timeout=60)
+ wait_until(lambda: self.nodes[0].is_node_stopped(), timeout=200)
self.log.info("Node crashed - now verifying restart fails")
self.nodes[0].assert_start_raises_init_error()
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index c7e98bd4db..95905f477b 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -1401,7 +1401,7 @@ class FullBlockTest(BitcoinTestFramework):
self.nodes[0].disconnect_p2ps()
self.bootstrap_p2p(timeout=timeout)
- def send_blocks(self, blocks, success=True, reject_reason=None, force_send=False, reconnect=False, timeout=60):
+ def send_blocks(self, blocks, success=True, reject_reason=None, force_send=False, reconnect=False, timeout=960):
"""Sends blocks to test node. Syncs and verifies that tip has advanced to most recent block.
Call with success = False if the tip shouldn't advance to the most recent block."""
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index 7d131e6045..2c6f2e733b 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -135,7 +135,7 @@ class BIP65Test(BitcoinTestFramework):
block.hashMerkleRoot = block.calc_merkle_root()
block.solve()
- with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]):
+ with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Negative locktime)'.format(block.vtx[-1].hash)]):
self.nodes[0].p2p.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
self.nodes[0].p2p.sync_with_ping()
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py
index 801209b1c0..311d822a87 100755
--- a/test/functional/feature_config_args.py
+++ b/test/functional/feature_config_args.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2017-2019 The Bitcoin Core developers
+# Copyright (c) 2017-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test various command line arguments and configuration file parameters."""
@@ -39,7 +39,7 @@ class ConfArgsTest(BitcoinTestFramework):
if self.is_wallet_compiled():
with open(inc_conf_file_path, 'w', encoding='utf8') as conf:
conf.write("wallet=foo\n")
- self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Config setting for -wallet only applied on regtest network when in [regtest] section.')
+ self.nodes[0].assert_start_raises_init_error(expected_msg='Error: Config setting for -wallet only applied on %s network when in [%s] section.' % (self.chain, self.chain))
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
conf.write('regtest=0\n') # mainnet
@@ -79,14 +79,44 @@ class ConfArgsTest(BitcoinTestFramework):
conf.write('') # clear
def test_log_buffer(self):
- with self.nodes[0].assert_debug_log(expected_msgs=['Warning: parsed potentially confusing double-negative -connect=0']):
+ with self.nodes[0].assert_debug_log(expected_msgs=['Warning: parsed potentially confusing double-negative -connect=0\n']):
self.start_node(0, extra_args=['-noconnect=0'])
self.stop_node(0)
+ def test_args_log(self):
+ self.log.info('Test config args logging')
+ with self.nodes[0].assert_debug_log(
+ expected_msgs=[
+ 'Command-line arg: addnode="some.node"',
+ 'Command-line arg: rpcauth=****',
+ 'Command-line arg: rpcbind=****',
+ 'Command-line arg: rpcpassword=****',
+ 'Command-line arg: rpcuser=****',
+ 'Command-line arg: torpassword=****',
+ 'Config file arg: %s="1"' % self.chain,
+ 'Config file arg: [%s] server="1"' % self.chain,
+ ],
+ unexpected_msgs=[
+ 'alice:f7efda5c189b999524f151318c0c86$d5b51b3beffbc0',
+ '127.1.1.1',
+ 'secret-rpcuser',
+ 'secret-torpassword',
+ ]):
+ self.start_node(0, extra_args=[
+ '-addnode=some.node',
+ '-rpcauth=alice:f7efda5c189b999524f151318c0c86$d5b51b3beffbc0',
+ '-rpcbind=127.1.1.1',
+ '-rpcpassword=',
+ '-rpcuser=secret-rpcuser',
+ '-torpassword=secret-torpassword',
+ ])
+ self.stop_node(0)
+
def run_test(self):
self.stop_node(0)
self.test_log_buffer()
+ self.test_args_log()
self.test_config_file_parser()
@@ -104,7 +134,7 @@ class ConfArgsTest(BitcoinTestFramework):
# Check that using non-existent datadir in conf file fails
conf_file = os.path.join(default_data_dir, "bitcoin.conf")
- # datadir needs to be set before [regtest] section
+ # datadir needs to be set before [chain] section
conf_file_contents = open(conf_file, encoding='utf8').read()
with open(conf_file, 'w', encoding='utf8') as f:
f.write("datadir=" + new_data_dir + "\n")
@@ -116,17 +146,17 @@ class ConfArgsTest(BitcoinTestFramework):
os.mkdir(new_data_dir)
self.start_node(0, ['-conf='+conf_file, '-wallet=w1'])
self.stop_node(0)
- assert os.path.exists(os.path.join(new_data_dir, 'regtest', 'blocks'))
+ assert os.path.exists(os.path.join(new_data_dir, self.chain, 'blocks'))
if self.is_wallet_compiled():
- assert os.path.exists(os.path.join(new_data_dir, 'regtest', 'wallets', 'w1'))
+ assert os.path.exists(os.path.join(new_data_dir, self.chain, 'wallets', 'w1'))
# Ensure command line argument overrides datadir in conf
os.mkdir(new_data_dir_2)
self.nodes[0].datadir = new_data_dir_2
self.start_node(0, ['-datadir='+new_data_dir_2, '-conf='+conf_file, '-wallet=w2'])
- assert os.path.exists(os.path.join(new_data_dir_2, 'regtest', 'blocks'))
+ assert os.path.exists(os.path.join(new_data_dir_2, self.chain, 'blocks'))
if self.is_wallet_compiled():
- assert os.path.exists(os.path.join(new_data_dir_2, 'regtest', 'wallets', 'w2'))
+ assert os.path.exists(os.path.join(new_data_dir_2, self.chain, 'wallets', 'w2'))
if __name__ == '__main__':
diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py
index 2ace96fef4..27da49cf24 100755
--- a/test/functional/feature_dersig.py
+++ b/test/functional/feature_dersig.py
@@ -120,7 +120,7 @@ class BIP66Test(BitcoinTestFramework):
block.rehash()
block.solve()
- with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputs on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]):
+ with self.nodes[0].assert_debug_log(expected_msgs=['CheckInputScripts on {} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)'.format(block.vtx[-1].hash)]):
self.nodes[0].p2p.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
self.nodes[0].p2p.sync_with_ping()
diff --git a/test/functional/feature_filelock.py b/test/functional/feature_filelock.py
index 93fef737e4..be1c044aa5 100755
--- a/test/functional/feature_filelock.py
+++ b/test/functional/feature_filelock.py
@@ -19,7 +19,7 @@ class FilelockTest(BitcoinTestFramework):
self.nodes[0].wait_for_rpc_connection()
def run_test(self):
- datadir = os.path.join(self.nodes[0].datadir, 'regtest')
+ datadir = os.path.join(self.nodes[0].datadir, self.chain)
self.log.info("Using datadir {}".format(datadir))
self.log.info("Check that we can't start a second bitcoind instance using the same datadir")
diff --git a/test/functional/feature_help.py b/test/functional/feature_help.py
index ed1d25c0d6..e3e2456183 100755
--- a/test/functional/feature_help.py
+++ b/test/functional/feature_help.py
@@ -17,7 +17,7 @@ class HelpTest(BitcoinTestFramework):
# Don't start the node
def get_node_output(self, *, ret_code_expected):
- ret_code = self.nodes[0].process.wait(timeout=5)
+ ret_code = self.nodes[0].process.wait(timeout=60)
assert_equal(ret_code, ret_code_expected)
self.nodes[0].stdout.seek(0)
self.nodes[0].stderr.seek(0)
diff --git a/test/functional/feature_loadblock.py b/test/functional/feature_loadblock.py
index bd4b271ca7..7f1e8f5bae 100755
--- a/test/functional/feature_loadblock.py
+++ b/test/functional/feature_loadblock.py
@@ -38,7 +38,7 @@ class LoadblockTest(BitcoinTestFramework):
cfg_file = os.path.join(data_dir, "linearize.cfg")
bootstrap_file = os.path.join(self.options.tmpdir, "bootstrap.dat")
genesis_block = self.nodes[0].getblockhash(0)
- blocks_dir = os.path.join(data_dir, "regtest", "blocks")
+ blocks_dir = os.path.join(data_dir, self.chain, "blocks")
hash_list = tempfile.NamedTemporaryFile(dir=data_dir,
mode='w',
delete=False,
diff --git a/test/functional/feature_logging.py b/test/functional/feature_logging.py
index 36d6d70fcc..1bae29b302 100755
--- a/test/functional/feature_logging.py
+++ b/test/functional/feature_logging.py
@@ -16,7 +16,7 @@ class LoggingTest(BitcoinTestFramework):
self.setup_clean_chain = True
def relative_log_path(self, name):
- return os.path.join(self.nodes[0].datadir, "regtest", name)
+ return os.path.join(self.nodes[0].datadir, self.chain, name)
def run_test(self):
# test default log file name
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
index e1e0f00530..21b6b299f6 100755
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -101,7 +101,7 @@ class PruneTest(BitcoinTestFramework):
def setup_network(self):
self.setup_nodes()
- self.prunedir = os.path.join(self.nodes[2].datadir, 'regtest', 'blocks', '')
+ self.prunedir = os.path.join(self.nodes[2].datadir, self.chain, 'blocks', '')
connect_nodes(self.nodes[0], 1)
connect_nodes(self.nodes[1], 2)
@@ -279,7 +279,7 @@ class PruneTest(BitcoinTestFramework):
assert_equal(ret, node.getblockchaininfo()['pruneheight'])
def has_block(index):
- return os.path.isfile(os.path.join(self.nodes[node_number].datadir, "regtest", "blocks", "blk{:05}.dat".format(index)))
+ return os.path.isfile(os.path.join(self.nodes[node_number].datadir, self.chain, "blocks", "blk{:05}.dat".format(index)))
# should not prune because chain tip of node 3 (995) < PruneAfterHeight (1000)
assert_raises_rpc_error(-1, "Blockchain is too short for pruning", node.pruneblockchain, height(500))
diff --git a/test/functional/interface_rpc.py b/test/functional/interface_rpc.py
index e460db39f8..3b3b5bb0c1 100755
--- a/test/functional/interface_rpc.py
+++ b/test/functional/interface_rpc.py
@@ -33,7 +33,7 @@ class RPCInterfaceTest(BitcoinTestFramework):
command = info['active_commands'][0]
assert_equal(command['method'], 'getrpcinfo')
assert_greater_than_or_equal(command['duration'], 0)
- assert_equal(info['logpath'], os.path.join(self.nodes[0].datadir, 'regtest', 'debug.log'))
+ assert_equal(info['logpath'], os.path.join(self.nodes[0].datadir, self.chain, 'debug.log'))
def test_batch_request(self):
self.log.info("Testing basic JSON-RPC batch request...")
diff --git a/test/functional/interface_zmq.py b/test/functional/interface_zmq.py
index 5aea10fbce..89c55f31f3 100755
--- a/test/functional/interface_zmq.py
+++ b/test/functional/interface_zmq.py
@@ -59,6 +59,10 @@ class ZMQTest (BitcoinTestFramework):
# Note that the publishing order is not defined in the documentation and
# is subject to change.
import zmq
+
+ # Invalid zmq arguments don't take down the node, see #17185.
+ self.restart_node(0, ["-zmqpubrawtx=foo", "-zmqpubhashtx=bar"])
+
address = 'tcp://127.0.0.1:28332'
socket = self.ctx.socket(zmq.SUB)
socket.set(zmq.RCVTIMEO, 60000)
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index 9cb6b03ee0..900cabccda 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -8,6 +8,7 @@ from io import BytesIO
import math
from test_framework.test_framework import BitcoinTestFramework
+from test_framework.key import ECKey
from test_framework.messages import (
BIP125_SEQUENCE_NUMBER,
COIN,
@@ -20,6 +21,9 @@ from test_framework.script import (
hash160,
CScript,
OP_0,
+ OP_2,
+ OP_3,
+ OP_CHECKMULTISIG,
OP_EQUAL,
OP_HASH160,
OP_RETURN,
@@ -35,7 +39,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.extra_args = [[
- '-txindex',
+ '-txindex','-permitbaremultisig=0',
]] * self.num_nodes
self.supports_cli = False
@@ -262,6 +266,15 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
rawtxs=[tx.serialize().hex()],
)
tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference)))
+ key = ECKey()
+ key.generate()
+ pubkey = key.get_pubkey().get_bytes()
+ tx.vout[0].scriptPubKey = CScript([OP_2, pubkey, pubkey, pubkey, OP_3, OP_CHECKMULTISIG]) # Some bare multisig script (2-of-3)
+ self.check_mempool_result(
+ result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'bare-multisig'}],
+ rawtxs=[tx.serialize().hex()],
+ )
+ tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_reference)))
tx.vin[0].scriptSig = CScript([OP_HASH160]) # Some not-pushonly scriptSig
self.check_mempool_result(
result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': 'scriptsig-not-pushonly'}],
diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py
index ef84de5a14..d3690b245e 100755
--- a/test/functional/mempool_persist.py
+++ b/test/functional/mempool_persist.py
@@ -117,8 +117,8 @@ class MempoolPersistTest(BitcoinTestFramework):
wait_until(lambda: self.nodes[0].getmempoolinfo()["loaded"])
assert_equal(len(self.nodes[0].getrawmempool()), 5)
- mempooldat0 = os.path.join(self.nodes[0].datadir, 'regtest', 'mempool.dat')
- mempooldat1 = os.path.join(self.nodes[1].datadir, 'regtest', 'mempool.dat')
+ mempooldat0 = os.path.join(self.nodes[0].datadir, self.chain, 'mempool.dat')
+ mempooldat1 = os.path.join(self.nodes[1].datadir, self.chain, 'mempool.dat')
self.log.debug("Remove the mempool.dat file. Verify that savemempool to disk via RPC re-creates it")
os.remove(mempooldat0)
self.nodes[0].savemempool()
diff --git a/test/functional/mempool_reorg.py b/test/functional/mempool_reorg.py
index 123f0b4c28..3b148d5cf0 100755
--- a/test/functional/mempool_reorg.py
+++ b/test/functional/mempool_reorg.py
@@ -76,7 +76,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
spend_101_id = self.nodes[0].sendrawtransaction(spend_101_raw)
spend_102_1_id = self.nodes[0].sendrawtransaction(spend_102_1_raw)
- self.sync_all()
+ self.sync_all(timeout=360)
assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, timelock_tx_id})
@@ -91,7 +91,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
for node in self.nodes:
node.invalidateblock(new_blocks[0])
- self.sync_all()
+ self.sync_all(timeout=360)
# mempool should be empty.
assert_equal(set(self.nodes[0].getrawmempool()), set())
diff --git a/test/functional/mining_basic.py b/test/functional/mining_basic.py
index bfeaa76c74..8262e30592 100755
--- a/test/functional/mining_basic.py
+++ b/test/functional/mining_basic.py
@@ -70,7 +70,7 @@ class MiningTest(BitcoinTestFramework):
self.log.info('getmininginfo')
mining_info = node.getmininginfo()
assert_equal(mining_info['blocks'], 200)
- assert_equal(mining_info['chain'], 'regtest')
+ assert_equal(mining_info['chain'], self.chain)
assert 'currentblocktx' not in mining_info
assert 'currentblockweight' not in mining_info
assert_equal(mining_info['difficulty'], Decimal('4.656542373906925E-10'))
diff --git a/test/functional/p2p_invalid_messages.py b/test/functional/p2p_invalid_messages.py
index 20864881c1..9876d749ff 100755
--- a/test/functional/p2p_invalid_messages.py
+++ b/test/functional/p2p_invalid_messages.py
@@ -78,7 +78,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=320)
+ node.p2p.sync_with_ping(timeout=400)
assert node.p2p.is_connected
#
@@ -145,13 +145,13 @@ class InvalidMessagesTest(BitcoinTestFramework):
def test_magic_bytes(self):
conn = self.nodes[0].add_p2p_connection(P2PDataStore())
- def swap_magic_bytes():
+ async def swap_magic_bytes():
conn._on_data = lambda: None # Need to ignore all incoming messages from now, since they come with "invalid" magic bytes
conn.magic_bytes = b'\x00\x11\x22\x32'
# Call .result() to block until the atomic swap is complete, otherwise
# we might run into races later on
- asyncio.run_coroutine_threadsafe(asyncio.coroutine(swap_magic_bytes)(), NetworkThread.network_event_loop).result()
+ asyncio.run_coroutine_threadsafe(swap_magic_bytes(), NetworkThread.network_event_loop).result()
with self.nodes[0].assert_debug_log(['PROCESSMESSAGE: INVALID MESSAGESTART ping']):
conn.send_message(messages.msg_ping(nonce=0xff))
diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py
index 37101d6143..93e2957fd0 100755
--- a/test/functional/p2p_permissions.py
+++ b/test/functional/p2p_permissions.py
@@ -7,21 +7,35 @@
Test that permissions are correctly calculated and applied
"""
+from test_framework.address import ADDRESS_BCRT1_P2WSH_OP_TRUE
+from test_framework.messages import (
+ CTransaction,
+ CTxInWitness,
+ FromHex,
+)
+from test_framework.mininode import P2PDataStore
+from test_framework.script import (
+ CScript,
+ OP_TRUE,
+)
from test_framework.test_node import ErrorMatch
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
connect_nodes,
p2p_port,
+ wait_until,
)
+
class P2PPermissionsTests(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
- self.extra_args = [[],[]]
def run_test(self):
+ self.check_tx_relay()
+
self.checkpermission(
# default permissions (no specific permissions)
["-whitelist=127.0.0.1"],
@@ -48,9 +62,9 @@ class P2PPermissionsTests(BitcoinTestFramework):
ip_port = "127.0.0.1:{}".format(p2p_port(1))
self.replaceinconfig(1, "bind=127.0.0.1", "whitebind=bloomfilter,forcerelay@" + ip_port)
self.checkpermission(
- ["-whitelist=noban@127.0.0.1" ],
+ ["-whitelist=noban@127.0.0.1"],
# Check parameter interaction forcerelay should activate relay
- ["noban", "bloomfilter", "forcerelay", "relay" ],
+ ["noban", "bloomfilter", "forcerelay", "relay"],
False)
self.replaceinconfig(1, "whitebind=bloomfilter,forcerelay@" + ip_port, "bind=127.0.0.1")
@@ -83,6 +97,41 @@ class P2PPermissionsTests(BitcoinTestFramework):
self.nodes[1].assert_start_raises_init_error(["-whitelist=noban@127.0.0.1:230"], "Invalid netmask specified in", 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)
+ def check_tx_relay(self):
+ block_op_true = self.nodes[0].getblock(self.nodes[0].generatetoaddress(100, ADDRESS_BCRT1_P2WSH_OP_TRUE)[0])
+ self.sync_all()
+
+ self.log.debug("Create a connection from a whitelisted wallet 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 whitelisted 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())
+
+ 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_BCRT1_P2WSH_OP_TRUE: 5,
+ }]),
+ )
+ tx.wit.vtxinwit = [CTxInWitness()]
+ tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
+ txid = tx.rehash()
+
+ self.log.debug("Wait until tx is in node[1]'s mempool")
+ p2p_rebroadcast_wallet.send_txs_and_test([tx], self.nodes[1])
+
+ self.log.debug("Check that node[1] will send the tx to node[0] even though it is already in the mempool")
+ connect_nodes(self.nodes[1], 0)
+ with self.nodes[1].assert_debug_log(["Force relaying tx {} from whitelisted peer=0".format(txid)]):
+ p2p_rebroadcast_wallet.send_txs_and_test([tx], self.nodes[1])
+ wait_until(lambda: txid in self.nodes[0].getrawmempool())
+
def checkpermission(self, args, expectedPermissions, whitelisted):
self.restart_node(1, args)
connect_nodes(self.nodes[0], 1)
@@ -95,9 +144,10 @@ class P2PPermissionsTests(BitcoinTestFramework):
def replaceinconfig(self, nodeid, old, new):
with open(self.nodes[nodeid].bitcoinconf, encoding="utf8") as f:
- newText=f.read().replace(old, new)
+ newText = f.read().replace(old, new)
with open(self.nodes[nodeid].bitcoinconf, 'w', encoding="utf8") as f:
f.write(newText)
+
if __name__ == '__main__':
P2PPermissionsTests().main()
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index 297fa88fbe..3223c27e0b 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -31,7 +31,7 @@ from test_framework.messages import (
msg_inv,
msg_tx,
msg_block,
- msg_witness_tx,
+ msg_no_witness_tx,
ser_uint256,
ser_vector,
sha256,
@@ -125,10 +125,11 @@ def test_transaction_acceptance(node, p2p, tx, with_witness, accepted, reason=No
- use the getrawmempool rpc to check for acceptance."""
reason = [reason] if reason else []
with node.assert_debug_log(expected_msgs=reason):
- p2p.send_message(msg_witness_tx(tx) if with_witness else msg_tx(tx))
+ p2p.send_message(msg_tx(tx) if with_witness else msg_no_witness_tx(tx))
p2p.sync_with_ping()
assert_equal(tx.hash in node.getrawmempool(), accepted)
+
def test_witness_block(node, p2p, block, accepted, with_witness=True, reason=None):
"""Send a block to the node and check that it's accepted
@@ -311,9 +312,9 @@ class SegWitTest(BitcoinTestFramework):
# Check that serializing it with or without witness is the same
# This is a sanity check of our testing framework.
- assert_equal(msg_tx(tx).serialize(), msg_witness_tx(tx).serialize())
+ assert_equal(msg_no_witness_tx(tx).serialize(), msg_tx(tx).serialize())
- self.test_node.send_message(msg_witness_tx(tx))
+ self.test_node.send_message(msg_tx(tx))
self.test_node.sync_with_ping() # make sure the tx was processed
assert tx.hash in self.nodes[0].getrawmempool()
# Save this transaction for later
diff --git a/test/functional/rpc_dumptxoutset.py b/test/functional/rpc_dumptxoutset.py
index 7527bdfb08..438e7f68e0 100755
--- a/test/functional/rpc_dumptxoutset.py
+++ b/test/functional/rpc_dumptxoutset.py
@@ -25,7 +25,7 @@ class DumptxoutsetTest(BitcoinTestFramework):
FILENAME = 'txoutset.dat'
out = node.dumptxoutset(FILENAME)
- expected_path = Path(node.datadir) / 'regtest' / FILENAME
+ expected_path = Path(node.datadir) / self.chain / FILENAME
assert expected_path.is_file()
diff --git a/test/functional/rpc_getaddressinfo_label_deprecation.py b/test/functional/rpc_getaddressinfo_label_deprecation.py
new file mode 100755
index 0000000000..5e739ebede
--- /dev/null
+++ b/test/functional/rpc_getaddressinfo_label_deprecation.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""
+Test deprecation of the RPC getaddressinfo `label` field. It has been
+superceded by the `labels` field.
+
+"""
+from test_framework.test_framework import BitcoinTestFramework
+
+class GetAddressInfoLabelDeprecationTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 2
+ self.setup_clean_chain = False
+ # Start node[0] with -deprecatedrpc=label, and node[1] without.
+ self.extra_args = [["-deprecatedrpc=label"], []]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ def test_label_with_deprecatedrpc_flag(self):
+ self.log.info("Test getaddressinfo label with -deprecatedrpc flag")
+ node = self.nodes[0]
+ address = node.getnewaddress()
+ info = node.getaddressinfo(address)
+ assert "label" in info
+
+ def test_label_without_deprecatedrpc_flag(self):
+ self.log.info("Test getaddressinfo label without -deprecatedrpc flag")
+ node = self.nodes[1]
+ address = node.getnewaddress()
+ info = node.getaddressinfo(address)
+ assert "label" not in info
+
+ def run_test(self):
+ """Test getaddressinfo label with and without -deprecatedrpc flag."""
+ self.test_label_with_deprecatedrpc_flag()
+ self.test_label_without_deprecatedrpc_flag()
+
+
+if __name__ == '__main__':
+ GetAddressInfoLabelDeprecationTest().main()
diff --git a/test/functional/rpc_getaddressinfo_labels_purpose_deprecation.py b/test/functional/rpc_getaddressinfo_labels_purpose_deprecation.py
new file mode 100755
index 0000000000..3f2e8dee18
--- /dev/null
+++ b/test/functional/rpc_getaddressinfo_labels_purpose_deprecation.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+# Copyright (c) 2020-2019 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""
+Test deprecation of RPC getaddressinfo `labels` returning an array
+containing a JSON object of `name` and purpose` key-value pairs. It now
+returns an array containing only the label name.
+
+"""
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal
+
+LABELS_TO_TEST = frozenset({"" , "New 𝅘𝅥𝅯 $<#>&!рыба Label"})
+
+class GetAddressInfoLabelsPurposeDeprecationTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 2
+ self.setup_clean_chain = False
+ # Start node[0] with -deprecatedrpc=labelspurpose and node[1] without.
+ self.extra_args = [["-deprecatedrpc=labelspurpose"], []]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ def test_labels(self, node_num, label_name, expected_value):
+ node = self.nodes[node_num]
+ address = node.getnewaddress()
+ if label_name != "":
+ node.setlabel(address, label_name)
+ self.log.info(" set label to {}".format(label_name))
+ labels = node.getaddressinfo(address)["labels"]
+ self.log.info(" labels = {}".format(labels))
+ assert_equal(labels, expected_value)
+
+ def run_test(self):
+ """Test getaddressinfo labels with and without -deprecatedrpc flag."""
+ self.log.info("Test getaddressinfo labels with -deprecatedrpc flag")
+ for label in LABELS_TO_TEST:
+ self.test_labels(node_num=0, label_name=label, expected_value=[{"name": label, "purpose": "receive"}])
+
+ self.log.info("Test getaddressinfo labels without -deprecatedrpc flag")
+ for label in LABELS_TO_TEST:
+ self.test_labels(node_num=1, label_name=label, expected_value=[label])
+
+
+if __name__ == '__main__':
+ GetAddressInfoLabelsPurposeDeprecationTest().main()
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index 2cc9650cb2..33af819d34 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -422,5 +422,20 @@ class PSBTTest(BitcoinTestFramework):
assert_equal(analysis['next'], 'creator')
assert_equal(analysis['error'], 'PSBT is not valid. Input 0 spends unspendable output')
+ self.log.info("PSBT with invalid values should have error message and Creator as next")
+ analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8AgIFq49AHABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
+ assert_equal(analysis['next'], 'creator')
+ assert_equal(analysis['error'], 'PSBT is not valid. Input 0 has invalid value')
+
+ analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgCAgWrj0AcAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8A8gUqAQAAABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
+ assert_equal(analysis['next'], 'creator')
+ assert_equal(analysis['error'], 'PSBT is not valid. Output amount invalid')
+
+ analysis = self.nodes[0].analyzepsbt('cHNidP8BAJoCAAAAAkvEW8NnDtdNtDpsmze+Ht2LH35IJcKv00jKAlUs21RrAwAAAAD/////S8Rbw2cO1020OmybN74e3Ysffkglwq/TSMoCVSzbVGsBAAAAAP7///8CwLYClQAAAAAWABSNJKzjaUb3uOxixsvh1GGE3fW7zQD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XIAAAAAAAEAnQIAAAACczMa321tVHuN4GKWKRncycI22aX3uXgwSFUKM2orjRsBAAAAAP7///9zMxrfbW1Ue43gYpYpGdzJwjbZpfe5eDBIVQozaiuNGwAAAAAA/v///wIA+QKVAAAAABl2qRT9zXUVA8Ls5iVqynLHe5/vSe1XyYisQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAAAAAQEfQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAA==')
+ assert_equal(analysis['next'], 'creator')
+ assert_equal(analysis['error'], 'PSBT is not valid. Input 0 specifies invalid prevout')
+
+ assert_raises_rpc_error(-25, 'Missing inputs', self.nodes[0].walletprocesspsbt, 'cHNidP8BAJoCAAAAAkvEW8NnDtdNtDpsmze+Ht2LH35IJcKv00jKAlUs21RrAwAAAAD/////S8Rbw2cO1020OmybN74e3Ysffkglwq/TSMoCVSzbVGsBAAAAAP7///8CwLYClQAAAAAWABSNJKzjaUb3uOxixsvh1GGE3fW7zQD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XIAAAAAAAEAnQIAAAACczMa321tVHuN4GKWKRncycI22aX3uXgwSFUKM2orjRsBAAAAAP7///9zMxrfbW1Ue43gYpYpGdzJwjbZpfe5eDBIVQozaiuNGwAAAAAA/v///wIA+QKVAAAAABl2qRT9zXUVA8Ls5iVqynLHe5/vSe1XyYisQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAAAAAQEfQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAA==')
+
if __name__ == '__main__':
PSBTTest().main()
diff --git a/test/functional/rpc_scantxoutset.py b/test/functional/rpc_scantxoutset.py
index f31e4f43bd..c3d34be0dd 100755
--- a/test/functional/rpc_scantxoutset.py
+++ b/test/functional/rpc_scantxoutset.py
@@ -54,7 +54,7 @@ class ScantxoutsetTest(BitcoinTestFramework):
self.log.info("Stop node, remove wallet, mine again some blocks...")
self.stop_node(0)
- shutil.rmtree(os.path.join(self.nodes[0].datadir, "regtest", 'wallets'))
+ shutil.rmtree(os.path.join(self.nodes[0].datadir, self.chain, 'wallets'))
self.start_node(0)
self.nodes[0].generate(110)
diff --git a/test/functional/rpc_setban.py b/test/functional/rpc_setban.py
index b1d2b6f431..1cc1fb164b 100755
--- a/test/functional/rpc_setban.py
+++ b/test/functional/rpc_setban.py
@@ -26,7 +26,7 @@ class SetBanTests(BitcoinTestFramework):
self.nodes[1].setban("127.0.0.1", "add")
# Node 0 should not be able to reconnect
- with self.nodes[1].assert_debug_log(expected_msgs=['dropped (banned)\n'], timeout=5):
+ with self.nodes[1].assert_debug_log(expected_msgs=['dropped (banned)\n'], timeout=50):
self.restart_node(1, [])
self.nodes[0].addnode("127.0.0.1:" + str(p2p_port(1)), "onetry")
diff --git a/test/functional/test_framework/address.py b/test/functional/test_framework/address.py
index 97585fe054..6a7e91216a 100644
--- a/test/functional/test_framework/address.py
+++ b/test/functional/test_framework/address.py
@@ -13,6 +13,8 @@ from . import segwit_addr
ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
+# Coins sent to this address can be spent with a witness stack of just OP_TRUE
+ADDRESS_BCRT1_P2WSH_OP_TRUE = 'bcrt1qft5p2uhsdcdc3l2ua4ap5qqfg4pjaqlp250x7us7a8qqhrxrxfsqseac85'
class AddressType(enum.Enum):
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 25520a2151..4f7a9a8b13 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -1105,17 +1105,17 @@ class msg_tx:
self.tx.deserialize(f)
def serialize(self):
- return self.tx.serialize_without_witness()
+ return self.tx.serialize_with_witness()
def __repr__(self):
return "msg_tx(tx=%s)" % (repr(self.tx))
-class msg_witness_tx(msg_tx):
+class msg_no_witness_tx(msg_tx):
__slots__ = ()
def serialize(self):
- return self.tx.serialize_with_witness()
+ return self.tx.serialize_without_witness()
class msg_block:
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index e5c77ae5fa..0742dbe617 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -298,7 +298,9 @@ class TestNode():
wait_until(self.is_node_stopped, timeout=timeout)
@contextlib.contextmanager
- def assert_debug_log(self, expected_msgs, timeout=2):
+ def assert_debug_log(self, expected_msgs, unexpected_msgs=None, timeout=2):
+ if unexpected_msgs is None:
+ unexpected_msgs = []
time_end = time.time() + timeout
debug_log = os.path.join(self.datadir, self.chain, 'debug.log')
with open(debug_log, encoding='utf-8') as dl:
@@ -313,6 +315,9 @@ class TestNode():
dl.seek(prev_size)
log = dl.read()
print_log = " - " + "\n - ".join(log.splitlines())
+ for unexpected_msg in unexpected_msgs:
+ if re.search(re.escape(unexpected_msg), log, flags=re.MULTILINE):
+ self._raise_assertion_error('Unexpected message "{}" partially matches log:\n\n{}\n\n'.format(unexpected_msg, print_log))
for expected_msg in expected_msgs:
if re.search(re.escape(expected_msg), log, flags=re.MULTILINE) is None:
found = False
diff --git a/test/functional/test_framework/wallet_util.py b/test/functional/test_framework/wallet_util.py
index 881df80f64..eb537015fb 100755
--- a/test/functional/test_framework/wallet_util.py
+++ b/test/functional/test_framework/wallet_util.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2018-2019 The Bitcoin Core developers
+# Copyright (c) 2018-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Useful util functions for testing the wallet"""
@@ -88,11 +88,6 @@ def get_multisig(node):
p2sh_p2wsh_script=CScript([OP_HASH160, witness_script, OP_EQUAL]).hex(),
p2sh_p2wsh_addr=script_to_p2sh_p2wsh(script_code))
-def labels_value(name="", purpose="receive"):
- """Generate a getaddressinfo labels array from a name and purpose.
- Often used as the value of a labels kwarg for calling test_address below."""
- return [{"name": name, "purpose": purpose}]
-
def test_address(node, address, **kwargs):
"""Get address info for `address` and test whether the returned values are as expected."""
addr_info = node.getaddressinfo(address)
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 110733c529..8b527bcff0 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -212,6 +212,8 @@ BASE_SCRIPTS = [
'p2p_permissions.py',
'feature_blocksdir.py',
'feature_config_args.py',
+ 'rpc_getaddressinfo_labels_purpose_deprecation.py',
+ 'rpc_getaddressinfo_label_deprecation.py',
'rpc_help.py',
'feature_help.py',
'feature_shutdown.py',
diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py
index 32ef257456..d2629ff1ed 100755
--- a/test/functional/tool_wallet.py
+++ b/test/functional/tool_wallet.py
@@ -27,7 +27,7 @@ class ToolWalletTest(BitcoinTestFramework):
def bitcoin_wallet_process(self, *args):
binary = self.config["environment"]["BUILDDIR"] + '/src/bitcoin-wallet' + self.config["environment"]["EXEEXT"]
- args = ['-datadir={}'.format(self.nodes[0].datadir), '-regtest'] + list(args)
+ args = ['-datadir={}'.format(self.nodes[0].datadir), '-chain=%s' % self.chain] + list(args)
return subprocess.Popen([binary] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
def assert_raises_tool_error(self, error, *args):
@@ -198,7 +198,7 @@ class ToolWalletTest(BitcoinTestFramework):
self.log.debug('Wallet file shasum unchanged\n')
def run_test(self):
- self.wallet_path = os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat')
+ self.wallet_path = os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat')
self.test_invalid_tool_commands_and_args()
# Warning: The following tests are order-dependent.
self.test_tool_wallet_info()
diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py
index 3cfb5a648b..1ca02a695c 100755
--- a/test/functional/wallet_avoidreuse.py
+++ b/test/functional/wallet_avoidreuse.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2018-2019 The Bitcoin Core developers
+# Copyright (c) 2018-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the avoid_reuse and setwalletflag features."""
@@ -86,7 +86,13 @@ class AvoidReuseTest(BitcoinTestFramework):
reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
self.test_fund_send_fund_senddirty()
reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
- self.test_fund_send_fund_send()
+ self.test_fund_send_fund_send("legacy")
+ reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
+ self.test_fund_send_fund_send("p2sh-segwit")
+ reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
+ self.test_fund_send_fund_send("bech32")
+ reset_balance(self.nodes[1], self.nodes[0].getnewaddress())
+ self.test_getbalances_used()
def test_persistence(self):
'''Test that wallet files persist the avoid_reuse flag.'''
@@ -182,7 +188,7 @@ class AvoidReuseTest(BitcoinTestFramework):
assert_approx(self.nodes[1].getbalance(), 5, 0.001)
assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 5, 0.001)
- def test_fund_send_fund_send(self):
+ def test_fund_send_fund_send(self, second_addr_type):
'''
Test the simple case where [1] generates a new address A, then
[0] sends 10 BTC to A.
@@ -193,7 +199,7 @@ class AvoidReuseTest(BitcoinTestFramework):
'''
self.log.info("Test fund send fund send")
- fundaddr = self.nodes[1].getnewaddress()
+ fundaddr = self.nodes[1].getnewaddress(label="", address_type="legacy")
retaddr = self.nodes[0].getnewaddress()
self.nodes[0].sendtoaddress(fundaddr, 10)
@@ -214,7 +220,19 @@ class AvoidReuseTest(BitcoinTestFramework):
# getbalances should show no used, 5 btc trusted
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5})
- self.nodes[0].sendtoaddress(fundaddr, 10)
+ # For the second send, we transmute it to a related single-key address
+ # to make sure it's also detected as re-use
+ fund_spk = self.nodes[0].getaddressinfo(fundaddr)["scriptPubKey"]
+ fund_decoded = self.nodes[0].decodescript(fund_spk)
+ if second_addr_type == "p2sh-segwit":
+ new_fundaddr = fund_decoded["segwit"]["p2sh-segwit"]
+ elif second_addr_type == "bech32":
+ new_fundaddr = fund_decoded["segwit"]["addresses"][0]
+ else:
+ new_fundaddr = fundaddr
+ assert_equal(second_addr_type, "legacy")
+
+ self.nodes[0].sendtoaddress(new_fundaddr, 10)
self.nodes[0].generate(1)
self.sync_all()
@@ -240,5 +258,35 @@ class AvoidReuseTest(BitcoinTestFramework):
assert_approx(self.nodes[1].getbalance(), 1, 0.001)
assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 11, 0.001)
+ def test_getbalances_used(self):
+ '''
+ getbalances and listunspent should pick up on reused addresses
+ immediately, even for address reusing outputs created before the first
+ transaction was spending from that address
+ '''
+ self.log.info("Test getbalances used category")
+
+ # node under test should be completely empty
+ assert_equal(self.nodes[1].getbalance(avoid_reuse=False), 0)
+
+ new_addr = self.nodes[1].getnewaddress()
+ ret_addr = self.nodes[0].getnewaddress()
+
+ # send multiple transactions, reusing one address
+ for _ in range(11):
+ self.nodes[0].sendtoaddress(new_addr, 1)
+
+ self.nodes[0].generate(1)
+ self.sync_all()
+
+ # send transaction that should not use all the available outputs
+ # per the current coin selection algorithm
+ self.nodes[1].sendtoaddress(ret_addr, 5)
+
+ # getbalances and listunspent should show the remaining outputs
+ # in the reused address as used/reused
+ assert_unspent(self.nodes[1], total_count=2, total_sum=6, reused_count=1, reused_sum=1)
+ assert_balances(self.nodes[1], mine={"used": 1, "trusted": 5})
+
if __name__ == '__main__':
AvoidReuseTest().main()
diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py
index bb835dc811..16c69f304a 100755
--- a/test/functional/wallet_backup.py
+++ b/test/functional/wallet_backup.py
@@ -107,9 +107,9 @@ class WalletBackupTest(BitcoinTestFramework):
self.stop_node(2)
def erase_three(self):
- os.remove(os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat'))
- os.remove(os.path.join(self.nodes[1].datadir, 'regtest', 'wallets', 'wallet.dat'))
- os.remove(os.path.join(self.nodes[2].datadir, 'regtest', 'wallets', 'wallet.dat'))
+ os.remove(os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat'))
+ os.remove(os.path.join(self.nodes[1].datadir, self.chain, 'wallets', 'wallet.dat'))
+ os.remove(os.path.join(self.nodes[2].datadir, self.chain, 'wallets', 'wallet.dat'))
def run_test(self):
self.log.info("Generating initial blockchain")
@@ -167,13 +167,13 @@ class WalletBackupTest(BitcoinTestFramework):
self.erase_three()
# Start node2 with no chain
- shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'blocks'))
- shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'chainstate'))
+ shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'blocks'))
+ shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'chainstate'))
# Restore wallets from backup
- shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat'))
- shutil.copyfile(os.path.join(self.nodes[1].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, 'regtest', 'wallets', 'wallet.dat'))
- shutil.copyfile(os.path.join(self.nodes[2].datadir, 'wallet.bak'), os.path.join(self.nodes[2].datadir, 'regtest', 'wallets', 'wallet.dat'))
+ shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat'))
+ shutil.copyfile(os.path.join(self.nodes[1].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, self.chain, 'wallets', 'wallet.dat'))
+ shutil.copyfile(os.path.join(self.nodes[2].datadir, 'wallet.bak'), os.path.join(self.nodes[2].datadir, self.chain, 'wallets', 'wallet.dat'))
self.log.info("Re-starting nodes")
self.start_three()
@@ -188,8 +188,8 @@ class WalletBackupTest(BitcoinTestFramework):
self.erase_three()
#start node2 with no chain
- shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'blocks'))
- shutil.rmtree(os.path.join(self.nodes[2].datadir, 'regtest', 'chainstate'))
+ shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'blocks'))
+ shutil.rmtree(os.path.join(self.nodes[2].datadir, self.chain, 'chainstate'))
self.start_three()
@@ -209,10 +209,10 @@ class WalletBackupTest(BitcoinTestFramework):
# Backup to source wallet file must fail
sourcePaths = [
- os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', 'wallet.dat'),
- os.path.join(self.nodes[0].datadir, 'regtest', '.', 'wallets', 'wallet.dat'),
- os.path.join(self.nodes[0].datadir, 'regtest', 'wallets', ''),
- os.path.join(self.nodes[0].datadir, 'regtest', 'wallets')]
+ os.path.join(self.nodes[0].datadir, self.chain, 'wallets', 'wallet.dat'),
+ os.path.join(self.nodes[0].datadir, self.chain, '.', 'wallets', 'wallet.dat'),
+ os.path.join(self.nodes[0].datadir, self.chain, 'wallets', ''),
+ os.path.join(self.nodes[0].datadir, self.chain, 'wallets')]
for sourcePath in sourcePaths:
assert_raises_rpc_error(-4, "backup failed", self.nodes[0].backupwallet, sourcePath)
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 2606afa0e4..15746d312c 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -15,10 +15,7 @@ from test_framework.util import (
connect_nodes,
wait_until,
)
-from test_framework.wallet_util import (
- labels_value,
- test_address,
-)
+from test_framework.wallet_util import test_address
class WalletTest(BitcoinTestFramework):
@@ -395,7 +392,7 @@ class WalletTest(BitcoinTestFramework):
for label in [u'рыба', u'𝅘𝅥𝅯']:
addr = self.nodes[0].getnewaddress()
self.nodes[0].setlabel(addr, label)
- test_address(self.nodes[0], addr, label=label, labels=labels_value(name=label))
+ test_address(self.nodes[0], addr, labels=[label])
assert label in self.nodes[0].listlabels()
self.nodes[0].rpc.ensure_ascii = True # restore to default
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index 0c08655833..4eb0d19a4f 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -78,6 +78,7 @@ class BumpFeeTest(BitcoinTestFramework):
test_small_output_fails(rbf_node, dest_address)
test_dust_to_fee(rbf_node, dest_address)
test_settxfee(rbf_node, dest_address)
+ test_watchonly_psbt(self, peer_node, rbf_node, dest_address)
test_rebumping(rbf_node, dest_address)
test_rebumping_not_replaceable(rbf_node, dest_address)
test_unconfirmed_not_spendable(rbf_node, rbf_node_address)
@@ -103,6 +104,7 @@ def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address):
assert_equal(bumped_tx["errors"], [])
assert bumped_tx["fee"] > -rbftx["fee"]
assert_equal(bumped_tx["origfee"], -rbftx["fee"])
+ assert "psbt" not in bumped_tx
# check that bumped_tx propagates, original tx was evicted and has a wallet conflict
self.sync_mempools((rbf_node, peer_node))
assert bumped_tx["txid"] in rbf_node.getrawmempool()
@@ -280,6 +282,86 @@ def test_maxtxfee_fails(test, rbf_node, dest_address):
test.restart_node(1, test.extra_args[1])
rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
+def test_watchonly_psbt(test, peer_node, rbf_node, dest_address):
+ priv_rec_desc = "wpkh([00000001/84'/1'/0']tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0/*)#rweraev0"
+ pub_rec_desc = rbf_node.getdescriptorinfo(priv_rec_desc)["descriptor"]
+ priv_change_desc = "wpkh([00000001/84'/1'/0']tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/*)#j6uzqvuh"
+ pub_change_desc = rbf_node.getdescriptorinfo(priv_change_desc)["descriptor"]
+ # Create a wallet with private keys that can sign PSBTs
+ rbf_node.createwallet(wallet_name="signer", disable_private_keys=False, blank=True)
+ signer = rbf_node.get_wallet_rpc("signer")
+ assert signer.getwalletinfo()['private_keys_enabled']
+ result = signer.importmulti([{
+ "desc": priv_rec_desc,
+ "timestamp": 0,
+ "range": [0,1],
+ "internal": False,
+ "keypool": False # Keys can only be imported to the keypool when private keys are disabled
+ },
+ {
+ "desc": priv_change_desc,
+ "timestamp": 0,
+ "range": [0, 0],
+ "internal": True,
+ "keypool": False
+ }])
+ assert_equal(result, [{'success': True}, {'success': True}])
+
+ # Create another wallet with just the public keys, which creates PSBTs
+ rbf_node.createwallet(wallet_name="watcher", disable_private_keys=True, blank=True)
+ watcher = rbf_node.get_wallet_rpc("watcher")
+ assert not watcher.getwalletinfo()['private_keys_enabled']
+
+ result = watcher.importmulti([{
+ "desc": pub_rec_desc,
+ "timestamp": 0,
+ "range": [0,10],
+ "internal": False,
+ "keypool": True,
+ "watchonly": True
+ },
+ {
+ "desc": pub_change_desc,
+ "timestamp": 0,
+ "range": [0, 10],
+ "internal": True,
+ "keypool": True,
+ "watchonly": True
+ }])
+ assert_equal(result, [{'success': True}, {'success': True}])
+
+ funding_address1 = watcher.getnewaddress(address_type='bech32')
+ funding_address2 = watcher.getnewaddress(address_type='bech32')
+ peer_node.sendmany("", {funding_address1: 0.001, funding_address2: 0.001})
+ peer_node.generate(1)
+ test.sync_all()
+
+ # Create single-input PSBT for transaction to be bumped
+ psbt = watcher.walletcreatefundedpsbt([], {dest_address:0.0005}, 0, {"feeRate": 0.00001}, True)['psbt']
+ psbt_signed = signer.walletprocesspsbt(psbt=psbt, sign=True, sighashtype="ALL", bip32derivs=True)
+ psbt_final = watcher.finalizepsbt(psbt_signed["psbt"])
+ original_txid = watcher.sendrawtransaction(psbt_final["hex"])
+ assert_equal(len(watcher.decodepsbt(psbt)["tx"]["vin"]), 1)
+
+ # Bump fee, obnoxiously high to add additional watchonly input
+ bumped_psbt = watcher.bumpfee(original_txid, {"fee_rate":0.005})
+ assert_greater_than(len(watcher.decodepsbt(bumped_psbt['psbt'])["tx"]["vin"]), 1)
+ assert "txid" not in bumped_psbt
+ assert_equal(bumped_psbt["origfee"], -watcher.gettransaction(original_txid)["fee"])
+ assert not watcher.finalizepsbt(bumped_psbt["psbt"])["complete"]
+
+ # Sign bumped transaction
+ bumped_psbt_signed = signer.walletprocesspsbt(psbt=bumped_psbt["psbt"], sign=True, sighashtype="ALL", bip32derivs=True)
+ bumped_psbt_final = watcher.finalizepsbt(bumped_psbt_signed["psbt"])
+ assert bumped_psbt_final["complete"]
+
+ # Broadcast bumped transaction
+ bumped_txid = watcher.sendrawtransaction(bumped_psbt_final["hex"])
+ assert bumped_txid in rbf_node.getrawmempool()
+ assert original_txid not in rbf_node.getrawmempool()
+
+ rbf_node.unloadwallet("watcher")
+ rbf_node.unloadwallet("signer")
def test_rebumping(rbf_node, dest_address):
# check that re-bumping the original tx fails, but bumping the bumper succeeds
diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py
index 53edf710b9..a39dfc7895 100755
--- a/test/functional/wallet_dump.py
+++ b/test/functional/wallet_dump.py
@@ -137,7 +137,7 @@ class WalletDumpTest(BitcoinTestFramework):
# encrypt wallet, restart, unlock and dump
self.nodes[0].encryptwallet('test')
- self.nodes[0].walletpassphrase('test', 10)
+ self.nodes[0].walletpassphrase('test', 100)
# Should be a no-op:
self.nodes[0].keypoolrefill()
self.nodes[0].dumpwallet(wallet_enc_dump)
diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py
index 3cf8aaf3dc..f2fa1d3e40 100755
--- a/test/functional/wallet_groups.py
+++ b/test/functional/wallet_groups.py
@@ -16,7 +16,7 @@ class WalletGroupTest(BitcoinTestFramework):
self.setup_clean_chain = True
self.num_nodes = 3
self.extra_args = [[], [], ['-avoidpartialspends']]
- self.rpc_timeout = 120
+ self.rpc_timeout = 240
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py
index 575b501f50..7497475b67 100755
--- a/test/functional/wallet_hd.py
+++ b/test/functional/wallet_hd.py
@@ -68,11 +68,11 @@ class WalletHDTest(BitcoinTestFramework):
self.log.info("Restore backup ...")
self.stop_node(1)
- # we need to delete the complete regtest directory
+ # we need to delete the complete chain directory
# otherwise node1 would auto-recover all funds in flag the keypool keys as used
- shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "blocks"))
- 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"))
+ shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "blocks"))
+ shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "chainstate"))
+ shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat"))
self.start_node(1)
# Assert that derivation is deterministic
@@ -93,9 +93,9 @@ class WalletHDTest(BitcoinTestFramework):
# Try a RPC based rescan
self.stop_node(1)
- shutil.rmtree(os.path.join(self.nodes[1].datadir, "regtest", "blocks"))
- 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"))
+ shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "blocks"))
+ shutil.rmtree(os.path.join(self.nodes[1].datadir, self.chain, "chainstate"))
+ shutil.copyfile(os.path.join(self.nodes[1].datadir, "hd.bak"), os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat"))
self.start_node(1, extra_args=self.extra_args[1])
connect_nodes(self.nodes[0], 1)
self.sync_all()
diff --git a/test/functional/wallet_import_with_label.py b/test/functional/wallet_import_with_label.py
index 651ecd18b2..6a9d2e8290 100755
--- a/test/functional/wallet_import_with_label.py
+++ b/test/functional/wallet_import_with_label.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2018-2019 The Bitcoin Core developers
+# Copyright (c) 2018-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the behavior of RPC importprivkey on set and unset labels of
@@ -11,10 +11,7 @@ with and without a label.
"""
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.wallet_util import (
- labels_value,
- test_address,
-)
+from test_framework.wallet_util import test_address
class ImportWithLabel(BitcoinTestFramework):
@@ -39,8 +36,7 @@ class ImportWithLabel(BitcoinTestFramework):
address,
iswatchonly=True,
ismine=False,
- label=label,
- labels=labels_value(name=label))
+ labels=[label])
self.log.info(
"Import the watch-only address's private key without a "
@@ -48,11 +44,7 @@ class ImportWithLabel(BitcoinTestFramework):
)
priv_key = self.nodes[0].dumpprivkey(address)
self.nodes[1].importprivkey(priv_key)
-
- test_address(self.nodes[1],
- address,
- label=label,
- labels=labels_value(name=label))
+ test_address(self.nodes[1], address, labels=[label])
self.log.info(
"Test importaddress without label and importprivkey with label."
@@ -64,8 +56,7 @@ class ImportWithLabel(BitcoinTestFramework):
address2,
iswatchonly=True,
ismine=False,
- label="",
- labels=labels_value())
+ labels=[""])
self.log.info(
"Import the watch-only address's private key with a "
@@ -75,10 +66,7 @@ class ImportWithLabel(BitcoinTestFramework):
label2 = "Test Label 2"
self.nodes[1].importprivkey(priv_key2, label2)
- test_address(self.nodes[1],
- address2,
- label=label2,
- labels=labels_value(name=label2))
+ test_address(self.nodes[1], address2, labels=[label2])
self.log.info("Test importaddress with label and importprivkey with label.")
self.log.info("Import a watch-only address with a label.")
@@ -89,8 +77,7 @@ class ImportWithLabel(BitcoinTestFramework):
address3,
iswatchonly=True,
ismine=False,
- label=label3_addr,
- labels=labels_value(name=label3_addr))
+ labels=[label3_addr])
self.log.info(
"Import the watch-only address's private key with a "
@@ -100,10 +87,7 @@ class ImportWithLabel(BitcoinTestFramework):
label3_priv = "Test Label 3 for importprivkey"
self.nodes[1].importprivkey(priv_key3, label3_priv)
- test_address(self.nodes[1],
- address3,
- label=label3_priv,
- labels=labels_value(name=label3_priv))
+ test_address(self.nodes[1], address3, labels=[label3_priv])
self.log.info(
"Test importprivkey won't label new dests with the same "
@@ -117,8 +101,7 @@ class ImportWithLabel(BitcoinTestFramework):
address4,
iswatchonly=True,
ismine=False,
- label=label4_addr,
- labels=labels_value(name=label4_addr),
+ labels=[label4_addr],
embedded=None)
self.log.info(
@@ -131,15 +114,9 @@ class ImportWithLabel(BitcoinTestFramework):
self.nodes[1].importprivkey(priv_key4)
embedded_addr = self.nodes[1].getaddressinfo(address4)['embedded']['address']
- test_address(self.nodes[1],
- embedded_addr,
- label="",
- labels=labels_value())
+ test_address(self.nodes[1], embedded_addr, labels=[""])
- test_address(self.nodes[1],
- address4,
- label=label4_addr,
- labels=labels_value(name=label4_addr))
+ test_address(self.nodes[1], address4, labels=[label4_addr])
self.stop_nodes()
diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py
index 5febac5998..f152fcd1a4 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -29,7 +29,6 @@ from test_framework.util import (
from test_framework.wallet_util import (
get_key,
get_multisig,
- labels_value,
test_address,
)
@@ -570,8 +569,7 @@ class ImportMultiTest(BitcoinTestFramework):
key.p2sh_p2wpkh_addr,
solvable=True,
ismine=True,
- label=p2sh_p2wpkh_label,
- labels=labels_value(name=p2sh_p2wpkh_label))
+ labels=[p2sh_p2wpkh_label])
# Test ranged descriptor fails if range is not specified
xpriv = "tprv8ZgxMBicQKsPeuVhWwi6wuMQGfPKi9Li5GtX35jVNknACgqe3CY4g5xgkfDDJcmtF7o1QnxWDRYw4H5P26PXq7sbcUkEqeR4fg3Kxp2tigg"
@@ -642,8 +640,7 @@ class ImportMultiTest(BitcoinTestFramework):
key.p2pkh_addr,
solvable=True,
ismine=False,
- label=p2pkh_label,
- labels=labels_value(name=p2pkh_label))
+ labels=[p2pkh_label])
# Test import fails if both desc and scriptPubKey are provided
key = get_key(self.nodes[0])
diff --git a/test/functional/wallet_keypool_topup.py b/test/functional/wallet_keypool_topup.py
index 2e70a9e0a5..829633a050 100755
--- a/test/functional/wallet_keypool_topup.py
+++ b/test/functional/wallet_keypool_topup.py
@@ -30,7 +30,7 @@ class KeypoolRestoreTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def run_test(self):
- wallet_path = os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")
+ wallet_path = os.path.join(self.nodes[1].datadir, self.chain, "wallets", "wallet.dat")
wallet_backup_path = os.path.join(self.nodes[1].datadir, "wallet.bak")
self.nodes[0].generate(101)
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
index 33e067601e..337d2e55d9 100755
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2016-2019 The Bitcoin Core developers
+# Copyright (c) 2016-2020 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test label RPCs.
@@ -13,10 +13,8 @@ from collections import defaultdict
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error
-from test_framework.wallet_util import (
- labels_value,
- test_address,
-)
+from test_framework.wallet_util import test_address
+
class WalletLabelsTest(BitcoinTestFramework):
def set_test_params(self):
@@ -157,12 +155,7 @@ class Label:
if self.receive_address is not None:
assert self.receive_address in self.addresses
for address in self.addresses:
- test_address(
- node,
- address,
- label=self.name,
- labels=labels_value(name=self.name, purpose=self.purpose[address])
- )
+ test_address(node, address, labels=[self.name])
assert self.name in node.listlabels()
assert_equal(
node.getaddressesbylabel(self.name),
diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py
index afd473306d..b0590b149a 100755
--- a/test/functional/wallet_listreceivedby.py
+++ b/test/functional/wallet_listreceivedby.py
@@ -11,10 +11,7 @@ from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
)
-from test_framework.wallet_util import (
- labels_value,
- test_address,
-)
+from test_framework.wallet_util import test_address
class ReceivedByTest(BitcoinTestFramework):
@@ -131,7 +128,7 @@ class ReceivedByTest(BitcoinTestFramework):
# set pre-state
label = ''
address = self.nodes[1].getnewaddress()
- test_address(self.nodes[1], address, label=label, labels=labels_value(name=label))
+ test_address(self.nodes[1], address, labels=[label])
received_by_label_json = [r for r in self.nodes[1].listreceivedbylabel() if r["label"] == label][0]
balance_by_label = self.nodes[1].getreceivedbylabel(label)
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 85d900f6cc..f2fa41b647 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -38,7 +38,7 @@ class MultiWalletTest(BitcoinTestFramework):
def run_test(self):
node = self.nodes[0]
- data_dir = lambda *p: os.path.join(node.datadir, 'regtest', *p)
+ data_dir = lambda *p: os.path.join(node.datadir, self.chain, *p)
wallet_dir = lambda *p: data_dir('wallets', *p)
wallet = lambda name: node.get_wallet_rpc(name)
@@ -186,7 +186,7 @@ class MultiWalletTest(BitcoinTestFramework):
assert_equal(w4.getbalance(), 3)
batch = w1.batch([w1.getblockchaininfo.get_request(), w1.getwalletinfo.get_request()])
- assert_equal(batch[0]["result"]["chain"], "regtest")
+ assert_equal(batch[0]["result"]["chain"], self.chain)
assert_equal(batch[1]["result"]["walletname"], "w1")
self.log.info('Check for per-wallet settxfee call')
diff --git a/test/functional/wallet_reorgsrestore.py b/test/functional/wallet_reorgsrestore.py
index f48018e9fb..497a5dd95e 100755
--- a/test/functional/wallet_reorgsrestore.py
+++ b/test/functional/wallet_reorgsrestore.py
@@ -90,7 +90,7 @@ class ReorgsRestoreTest(BitcoinTestFramework):
# Node0 wallet file is loaded on longest sync'ed node1
self.stop_node(1)
self.nodes[0].backupwallet(os.path.join(self.nodes[0].datadir, 'wallet.bak'))
- shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, 'regtest', 'wallet.dat'))
+ shutil.copyfile(os.path.join(self.nodes[0].datadir, 'wallet.bak'), os.path.join(self.nodes[1].datadir, self.chain, 'wallet.dat'))
self.start_node(1)
tx_after_reorg = self.nodes[1].gettransaction(txid)
# Check that normal confirmed tx is confirmed again but with different blockhash
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index bbdd047465..50e86cf9dc 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -15,11 +15,13 @@ import logging
# Fuzzers known to lack a seed corpus in https://github.com/bitcoin-core/qa-assets/tree/master/fuzz_seed_corpus
FUZZERS_MISSING_CORPORA = [
"addr_info_deserialize",
+ "asmap",
"base_encode_decode",
"block",
"block_file_info_deserialize",
"block_filter_deserialize",
"block_header_and_short_txids_deserialize",
+ "decode_tx",
"fee_rate_deserialize",
"flat_file_pos_deserialize",
"hex",
@@ -38,6 +40,7 @@ FUZZERS_MISSING_CORPORA = [
"psbt_output_deserialize",
"pub_key_deserialize",
"script_deserialize",
+ "strprintf",
"sub_net_deserialize",
"tx_in",
"tx_in_deserialize",
diff --git a/test/lint/extended-lint-all.sh b/test/lint/extended-lint-all.sh
index 1cdd52621b..65c51e02f5 100755
--- a/test/lint/extended-lint-all.sh
+++ b/test/lint/extended-lint-all.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
-# Copyright (c) 2019-2018 The Bitcoin Core developers
+# Copyright (c) 2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
diff --git a/test/lint/extended-lint-cppcheck.sh b/test/lint/extended-lint-cppcheck.sh
index 06c11ebba9..47df25ba6b 100755
--- a/test/lint/extended-lint-cppcheck.sh
+++ b/test/lint/extended-lint-cppcheck.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
-# Copyright (c) 2019-2018 The Bitcoin Core developers
+# Copyright (c) 2019 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
diff --git a/test/lint/lint-circular-dependencies.sh b/test/lint/lint-circular-dependencies.sh
index ee17e7912d..bbd94dd6c7 100755
--- a/test/lint/lint-circular-dependencies.sh
+++ b/test/lint/lint-circular-dependencies.sh
@@ -13,11 +13,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"index/txindex -> validation -> index/txindex"
"policy/fees -> txmempool -> policy/fees"
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel"
- "qt/bantablemodel -> qt/clientmodel -> qt/bantablemodel"
- "qt/bitcoingui -> qt/utilitydialog -> qt/bitcoingui"
"qt/bitcoingui -> qt/walletframe -> qt/bitcoingui"
- "qt/bitcoingui -> qt/walletview -> qt/bitcoingui"
- "qt/clientmodel -> qt/peertablemodel -> qt/clientmodel"
"qt/recentrequeststablemodel -> qt/walletmodel -> qt/recentrequeststablemodel"
"qt/sendcoinsdialog -> qt/walletmodel -> qt/sendcoinsdialog"
"qt/transactiontablemodel -> qt/walletmodel -> qt/transactiontablemodel"
@@ -25,7 +21,6 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
"wallet/fees -> wallet/wallet -> wallet/fees"
"wallet/wallet -> wallet/walletdb -> wallet/wallet"
"policy/fees -> txmempool -> validation -> policy/fees"
- "wallet/scriptpubkeyman -> wallet/wallet -> wallet/scriptpubkeyman"
)
EXIT_CODE=0
diff --git a/test/lint/lint-format-strings.py b/test/lint/lint-format-strings.py
index 99127e01f8..2870432bff 100755
--- a/test/lint/lint-format-strings.py
+++ b/test/lint/lint-format-strings.py
@@ -17,12 +17,13 @@ FALSE_POSITIVES = [
("src/index/base.cpp", "FatalError(const char* fmt, const Args&... args)"),
("src/netbase.cpp", "LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args)"),
("src/util/system.cpp", "strprintf(_(COPYRIGHT_HOLDERS).translated, COPYRIGHT_HOLDERS_SUBSTITUTION)"),
+ ("src/validationinterface.cpp", "LogPrint(BCLog::VALIDATION, fmt \"\\n\", __VA_ARGS__)"),
("src/wallet/wallet.h", "WalletLogPrintf(std::string fmt, Params... parameters)"),
("src/wallet/wallet.h", "LogPrintf((\"%s \" + fmt).c_str(), GetDisplayName(), parameters...)"),
+ ("src/wallet/scriptpubkeyman.h", "WalletLogPrintf(std::string fmt, Params... parameters)"),
+ ("src/wallet/scriptpubkeyman.h", "LogPrintf((\"%s \" + fmt).c_str(), m_storage.GetDisplayName(), parameters...)"),
("src/logging.h", "LogPrintf(const char* fmt, const Args&... args)"),
("src/wallet/scriptpubkeyman.h", "WalletLogPrintf(const std::string& fmt, const Params&... parameters)"),
- ("src/wallet/scriptpubkeyman.cpp", "WalletLogPrintf(fmt, parameters...)"),
- ("src/wallet/scriptpubkeyman.cpp", "WalletLogPrintf(const std::string& fmt, const Params&... parameters)"),
]
diff --git a/test/lint/lint-format-strings.sh b/test/lint/lint-format-strings.sh
index 6cb486689b..184c3682c8 100755
--- a/test/lint/lint-format-strings.sh
+++ b/test/lint/lint-format-strings.sh
@@ -34,7 +34,7 @@ if ! python3 -m doctest test/lint/lint-format-strings.py; then
fi
for S in "${FUNCTION_NAMES_AND_NUMBER_OF_LEADING_ARGUMENTS[@]}"; do
IFS="," read -r FUNCTION_NAME SKIP_ARGUMENTS <<< "${S}"
- for MATCHING_FILE in $(git grep --full-name -l "${FUNCTION_NAME}" -- "*.c" "*.cpp" "*.h" | sort | grep -vE "^src/(leveldb|secp256k1|tinyformat|univalue)"); do
+ for MATCHING_FILE in $(git grep --full-name -l "${FUNCTION_NAME}" -- "*.c" "*.cpp" "*.h" | sort | grep -vE "^src/(leveldb|secp256k1|tinyformat|univalue|test/fuzz/strprintf.cpp)"); do
MATCHING_FILES+=("${MATCHING_FILE}")
done
if ! test/lint/lint-format-strings.py --skip-arguments "${SKIP_ARGUMENTS}" "${FUNCTION_NAME}" "${MATCHING_FILES[@]}"; then
diff --git a/test/lint/lint-locale-dependence.sh b/test/lint/lint-locale-dependence.sh
index ea9ea7a58d..35e58c2df6 100755
--- a/test/lint/lint-locale-dependence.sh
+++ b/test/lint/lint-locale-dependence.sh
@@ -1,17 +1,35 @@
#!/usr/bin/env bash
+# Copyright (c) 2018-2019 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
export LC_ALL=C
KNOWN_VIOLATIONS=(
"src/bitcoin-tx.cpp.*stoul"
+ "src/bitcoin-tx.cpp.*std::to_string"
"src/bitcoin-tx.cpp.*trim_right"
"src/dbwrapper.cpp.*stoul"
"src/dbwrapper.cpp:.*vsnprintf"
"src/httprpc.cpp.*trim"
"src/init.cpp:.*atoi"
+ "src/qt/optionsmodel.cpp.*std::to_string"
"src/qt/rpcconsole.cpp:.*atoi"
"src/rest.cpp:.*strtol"
+ "src/rpc/net.cpp.*std::to_string"
+ "src/rpc/rawtransaction.cpp.*std::to_string"
+ "src/rpc/util.cpp.*std::to_string"
+ "src/test/addrman_tests.cpp.*std::to_string"
+ "src/test/blockchain_tests.cpp.*std::to_string"
"src/test/dbwrapper_tests.cpp:.*snprintf"
+ "src/test/denialofservice_tests.cpp.*std::to_string"
"src/test/fuzz/parse_numbers.cpp:.*atoi"
+ "src/test/key_tests.cpp.*std::to_string"
+ "src/test/net_tests.cpp.*std::to_string"
+ "src/test/settings_tests.cpp.*std::to_string"
+ "src/test/timedata_tests.cpp.*std::to_string"
+ "src/test/util/setup_common.cpp.*std::to_string"
+ "src/test/util_tests.cpp.*std::to_string"
+ "src/test/util_threadnames_tests.cpp.*std::to_string"
"src/torcontrol.cpp:.*atoi"
"src/torcontrol.cpp:.*strtol"
"src/util/strencodings.cpp:.*atoi"
@@ -19,6 +37,7 @@ KNOWN_VIOLATIONS=(
"src/util/strencodings.cpp:.*strtoul"
"src/util/strencodings.h:.*atoi"
"src/util/system.cpp:.*atoi"
+ "src/wallet/scriptpubkeyman.cpp.*std::to_string"
)
REGEXP_IGNORE_EXTERNAL_DEPENDENCIES="^src/(crypto/ctaes/|leveldb/|secp256k1/|tinyformat.h|univalue/)"
@@ -93,6 +112,7 @@ LOCALE_DEPENDENT_FUNCTIONS=(
snprintf
sprintf
sscanf
+ std::to_string
stod
stof
stoi
diff --git a/test/lint/lint-shebang.sh b/test/lint/lint-shebang.sh
index fda22592d3..a666fdfecf 100755
--- a/test/lint/lint-shebang.sh
+++ b/test/lint/lint-shebang.sh
@@ -1,4 +1,8 @@
#!/usr/bin/env bash
+# Copyright (c) 2018 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
# Assert expected shebang lines
export LC_ALL=C
diff --git a/test/sanitizer_suppressions/tsan b/test/sanitizer_suppressions/tsan
index 70eea34363..b9c5c038d0 100644
--- a/test/sanitizer_suppressions/tsan
+++ b/test/sanitizer_suppressions/tsan
@@ -7,6 +7,14 @@ deadlock:WalletBatch
# Intentional deadlock in tests
deadlock:TestPotentialDeadLockDetected
+# Race due to unprotected calls to thread-unsafe BOOST_TEST_MESSAGE from different threads:
+# * G_TEST_LOG_FUN in the index thread
+# * boost test case invoker (entering a test case) in the main thread
+# TODO: get rid of BOOST_ macros, see also https://github.com/bitcoin/bitcoin/issues/8670
+race:blockfilter_index_initial_sync_invoker
+race:txindex_initial_sync_invoker
+race:validation_block_tests::TestSubscriber
+
# Wildcard for all gui tests, should be replaced with non-wildcard suppressions
race:src/qt/test/*
deadlock:src/qt/test/*