aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/feature_anchors.py85
-rwxr-xr-xtest/functional/feature_notifications.py54
-rwxr-xr-xtest/functional/feature_nulldummy.py30
-rwxr-xr-xtest/functional/feature_rbf.py7
-rwxr-xr-xtest/functional/feature_segwit.py2
-rwxr-xr-xtest/functional/feature_utxo_set_hash.py30
-rwxr-xr-xtest/functional/interface_rpc.py26
-rwxr-xr-xtest/functional/mempool_package_onemore.py2
-rwxr-xr-xtest/functional/p2p_feefilter.py14
-rwxr-xr-xtest/functional/p2p_filter.py6
-rw-r--r--test/functional/rpc_addresses_deprecation.py58
-rwxr-xr-xtest/functional/rpc_createmultisig.py2
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py24
-rwxr-xr-xtest/functional/rpc_generateblock.py8
-rwxr-xr-xtest/functional/rpc_invalid_address_message.py20
-rwxr-xr-xtest/functional/rpc_psbt.py12
-rwxr-xr-xtest/functional/test_framework/messages.py12
-rw-r--r--test/functional/test_framework/segwit_addr.py54
-rw-r--r--test/functional/test_framework/util.py2
-rw-r--r--test/functional/test_framework/wallet.py3
-rwxr-xr-xtest/functional/test_runner.py2
-rwxr-xr-xtest/functional/wallet_address_types.py2
-rwxr-xr-xtest/functional/wallet_avoidreuse.py2
-rwxr-xr-xtest/functional/wallet_basic.py2
-rwxr-xr-xtest/functional/wallet_bumpfee.py2
-rwxr-xr-xtest/functional/wallet_groups.py16
-rwxr-xr-xtest/functional/wallet_hd.py2
-rwxr-xr-xtest/functional/wallet_labels.py10
-rwxr-xr-xtest/functional/wallet_multiwallet.py2
-rwxr-xr-xtest/functional/wallet_send.py4
-rwxr-xr-xtest/functional/wallet_txn_clone.py4
-rwxr-xr-xtest/fuzz/test_runner.py54
-rwxr-xr-xtest/lint/extended-lint-cppcheck.sh1
-rw-r--r--test/util/data/tt-delin1-out.json14
-rw-r--r--test/util/data/tt-delout1-out.json7
-rw-r--r--test/util/data/tt-locktime317000-out.json14
-rw-r--r--test/util/data/txcreate1.json14
-rw-r--r--test/util/data/txcreatedata1.json7
-rw-r--r--test/util/data/txcreatedata2.json7
-rw-r--r--test/util/data/txcreatedata_seq0.json7
-rw-r--r--test/util/data/txcreatedata_seq1.json7
-rw-r--r--test/util/data/txcreatemultisig1.json8
-rw-r--r--test/util/data/txcreatemultisig2.json7
-rw-r--r--test/util/data/txcreatemultisig3.json7
-rw-r--r--test/util/data/txcreatemultisig4.json7
-rw-r--r--test/util/data/txcreatemultisig5.json7
-rw-r--r--test/util/data/txcreateoutpubkey2.json7
-rw-r--r--test/util/data/txcreateoutpubkey3.json7
-rw-r--r--test/util/data/txcreatescript2.json7
-rw-r--r--test/util/data/txcreatescript3.json7
-rw-r--r--test/util/data/txcreatescript4.json7
-rw-r--r--test/util/data/txcreatesignv1.json7
52 files changed, 435 insertions, 274 deletions
diff --git a/test/functional/feature_anchors.py b/test/functional/feature_anchors.py
new file mode 100755
index 0000000000..a60a723b3e
--- /dev/null
+++ b/test/functional/feature_anchors.py
@@ -0,0 +1,85 @@
+#!/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 Anchors functionality"""
+
+import os
+
+from test_framework.p2p import P2PInterface
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal
+
+
+def check_node_connections(*, node, num_in, num_out):
+ info = node.getnetworkinfo()
+ assert_equal(info["connections_in"], num_in)
+ assert_equal(info["connections_out"], num_out)
+
+
+class AnchorsTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+
+ def setup_network(self):
+ self.setup_nodes()
+
+ def run_test(self):
+ self.log.info("Add 2 block-relay-only connections to node 0")
+ for i in range(2):
+ self.log.debug(f"block-relay-only: {i}")
+ self.nodes[0].add_outbound_p2p_connection(
+ P2PInterface(), p2p_idx=i, connection_type="block-relay-only"
+ )
+
+ self.log.info("Add 5 inbound connections to node 0")
+ for i in range(5):
+ self.log.debug(f"inbound: {i}")
+ self.nodes[0].add_p2p_connection(P2PInterface())
+
+ self.log.info("Check node 0 connections")
+ check_node_connections(node=self.nodes[0], num_in=5, num_out=2)
+
+ # 127.0.0.1
+ ip = "7f000001"
+
+ # Since the ip is always 127.0.0.1 for this case,
+ # we store only the port to identify the peers
+ block_relay_nodes_port = []
+ inbound_nodes_port = []
+ for p in self.nodes[0].getpeerinfo():
+ addr_split = p["addr"].split(":")
+ if p["connection_type"] == "block-relay-only":
+ block_relay_nodes_port.append(hex(int(addr_split[1]))[2:])
+ else:
+ inbound_nodes_port.append(hex(int(addr_split[1]))[2:])
+
+ self.log.info("Stop node 0")
+ self.stop_node(0)
+
+ node0_anchors_path = os.path.join(
+ self.nodes[0].datadir, "regtest", "anchors.dat"
+ )
+
+ # It should contain only the block-relay-only addresses
+ self.log.info("Check the addresses in anchors.dat")
+
+ with open(node0_anchors_path, "rb") as file_handler:
+ anchors = file_handler.read().hex()
+
+ for port in block_relay_nodes_port:
+ ip_port = ip + port
+ assert ip_port in anchors
+ for port in inbound_nodes_port:
+ ip_port = ip + port
+ assert ip_port not in anchors
+
+ self.log.info("Start node 0")
+ self.start_node(0)
+
+ self.log.info("When node starts, check if anchors.dat doesn't exist anymore")
+ assert not os.path.exists(node0_anchors_path)
+
+
+if __name__ == "__main__":
+ AnchorsTest().main()
diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py
index b068ce612c..4e2de1daf4 100755
--- a/test/functional/feature_notifications.py
+++ b/test/functional/feature_notifications.py
@@ -17,7 +17,7 @@ from test_framework.util import (
FILE_CHAR_START = 32 if os.name == 'nt' else 1
FILE_CHAR_END = 128
FILE_CHARS_DISALLOWED = '/\\?%*:|"<>' if os.name == 'nt' else '/'
-
+UNCONFIRMED_HASH_STRING = 'unconfirmed'
def notify_outputname(walletname, txid):
return txid if os.name == 'nt' else '{}_{}'.format(walletname, txid)
@@ -43,7 +43,7 @@ class NotificationsTest(BitcoinTestFramework):
"-blocknotify=echo > {}".format(os.path.join(self.blocknotify_dir, '%s')),
], [
"-rescan",
- "-walletnotify=echo > {}".format(os.path.join(self.walletnotify_dir, notify_outputname('%w', '%s'))),
+ "-walletnotify=echo %h_%b > {}".format(os.path.join(self.walletnotify_dir, notify_outputname('%w', '%s'))),
]]
self.wallet_names = [self.default_wallet_name, self.wallet]
super().setup_network()
@@ -90,11 +90,9 @@ class NotificationsTest(BitcoinTestFramework):
self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
# directory content should equal the generated transaction hashes
- txids_rpc = list(map(lambda t: notify_outputname(self.wallet, t['txid']), self.nodes[1].listtransactions("*", block_count)))
- assert_equal(sorted(txids_rpc), sorted(os.listdir(self.walletnotify_dir)))
+ tx_details = list(map(lambda t: (t['txid'], t['blockheight'], t['blockhash']), self.nodes[1].listtransactions("*", block_count)))
self.stop_node(1)
- for tx_file in os.listdir(self.walletnotify_dir):
- os.remove(os.path.join(self.walletnotify_dir, tx_file))
+ self.expect_wallet_notify(tx_details)
self.log.info("test -walletnotify after rescan")
# restart node to rescan to force wallet notifications
@@ -104,10 +102,8 @@ class NotificationsTest(BitcoinTestFramework):
self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) == block_count, timeout=10)
# directory content should equal the generated transaction hashes
- txids_rpc = list(map(lambda t: notify_outputname(self.wallet, t['txid']), self.nodes[1].listtransactions("*", block_count)))
- assert_equal(sorted(txids_rpc), sorted(os.listdir(self.walletnotify_dir)))
- for tx_file in os.listdir(self.walletnotify_dir):
- os.remove(os.path.join(self.walletnotify_dir, tx_file))
+ tx_details = list(map(lambda t: (t['txid'], t['blockheight'], t['blockhash']), self.nodes[1].listtransactions("*", block_count)))
+ self.expect_wallet_notify(tx_details)
# Conflicting transactions tests.
# Generate spends from node 0, and check notifications
@@ -122,7 +118,7 @@ class NotificationsTest(BitcoinTestFramework):
tx1 = self.nodes[0].sendtoaddress(address=ADDRESS_BCRT1_UNSPENDABLE, amount=1, replaceable=True)
assert_equal(tx1 in self.nodes[0].getrawmempool(), True)
self.sync_mempools()
- self.expect_wallet_notify([tx1])
+ self.expect_wallet_notify([(tx1, -1, UNCONFIRMED_HASH_STRING)])
# Generate bump transaction, sync mempools, and check for bump1
# notification. In the future, per
@@ -131,39 +127,57 @@ class NotificationsTest(BitcoinTestFramework):
bump1 = self.nodes[0].bumpfee(tx1)["txid"]
assert_equal(bump1 in self.nodes[0].getrawmempool(), True)
self.sync_mempools()
- self.expect_wallet_notify([bump1])
+ self.expect_wallet_notify([(bump1, -1, UNCONFIRMED_HASH_STRING)])
# Add bump1 transaction to new block, checking for a notification
# and the correct number of confirmations.
- self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)
+ blockhash1 = self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)[0]
+ blockheight1 = self.nodes[0].getblockcount()
self.sync_blocks()
- self.expect_wallet_notify([bump1])
+ self.expect_wallet_notify([(bump1, blockheight1, blockhash1)])
assert_equal(self.nodes[1].gettransaction(bump1)["confirmations"], 1)
# Generate a second transaction to be bumped.
tx2 = self.nodes[0].sendtoaddress(address=ADDRESS_BCRT1_UNSPENDABLE, amount=1, replaceable=True)
assert_equal(tx2 in self.nodes[0].getrawmempool(), True)
self.sync_mempools()
- self.expect_wallet_notify([tx2])
+ self.expect_wallet_notify([(tx2, -1, UNCONFIRMED_HASH_STRING)])
# Bump tx2 as bump2 and generate a block on node 0 while
# disconnected, then reconnect and check for notifications on node 1
# about newly confirmed bump2 and newly conflicted tx2.
self.disconnect_nodes(0, 1)
bump2 = self.nodes[0].bumpfee(tx2)["txid"]
- self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)
+ blockhash2 = self.nodes[0].generatetoaddress(1, ADDRESS_BCRT1_UNSPENDABLE)[0]
+ blockheight2 = self.nodes[0].getblockcount()
assert_equal(self.nodes[0].gettransaction(bump2)["confirmations"], 1)
assert_equal(tx2 in self.nodes[1].getrawmempool(), True)
self.connect_nodes(0, 1)
self.sync_blocks()
- self.expect_wallet_notify([bump2, tx2])
+ self.expect_wallet_notify([(bump2, blockheight2, blockhash2), (tx2, -1, UNCONFIRMED_HASH_STRING)])
assert_equal(self.nodes[1].gettransaction(bump2)["confirmations"], 1)
# TODO: add test for `-alertnotify` large fork notifications
- def expect_wallet_notify(self, tx_ids):
- self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) >= len(tx_ids), timeout=10)
- assert_equal(sorted(notify_outputname(self.wallet, tx_id) for tx_id in tx_ids), sorted(os.listdir(self.walletnotify_dir)))
+ def expect_wallet_notify(self, tx_details):
+ self.wait_until(lambda: len(os.listdir(self.walletnotify_dir)) >= len(tx_details), timeout=10)
+ # Should have no more and no less files than expected
+ assert_equal(sorted(notify_outputname(self.wallet, tx_id) for tx_id, _, _ in tx_details), sorted(os.listdir(self.walletnotify_dir)))
+ # Should now verify contents of each file
+ for tx_id, blockheight, blockhash in tx_details:
+ fname = os.path.join(self.walletnotify_dir, notify_outputname(self.wallet, tx_id))
+ with open(fname, 'rt', encoding='utf-8') as f:
+ text = f.read()
+ # Universal newline ensures '\n' on 'nt'
+ assert_equal(text[-1], '\n')
+ text = text[:-1]
+ if os.name == 'nt':
+ # On Windows, echo as above will append a whitespace
+ assert_equal(text[-1], ' ')
+ text = text[:-1]
+ expected = str(blockheight) + '_' + blockhash
+ assert_equal(text, expected)
+
for tx_file in os.listdir(self.walletnotify_dir):
os.remove(os.path.join(self.walletnotify_dir, tx_file))
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index bdbfa5aed1..c7981d31dc 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -6,11 +6,11 @@
Connect to a single node.
Generate 2 blocks (save the coinbases for later).
-Generate 427 more blocks.
-[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in the 430th block.
+Generate COINBASE_MATURITY (CB) more blocks to ensure the coinbases are mature.
+[Policy/Consensus] Check that NULLDUMMY compliant transactions are accepted in block CB + 3.
[Policy] Check that non-NULLDUMMY transactions are rejected before activation.
-[Consensus] Check that the new NULLDUMMY rules are not enforced on the 431st block.
-[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block.
+[Consensus] Check that the new NULLDUMMY rules are not enforced on block CB + 4.
+[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on block CB + 5.
"""
import time
@@ -20,13 +20,14 @@ from test_framework.script import CScript
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error
+COINBASE_MATURITY = 100
NULLDUMMY_ERROR = "non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)"
def trueDummy(tx):
scriptSig = CScript(tx.vin[0].scriptSig)
newscript = []
for i in scriptSig:
- if (len(newscript) == 0):
+ if len(newscript) == 0:
assert len(i) == 0
newscript.append(b'\x51')
else:
@@ -37,13 +38,13 @@ def trueDummy(tx):
class NULLDUMMYTest(BitcoinTestFramework):
def set_test_params(self):
- # Need two nodes only so GBT doesn't complain that it's not connected
+ # Need two nodes so GBT (getblocktemplate) doesn't complain that it's not connected.
self.num_nodes = 2
self.setup_clean_chain = True
# This script tests NULLDUMMY activation, which is part of the 'segwit' deployment, so we go through
# normal segwit activation here (and don't use the default always-on behaviour).
self.extra_args = [[
- '-segwitheight=432',
+ f'-segwitheight={COINBASE_MATURITY + 5}',
'-addresstype=legacy',
]] * 2
@@ -64,16 +65,16 @@ class NULLDUMMYTest(BitcoinTestFramework):
wmulti.importaddress(self.ms_address)
wmulti.importaddress(self.wit_ms_address)
- self.coinbase_blocks = self.nodes[0].generate(2) # Block 2
+ self.coinbase_blocks = self.nodes[0].generate(2) # block height = 2
coinbase_txid = []
for i in self.coinbase_blocks:
coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0])
- self.nodes[0].generate(427) # Block 429
+ self.nodes[0].generate(COINBASE_MATURITY) # block height = COINBASE_MATURITY + 2
self.lastblockhash = self.nodes[0].getbestblockhash()
- self.lastblockheight = 429
- self.lastblocktime = int(time.time()) + 429
+ self.lastblockheight = COINBASE_MATURITY + 2
+ self.lastblocktime = int(time.time()) + self.lastblockheight
- self.log.info("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]")
+ self.log.info(f"Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [{COINBASE_MATURITY + 3}]")
test1txs = [create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, amount=49)]
txid1 = self.nodes[0].sendrawtransaction(test1txs[0].serialize_with_witness().hex(), 0)
test1txs.append(create_transaction(self.nodes[0], txid1, self.ms_address, amount=48))
@@ -87,7 +88,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
trueDummy(test2tx)
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize_with_witness().hex(), 0)
- self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]")
+ self.log.info(f"Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [{COINBASE_MATURITY + 4}]")
self.block_submit(self.nodes[0], [test2tx], False, True)
self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
@@ -104,7 +105,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test5tx.serialize_with_witness().hex(), 0)
self.block_submit(self.nodes[0], [test5tx], True)
- self.log.info("Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [432]")
+ self.log.info(f"Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [{COINBASE_MATURITY + 5}]")
for i in test6txs:
self.nodes[0].sendrawtransaction(i.serialize_with_witness().hex(), 0)
self.block_submit(self.nodes[0], test6txs, True, True)
@@ -130,5 +131,6 @@ class NULLDUMMYTest(BitcoinTestFramework):
else:
assert_equal(node.getbestblockhash(), self.lastblockhash)
+
if __name__ == '__main__':
NULLDUMMYTest().main()
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index c6f55c62b4..945880cc3b 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -33,12 +33,7 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=DUMMY_P2WPKH_SCRIPT):
txid = node.sendtoaddress(new_addr, satoshi_round((amount+fee)/COIN))
tx1 = node.getrawtransaction(txid, 1)
txid = int(txid, 16)
- i = None
-
- for i, txout in enumerate(tx1['vout']):
- if txout['scriptPubKey']['addresses'] == [new_addr]:
- break
- assert i is not None
+ i, _ = next(filter(lambda vout: new_addr == vout[1]['scriptPubKey']['address'], enumerate(tx1['vout'])))
tx2 = CTransaction()
tx2.vin = [CTxIn(COutPoint(txid, i))]
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index 7bd2fc7847..ad8767556b 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -523,7 +523,7 @@ class SegWitTest(BitcoinTestFramework):
v1_addr = program_to_witness(1, [3, 5])
v1_tx = self.nodes[0].createrawtransaction([getutxo(spendable_txid[0])], {v1_addr: 1})
v1_decoded = self.nodes[1].decoderawtransaction(v1_tx)
- assert_equal(v1_decoded['vout'][0]['scriptPubKey']['addresses'][0], v1_addr)
+ assert_equal(v1_decoded['vout'][0]['scriptPubKey']['address'], v1_addr)
assert_equal(v1_decoded['vout'][0]['scriptPubKey']['hex'], "51020305")
# Check that spendable outputs are really spendable
diff --git a/test/functional/feature_utxo_set_hash.py b/test/functional/feature_utxo_set_hash.py
index 6e6046d84d..ce00faffee 100755
--- a/test/functional/feature_utxo_set_hash.py
+++ b/test/functional/feature_utxo_set_hash.py
@@ -6,7 +6,6 @@
import struct
-from test_framework.blocktools import create_transaction
from test_framework.messages import (
CBlock,
COutPoint,
@@ -15,38 +14,30 @@ from test_framework.messages import (
from test_framework.muhash import MuHash3072
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
+from test_framework.wallet import MiniWallet
class UTXOSetHashTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
- def skip_test_if_missing_module(self):
- self.skip_if_no_wallet()
-
- def test_deterministic_hash_results(self):
- self.log.info("Test deterministic UTXO set hash results")
-
- # These depend on the setup_clean_chain option, the chain loaded from the cache
- assert_equal(self.nodes[0].gettxoutsetinfo()['hash_serialized_2'], "b32ec1dda5a53cd025b95387aad344a801825fe46a60ff952ce26528f01d3be8")
- assert_equal(self.nodes[0].gettxoutsetinfo("muhash")['muhash'], "dd5ad2a105c2d29495f577245c357409002329b9f4d6182c0af3dc2f462555c8")
-
def test_muhash_implementation(self):
self.log.info("Test MuHash implementation consistency")
node = self.nodes[0]
+ wallet = MiniWallet(node)
+ mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
+ node.setmocktime(mocktime)
# Generate 100 blocks and remove the first since we plan to spend its
# coinbase
- block_hashes = node.generate(100)
+ block_hashes = wallet.generate(1) + node.generate(99)
blocks = list(map(lambda block: FromHex(CBlock(), node.getblock(block, False)), block_hashes))
- spending = blocks.pop(0)
+ blocks.pop(0)
# Create a spending transaction and mine a block which includes it
- tx = create_transaction(node, spending.vtx[0].rehash(), node.getnewaddress(), amount=49)
- txid = node.sendrawtransaction(hexstring=tx.serialize_with_witness().hex(), maxfeerate=0)
-
- tx_block = node.generateblock(output=node.getnewaddress(), transactions=[txid])
+ txid = wallet.send_self_transfer(from_node=node)['txid']
+ tx_block = node.generateblock(output=wallet.get_address(), transactions=[txid])
blocks.append(FromHex(CBlock(), node.getblock(tx_block['hash'], False)))
# Serialize the outputs that should be in the UTXO set and add them to
@@ -77,8 +68,11 @@ class UTXOSetHashTest(BitcoinTestFramework):
assert_equal(finalized[::-1].hex(), node_muhash)
+ self.log.info("Test deterministic UTXO set hash results")
+ assert_equal(node.gettxoutsetinfo()['hash_serialized_2'], "5b1b44097406226c0eb8e1362cd17a1f346522cf9390a8175a57a5262cb1963f")
+ assert_equal(node.gettxoutsetinfo("muhash")['muhash'], "4b8803075d7151d06fad3e88b68ba726886794873fbfa841d12aefb2cc2b881b")
+
def run_test(self):
- self.test_deterministic_hash_results()
self.test_muhash_implementation()
diff --git a/test/functional/interface_rpc.py b/test/functional/interface_rpc.py
index 9c877aaeae..4d5666f414 100755
--- a/test/functional/interface_rpc.py
+++ b/test/functional/interface_rpc.py
@@ -8,6 +8,9 @@ import os
from test_framework.authproxy import JSONRPCException
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_greater_than_or_equal
+from threading import Thread
+import subprocess
+
def expect_http_status(expected_http_status, expected_rpc_code,
fcn, *args):
@@ -18,6 +21,16 @@ def expect_http_status(expected_http_status, expected_rpc_code,
assert_equal(exc.error["code"], expected_rpc_code)
assert_equal(exc.http_status, expected_http_status)
+
+def test_work_queue_getblock(node, got_exceeded_error):
+ while not got_exceeded_error:
+ try:
+ node.cli('getrpcinfo').send_cli()
+ except subprocess.CalledProcessError as e:
+ assert_equal(e.output, 'error: Server response: Work queue depth exceeded\n')
+ got_exceeded_error.append(True)
+
+
class RPCInterfaceTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
@@ -67,10 +80,23 @@ class RPCInterfaceTest(BitcoinTestFramework):
expect_http_status(404, -32601, self.nodes[0].invalidmethod)
expect_http_status(500, -8, self.nodes[0].getblockhash, 42)
+ def test_work_queue_exceeded(self):
+ self.log.info("Testing work queue exceeded...")
+ self.restart_node(0, ['-rpcworkqueue=1', '-rpcthreads=1'])
+ got_exceeded_error = []
+ threads = []
+ for _ in range(3):
+ t = Thread(target=test_work_queue_getblock, args=(self.nodes[0], got_exceeded_error))
+ t.start()
+ threads.append(t)
+ for t in threads:
+ t.join()
+
def run_test(self):
self.test_getrpcinfo()
self.test_batch_request()
self.test_http_status_codes()
+ self.test_work_queue_exceeded()
if __name__ == '__main__':
diff --git a/test/functional/mempool_package_onemore.py b/test/functional/mempool_package_onemore.py
index a9e2b000fb..884a2fef11 100755
--- a/test/functional/mempool_package_onemore.py
+++ b/test/functional/mempool_package_onemore.py
@@ -80,7 +80,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
self.chain_transaction(self.nodes[0], [second_chain], [0], second_chain_value, fee, 1)
# Make sure we can RBF the chain which used our carve-out rule
- second_tx_outputs = {self.nodes[0].getrawtransaction(replacable_txid, True)["vout"][0]['scriptPubKey']['addresses'][0]: replacable_orig_value - (Decimal(1) / Decimal(100))}
+ second_tx_outputs = {self.nodes[0].getrawtransaction(replacable_txid, True)["vout"][0]['scriptPubKey']['address']: replacable_orig_value - (Decimal(1) / Decimal(100))}
second_tx = self.nodes[0].createrawtransaction([{'txid': chain[0][0], 'vout': 1}], second_tx_outputs)
signed_second_tx = self.nodes[0].signrawtransactionwithwallet(second_tx)
self.nodes[0].sendrawtransaction(signed_second_tx['hex'])
diff --git a/test/functional/p2p_feefilter.py b/test/functional/p2p_feefilter.py
index a2a122b352..52dc4de3bd 100755
--- a/test/functional/p2p_feefilter.py
+++ b/test/functional/p2p_feefilter.py
@@ -61,6 +61,7 @@ class FeeFilterTest(BitcoinTestFramework):
def run_test(self):
self.test_feefilter_forcerelay()
self.test_feefilter()
+ self.test_feefilter_blocksonly()
def test_feefilter_forcerelay(self):
self.log.info('Check that peers without forcerelay permission (default) get a feefilter message')
@@ -119,6 +120,19 @@ class FeeFilterTest(BitcoinTestFramework):
conn.wait_for_invs_to_match(txids)
conn.clear_invs()
+ def test_feefilter_blocksonly(self):
+ """Test that we don't send fee filters to block-relay-only peers and when we're in blocksonly mode."""
+ self.log.info("Check that we don't send fee filters to block-relay-only peers.")
+ feefilter_peer = self.nodes[0].add_outbound_p2p_connection(FeefilterConn(), p2p_idx=0, connection_type="block-relay-only")
+ feefilter_peer.sync_with_ping()
+ feefilter_peer.assert_feefilter_received(False)
+
+ self.log.info("Check that we don't send fee filters when in blocksonly mode.")
+ self.restart_node(0, ["-blocksonly"])
+ feefilter_peer = self.nodes[0].add_p2p_connection(FeefilterConn())
+ feefilter_peer.sync_with_ping()
+ feefilter_peer.assert_feefilter_received(False)
+
if __name__ == '__main__':
FeeFilterTest().main()
diff --git a/test/functional/p2p_filter.py b/test/functional/p2p_filter.py
index 8f64419138..4bee33f825 100755
--- a/test/functional/p2p_filter.py
+++ b/test/functional/p2p_filter.py
@@ -130,7 +130,7 @@ class FilterTest(BitcoinTestFramework):
filter_peer = P2PBloomFilter()
self.log.debug("Create a tx relevant to the peer before connecting")
- filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0]
+ filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
txid = self.nodes[0].sendtoaddress(filter_address, 90)
self.log.debug("Send a mempool msg after connecting and check that the tx is received")
@@ -142,7 +142,7 @@ class FilterTest(BitcoinTestFramework):
def test_frelay_false(self, filter_peer):
self.log.info("Check that a node with fRelay set to false does not receive invs until the filter is set")
filter_peer.tx_received = False
- filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0]
+ filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
self.nodes[0].sendtoaddress(filter_address, 90)
# Sync to make sure the reason filter_peer doesn't receive the tx is not p2p delays
filter_peer.sync_with_ping()
@@ -156,7 +156,7 @@ class FilterTest(BitcoinTestFramework):
filter_peer.send_and_ping(filter_peer.watch_filter_init)
# If fRelay is not already True, sending filterload sets it to True
assert self.nodes[0].getpeerinfo()[0]['relaytxes']
- filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['addresses'][0]
+ filter_address = self.nodes[0].decodescript(filter_peer.watch_script_pubkey)['address']
self.log.info('Check that we receive merkleblock and tx if the filter matches a tx in a block')
block_hash = self.nodes[0].generatetoaddress(1, filter_address)[0]
diff --git a/test/functional/rpc_addresses_deprecation.py b/test/functional/rpc_addresses_deprecation.py
new file mode 100644
index 0000000000..bc0559f3b5
--- /dev/null
+++ b/test/functional/rpc_addresses_deprecation.py
@@ -0,0 +1,58 @@
+#!/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 reqSigs and addresses RPC fields."""
+
+from io import BytesIO
+
+from test_framework.messages import CTransaction
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import (
+ assert_equal,
+ hex_str_to_bytes
+)
+
+
+class AddressesDeprecationTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 2
+ self.extra_args = [[], ["-deprecatedrpc=addresses"]]
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ def run_test(self):
+ self.test_addresses_deprecation()
+
+ def test_addresses_deprecation(self):
+ node = self.nodes[0]
+ coin = node.listunspent().pop()
+
+ inputs = [{'txid': coin['txid'], 'vout': coin['vout']}]
+ outputs = {node.getnewaddress(): 0.99}
+ raw = node.createrawtransaction(inputs, outputs)
+ signed = node.signrawtransactionwithwallet(raw)['hex']
+
+ # This transaction is derived from test/util/data/txcreatemultisig1.json
+ tx = CTransaction()
+ tx.deserialize(BytesIO(hex_str_to_bytes(signed)))
+ tx.vout[0].scriptPubKey = hex_str_to_bytes("522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae")
+ tx_signed = node.signrawtransactionwithwallet(tx.serialize().hex())['hex']
+ txid = node.sendrawtransaction(hexstring=tx_signed, maxfeerate=0)
+
+ self.log.info("Test RPCResult scriptPubKey no longer returns the fields addresses or reqSigs by default")
+ hash = node.generateblock(output=node.getnewaddress(), transactions=[txid])['hash']
+ # Ensure both nodes have the newly generated block on disk.
+ self.sync_blocks()
+ script_pub_key = node.getblock(blockhash=hash, verbose=2)['tx'][-1]['vout'][0]['scriptPubKey']
+ assert 'addresses' not in script_pub_key and 'reqSigs' not in script_pub_key
+
+ self.log.info("Test RPCResult scriptPubKey returns the addresses field with -deprecatedrpc=addresses")
+ script_pub_key = self.nodes[1].getblock(blockhash=hash, verbose=2)['tx'][-1]['vout'][0]['scriptPubKey']
+ assert_equal(script_pub_key['addresses'], ['mvKDK6D54HU8wQumJBLHY95eq5iHFqXSBz', 'mv3rHCQSwKp2BLSuMHD8uCS32LW5xiNAA5', 'mirrsyhAQYzo5CwVhcaYJKwUJu1WJRCRJe'])
+ assert_equal(script_pub_key['reqSigs'], 2)
+
+
+if __name__ == "__main__":
+ AddressesDeprecationTest().main()
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index 31baeba582..19f0d5765a 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -165,7 +165,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
txid = node0.sendtoaddress(madd, 40)
tx = node0.getrawtransaction(txid, True)
- vout = [v["n"] for v in tx["vout"] if madd in v["scriptPubKey"].get("addresses", [])]
+ vout = [v["n"] for v in tx["vout"] if madd == v["scriptPubKey"]["address"]]
assert len(vout) == 1
vout = vout[0]
scriptPubKey = tx["vout"][vout]["scriptPubKey"]["hex"]
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 6b300e7231..5129ecb895 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -32,6 +32,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# This test isn't testing tx relay. Set whitelist on the peers for
# instant tx relay.
self.extra_args = [['-whitelist=noban@127.0.0.1']] * self.num_nodes
+ self.rpc_timeout = 90 # to prevent timeouts in `test_transaction_too_large`
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
@@ -247,7 +248,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx, {'changeAddress': change, 'changePosition': 0})
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
out = dec_tx['vout'][0]
- assert_equal(change, out['scriptPubKey']['addresses'][0])
+ assert_equal(change, out['scriptPubKey']['address'])
def test_change_type(self):
self.log.info("Test fundrawtxn with a provided change type")
@@ -287,7 +288,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for i, out in enumerate(dec_tx['vout']):
totalOut += out['value']
- if out['scriptPubKey']['addresses'][0] in outputs:
+ if out['scriptPubKey']['address'] in outputs:
matchingOuts+=1
else:
assert_equal(i, rawtxfund['changepos'])
@@ -318,7 +319,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
- if out['scriptPubKey']['addresses'][0] in outputs:
+ if out['scriptPubKey']['address'] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 1)
@@ -352,7 +353,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
- if out['scriptPubKey']['addresses'][0] in outputs:
+ if out['scriptPubKey']['address'] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 2)
@@ -801,7 +802,7 @@ class RawTransactionsTest(BitcoinTestFramework):
changeaddress = ""
for out in res_dec['vout']:
if out['value'] > 1.0:
- changeaddress += out['scriptPubKey']['addresses'][0]
+ changeaddress += out['scriptPubKey']['address']
assert changeaddress != ""
nextaddr = self.nodes[3].getnewaddress()
# Now the change address key should be removed from the keypool.
@@ -910,22 +911,23 @@ class RawTransactionsTest(BitcoinTestFramework):
def test_transaction_too_large(self):
self.log.info("Test fundrawtx where BnB solution would result in a too large transaction, but Knapsack would not")
-
self.nodes[0].createwallet("large")
wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
recipient = self.nodes[0].get_wallet_rpc("large")
outputs = {}
rawtx = recipient.createrawtransaction([], {wallet.getnewaddress(): 147.99899260})
- # Make 1500 0.1 BTC outputs
- # The amount that we target for funding is in the BnB range when these outputs are used.
- # However if these outputs are selected, the transaction will end up being too large, so it shouldn't use BnB and instead fallback to Knapsack
- # but that behavior is not implemented yet. For now we just check that we get an error.
- for i in range(0, 1500):
+ # Make 1500 0.1 BTC outputs. The amount that we target for funding is in
+ # the BnB range when these outputs are used. However if these outputs
+ # are selected, the transaction will end up being too large, so it
+ # shouldn't use BnB and instead fall back to Knapsack but that behavior
+ # is not implemented yet. For now we just check that we get an error.
+ for _ in range(1500):
outputs[recipient.getnewaddress()] = 0.1
wallet.sendmany("", outputs)
self.nodes[0].generate(10)
assert_raises_rpc_error(-4, "Transaction too large", recipient.fundrawtransaction, rawtx)
+
if __name__ == '__main__':
RawTransactionsTest().main()
diff --git a/test/functional/rpc_generateblock.py b/test/functional/rpc_generateblock.py
index 08ff0fba50..7424416484 100755
--- a/test/functional/rpc_generateblock.py
+++ b/test/functional/rpc_generateblock.py
@@ -27,13 +27,13 @@ class GenerateBlockTest(BitcoinTestFramework):
hash = node.generateblock(output=address, transactions=[])['hash']
block = node.getblock(blockhash=hash, verbose=2)
assert_equal(len(block['tx']), 1)
- assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], address)
+ assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], address)
self.log.info('Generate an empty block to a descriptor')
hash = node.generateblock('addr(' + address + ')', [])['hash']
block = node.getblock(blockhash=hash, verbosity=2)
assert_equal(len(block['tx']), 1)
- assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], address)
+ assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], address)
self.log.info('Generate an empty block to a combo descriptor with compressed pubkey')
combo_key = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'
@@ -41,7 +41,7 @@ class GenerateBlockTest(BitcoinTestFramework):
hash = node.generateblock('combo(' + combo_key + ')', [])['hash']
block = node.getblock(hash, 2)
assert_equal(len(block['tx']), 1)
- assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], combo_address)
+ assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], combo_address)
self.log.info('Generate an empty block to a combo descriptor with uncompressed pubkey')
combo_key = '0408ef68c46d20596cc3f6ddf7c8794f71913add807f1dc55949fa805d764d191c0b7ce6894c126fce0babc6663042f3dde9b0cf76467ea315514e5a6731149c67'
@@ -49,7 +49,7 @@ class GenerateBlockTest(BitcoinTestFramework):
hash = node.generateblock('combo(' + combo_key + ')', [])['hash']
block = node.getblock(hash, 2)
assert_equal(len(block['tx']), 1)
- assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['addresses'][0], combo_address)
+ assert_equal(block['tx'][0]['vout'][0]['scriptPubKey']['address'], combo_address)
# Generate 110 blocks to spend
node.generatetoaddress(110, address)
diff --git a/test/functional/rpc_invalid_address_message.py b/test/functional/rpc_invalid_address_message.py
index 469d6bdb05..e362642f0f 100755
--- a/test/functional/rpc_invalid_address_message.py
+++ b/test/functional/rpc_invalid_address_message.py
@@ -12,8 +12,12 @@ from test_framework.util import (
)
BECH32_VALID = 'bcrt1qtmp74ayg7p24uslctssvjm06q5phz4yrxucgnv'
-BECH32_INVALID_SIZE = 'bcrt1sqqpl9r5c'
-BECH32_INVALID_PREFIX = 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'
+BECH32_INVALID_BECH32 = 'bcrt1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqdmchcc'
+BECH32_INVALID_BECH32M = 'bcrt1qw508d6qejxtdg4y5r3zarvary0c5xw7k35mrzd'
+BECH32_INVALID_VERSION = 'bcrt130xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqynjegk'
+BECH32_INVALID_SIZE = 'bcrt1s0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7v8n0nx0muaewav25430mtr'
+BECH32_INVALID_V0_SIZE = 'bcrt1qw508d6qejxtdg4y5r3zarvary0c5xw7kqqq5k3my'
+BECH32_INVALID_PREFIX = 'bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx'
BASE58_VALID = 'mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn'
BASE58_INVALID_PREFIX = '17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem'
@@ -40,6 +44,18 @@ class InvalidAddressErrorMessageTest(BitcoinTestFramework):
assert not info['isvalid']
assert_equal(info['error'], 'Invalid prefix for Bech32 address')
+ info = node.validateaddress(BECH32_INVALID_BECH32)
+ assert not info['isvalid']
+ assert_equal(info['error'], 'Version 1+ witness address must use Bech32m checksum')
+
+ info = node.validateaddress(BECH32_INVALID_BECH32M)
+ assert not info['isvalid']
+ assert_equal(info['error'], 'Version 0 witness address must use Bech32 checksum')
+
+ info = node.validateaddress(BECH32_INVALID_V0_SIZE)
+ assert not info['isvalid']
+ assert_equal(info['error'], 'Invalid Bech32 v0 address data size')
+
info = node.validateaddress(BECH32_VALID)
assert info['isvalid']
assert 'error' not in info
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index ed6abaed78..079a3bd3ba 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -158,17 +158,17 @@ class PSBTTest(BitcoinTestFramework):
p2sh_p2wpkh_pos = -1
decoded = self.nodes[0].decoderawtransaction(signed_tx)
for out in decoded['vout']:
- if out['scriptPubKey']['addresses'][0] == p2sh:
+ if out['scriptPubKey']['address'] == p2sh:
p2sh_pos = out['n']
- elif out['scriptPubKey']['addresses'][0] == p2wsh:
+ elif out['scriptPubKey']['address'] == p2wsh:
p2wsh_pos = out['n']
- elif out['scriptPubKey']['addresses'][0] == p2wpkh:
+ elif out['scriptPubKey']['address'] == p2wpkh:
p2wpkh_pos = out['n']
- elif out['scriptPubKey']['addresses'][0] == p2sh_p2wsh:
+ elif out['scriptPubKey']['address'] == p2sh_p2wsh:
p2sh_p2wsh_pos = out['n']
- elif out['scriptPubKey']['addresses'][0] == p2sh_p2wpkh:
+ elif out['scriptPubKey']['address'] == p2sh_p2wpkh:
p2sh_p2wpkh_pos = out['n']
- elif out['scriptPubKey']['addresses'][0] == p2pkh:
+ elif out['scriptPubKey']['address'] == p2pkh:
p2pkh_pos = out['n']
inputs = [{"txid": txid, "vout": p2wpkh_pos}, {"txid": txid, "vout": p2sh_p2wpkh_pos}, {"txid": txid, "vout": p2pkh_pos}]
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index a18a9ec109..5a9736a7a3 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -1045,13 +1045,11 @@ class msg_version:
self.nStartingHeight = struct.unpack("<i", f.read(4))[0]
- if self.nVersion >= 70001:
- # Relay field is optional for version 70001 onwards
- try:
- self.relay = struct.unpack("<b", f.read(1))[0]
- except:
- self.relay = 0
- else:
+ # Relay field is optional for version 70001 onwards
+ # But, unconditionally check it to match behaviour in bitcoind
+ try:
+ self.relay = struct.unpack("<b", f.read(1))[0]
+ except struct.error:
self.relay = 0
def serialize(self):
diff --git a/test/functional/test_framework/segwit_addr.py b/test/functional/test_framework/segwit_addr.py
index 00c0d8a919..861ca2b949 100644
--- a/test/functional/test_framework/segwit_addr.py
+++ b/test/functional/test_framework/segwit_addr.py
@@ -2,10 +2,18 @@
# Copyright (c) 2017 Pieter Wuille
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
-"""Reference implementation for Bech32 and segwit addresses."""
+"""Reference implementation for Bech32/Bech32m and segwit addresses."""
import unittest
+from enum import Enum
CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+BECH32_CONST = 1
+BECH32M_CONST = 0x2bc830a3
+
+class Encoding(Enum):
+ """Enumeration type to list the various supported encodings."""
+ BECH32 = 1
+ BECH32M = 2
def bech32_polymod(values):
@@ -27,38 +35,45 @@ def bech32_hrp_expand(hrp):
def bech32_verify_checksum(hrp, data):
"""Verify a checksum given HRP and converted data characters."""
- return bech32_polymod(bech32_hrp_expand(hrp) + data) == 1
-
+ check = bech32_polymod(bech32_hrp_expand(hrp) + data)
+ if check == BECH32_CONST:
+ return Encoding.BECH32
+ elif check == BECH32M_CONST:
+ return Encoding.BECH32M
+ else:
+ return None
-def bech32_create_checksum(hrp, data):
+def bech32_create_checksum(encoding, hrp, data):
"""Compute the checksum values given HRP and data."""
values = bech32_hrp_expand(hrp) + data
- polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ 1
+ const = BECH32M_CONST if encoding == Encoding.BECH32M else BECH32_CONST
+ polymod = bech32_polymod(values + [0, 0, 0, 0, 0, 0]) ^ const
return [(polymod >> 5 * (5 - i)) & 31 for i in range(6)]
-def bech32_encode(hrp, data):
- """Compute a Bech32 string given HRP and data values."""
- combined = data + bech32_create_checksum(hrp, data)
+def bech32_encode(encoding, hrp, data):
+ """Compute a Bech32 or Bech32m string given HRP and data values."""
+ combined = data + bech32_create_checksum(encoding, hrp, data)
return hrp + '1' + ''.join([CHARSET[d] for d in combined])
def bech32_decode(bech):
- """Validate a Bech32 string, and determine HRP and data."""
+ """Validate a Bech32/Bech32m string, and determine HRP and data."""
if ((any(ord(x) < 33 or ord(x) > 126 for x in bech)) or
(bech.lower() != bech and bech.upper() != bech)):
- return (None, None)
+ return (None, None, None)
bech = bech.lower()
pos = bech.rfind('1')
if pos < 1 or pos + 7 > len(bech) or len(bech) > 90:
- return (None, None)
+ return (None, None, None)
if not all(x in CHARSET for x in bech[pos+1:]):
- return (None, None)
+ return (None, None, None)
hrp = bech[:pos]
data = [CHARSET.find(x) for x in bech[pos+1:]]
- if not bech32_verify_checksum(hrp, data):
- return (None, None)
- return (hrp, data[:-6])
+ encoding = bech32_verify_checksum(hrp, data)
+ if encoding is None:
+ return (None, None, None)
+ return (encoding, hrp, data[:-6])
def convertbits(data, frombits, tobits, pad=True):
@@ -86,7 +101,7 @@ def convertbits(data, frombits, tobits, pad=True):
def decode_segwit_address(hrp, addr):
"""Decode a segwit address."""
- hrpgot, data = bech32_decode(addr)
+ encoding, hrpgot, data = bech32_decode(addr)
if hrpgot != hrp:
return (None, None)
decoded = convertbits(data[1:], 5, 8, False)
@@ -96,12 +111,15 @@ def decode_segwit_address(hrp, addr):
return (None, None)
if data[0] == 0 and len(decoded) != 20 and len(decoded) != 32:
return (None, None)
+ if (data[0] == 0 and encoding != Encoding.BECH32) or (data[0] != 0 and encoding != Encoding.BECH32M):
+ return (None, None)
return (data[0], decoded)
def encode_segwit_address(hrp, witver, witprog):
"""Encode a segwit address."""
- ret = bech32_encode(hrp, [witver] + convertbits(witprog, 8, 5))
+ encoding = Encoding.BECH32 if witver == 0 else Encoding.BECH32M
+ ret = bech32_encode(encoding, hrp, [witver] + convertbits(witprog, 8, 5))
if decode_segwit_address(hrp, ret) == (None, None):
return None
return ret
@@ -119,3 +137,5 @@ class TestFrameworkScript(unittest.TestCase):
# P2WSH
test_python_bech32('bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj')
test_python_bech32('bcrt1qft5p2uhsdcdc3l2ua4ap5qqfg4pjaqlp250x7us7a8qqhrxrxfsqseac85')
+ # P2TR
+ test_python_bech32('bcrt1p0xlxvlhemja6c4dqv22uapctqupfhlxm9h8z3k2e72q4k9hcz7vqc8gma6')
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index d335d4ea79..5c774934be 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -543,7 +543,7 @@ def find_vout_for_address(node, txid, addr):
"""
tx = node.getrawtransaction(txid, True)
for i in range(len(tx["vout"])):
- if any([addr == a for a in tx["vout"][i]["scriptPubKey"]["addresses"]]):
+ if addr == tx["vout"][i]["scriptPubKey"]["address"]:
return i
raise RuntimeError("Vout not found for address: txid=%s, addr=%s" % (txid, addr))
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index 38fbf3c1a6..a906a21dd0 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -49,6 +49,9 @@ class MiniWallet:
self._utxos.append({'txid': cb_tx['txid'], 'vout': 0, 'value': cb_tx['vout'][0]['value']})
return blocks
+ def get_address(self):
+ return self._address
+
def get_utxo(self, *, txid=''):
"""
Returns a utxo and marks it as spent (pops it from the internal list)
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 79ad2cf161..001d161612 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -279,6 +279,7 @@ BASE_SCRIPTS = [
'p2p_ping.py',
'rpc_scantxoutset.py',
'feature_logging.py',
+ 'feature_anchors.py',
'p2p_node_network_limited.py',
'p2p_permissions.py',
'feature_blocksdir.py',
@@ -286,6 +287,7 @@ BASE_SCRIPTS = [
'feature_config_args.py',
'feature_settings.py',
'rpc_getdescriptorinfo.py',
+ 'rpc_addresses_deprecation.py',
'rpc_help.py',
'feature_help.py',
'feature_shutdown.py',
diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py
index 2db5eae33b..b3bee1876d 100755
--- a/test/functional/wallet_address_types.py
+++ b/test/functional/wallet_address_types.py
@@ -210,7 +210,7 @@ class AddressTypeTest(BitcoinTestFramework):
assert_equal(len(tx["vout"]), len(destinations) + 1)
# Make sure the destinations are included, and remove them:
- output_addresses = [vout['scriptPubKey']['addresses'][0] for vout in tx["vout"]]
+ output_addresses = [vout['scriptPubKey']['address'] for vout in tx["vout"]]
change_addresses = [d for d in output_addresses if d not in destinations]
assert_equal(len(change_addresses), 1)
diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py
index bc4fa90e83..1d3736d9b1 100755
--- a/test/functional/wallet_avoidreuse.py
+++ b/test/functional/wallet_avoidreuse.py
@@ -253,7 +253,7 @@ class AvoidReuseTest(BitcoinTestFramework):
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]
+ new_fundaddr = fund_decoded["segwit"]["address"]
else:
new_fundaddr = fundaddr
assert_equal(second_addr_type, "legacy")
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 4a589f0393..dc6f8ed9c4 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -600,7 +600,7 @@ class WalletTest(BitcoinTestFramework):
destination = self.nodes[1].getnewaddress()
txid = self.nodes[0].sendtoaddress(destination, 0.123)
tx = self.nodes[0].decoderawtransaction(self.nodes[0].gettransaction(txid)['hex'])
- output_addresses = [vout['scriptPubKey']['addresses'][0] for vout in tx["vout"]]
+ output_addresses = [vout['scriptPubKey']['address'] for vout in tx["vout"]]
assert len(output_addresses) > 1
for address in output_addresses:
ischange = self.nodes[0].getaddressinfo(address)['ischange']
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index 5fc8438e8f..0d1b6c54ce 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -535,7 +535,7 @@ def test_change_script_match(self, rbf_node, dest_address):
def get_change_address(tx):
tx_details = rbf_node.getrawtransaction(tx, 1)
- txout_addresses = [txout['scriptPubKey']['addresses'][0] for txout in tx_details["vout"]]
+ txout_addresses = [txout['scriptPubKey']['address'] for txout in tx_details["vout"]]
return [address for address in txout_addresses if rbf_node.getaddressinfo(address)["ischange"]]
# Check that there is only one change output
diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py
index e5c4f12f20..c0b76d960f 100755
--- a/test/functional/wallet_groups.py
+++ b/test/functional/wallet_groups.py
@@ -29,8 +29,9 @@ class WalletGroupTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def run_test(self):
+ self.log.info("Setting up")
# Mine some coins
- self.nodes[0].generate(110)
+ self.nodes[0].generate(101)
# Get some addresses from the two nodes
addr1 = [self.nodes[1].getnewaddress() for _ in range(3)]
@@ -48,6 +49,7 @@ class WalletGroupTest(BitcoinTestFramework):
# - node[1] should pick one 0.5 UTXO and leave the rest
# - node[2] should pick one (1.0 + 0.5) UTXO group corresponding to a
# given address, and leave the rest
+ self.log.info("Test sending transactions picks one UTXO group and leaves the rest")
txid1 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
tx1 = self.nodes[1].getrawtransaction(txid1, True)
# txid1 should have 1 input and 2 outputs
@@ -70,7 +72,7 @@ class WalletGroupTest(BitcoinTestFramework):
assert_approx(v[0], vexp=0.2, vspan=0.0001)
assert_approx(v[1], vexp=1.3, vspan=0.0001)
- # Test 'avoid partial if warranted, even if disabled'
+ self.log.info("Test avoiding partial spends if warranted, even if avoidpartialspends is disabled")
self.sync_all()
self.nodes[0].generate(1)
# Nodes 1-2 now have confirmed UTXOs (letters denote destinations):
@@ -104,7 +106,7 @@ class WalletGroupTest(BitcoinTestFramework):
assert_equal(input_addrs[0], input_addrs[1])
# Node 2 enforces avoidpartialspends so needs no checking here
- # Test wallet option maxapsfee with Node 3
+ self.log.info("Test wallet option maxapsfee")
addr_aps = self.nodes[3].getnewaddress()
self.nodes[0].sendtoaddress(addr_aps, 1.0)
self.nodes[0].sendtoaddress(addr_aps, 1.0)
@@ -131,6 +133,7 @@ class WalletGroupTest(BitcoinTestFramework):
# Test wallet option maxapsfee with node 4, which sets maxapsfee
# 1 sat higher, crossing the threshold from non-grouped to grouped.
+ self.log.info("Test wallet option maxapsfee threshold from non-grouped to grouped")
addr_aps3 = self.nodes[4].getnewaddress()
[self.nodes[0].sendtoaddress(addr_aps3, 1.0) for _ in range(5)]
self.nodes[0].generate(1)
@@ -147,8 +150,7 @@ class WalletGroupTest(BitcoinTestFramework):
self.sync_all()
self.nodes[0].generate(1)
- # Fill node2's wallet with 10000 outputs corresponding to the same
- # scriptPubKey
+ self.log.info("Fill a wallet with 10,000 outputs corresponding to the same scriptPubKey")
for _ in range(5):
raw_tx = self.nodes[0].createrawtransaction([{"txid":"0"*64, "vout":0}], [{addr2[0]: 0.05}])
tx = FromHex(CTransaction(), raw_tx)
@@ -158,12 +160,12 @@ class WalletGroupTest(BitcoinTestFramework):
signed_tx = self.nodes[0].signrawtransactionwithwallet(funded_tx['hex'])
self.nodes[0].sendrawtransaction(signed_tx['hex'])
self.nodes[0].generate(1)
-
- self.sync_all()
+ self.sync_all()
# Check that we can create a transaction that only requires ~100 of our
# utxos, without pulling in all outputs and creating a transaction that
# is way too big.
+ self.log.info("Test creating txn that only requires ~100 of our UTXOs without pulling in all outputs")
assert self.nodes[2].sendtoaddress(address=addr2[0], amount=5)
diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py
index d45cf05689..23d132df41 100755
--- a/test/functional/wallet_hd.py
+++ b/test/functional/wallet_hd.py
@@ -132,7 +132,7 @@ class WalletHDTest(BitcoinTestFramework):
keypath = ""
for out in outs:
if out['value'] != 1:
- keypath = self.nodes[1].getaddressinfo(out['scriptPubKey']['addresses'][0])['hdkeypath']
+ keypath = self.nodes[1].getaddressinfo(out['scriptPubKey']['address'])['hdkeypath']
if self.options.descriptors:
assert_equal(keypath[0:14], "m/84'/1'/0'/1/")
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
index 883b97561e..551eb72720 100755
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -138,13 +138,13 @@ class WalletLabelsTest(BitcoinTestFramework):
node.createwallet(wallet_name='watch_only', disable_private_keys=True)
wallet_watch_only = node.get_wallet_rpc('watch_only')
BECH32_VALID = {
- '✔️_VER15_PROG40': 'bcrt10qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqn2cjv3',
- '✔️_VER16_PROG03': 'bcrt1sqqqqqjq8pdp',
- '✔️_VER16_PROB02': 'bcrt1sqqqqqjq8pv',
+ '✔️_VER15_PROG40': 'bcrt10qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxkg7fn',
+ '✔️_VER16_PROG03': 'bcrt1sqqqqq8uhdgr',
+ '✔️_VER16_PROB02': 'bcrt1sqqqq4wstyw',
}
BECH32_INVALID = {
- '❌_VER15_PROG41': 'bcrt10qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqzc7xyq',
- '❌_VER16_PROB01': 'bcrt1sqqpl9r5c',
+ '❌_VER15_PROG41': 'bcrt1sqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqajlxj8',
+ '❌_VER16_PROB01': 'bcrt1sqq5r4036',
}
for l in BECH32_VALID:
ad = BECH32_VALID[l]
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index bf24b9c7b3..71d1b96a95 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -34,7 +34,7 @@ def test_load_unload(node, name):
node.loadwallet(name)
node.unloadwallet(name)
except JSONRPCException as e:
- if e.error['code'] == -4 and 'Wallet already being loading' in e.error['message']:
+ if e.error['code'] == -4 and 'Wallet already loading' in e.error['message']:
got_loading_error = True
return
diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py
index 880341fdd9..53553dcd80 100755
--- a/test/functional/wallet_send.py
+++ b/test/functional/wallet_send.py
@@ -389,10 +389,10 @@ class WalletSendTest(BitcoinTestFramework):
assert res["complete"]
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, add_to_wallet=False, change_address=change_address, change_position=0)
assert res["complete"]
- assert_equal(self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["addresses"], [change_address])
+ assert_equal(self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["address"], change_address)
res = self.test_send(from_wallet=w0, to_wallet=w1, amount=1, add_to_wallet=False, change_type="legacy", change_position=0)
assert res["complete"]
- change_address = self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["addresses"][0]
+ change_address = self.nodes[0].decodepsbt(res["psbt"])["tx"]["vout"][0]["scriptPubKey"]["address"]
assert change_address[0] == "m" or change_address[0] == "n"
self.log.info("Set lock time...")
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index 6fc1d13c53..84ff9ad772 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -65,8 +65,8 @@ class TxnMallTest(BitcoinTestFramework):
# Construct a clone of tx1, to be malleated
rawtx1 = self.nodes[0].getrawtransaction(txid1, 1)
clone_inputs = [{"txid": rawtx1["vin"][0]["txid"], "vout": rawtx1["vin"][0]["vout"], "sequence": rawtx1["vin"][0]["sequence"]}]
- clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][0]["value"],
- rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][1]["value"]}
+ clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["address"]: rawtx1["vout"][0]["value"],
+ rawtx1["vout"][1]["scriptPubKey"]["address"]: rawtx1["vout"][1]["value"]}
clone_locktime = rawtx1["locktime"]
clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime)
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index 611061072f..eeff7a4515 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -27,7 +27,7 @@ def get_fuzz_env(*, target, source_dir):
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
- description='''Run the fuzz targets with all inputs from the seed_dir once.''',
+ description='''Run the fuzz targets with all inputs from the corpus_dir once.''',
)
parser.add_argument(
"-l",
@@ -54,8 +54,8 @@ def main():
help='How many targets to merge or execute in parallel.',
)
parser.add_argument(
- 'seed_dir',
- help='The seed corpus to run on (must contain subfolders for each fuzz target).',
+ 'corpus_dir',
+ help='The corpus to run on (must contain subfolders for each fuzz target).',
)
parser.add_argument(
'target',
@@ -64,15 +64,15 @@ def main():
)
parser.add_argument(
'--m_dir',
- help='Merge inputs from this directory into the seed_dir.',
+ help='Merge inputs from this directory into the corpus_dir.',
)
parser.add_argument(
'-g',
'--generate',
action='store_true',
- help='Create new corpus seeds (or extend the existing ones) by running'
+ help='Create new corpus (or extend the existing ones) by running'
' the given targets for a finite number of times. Outputs them to'
- ' the passed seed_dir.'
+ ' the passed corpus_dir.'
)
args = parser.parse_args()
@@ -119,19 +119,19 @@ def main():
logging.info("{} of {} detected fuzz target(s) selected: {}".format(len(test_list_selection), len(test_list_all), " ".join(test_list_selection)))
if not args.generate:
- test_list_seedless = []
+ test_list_missing_corpus = []
for t in test_list_selection:
- corpus_path = os.path.join(args.seed_dir, t)
+ corpus_path = os.path.join(args.corpus_dir, t)
if not os.path.exists(corpus_path) or len(os.listdir(corpus_path)) == 0:
- test_list_seedless.append(t)
- test_list_seedless.sort()
- if test_list_seedless:
+ test_list_missing_corpus.append(t)
+ test_list_missing_corpus.sort()
+ if test_list_missing_corpus:
logging.info(
- "Fuzzing harnesses lacking a seed corpus: {}".format(
- " ".join(test_list_seedless)
+ "Fuzzing harnesses lacking a corpus: {}".format(
+ " ".join(test_list_missing_corpus)
)
)
- logging.info("Please consider adding a fuzz seed corpus at https://github.com/bitcoin-core/qa-assets")
+ logging.info("Please consider adding a fuzz corpus at https://github.com/bitcoin-core/qa-assets")
try:
help_output = subprocess.run(
@@ -154,18 +154,18 @@ def main():
with ThreadPoolExecutor(max_workers=args.par) as fuzz_pool:
if args.generate:
- return generate_corpus_seeds(
+ return generate_corpus(
fuzz_pool=fuzz_pool,
src_dir=config['environment']['SRCDIR'],
build_dir=config["environment"]["BUILDDIR"],
- seed_dir=args.seed_dir,
+ corpus_dir=args.corpus_dir,
targets=test_list_selection,
)
if args.m_dir:
merge_inputs(
fuzz_pool=fuzz_pool,
- corpus=args.seed_dir,
+ corpus=args.corpus_dir,
test_list=test_list_selection,
src_dir=config['environment']['SRCDIR'],
build_dir=config["environment"]["BUILDDIR"],
@@ -175,7 +175,7 @@ def main():
run_once(
fuzz_pool=fuzz_pool,
- corpus=args.seed_dir,
+ corpus=args.corpus_dir,
test_list=test_list_selection,
src_dir=config['environment']['SRCDIR'],
build_dir=config["environment"]["BUILDDIR"],
@@ -183,13 +183,13 @@ def main():
)
-def generate_corpus_seeds(*, fuzz_pool, src_dir, build_dir, seed_dir, targets):
- """Generates new corpus seeds.
+def generate_corpus(*, fuzz_pool, src_dir, build_dir, corpus_dir, targets):
+ """Generates new corpus.
- Run {targets} without input, and outputs the generated corpus seeds to
- {seed_dir}.
+ Run {targets} without input, and outputs the generated corpus to
+ {corpus_dir}.
"""
- logging.info("Generating corpus seeds to {}".format(seed_dir))
+ logging.info("Generating corpus to {}".format(corpus_dir))
def job(command, t):
logging.debug("Running '{}'\n".format(" ".join(command)))
@@ -205,12 +205,12 @@ def generate_corpus_seeds(*, fuzz_pool, src_dir, build_dir, seed_dir, targets):
futures = []
for target in targets:
- target_seed_dir = os.path.join(seed_dir, target)
- os.makedirs(target_seed_dir, exist_ok=True)
+ target_corpus_dir = os.path.join(corpus_dir, target)
+ os.makedirs(target_corpus_dir, exist_ok=True)
command = [
os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
"-runs=100000",
- target_seed_dir,
+ target_corpus_dir,
]
futures.append(fuzz_pool.submit(job, command, target))
@@ -219,7 +219,7 @@ def generate_corpus_seeds(*, fuzz_pool, src_dir, build_dir, seed_dir, targets):
def merge_inputs(*, fuzz_pool, corpus, test_list, src_dir, build_dir, merge_dir):
- logging.info("Merge the inputs from the passed dir into the seed_dir. Passed dir {}".format(merge_dir))
+ logging.info("Merge the inputs from the passed dir into the corpus_dir. Passed dir {}".format(merge_dir))
jobs = []
for t in test_list:
args = [
diff --git a/test/lint/extended-lint-cppcheck.sh b/test/lint/extended-lint-cppcheck.sh
index b2ed811cda..0ab6aad50c 100755
--- a/test/lint/extended-lint-cppcheck.sh
+++ b/test/lint/extended-lint-cppcheck.sh
@@ -57,7 +57,6 @@ IGNORED_WARNINGS=(
"src/test/checkqueue_tests.cpp:.* Struct 'UniqueCheck' has a constructor with 1 argument that is not explicit."
"src/test/fuzz/util.h:.* Class 'FuzzedFileProvider' has a constructor with 1 argument that is not explicit."
"src/test/fuzz/util.h:.* Class 'FuzzedAutoFileProvider' has a constructor with 1 argument that is not explicit."
- "src/util/ref.h:.* Class 'Ref' has a constructor with 1 argument that is not explicit."
"src/wallet/db.h:.* Class 'BerkeleyEnvironment' has a constructor with 1 argument that is not explicit."
)
diff --git a/test/util/data/tt-delin1-out.json b/test/util/data/tt-delin1-out.json
index 9fc2ddc376..c5b9f6df01 100644
--- a/test/util/data/tt-delin1-out.json
+++ b/test/util/data/tt-delin1-out.json
@@ -195,11 +195,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o"
- ]
+ "address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
+ "type": "pubkeyhash"
}
},
{
@@ -208,11 +205,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb"
- ]
+ "address": "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb",
+ "type": "pubkeyhash"
}
}
],
diff --git a/test/util/data/tt-delout1-out.json b/test/util/data/tt-delout1-out.json
index 922d048900..3863416430 100644
--- a/test/util/data/tt-delout1-out.json
+++ b/test/util/data/tt-delout1-out.json
@@ -204,11 +204,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o"
- ]
+ "address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
+ "type": "pubkeyhash"
}
}
],
diff --git a/test/util/data/tt-locktime317000-out.json b/test/util/data/tt-locktime317000-out.json
index c97206f1ea..62e785f7d0 100644
--- a/test/util/data/tt-locktime317000-out.json
+++ b/test/util/data/tt-locktime317000-out.json
@@ -204,11 +204,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o"
- ]
+ "address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
+ "type": "pubkeyhash"
}
},
{
@@ -217,11 +214,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb"
- ]
+ "address": "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb",
+ "type": "pubkeyhash"
}
}
],
diff --git a/test/util/data/txcreate1.json b/test/util/data/txcreate1.json
index ca9eacd546..96d77ef273 100644
--- a/test/util/data/txcreate1.json
+++ b/test/util/data/txcreate1.json
@@ -42,11 +42,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
- ]
+ "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "type": "pubkeyhash"
}
},
{
@@ -55,11 +52,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"
- ]
+ "address": "1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46",
+ "type": "pubkeyhash"
}
}
],
diff --git a/test/util/data/txcreatedata1.json b/test/util/data/txcreatedata1.json
index 39909c2e3f..87fc7e9cf7 100644
--- a/test/util/data/txcreatedata1.json
+++ b/test/util/data/txcreatedata1.json
@@ -24,11 +24,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
- ]
+ "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "type": "pubkeyhash"
}
},
{
diff --git a/test/util/data/txcreatedata2.json b/test/util/data/txcreatedata2.json
index 2958006e58..d03b1c8244 100644
--- a/test/util/data/txcreatedata2.json
+++ b/test/util/data/txcreatedata2.json
@@ -24,11 +24,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
- ]
+ "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "type": "pubkeyhash"
}
},
{
diff --git a/test/util/data/txcreatedata_seq0.json b/test/util/data/txcreatedata_seq0.json
index a6656b5ad5..8a123f1ba8 100644
--- a/test/util/data/txcreatedata_seq0.json
+++ b/test/util/data/txcreatedata_seq0.json
@@ -24,11 +24,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
- ]
+ "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "type": "pubkeyhash"
}
}
],
diff --git a/test/util/data/txcreatedata_seq1.json b/test/util/data/txcreatedata_seq1.json
index e5980427b1..006fd7259f 100644
--- a/test/util/data/txcreatedata_seq1.json
+++ b/test/util/data/txcreatedata_seq1.json
@@ -33,11 +33,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
- ]
+ "address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
+ "type": "pubkeyhash"
}
}
],
diff --git a/test/util/data/txcreatemultisig1.json b/test/util/data/txcreatemultisig1.json
index c32e755db1..baa290c2b1 100644
--- a/test/util/data/txcreatemultisig1.json
+++ b/test/util/data/txcreatemultisig1.json
@@ -15,13 +15,7 @@
"scriptPubKey": {
"asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG",
"hex": "522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae",
- "reqSigs": 2,
- "type": "multisig",
- "addresses": [
- "1FoG2386FG2tAJS9acMuiDsKy67aGg9MKz",
- "1FXtz9KU8JNmQDyHdiEm5HDiALuP3zdHvV",
- "14LuavcBbXZYJ6Tsz3cAUQj9SuQoL2xCQX"
- ]
+ "type": "multisig"
}
}
],
diff --git a/test/util/data/txcreatemultisig2.json b/test/util/data/txcreatemultisig2.json
index f97d265894..6685512587 100644
--- a/test/util/data/txcreatemultisig2.json
+++ b/test/util/data/txcreatemultisig2.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL",
"hex": "a9141c6fbaf46d64221e80cbae182c33ddf81b9294ac87",
- "reqSigs": 1,
- "type": "scripthash",
- "addresses": [
- "34HNh57oBCRKkxNyjTuWAJkTbuGh6jg2Ms"
- ]
+ "address": "34HNh57oBCRKkxNyjTuWAJkTbuGh6jg2Ms",
+ "type": "scripthash"
}
}
],
diff --git a/test/util/data/txcreatemultisig3.json b/test/util/data/txcreatemultisig3.json
index b355d7b191..be96f4c704 100644
--- a/test/util/data/txcreatemultisig3.json
+++ b/test/util/data/txcreatemultisig3.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",
"hex": "0020e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",
- "reqSigs": 1,
- "type": "witness_v0_scripthash",
- "addresses": [
- "bc1qu9dgdg330r6r84g5mw7wqshg04exv2uttmw2elfwx74h5tgntuzs44gyfg"
- ]
+ "address": "bc1qu9dgdg330r6r84g5mw7wqshg04exv2uttmw2elfwx74h5tgntuzs44gyfg",
+ "type": "witness_v0_scripthash"
}
}
],
diff --git a/test/util/data/txcreatemultisig4.json b/test/util/data/txcreatemultisig4.json
index a00dbe3f5d..08831ecdca 100644
--- a/test/util/data/txcreatemultisig4.json
+++ b/test/util/data/txcreatemultisig4.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL",
"hex": "a9146edf12858999f0dae74f9c692e6694ee3621b2ac87",
- "reqSigs": 1,
- "type": "scripthash",
- "addresses": [
- "3BoFUz1StqcNcgUTZE5cC1eFhuYFzj3fGH"
- ]
+ "address": "3BoFUz1StqcNcgUTZE5cC1eFhuYFzj3fGH",
+ "type": "scripthash"
}
}
],
diff --git a/test/util/data/txcreatemultisig5.json b/test/util/data/txcreatemultisig5.json
index ea07822ddd..93048cf261 100644
--- a/test/util/data/txcreatemultisig5.json
+++ b/test/util/data/txcreatemultisig5.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "OP_HASH160 a4051c02398868af83f28f083208fae99a769263 OP_EQUAL",
"hex": "a914a4051c02398868af83f28f083208fae99a76926387",
- "reqSigs": 1,
- "type": "scripthash",
- "addresses": [
- "3GeGs1eHUxPz5YyuFe9WPpXid2UsUb5Jos"
- ]
+ "address": "3GeGs1eHUxPz5YyuFe9WPpXid2UsUb5Jos",
+ "type": "scripthash"
}
}
],
diff --git a/test/util/data/txcreateoutpubkey2.json b/test/util/data/txcreateoutpubkey2.json
index c0ee181ede..52168a889b 100644
--- a/test/util/data/txcreateoutpubkey2.json
+++ b/test/util/data/txcreateoutpubkey2.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "0 a2516e770582864a6a56ed21a102044e388c62e3",
"hex": "0014a2516e770582864a6a56ed21a102044e388c62e3",
- "reqSigs": 1,
- "type": "witness_v0_keyhash",
- "addresses": [
- "bc1q5fgkuac9s2ry56jka5s6zqsyfcugcchry5cwu0"
- ]
+ "address": "bc1q5fgkuac9s2ry56jka5s6zqsyfcugcchry5cwu0",
+ "type": "witness_v0_keyhash"
}
}
],
diff --git a/test/util/data/txcreateoutpubkey3.json b/test/util/data/txcreateoutpubkey3.json
index 4d904df3c8..fce210f8a3 100644
--- a/test/util/data/txcreateoutpubkey3.json
+++ b/test/util/data/txcreateoutpubkey3.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL",
"hex": "a914a5ab14c9804d0d8bf02f1aea4e82780733ad0a8387",
- "reqSigs": 1,
- "type": "scripthash",
- "addresses": [
- "3GnzN8FqgvYGYdhj8NW6UNxxVv3Uj1ApQn"
- ]
+ "address": "3GnzN8FqgvYGYdhj8NW6UNxxVv3Uj1ApQn",
+ "type": "scripthash"
}
}
],
diff --git a/test/util/data/txcreatescript2.json b/test/util/data/txcreatescript2.json
index 32dd644579..2cde70fdf7 100644
--- a/test/util/data/txcreatescript2.json
+++ b/test/util/data/txcreatescript2.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL",
"hex": "a91471ed53322d470bb96657deb786b94f97dd46fb1587",
- "reqSigs": 1,
- "type": "scripthash",
- "addresses": [
- "3C5QarEGh9feKbDJ3QbMf2YNjnMoiPDhNp"
- ]
+ "address": "3C5QarEGh9feKbDJ3QbMf2YNjnMoiPDhNp",
+ "type": "scripthash"
}
}
],
diff --git a/test/util/data/txcreatescript3.json b/test/util/data/txcreatescript3.json
index b9192d9a82..7a282faf4f 100644
--- a/test/util/data/txcreatescript3.json
+++ b/test/util/data/txcreatescript3.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",
"hex": "00200bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",
- "reqSigs": 1,
- "type": "witness_v0_scripthash",
- "addresses": [
- "bc1qp0lfxhnscvsu0j36l36uurgv5tuck4pzuqytkvwqp3kh78cupttqyf705v"
- ]
+ "address": "bc1qp0lfxhnscvsu0j36l36uurgv5tuck4pzuqytkvwqp3kh78cupttqyf705v",
+ "type": "witness_v0_scripthash"
}
}
],
diff --git a/test/util/data/txcreatescript4.json b/test/util/data/txcreatescript4.json
index 2271ecfa0a..298b37bb4a 100644
--- a/test/util/data/txcreatescript4.json
+++ b/test/util/data/txcreatescript4.json
@@ -15,11 +15,8 @@
"scriptPubKey": {
"asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL",
"hex": "a9146a2c482f4985f57e702f325816c90e3723ca81ae87",
- "reqSigs": 1,
- "type": "scripthash",
- "addresses": [
- "3BNQbeFeJJGMAyDxPwWPuqxPMrjsFLjk3f"
- ]
+ "address": "3BNQbeFeJJGMAyDxPwWPuqxPMrjsFLjk3f",
+ "type": "scripthash"
}
}
],
diff --git a/test/util/data/txcreatesignv1.json b/test/util/data/txcreatesignv1.json
index 7a06aa9ffe..ca5e003110 100644
--- a/test/util/data/txcreatesignv1.json
+++ b/test/util/data/txcreatesignv1.json
@@ -24,11 +24,8 @@
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac",
- "reqSigs": 1,
- "type": "pubkeyhash",
- "addresses": [
- "193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"
- ]
+ "address": "193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7",
+ "type": "pubkeyhash"
}
}
],