aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/data/rpc_decodescript.json11
-rwxr-xr-xtest/functional/feature_cltv.py2
-rwxr-xr-xtest/functional/feature_dersig.py2
-rwxr-xr-xtest/functional/feature_init.py41
-rwxr-xr-xtest/functional/feature_maxtipage.py56
-rwxr-xr-xtest/functional/interface_rest.py18
-rwxr-xr-xtest/functional/mempool_updatefromblock.py2
-rwxr-xr-xtest/functional/rpc_blockchain.py57
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py53
-rwxr-xr-xtest/functional/rpc_getblockfrompeer.py16
-rwxr-xr-xtest/functional/rpc_psbt.py89
-rwxr-xr-xtest/functional/rpc_rawtransaction.py39
-rwxr-xr-xtest/functional/rpc_signrawtransaction.py4
-rwxr-xr-xtest/functional/test_framework/test_node.py9
-rw-r--r--test/functional/test_framework/util.py2
-rwxr-xr-xtest/functional/test_runner.py2
-rwxr-xr-xtest/functional/wallet_multiwallet.py2
-rwxr-xr-xtest/functional/wallet_send.py40
-rwxr-xr-xtest/functional/wallet_timelock.py50
-rwxr-xr-xtest/lint/commit-script-check.sh5
-rw-r--r--test/lint/lint-spelling.ignore-words.txt2
-rw-r--r--test/sanitizer_suppressions/ubsan24
-rw-r--r--test/util/data/tt-delin1-out.json2
-rw-r--r--test/util/data/tt-delout1-out.json1
-rw-r--r--test/util/data/tt-locktime317000-out.json2
-rw-r--r--test/util/data/txcreate1.json2
-rw-r--r--test/util/data/txcreate2.json1
-rw-r--r--test/util/data/txcreatedata1.json2
-rw-r--r--test/util/data/txcreatedata2.json2
-rw-r--r--test/util/data/txcreatedata_seq0.json1
-rw-r--r--test/util/data/txcreatedata_seq1.json1
-rw-r--r--test/util/data/txcreatemultisig1.json1
-rw-r--r--test/util/data/txcreatemultisig2.json1
-rw-r--r--test/util/data/txcreatemultisig3.json1
-rw-r--r--test/util/data/txcreatemultisig4.json1
-rw-r--r--test/util/data/txcreatemultisig5.json1
-rw-r--r--test/util/data/txcreateoutpubkey1.json1
-rw-r--r--test/util/data/txcreateoutpubkey2.json1
-rw-r--r--test/util/data/txcreateoutpubkey3.json1
-rw-r--r--test/util/data/txcreatescript1.json1
-rw-r--r--test/util/data/txcreatescript2.json1
-rw-r--r--test/util/data/txcreatescript3.json1
-rw-r--r--test/util/data/txcreatescript4.json1
-rw-r--r--test/util/data/txcreatesignv1.json1
44 files changed, 424 insertions, 129 deletions
diff --git a/test/functional/data/rpc_decodescript.json b/test/functional/data/rpc_decodescript.json
index d1aa9ab00d..8903f5efac 100644
--- a/test/functional/data/rpc_decodescript.json
+++ b/test/functional/data/rpc_decodescript.json
@@ -4,6 +4,7 @@
{
"asm": "1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"address": "bcrt1pamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqz6nvlh",
+ "desc": "addr(bcrt1pamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqz6nvlh)#v52jnujz",
"type": "witness_v1_taproot"
}
],
@@ -12,6 +13,7 @@
{
"asm": "1 -28398",
"address": "bcrt1pamhqk96edn",
+ "desc": "addr(bcrt1pamhqk96edn)#vkh8uj5a",
"type": "witness_unknown"
}
],
@@ -20,6 +22,7 @@
{
"asm": "0 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"address": "bcrt1qamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqgdn98t",
+ "desc": "addr(bcrt1qamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhwamhqgdn98t)#afaecevx",
"type": "witness_v0_scripthash",
"p2sh": "2MwGk8mw1GBP6U9D5X8gTvgvXpuknmAK3fo"
}
@@ -29,6 +32,7 @@
{
"asm": "OP_HASH160 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee OP_EQUAL",
"address": "2NF2b3KS8xXb9XHvbRMXdZh8s5g92rUZHtp",
+ "desc": "addr(2NF2b3KS8xXb9XHvbRMXdZh8s5g92rUZHtp)#ywfcpmh9",
"type": "scripthash"
}
],
@@ -36,6 +40,7 @@
"6a00",
{
"asm": "OP_RETURN 0",
+ "desc": "raw(6a00)#ncfmkl43",
"type": "nulldata"
}
],
@@ -43,6 +48,7 @@
"6aee",
{
"asm": "OP_RETURN OP_UNKNOWN",
+ "desc": "raw(6aee)#vsyzgqdt",
"type": "nonstandard"
}
],
@@ -50,6 +56,7 @@
"6a02ee",
{
"asm": "OP_RETURN [error]",
+ "desc": "raw(6a02ee)#gvdwnlzl",
"type": "nonstandard"
}
],
@@ -57,10 +64,12 @@
"02eeee",
{
"asm": "-28398",
+ "desc": "raw(02eeee)#5xzck7pr",
"type": "nonstandard",
"p2sh": "2N34iiGoUUkVSPiaaTFpJjB1FR9TXQu3PGM",
"segwit": {
"asm": "0 96c2368fc30514a438a8bd909f93c49a1549d77198ccbdb792043b666cb24f42",
+ "desc": "addr(bcrt1qjmprdr7rq522gw9ghkgfly7yng25n4m3nrxtmdujqsakvm9jfapqk795l5)#5akkdska",
"hex": "002096c2368fc30514a438a8bd909f93c49a1549d77198ccbdb792043b666cb24f42",
"address": "bcrt1qjmprdr7rq522gw9ghkgfly7yng25n4m3nrxtmdujqsakvm9jfapqk795l5",
"type": "witness_v0_scripthash",
@@ -72,6 +81,7 @@
"ba",
{
"asm": "OP_CHECKSIGADD",
+ "desc": "raw(ba)#yy0eg44l",
"type": "nonstandard"
}
],
@@ -79,6 +89,7 @@
"50",
{
"asm": "OP_RESERVED",
+ "desc": "raw(50)#a7tu03xf",
"type": "nonstandard"
}
]
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index 7fd0d0140b..9d32749a08 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -92,7 +92,7 @@ class BIP65Test(BitcoinTestFramework):
self.rpc_timeout = 480
def test_cltv_info(self, *, is_active):
- assert_equal(self.nodes[0].getblockchaininfo()['softforks']['bip65'], {
+ assert_equal(self.nodes[0].getdeploymentinfo()['deployments']['bip65'], {
"active": is_active,
"height": CLTV_HEIGHT,
"type": "buried",
diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py
index f35ce7e0c9..9a46839969 100755
--- a/test/functional/feature_dersig.py
+++ b/test/functional/feature_dersig.py
@@ -60,7 +60,7 @@ class BIP66Test(BitcoinTestFramework):
return self.miniwallet.create_self_transfer(utxo_to_spend=utxo_to_spend)['tx']
def test_dersig_info(self, *, is_active):
- assert_equal(self.nodes[0].getblockchaininfo()['softforks']['bip66'],
+ assert_equal(self.nodes[0].getdeploymentinfo()['deployments']['bip66'],
{
"active": is_active,
"height": DERSIG_HEIGHT,
diff --git a/test/functional/feature_init.py b/test/functional/feature_init.py
index 4b56b0c26b..dbd71a8b2d 100755
--- a/test/functional/feature_init.py
+++ b/test/functional/feature_init.py
@@ -3,8 +3,6 @@
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Stress tests related to node initialization."""
-import random
-import time
import os
from pathlib import Path
@@ -26,7 +24,6 @@ class InitStressTest(BitcoinTestFramework):
def run_test(self):
"""
- test terminating initialization after seeing a certain log line.
- - test terminating init after seeing a random number of log lines.
- test removing certain essential files to test startup error paths.
"""
# TODO: skip Windows for now since it isn't clear how to SIGTERM.
@@ -76,46 +73,14 @@ class InitStressTest(BitcoinTestFramework):
for terminate_line in lines_to_terminate_after:
self.log.info(f"Starting node and will exit after line '{terminate_line}'")
- node.start(extra_args=['-txindex=1'])
-
- num_total_logs = node.wait_for_debug_log([terminate_line], ignore_case=True)
- self.log.debug(f"Terminating node after {num_total_logs} log lines seen")
+ with node.wait_for_debug_log([terminate_line], ignore_case=True):
+ node.start(extra_args=['-txindex=1'])
+ self.log.debug("Terminating node after terminate line was found")
sigterm_node()
check_clean_start()
self.stop_node(0)
- self.log.info(
- f"Terminate at some random point in the init process (max logs: {num_total_logs})")
-
- for _ in range(40):
- num_logs = len(Path(node.debug_log_path).read_text().splitlines())
- additional_lines = random.randint(1, num_total_logs)
- self.log.debug(f"Starting node and will exit after {additional_lines} lines")
- node.start(extra_args=['-txindex=1'])
- logfile = open(node.debug_log_path, 'rb')
-
- MAX_SECS_TO_WAIT = 10
- start = time.time()
- num_lines = 0
-
- while True:
- line = logfile.readline()
- if line:
- num_lines += 1
-
- if num_lines >= (num_logs + additional_lines) or \
- (time.time() - start) > MAX_SECS_TO_WAIT:
- self.log.debug(f"Terminating node after {num_lines} log lines seen")
- sigterm_node()
- break
-
- if node.process.poll() is not None:
- raise AssertionError("node failed to start")
-
- check_clean_start()
- self.stop_node(0)
-
self.log.info("Test startup errors after removing certain essential files")
files_to_disturb = {
diff --git a/test/functional/feature_maxtipage.py b/test/functional/feature_maxtipage.py
new file mode 100755
index 0000000000..87f9d6962d
--- /dev/null
+++ b/test/functional/feature_maxtipage.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+# Copyright (c) 2022 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 logic for setting nMaxTipAge on command line.
+
+Nodes don't consider themselves out of "initial block download" as long as
+their best known block header time is more than nMaxTipAge in the past.
+"""
+
+import time
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal
+
+
+DEFAULT_MAX_TIP_AGE = 24 * 60 * 60
+
+
+class MaxTipAgeTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.setup_clean_chain = True
+ self.num_nodes = 2
+
+ def test_maxtipage(self, maxtipage, set_parameter=True):
+ node_miner = self.nodes[0]
+ node_ibd = self.nodes[1]
+
+ self.restart_node(1, [f'-maxtipage={maxtipage}'] if set_parameter else None)
+ self.connect_nodes(0, 1)
+
+ # tips older than maximum age -> stay in IBD
+ cur_time = int(time.time())
+ node_ibd.setmocktime(cur_time)
+ for delta in [5, 4, 3, 2, 1]:
+ node_miner.setmocktime(cur_time - maxtipage - delta)
+ self.generate(node_miner, 1)
+ assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], True)
+
+ # tip within maximum age -> leave IBD
+ node_miner.setmocktime(cur_time - maxtipage)
+ self.generate(node_miner, 1)
+ assert_equal(node_ibd.getblockchaininfo()['initialblockdownload'], False)
+
+ def run_test(self):
+ self.log.info("Test IBD with maximum tip age of 24 hours (default).")
+ self.test_maxtipage(DEFAULT_MAX_TIP_AGE, set_parameter=False)
+
+ for hours in [20, 10, 5, 2, 1]:
+ maxtipage = hours * 60 * 60
+ self.log.info(f"Test IBD with maximum tip age of {hours} hours (-maxtipage={maxtipage}).")
+ self.test_maxtipage(maxtipage)
+
+
+if __name__ == '__main__':
+ MaxTipAgeTest().main()
diff --git a/test/functional/interface_rest.py b/test/functional/interface_rest.py
index 2842b2534d..06aa5608bb 100755
--- a/test/functional/interface_rest.py
+++ b/test/functional/interface_rest.py
@@ -22,6 +22,10 @@ from test_framework.util import (
from test_framework.messages import BLOCK_HEADER_SIZE
+INVALID_PARAM = "abc"
+UNKNOWN_PARAM = "0000000000000000000000000000000000000000000000000000000000000000"
+
+
class ReqType(Enum):
JSON = 1
BIN = 2
@@ -103,6 +107,12 @@ class RESTTest (BitcoinTestFramework):
n, = filter_output_indices_by_value(json_obj['vout'], Decimal('0.1'))
spending = (txid, n)
+ # Test /tx with an invalid and an unknown txid
+ resp = self.test_rest_request(uri=f"/tx/{INVALID_PARAM}", ret_type=RetType.OBJ, status=400)
+ assert_equal(resp.read().decode('utf-8').rstrip(), f"Invalid hash: {INVALID_PARAM}")
+ resp = self.test_rest_request(uri=f"/tx/{UNKNOWN_PARAM}", ret_type=RetType.OBJ, status=404)
+ assert_equal(resp.read().decode('utf-8').rstrip(), f"{UNKNOWN_PARAM} not found")
+
self.log.info("Query an unspent TXO using the /getutxos URI")
self.generatetoaddress(self.nodes[1], 1, not_related_address)
@@ -205,8 +215,8 @@ class RESTTest (BitcoinTestFramework):
bb_hash = self.nodes[0].getbestblockhash()
# Check result if block does not exists
- assert_equal(self.test_rest_request('/headers/1/0000000000000000000000000000000000000000000000000000000000000000'), [])
- self.test_rest_request('/block/0000000000000000000000000000000000000000000000000000000000000000', status=404, ret_type=RetType.OBJ)
+ assert_equal(self.test_rest_request(f"/headers/1/{UNKNOWN_PARAM}"), [])
+ self.test_rest_request(f"/block/{UNKNOWN_PARAM}", status=404, ret_type=RetType.OBJ)
# Check result if block is not in the active chain
self.nodes[0].invalidateblock(bb_hash)
@@ -250,8 +260,8 @@ class RESTTest (BitcoinTestFramework):
assert_equal(blockhash, bb_hash)
# Check invalid blockhashbyheight requests
- resp = self.test_rest_request("/blockhashbyheight/abc", ret_type=RetType.OBJ, status=400)
- assert_equal(resp.read().decode('utf-8').rstrip(), "Invalid height: abc")
+ resp = self.test_rest_request(f"/blockhashbyheight/{INVALID_PARAM}", ret_type=RetType.OBJ, status=400)
+ assert_equal(resp.read().decode('utf-8').rstrip(), f"Invalid height: {INVALID_PARAM}")
resp = self.test_rest_request("/blockhashbyheight/1000000", ret_type=RetType.OBJ, status=404)
assert_equal(resp.read().decode('utf-8').rstrip(), "Block height out of range")
resp = self.test_rest_request("/blockhashbyheight/-1", ret_type=RetType.OBJ, status=400)
diff --git a/test/functional/mempool_updatefromblock.py b/test/functional/mempool_updatefromblock.py
index 16c15e3f74..51de582ce0 100755
--- a/test/functional/mempool_updatefromblock.py
+++ b/test/functional/mempool_updatefromblock.py
@@ -17,7 +17,7 @@ from test_framework.util import assert_equal
class MempoolUpdateFromBlockTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
- self.extra_args = [['-limitdescendantsize=1000', '-limitancestorsize=1000']]
+ self.extra_args = [['-limitdescendantsize=1000', '-limitancestorsize=1000', '-limitancestorcount=100']]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py
index 4dd4899f74..2d96ba74b5 100755
--- a/test/functional/rpc_blockchain.py
+++ b/test/functional/rpc_blockchain.py
@@ -6,6 +6,7 @@
Test the following RPCs:
- getblockchaininfo
+ - getdeploymentinfo
- getchaintxstats
- gettxoutsetinfo
- getblockheader
@@ -79,6 +80,7 @@ class BlockchainTest(BitcoinTestFramework):
self._test_stopatheight()
self._test_waitforblockheight()
self._test_getblock()
+ self._test_getdeploymentinfo()
assert self.nodes[0].verifychain(4, 0)
def mine_chain(self):
@@ -115,7 +117,6 @@ class BlockchainTest(BitcoinTestFramework):
'mediantime',
'pruned',
'size_on_disk',
- 'softforks',
'time',
'verificationprogress',
'warnings',
@@ -159,11 +160,6 @@ class BlockchainTest(BitcoinTestFramework):
self.start_node(0, extra_args=[
'-stopatheight=207',
'-prune=550',
- '-testactivationheight=bip34@2',
- '-testactivationheight=dersig@3',
- '-testactivationheight=cltv@4',
- '-testactivationheight=csv@5',
- '-testactivationheight=segwit@6',
])
res = self.nodes[0].getblockchaininfo()
@@ -177,7 +173,13 @@ class BlockchainTest(BitcoinTestFramework):
assert_equal(res['prune_target_size'], 576716800)
assert_greater_than(res['size_on_disk'], 0)
- assert_equal(res['softforks'], {
+ def check_signalling_deploymentinfo_result(self, gdi_result, height, blockhash, status_next):
+ assert height >= 144 and height <= 287
+
+ assert_equal(gdi_result, {
+ "hash": blockhash,
+ "height": height,
+ "deployments": {
'bip34': {'type': 'buried', 'active': True, 'height': 2},
'bip66': {'type': 'buried', 'active': True, 'height': 3},
'bip65': {'type': 'buried', 'active': True, 'height': 4},
@@ -186,36 +188,65 @@ class BlockchainTest(BitcoinTestFramework):
'testdummy': {
'type': 'bip9',
'bip9': {
- 'status': 'started',
'bit': 28,
'start_time': 0,
'timeout': 0x7fffffffffffffff, # testdummy does not have a timeout so is set to the max int64 value
+ 'min_activation_height': 0,
+ 'status': 'started',
+ 'status-next': status_next,
'since': 144,
'statistics': {
'period': 144,
'threshold': 108,
- 'elapsed': HEIGHT - 143,
- 'count': HEIGHT - 143,
+ 'elapsed': height - 143,
+ 'count': height - 143,
'possible': True,
},
- 'min_activation_height': 0,
+ 'signalling': '#'*(height-143),
},
'active': False
},
'taproot': {
'type': 'bip9',
'bip9': {
- 'status': 'active',
'start_time': -1,
'timeout': 9223372036854775807,
- 'since': 0,
'min_activation_height': 0,
+ 'status': 'active',
+ 'status-next': 'active',
+ 'since': 0,
},
'height': 0,
'active': True
}
+ }
})
+ def _test_getdeploymentinfo(self):
+ # Note: continues past -stopatheight height, so must be invoked
+ # after _test_stopatheight
+
+ self.log.info("Test getdeploymentinfo")
+ self.stop_node(0)
+ self.start_node(0, extra_args=[
+ '-testactivationheight=bip34@2',
+ '-testactivationheight=dersig@3',
+ '-testactivationheight=cltv@4',
+ '-testactivationheight=csv@5',
+ '-testactivationheight=segwit@6',
+ ])
+
+ gbci207 = self.nodes[0].getblockchaininfo()
+ self.check_signalling_deploymentinfo_result(self.nodes[0].getdeploymentinfo(), gbci207["blocks"], gbci207["bestblockhash"], "started")
+
+ # block just prior to lock in
+ self.generate(self.wallet, 287 - gbci207["blocks"])
+ gbci287 = self.nodes[0].getblockchaininfo()
+ self.check_signalling_deploymentinfo_result(self.nodes[0].getdeploymentinfo(), gbci287["blocks"], gbci287["bestblockhash"], "locked_in")
+
+ # calling with an explicit hash works
+ self.check_signalling_deploymentinfo_result(self.nodes[0].getdeploymentinfo(gbci207["bestblockhash"]), gbci207["blocks"], gbci207["bestblockhash"], "started")
+
def _test_getchaintxstats(self):
self.log.info("Test getchaintxstats")
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index a8e6acea45..759e43194b 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -4,8 +4,10 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the fundrawtransaction RPC."""
+
from decimal import Decimal
from itertools import product
+from math import ceil
from test_framework.descriptors import descsum_create
from test_framework.key import ECKey
@@ -1003,7 +1005,7 @@ class RawTransactionsTest(BitcoinTestFramework):
ext_utxo = self.nodes[0].listunspent(addresses=[addr])[0]
# An external input without solving data should result in an error
- raw_tx = wallet.createrawtransaction([ext_utxo], {self.nodes[0].getnewaddress(): 15})
+ raw_tx = wallet.createrawtransaction([ext_utxo], {self.nodes[0].getnewaddress(): ext_utxo["amount"] / 2})
assert_raises_rpc_error(-4, "Insufficient funds", wallet.fundrawtransaction, raw_tx)
# Error conditions
@@ -1011,6 +1013,12 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_raises_rpc_error(-5, "'01234567890a0b0c0d0e0f' is not a valid public key", wallet.fundrawtransaction, raw_tx, {"solving_data": {"pubkeys":["01234567890a0b0c0d0e0f"]}})
assert_raises_rpc_error(-5, "'not a script' is not hex", wallet.fundrawtransaction, raw_tx, {"solving_data": {"scripts":["not a script"]}})
assert_raises_rpc_error(-8, "Unable to parse descriptor 'not a descriptor'", wallet.fundrawtransaction, raw_tx, {"solving_data": {"descriptors":["not a descriptor"]}})
+ assert_raises_rpc_error(-8, "Invalid parameter, missing vout key", wallet.fundrawtransaction, raw_tx, {"input_weights": [{"txid": ext_utxo["txid"]}]})
+ assert_raises_rpc_error(-8, "Invalid parameter, vout cannot be negative", wallet.fundrawtransaction, raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": -1}]})
+ assert_raises_rpc_error(-8, "Invalid parameter, missing weight key", wallet.fundrawtransaction, raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"]}]})
+ assert_raises_rpc_error(-8, "Invalid parameter, weight cannot be less than 165", wallet.fundrawtransaction, raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 164}]})
+ assert_raises_rpc_error(-8, "Invalid parameter, weight cannot be less than 165", wallet.fundrawtransaction, raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": -1}]})
+ assert_raises_rpc_error(-8, "Invalid parameter, weight cannot be greater than", wallet.fundrawtransaction, raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 400001}]})
# But funding should work when the solving data is provided
funded_tx = wallet.fundrawtransaction(raw_tx, {"solving_data": {"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"]]}})
@@ -1020,10 +1028,45 @@ class RawTransactionsTest(BitcoinTestFramework):
assert signed_tx['complete']
funded_tx = wallet.fundrawtransaction(raw_tx, {"solving_data": {"descriptors": [desc]}})
- signed_tx = wallet.signrawtransactionwithwallet(funded_tx['hex'])
- assert not signed_tx['complete']
- signed_tx = self.nodes[0].signrawtransactionwithwallet(signed_tx['hex'])
- assert signed_tx['complete']
+ signed_tx1 = wallet.signrawtransactionwithwallet(funded_tx['hex'])
+ assert not signed_tx1['complete']
+ signed_tx2 = self.nodes[0].signrawtransactionwithwallet(signed_tx1['hex'])
+ assert signed_tx2['complete']
+
+ unsigned_weight = self.nodes[0].decoderawtransaction(signed_tx1["hex"])["weight"]
+ signed_weight = self.nodes[0].decoderawtransaction(signed_tx2["hex"])["weight"]
+ # Input's weight is difference between weight of signed and unsigned,
+ # and the weight of stuff that didn't change (prevout, sequence, 1 byte of scriptSig)
+ input_weight = signed_weight - unsigned_weight + (41 * 4)
+ low_input_weight = input_weight // 2
+ high_input_weight = input_weight * 2
+
+ # Funding should also work if the input weight is provided
+ funded_tx = wallet.fundrawtransaction(raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": input_weight}]})
+ signed_tx = wallet.signrawtransactionwithwallet(funded_tx["hex"])
+ signed_tx = self.nodes[0].signrawtransactionwithwallet(signed_tx["hex"])
+ assert_equal(self.nodes[0].testmempoolaccept([signed_tx["hex"]])[0]["allowed"], True)
+ assert_equal(signed_tx["complete"], True)
+ # Reducing the weight should have a lower fee
+ funded_tx2 = wallet.fundrawtransaction(raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": low_input_weight}]})
+ assert_greater_than(funded_tx["fee"], funded_tx2["fee"])
+ # Increasing the weight should have a higher fee
+ funded_tx2 = wallet.fundrawtransaction(raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}]})
+ assert_greater_than(funded_tx2["fee"], funded_tx["fee"])
+ # The provided weight should override the calculated weight when solving data is provided
+ funded_tx3 = wallet.fundrawtransaction(raw_tx, {"solving_data": {"descriptors": [desc]}, "input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}]})
+ assert_equal(funded_tx2["fee"], funded_tx3["fee"])
+ # The feerate should be met
+ funded_tx4 = wallet.fundrawtransaction(raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}], "fee_rate": 10})
+ input_add_weight = high_input_weight - (41 * 4)
+ tx4_weight = wallet.decoderawtransaction(funded_tx4["hex"])["weight"] + input_add_weight
+ tx4_vsize = int(ceil(tx4_weight / 4))
+ assert_fee_amount(funded_tx4["fee"], tx4_vsize, Decimal(0.0001))
+
+ # Funding with weight at csuint boundaries should not cause problems
+ funded_tx = wallet.fundrawtransaction(raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 255}]})
+ funded_tx = wallet.fundrawtransaction(raw_tx, {"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 65539}]})
+
self.nodes[2].unloadwallet("extfund")
def test_include_unsafe(self):
diff --git a/test/functional/rpc_getblockfrompeer.py b/test/functional/rpc_getblockfrompeer.py
index effcebe854..b65322d920 100755
--- a/test/functional/rpc_getblockfrompeer.py
+++ b/test/functional/rpc_getblockfrompeer.py
@@ -40,12 +40,8 @@ class GetBlockFromPeerTest(BitcoinTestFramework):
self.sync_blocks()
self.log.info("Node 0 should only have the header for node 1's block 3")
- for x in self.nodes[0].getchaintips():
- if x['hash'] == short_tip:
- assert_equal(x['status'], "headers-only")
- break
- else:
- raise AssertionError("short tip not synced")
+ x = next(filter(lambda x: x['hash'] == short_tip, self.nodes[0].getchaintips()))
+ assert_equal(x['status'], "headers-only")
assert_raises_rpc_error(-1, "Block not found on disk", self.nodes[0].getblock, short_tip)
self.log.info("Fetch block from node 1")
@@ -60,17 +56,15 @@ class GetBlockFromPeerTest(BitcoinTestFramework):
assert_raises_rpc_error(-1, "Block header missing", self.nodes[0].getblockfrompeer, "00" * 32, 0)
self.log.info("Non-existent peer generates error")
- assert_raises_rpc_error(-1, f"Peer nodeid {peer_0_peer_1_id + 1} does not exist", self.nodes[0].getblockfrompeer, short_tip, peer_0_peer_1_id + 1)
+ assert_raises_rpc_error(-1, "Peer does not exist", self.nodes[0].getblockfrompeer, short_tip, peer_0_peer_1_id + 1)
self.log.info("Successful fetch")
result = self.nodes[0].getblockfrompeer(short_tip, peer_0_peer_1_id)
self.wait_until(lambda: self.check_for_block(short_tip), timeout=1)
- assert(not "warnings" in result)
+ assert_equal(result, {})
self.log.info("Don't fetch blocks we already have")
- result = self.nodes[0].getblockfrompeer(short_tip, peer_0_peer_1_id)
- assert("warnings" in result)
- assert_equal(result["warnings"], "Block already downloaded")
+ assert_raises_rpc_error(-1, "Block already downloaded", self.nodes[0].getblockfrompeer, short_tip, peer_0_peer_1_id)
if __name__ == '__main__':
GetBlockFromPeerTest().main()
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index 153a201e95..b037807b53 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -606,11 +606,15 @@ class PSBTTest(BitcoinTestFramework):
assert_raises_rpc_error(-25, 'Inputs missing or spent', self.nodes[0].walletprocesspsbt, 'cHNidP8BAJoCAAAAAkvEW8NnDtdNtDpsmze+Ht2LH35IJcKv00jKAlUs21RrAwAAAAD/////S8Rbw2cO1020OmybN74e3Ysffkglwq/TSMoCVSzbVGsBAAAAAP7///8CwLYClQAAAAAWABSNJKzjaUb3uOxixsvh1GGE3fW7zQD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XIAAAAAAAEAnQIAAAACczMa321tVHuN4GKWKRncycI22aX3uXgwSFUKM2orjRsBAAAAAP7///9zMxrfbW1Ue43gYpYpGdzJwjbZpfe5eDBIVQozaiuNGwAAAAAA/v///wIA+QKVAAAAABl2qRT9zXUVA8Ls5iVqynLHe5/vSe1XyYisQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAAAAAQEfQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAA==')
- # Test that we can fund psbts with external inputs specified
+ self.log.info("Test that we can fund psbts with external inputs specified")
+
eckey = ECKey()
eckey.generate()
privkey = bytes_to_wif(eckey.get_bytes())
+ self.nodes[1].createwallet("extfund")
+ wallet = self.nodes[1].get_wallet_rpc("extfund")
+
# Make a weird but signable script. sh(pkh()) descriptor accomplishes this
desc = descsum_create("sh(pkh({}))".format(privkey))
if self.options.descriptors:
@@ -622,26 +626,97 @@ class PSBTTest(BitcoinTestFramework):
addr_info = self.nodes[0].getaddressinfo(addr)
self.nodes[0].sendtoaddress(addr, 10)
+ self.nodes[0].sendtoaddress(wallet.getnewaddress(), 10)
self.generate(self.nodes[0], 6)
ext_utxo = self.nodes[0].listunspent(addresses=[addr])[0]
# An external input without solving data should result in an error
- assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[1].walletcreatefundedpsbt, [ext_utxo], {self.nodes[0].getnewaddress(): 10 + ext_utxo['amount']}, 0, {'add_inputs': True})
+ assert_raises_rpc_error(-4, "Insufficient funds", wallet.walletcreatefundedpsbt, [ext_utxo], {self.nodes[0].getnewaddress(): 15})
# But funding should work when the solving data is provided
- psbt = self.nodes[1].walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {'add_inputs': True, "solving_data": {"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"]]}})
- signed = self.nodes[1].walletprocesspsbt(psbt['psbt'])
+ psbt = wallet.walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {"add_inputs": True, "solving_data": {"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"]]}})
+ signed = wallet.walletprocesspsbt(psbt['psbt'])
assert not signed['complete']
signed = self.nodes[0].walletprocesspsbt(signed['psbt'])
assert signed['complete']
self.nodes[0].finalizepsbt(signed['psbt'])
- psbt = self.nodes[1].walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {'add_inputs': True, "solving_data":{"descriptors": [desc]}})
- signed = self.nodes[1].walletprocesspsbt(psbt['psbt'])
+ psbt = wallet.walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {"add_inputs": True, "solving_data":{"descriptors": [desc]}})
+ signed = wallet.walletprocesspsbt(psbt['psbt'])
assert not signed['complete']
signed = self.nodes[0].walletprocesspsbt(signed['psbt'])
assert signed['complete']
- self.nodes[0].finalizepsbt(signed['psbt'])
+ final = self.nodes[0].finalizepsbt(signed['psbt'], False)
+
+ dec = self.nodes[0].decodepsbt(signed["psbt"])
+ for i, txin in enumerate(dec["tx"]["vin"]):
+ if txin["txid"] == ext_utxo["txid"] and txin["vout"] == ext_utxo["vout"]:
+ input_idx = i
+ break
+ psbt_in = dec["inputs"][input_idx]
+ # Calculate the input weight
+ # (prevout + sequence + length of scriptSig + 2 bytes buffer) * 4 + len of scriptwitness
+ len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
+ len_scriptwitness = len(psbt_in["final_scriptwitness"]["hex"]) // 2 if "final_scriptwitness" in psbt_in else 0
+ input_weight = ((41 + len_scriptsig + 2) * 4) + len_scriptwitness
+ low_input_weight = input_weight // 2
+ high_input_weight = input_weight * 2
+
+ # Input weight error conditions
+ assert_raises_rpc_error(
+ -8,
+ "Input weights should be specified in inputs rather than in options.",
+ wallet.walletcreatefundedpsbt,
+ inputs=[ext_utxo],
+ outputs={self.nodes[0].getnewaddress(): 15},
+ options={"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 1000}]}
+ )
+
+ # Funding should also work if the input weight is provided
+ psbt = wallet.walletcreatefundedpsbt(
+ inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": input_weight}],
+ outputs={self.nodes[0].getnewaddress(): 15},
+ options={"add_inputs": True}
+ )
+ signed = wallet.walletprocesspsbt(psbt["psbt"])
+ signed = self.nodes[0].walletprocesspsbt(signed["psbt"])
+ final = self.nodes[0].finalizepsbt(signed["psbt"])
+ assert self.nodes[0].testmempoolaccept([final["hex"]])[0]["allowed"]
+ # Reducing the weight should have a lower fee
+ psbt2 = wallet.walletcreatefundedpsbt(
+ inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": low_input_weight}],
+ outputs={self.nodes[0].getnewaddress(): 15},
+ options={"add_inputs": True}
+ )
+ assert_greater_than(psbt["fee"], psbt2["fee"])
+ # Increasing the weight should have a higher fee
+ psbt2 = wallet.walletcreatefundedpsbt(
+ inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}],
+ outputs={self.nodes[0].getnewaddress(): 15},
+ options={"add_inputs": True}
+ )
+ assert_greater_than(psbt2["fee"], psbt["fee"])
+ # The provided weight should override the calculated weight when solving data is provided
+ psbt3 = wallet.walletcreatefundedpsbt(
+ inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}],
+ outputs={self.nodes[0].getnewaddress(): 15},
+ options={'add_inputs': True, "solving_data":{"descriptors": [desc]}}
+ )
+ assert_equal(psbt2["fee"], psbt3["fee"])
+
+ # Import the external utxo descriptor so that we can sign for it from the test wallet
+ if self.options.descriptors:
+ res = wallet.importdescriptors([{"desc": desc, "timestamp": "now"}])
+ else:
+ res = wallet.importmulti([{"desc": desc, "timestamp": "now"}])
+ assert res[0]["success"]
+ # The provided weight should override the calculated weight for a wallet input
+ psbt3 = wallet.walletcreatefundedpsbt(
+ inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}],
+ outputs={self.nodes[0].getnewaddress(): 15},
+ options={"add_inputs": True}
+ )
+ assert_equal(psbt2["fee"], psbt3["fee"])
if __name__ == '__main__':
PSBTTest().main()
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index 96691b2686..a839af0288 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -99,25 +99,36 @@ class RawTransactionsTest(BitcoinTestFramework):
rawTx = self.nodes[1].createrawtransaction([{'txid': txid, 'vout': vout}], {self.nodes[1].getnewaddress(): 9.999})
rawTxSigned = self.nodes[1].signrawtransactionwithwallet(rawTx)
txId = self.nodes[1].sendrawtransaction(rawTxSigned['hex'])
- self.generate(self.nodes[0], 1)
+ self.generateblock(self.nodes[0], output=self.nodes[0].getnewaddress(), transactions=[rawTxSigned['hex']])
+ err_msg = (
+ "No such mempool transaction. Use -txindex or provide a block hash to enable"
+ " blockchain transaction queries. Use gettransaction for wallet transactions."
+ )
for n in [0, 3]:
self.log.info(f"Test getrawtransaction {'with' if n == 0 else 'without'} -txindex")
- # 1. valid parameters - only supply txid
- assert_equal(self.nodes[n].getrawtransaction(txId), rawTxSigned['hex'])
- # 2. valid parameters - supply txid and 0 for non-verbose
- assert_equal(self.nodes[n].getrawtransaction(txId, 0), rawTxSigned['hex'])
+ if n == 0:
+ # With -txindex.
+ # 1. valid parameters - only supply txid
+ assert_equal(self.nodes[n].getrawtransaction(txId), rawTxSigned['hex'])
- # 3. valid parameters - supply txid and False for non-verbose
- assert_equal(self.nodes[n].getrawtransaction(txId, False), rawTxSigned['hex'])
+ # 2. valid parameters - supply txid and 0 for non-verbose
+ assert_equal(self.nodes[n].getrawtransaction(txId, 0), rawTxSigned['hex'])
- # 4. valid parameters - supply txid and 1 for verbose.
- # We only check the "hex" field of the output so we don't need to update this test every time the output format changes.
- assert_equal(self.nodes[n].getrawtransaction(txId, 1)["hex"], rawTxSigned['hex'])
+ # 3. valid parameters - supply txid and False for non-verbose
+ assert_equal(self.nodes[n].getrawtransaction(txId, False), rawTxSigned['hex'])
- # 5. valid parameters - supply txid and True for non-verbose
- assert_equal(self.nodes[n].getrawtransaction(txId, True)["hex"], rawTxSigned['hex'])
+ # 4. valid parameters - supply txid and 1 for verbose.
+ # We only check the "hex" field of the output so we don't need to update this test every time the output format changes.
+ assert_equal(self.nodes[n].getrawtransaction(txId, 1)["hex"], rawTxSigned['hex'])
+
+ # 5. valid parameters - supply txid and True for non-verbose
+ assert_equal(self.nodes[n].getrawtransaction(txId, True)["hex"], rawTxSigned['hex'])
+ else:
+ # Without -txindex, expect to raise.
+ for verbose in [None, 0, False, 1, True]:
+ assert_raises_rpc_error(-5, err_msg, self.nodes[n].getrawtransaction, txId, verbose)
# 6. invalid parameters - supply txid and invalid boolean values (strings) for verbose
for value in ["True", "False"]:
@@ -145,10 +156,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert 'in_active_chain' not in gottx
else:
self.log.info("Test getrawtransaction without -txindex, without blockhash: expect the call to raise")
- err_msg = (
- "No such mempool transaction. Use -txindex or provide a block hash to enable"
- " blockchain transaction queries. Use gettransaction for wallet transactions."
- )
assert_raises_rpc_error(-5, err_msg, self.nodes[n].getrawtransaction, txid=tx, verbose=True)
# We should not get the tx if we provide an unrelated block
assert_raises_rpc_error(-5, "No such transaction found", self.nodes[n].getrawtransaction, txid=tx, blockhash=block2)
diff --git a/test/functional/rpc_signrawtransaction.py b/test/functional/rpc_signrawtransaction.py
index e648040278..a2091b4ece 100755
--- a/test/functional/rpc_signrawtransaction.py
+++ b/test/functional/rpc_signrawtransaction.py
@@ -270,7 +270,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
getcontext().prec = 8
# Make sure CSV is active
- assert self.nodes[0].getblockchaininfo()['softforks']['csv']['active']
+ assert self.nodes[0].getdeploymentinfo()['deployments']['csv']['active']
# Create a P2WSH script with CSV
script = CScript([1, OP_CHECKSEQUENCEVERIFY, OP_DROP])
@@ -305,7 +305,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
getcontext().prec = 8
# Make sure CLTV is active
- assert self.nodes[0].getblockchaininfo()['softforks']['bip65']['active']
+ assert self.nodes[0].getdeploymentinfo()['deployments']['bip65']['active']
# Create a P2WSH script with CLTV
script = CScript([100, OP_CHECKLOCKTIMEVERIFY, OP_DROP])
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 0b9154a030..289e83579b 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -422,7 +422,8 @@ class TestNode():
time.sleep(0.05)
self._raise_assertion_error('Expected messages "{}" does not partially match log:\n\n{}\n\n'.format(str(expected_msgs), print_log))
- def wait_for_debug_log(self, expected_msgs, timeout=10, ignore_case=False) -> int:
+ @contextlib.contextmanager
+ def wait_for_debug_log(self, expected_msgs, timeout=60, ignore_case=False):
"""
Block until we see a particular debug log message fragment or until we exceed the timeout.
Return:
@@ -432,6 +433,8 @@ class TestNode():
prev_size = self.debug_log_bytes()
re_flags = re.MULTILINE | (re.IGNORECASE if ignore_case else 0)
+ yield
+
while True:
found = True
with open(self.debug_log_path, encoding='utf-8') as dl:
@@ -443,8 +446,7 @@ class TestNode():
found = False
if found:
- num_logs = len(log.splitlines())
- return num_logs
+ return
if time.time() >= time_end:
print_log = " - " + "\n - ".join(log.splitlines())
@@ -456,7 +458,6 @@ class TestNode():
self._raise_assertion_error(
'Expected messages "{}" does not partially match log:\n\n{}\n\n'.format(
str(expected_msgs), print_log))
- return -1 # useless return to satisfy linter
@contextlib.contextmanager
def profile_with_perf(self, profile_name: str):
diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py
index 195af14914..dabde13bf1 100644
--- a/test/functional/test_framework/util.py
+++ b/test/functional/test_framework/util.py
@@ -438,7 +438,7 @@ def delete_cookie_file(datadir, chain):
def softfork_active(node, key):
"""Return whether a softfork is active."""
- return node.getblockchaininfo()['softforks'][key]['active']
+ return node.getdeploymentinfo()['deployments'][key]['active']
def set_node_times(nodes, t):
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index eb2d030f4a..e833128063 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -198,6 +198,7 @@ BASE_SCRIPTS = [
'wallet_keypool.py --legacy-wallet',
'wallet_keypool.py --descriptors',
'wallet_descriptor.py --descriptors',
+ 'feature_maxtipage.py',
'p2p_nobloomfilter_messages.py',
'p2p_filter.py',
'rpc_setban.py',
@@ -308,6 +309,7 @@ BASE_SCRIPTS = [
'feature_coinstatsindex.py --legacy-wallet',
'feature_coinstatsindex.py --descriptors',
'wallet_orphanedreward.py',
+ 'wallet_timelock.py',
'p2p_node_network_limited.py',
'p2p_permissions.py',
'feature_blocksdir.py',
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 0b868dde6c..317121eb68 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -141,7 +141,7 @@ class MultiWalletTest(BitcoinTestFramework):
# should raise rpc error if wallet path can't be created
err_code = -4 if self.options.descriptors else -1
- assert_raises_rpc_error(err_code, "boost::filesystem::create_directory:", self.nodes[0].createwallet, "w8/bad")
+ assert_raises_rpc_error(err_code, "boost::filesystem::create_director", self.nodes[0].createwallet, "w8/bad")
# check that all requested wallets were created
self.stop_node(0)
diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py
index d77d554baa..843a9f52b7 100755
--- a/test/functional/wallet_send.py
+++ b/test/functional/wallet_send.py
@@ -518,5 +518,45 @@ class WalletSendTest(BitcoinTestFramework):
assert signed["complete"]
self.nodes[0].finalizepsbt(signed["psbt"])
+ dec = self.nodes[0].decodepsbt(signed["psbt"])
+ for i, txin in enumerate(dec["tx"]["vin"]):
+ if txin["txid"] == ext_utxo["txid"] and txin["vout"] == ext_utxo["vout"]:
+ input_idx = i
+ break
+ psbt_in = dec["inputs"][input_idx]
+ # Calculate the input weight
+ # (prevout + sequence + length of scriptSig + 2 bytes buffer) * 4 + len of scriptwitness
+ len_scriptsig = len(psbt_in["final_scriptSig"]["hex"]) // 2 if "final_scriptSig" in psbt_in else 0
+ len_scriptwitness = len(psbt_in["final_scriptwitness"]["hex"]) // 2 if "final_scriptwitness" in psbt_in else 0
+ input_weight = ((41 + len_scriptsig + 2) * 4) + len_scriptwitness
+
+ # Input weight error conditions
+ assert_raises_rpc_error(
+ -8,
+ "Input weights should be specified in inputs rather than in options.",
+ ext_wallet.send,
+ outputs={self.nodes[0].getnewaddress(): 15},
+ options={"inputs": [ext_utxo], "input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 1000}]}
+ )
+
+ # Funding should also work when input weights are provided
+ res = self.test_send(
+ from_wallet=ext_wallet,
+ to_wallet=self.nodes[0],
+ amount=15,
+ inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": input_weight}],
+ add_inputs=True,
+ psbt=True,
+ include_watching=True,
+ fee_rate=10
+ )
+ signed = ext_wallet.walletprocesspsbt(res["psbt"])
+ signed = ext_fund.walletprocesspsbt(res["psbt"])
+ assert signed["complete"]
+ tx = self.nodes[0].finalizepsbt(signed["psbt"])
+ testres = self.nodes[0].testmempoolaccept([tx["hex"]])[0]
+ assert_equal(testres["allowed"], True)
+ assert_fee_amount(testres["fees"]["base"], testres["vsize"], Decimal(0.0001))
+
if __name__ == '__main__':
WalletSendTest().main()
diff --git a/test/functional/wallet_timelock.py b/test/functional/wallet_timelock.py
new file mode 100755
index 0000000000..cf233a00ef
--- /dev/null
+++ b/test/functional/wallet_timelock.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+# Copyright (c) 2022 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_equal
+
+
+class WalletLocktimeTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+
+ def skip_test_if_missing_module(self):
+ self.skip_if_no_wallet()
+
+ def run_test(self):
+ node = self.nodes[0]
+
+ mtp_tip = node.getblockheader(node.getbestblockhash())["mediantime"]
+
+ self.log.info("Get new address with label")
+ label = "timelock⌛🔓"
+ address = node.getnewaddress(label=label)
+
+ self.log.info("Send to new address with locktime")
+ node.send(
+ outputs={address: 5},
+ options={"locktime": mtp_tip - 1},
+ )
+ self.generate(node, 1)
+
+ self.log.info("Check that clock can not change finality of confirmed txs")
+ amount_before_ad = node.getreceivedbyaddress(address)
+ amount_before_lb = node.getreceivedbylabel(label)
+ list_before_ad = node.listreceivedbyaddress(address_filter=address)
+ list_before_lb = node.listreceivedbylabel(include_empty=False)
+ balance_before = node.getbalances()["mine"]["trusted"]
+ coin_before = node.listunspent(maxconf=1)
+ node.setmocktime(mtp_tip - 1)
+ assert_equal(node.getreceivedbyaddress(address), amount_before_ad)
+ assert_equal(node.getreceivedbylabel(label), amount_before_lb)
+ assert_equal(node.listreceivedbyaddress(address_filter=address), list_before_ad)
+ assert_equal(node.listreceivedbylabel(include_empty=False), list_before_lb)
+ assert_equal(node.getbalances()["mine"]["trusted"], balance_before)
+ assert_equal(node.listunspent(maxconf=1), coin_before)
+
+
+if __name__ == "__main__":
+ WalletLocktimeTest().main()
diff --git a/test/lint/commit-script-check.sh b/test/lint/commit-script-check.sh
index 6a8a15d05c..9449b393f1 100755
--- a/test/lint/commit-script-check.sh
+++ b/test/lint/commit-script-check.sh
@@ -17,6 +17,11 @@ if test -z "$1"; then
exit 1
fi
+if ! sed --help 2>&1 | grep -q 'GNU'; then
+ echo "Error: the installed sed package is not compatible. Please make sure you have GNU sed installed in your system.";
+ exit 1;
+fi
+
RET=0
PREV_BRANCH=$(git name-rev --name-only HEAD)
PREV_HEAD=$(git rev-parse HEAD)
diff --git a/test/lint/lint-spelling.ignore-words.txt b/test/lint/lint-spelling.ignore-words.txt
index 9906b15e9a..afdb0692d8 100644
--- a/test/lint/lint-spelling.ignore-words.txt
+++ b/test/lint/lint-spelling.ignore-words.txt
@@ -1,6 +1,8 @@
asend
+ba
blockin
cachable
+creat
fo
fpr
hights
diff --git a/test/sanitizer_suppressions/ubsan b/test/sanitizer_suppressions/ubsan
index 4292544dbd..a049693ee1 100644
--- a/test/sanitizer_suppressions/ubsan
+++ b/test/sanitizer_suppressions/ubsan
@@ -45,10 +45,7 @@ shift-base:test/fuzz/crypto_diff_fuzz_chacha20.cpp
# job.
unsigned-integer-overflow:addrman.cpp
unsigned-integer-overflow:arith_uint256.h
-unsigned-integer-overflow:bitcoin-tx.cpp
unsigned-integer-overflow:common/bloom.cpp
-unsigned-integer-overflow:chain.cpp
-unsigned-integer-overflow:chain.h
unsigned-integer-overflow:coins.cpp
unsigned-integer-overflow:compressor.cpp
unsigned-integer-overflow:core_write.cpp
@@ -64,41 +61,20 @@ unsigned-integer-overflow:validation.cpp
implicit-integer-sign-change:addrman.h
implicit-integer-sign-change:bech32.cpp
implicit-integer-sign-change:common/bloom.cpp
-implicit-integer-sign-change:chain.cpp
-implicit-integer-sign-change:chain.h
implicit-integer-sign-change:coins.h
implicit-integer-sign-change:compat/stdin.cpp
implicit-integer-sign-change:compressor.h
implicit-integer-sign-change:crypto/
implicit-integer-sign-change:key.cpp
-implicit-integer-sign-change:noui.cpp
implicit-integer-sign-change:policy/fees.cpp
implicit-integer-sign-change:prevector.h
implicit-integer-sign-change:script/bitcoinconsensus.cpp
implicit-integer-sign-change:script/interpreter.cpp
implicit-integer-sign-change:serialize.h
-implicit-integer-sign-change:test/arith_uint256_tests.cpp
-implicit-integer-sign-change:test/coins_tests.cpp
-implicit-integer-sign-change:test/pow_tests.cpp
-implicit-integer-sign-change:test/prevector_tests.cpp
-implicit-integer-sign-change:test/sighash_tests.cpp
-implicit-integer-sign-change:test/skiplist_tests.cpp
-implicit-integer-sign-change:test/streams_tests.cpp
-implicit-integer-sign-change:test/transaction_tests.cpp
implicit-integer-sign-change:txmempool.cpp
-implicit-integer-sign-change:zmq/zmqpublishnotifier.cpp
-implicit-signed-integer-truncation,implicit-integer-sign-change:chain.h
-implicit-signed-integer-truncation,implicit-integer-sign-change:test/skiplist_tests.cpp
implicit-signed-integer-truncation:addrman.cpp
implicit-signed-integer-truncation:addrman.h
-implicit-signed-integer-truncation:chain.h
implicit-signed-integer-truncation:crypto/
-implicit-signed-integer-truncation:node/miner.cpp
-implicit-signed-integer-truncation:net.cpp
-implicit-signed-integer-truncation:streams.h
-implicit-signed-integer-truncation:test/arith_uint256_tests.cpp
-implicit-signed-integer-truncation:test/skiplist_tests.cpp
-implicit-signed-integer-truncation:torcontrol.cpp
implicit-unsigned-integer-truncation:crypto/
shift-base:arith_uint256.cpp
shift-base:crypto/
diff --git a/test/util/data/tt-delin1-out.json b/test/util/data/tt-delin1-out.json
index c5b9f6df01..6e053fe2b9 100644
--- a/test/util/data/tt-delin1-out.json
+++ b/test/util/data/tt-delin1-out.json
@@ -194,6 +194,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o)#xvg87vgr",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
"address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
"type": "pubkeyhash"
@@ -204,6 +205,7 @@
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb)#tsyprkms",
"hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac",
"address": "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb",
"type": "pubkeyhash"
diff --git a/test/util/data/tt-delout1-out.json b/test/util/data/tt-delout1-out.json
index 3863416430..e61b9c79db 100644
--- a/test/util/data/tt-delout1-out.json
+++ b/test/util/data/tt-delout1-out.json
@@ -203,6 +203,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o)#xvg87vgr",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
"address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
"type": "pubkeyhash"
diff --git a/test/util/data/tt-locktime317000-out.json b/test/util/data/tt-locktime317000-out.json
index 62e785f7d0..873628e124 100644
--- a/test/util/data/tt-locktime317000-out.json
+++ b/test/util/data/tt-locktime317000-out.json
@@ -203,6 +203,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o)#xvg87vgr",
"hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac",
"address": "1E7SGgAZFCHDnVZLuRViX3gUmxpMfdvd2o",
"type": "pubkeyhash"
@@ -213,6 +214,7 @@
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb)#tsyprkms",
"hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac",
"address": "1AtWkdmfmYkErU16d3KYykJUbEp9MAj9Sb",
"type": "pubkeyhash"
diff --git a/test/util/data/txcreate1.json b/test/util/data/txcreate1.json
index 96d77ef273..c4a76f22a6 100644
--- a/test/util/data/txcreate1.json
+++ b/test/util/data/txcreate1.json
@@ -41,6 +41,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(13tuJJDR2RgArmgfv6JScSdreahzgc4T6o)#ztmwxg4c",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash"
@@ -51,6 +52,7 @@
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46)#vdmdu766",
"hex": "76a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac",
"address": "1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46",
"type": "pubkeyhash"
diff --git a/test/util/data/txcreate2.json b/test/util/data/txcreate2.json
index ee9b9c3c17..95953cc90e 100644
--- a/test/util/data/txcreate2.json
+++ b/test/util/data/txcreate2.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "",
+ "desc": "raw()#58lrscpx",
"hex": "",
"type": "nonstandard"
}
diff --git a/test/util/data/txcreatedata1.json b/test/util/data/txcreatedata1.json
index 87fc7e9cf7..1454ffdab7 100644
--- a/test/util/data/txcreatedata1.json
+++ b/test/util/data/txcreatedata1.json
@@ -23,6 +23,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(13tuJJDR2RgArmgfv6JScSdreahzgc4T6o)#ztmwxg4c",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash"
@@ -33,6 +34,7 @@
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
+ "desc": "raw(6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e)#zf2avljj",
"hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
"type": "nulldata"
}
diff --git a/test/util/data/txcreatedata2.json b/test/util/data/txcreatedata2.json
index d03b1c8244..ca20d2aa45 100644
--- a/test/util/data/txcreatedata2.json
+++ b/test/util/data/txcreatedata2.json
@@ -23,6 +23,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(13tuJJDR2RgArmgfv6JScSdreahzgc4T6o)#ztmwxg4c",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash"
@@ -33,6 +34,7 @@
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
+ "desc": "raw(6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e)#zf2avljj",
"hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
"type": "nulldata"
}
diff --git a/test/util/data/txcreatedata_seq0.json b/test/util/data/txcreatedata_seq0.json
index 8a123f1ba8..9838383c06 100644
--- a/test/util/data/txcreatedata_seq0.json
+++ b/test/util/data/txcreatedata_seq0.json
@@ -23,6 +23,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(13tuJJDR2RgArmgfv6JScSdreahzgc4T6o)#ztmwxg4c",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash"
diff --git a/test/util/data/txcreatedata_seq1.json b/test/util/data/txcreatedata_seq1.json
index 006fd7259f..c729f8dcfb 100644
--- a/test/util/data/txcreatedata_seq1.json
+++ b/test/util/data/txcreatedata_seq1.json
@@ -32,6 +32,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(13tuJJDR2RgArmgfv6JScSdreahzgc4T6o)#ztmwxg4c",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"address": "13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"type": "pubkeyhash"
diff --git a/test/util/data/txcreatemultisig1.json b/test/util/data/txcreatemultisig1.json
index baa290c2b1..9632b20ece 100644
--- a/test/util/data/txcreatemultisig1.json
+++ b/test/util/data/txcreatemultisig1.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG",
+ "desc": "multi(2,02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397,021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d,02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485)#8s88p9pl",
"hex": "522102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff39721021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d2102df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb48553ae",
"type": "multisig"
}
diff --git a/test/util/data/txcreatemultisig2.json b/test/util/data/txcreatemultisig2.json
index 6685512587..021cf539a8 100644
--- a/test/util/data/txcreatemultisig2.json
+++ b/test/util/data/txcreatemultisig2.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL",
+ "desc": "addr(34HNh57oBCRKkxNyjTuWAJkTbuGh6jg2Ms)#ngnz8933",
"hex": "a9141c6fbaf46d64221e80cbae182c33ddf81b9294ac87",
"address": "34HNh57oBCRKkxNyjTuWAJkTbuGh6jg2Ms",
"type": "scripthash"
diff --git a/test/util/data/txcreatemultisig3.json b/test/util/data/txcreatemultisig3.json
index be96f4c704..3c20a88a91 100644
--- a/test/util/data/txcreatemultisig3.json
+++ b/test/util/data/txcreatemultisig3.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",
+ "desc": "addr(bc1qu9dgdg330r6r84g5mw7wqshg04exv2uttmw2elfwx74h5tgntuzs44gyfg)#yvt39j9m",
"hex": "0020e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",
"address": "bc1qu9dgdg330r6r84g5mw7wqshg04exv2uttmw2elfwx74h5tgntuzs44gyfg",
"type": "witness_v0_scripthash"
diff --git a/test/util/data/txcreatemultisig4.json b/test/util/data/txcreatemultisig4.json
index 08831ecdca..7ae18fd90a 100644
--- a/test/util/data/txcreatemultisig4.json
+++ b/test/util/data/txcreatemultisig4.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL",
+ "desc": "addr(3BoFUz1StqcNcgUTZE5cC1eFhuYFzj3fGH)#466tx6fn",
"hex": "a9146edf12858999f0dae74f9c692e6694ee3621b2ac87",
"address": "3BoFUz1StqcNcgUTZE5cC1eFhuYFzj3fGH",
"type": "scripthash"
diff --git a/test/util/data/txcreatemultisig5.json b/test/util/data/txcreatemultisig5.json
index 93048cf261..98a5c2d8d1 100644
--- a/test/util/data/txcreatemultisig5.json
+++ b/test/util/data/txcreatemultisig5.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 a4051c02398868af83f28f083208fae99a769263 OP_EQUAL",
+ "desc": "addr(3GeGs1eHUxPz5YyuFe9WPpXid2UsUb5Jos)#juhnnegr",
"hex": "a914a4051c02398868af83f28f083208fae99a76926387",
"address": "3GeGs1eHUxPz5YyuFe9WPpXid2UsUb5Jos",
"type": "scripthash"
diff --git a/test/util/data/txcreateoutpubkey1.json b/test/util/data/txcreateoutpubkey1.json
index 42b519bb21..3baf479991 100644
--- a/test/util/data/txcreateoutpubkey1.json
+++ b/test/util/data/txcreateoutpubkey1.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 OP_CHECKSIG",
+ "desc": "pk(02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397)#rk5v7uqw",
"hex": "2102a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397ac",
"type": "pubkey"
}
diff --git a/test/util/data/txcreateoutpubkey2.json b/test/util/data/txcreateoutpubkey2.json
index 52168a889b..78acf1658b 100644
--- a/test/util/data/txcreateoutpubkey2.json
+++ b/test/util/data/txcreateoutpubkey2.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "0 a2516e770582864a6a56ed21a102044e388c62e3",
+ "desc": "addr(bc1q5fgkuac9s2ry56jka5s6zqsyfcugcchry5cwu0)#gm7zhxq2",
"hex": "0014a2516e770582864a6a56ed21a102044e388c62e3",
"address": "bc1q5fgkuac9s2ry56jka5s6zqsyfcugcchry5cwu0",
"type": "witness_v0_keyhash"
diff --git a/test/util/data/txcreateoutpubkey3.json b/test/util/data/txcreateoutpubkey3.json
index fce210f8a3..632ed52ccf 100644
--- a/test/util/data/txcreateoutpubkey3.json
+++ b/test/util/data/txcreateoutpubkey3.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL",
+ "desc": "addr(3GnzN8FqgvYGYdhj8NW6UNxxVv3Uj1ApQn)#zsln680u",
"hex": "a914a5ab14c9804d0d8bf02f1aea4e82780733ad0a8387",
"address": "3GnzN8FqgvYGYdhj8NW6UNxxVv3Uj1ApQn",
"type": "scripthash"
diff --git a/test/util/data/txcreatescript1.json b/test/util/data/txcreatescript1.json
index af1c4c35e2..cdee9dbbfa 100644
--- a/test/util/data/txcreatescript1.json
+++ b/test/util/data/txcreatescript1.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DROP",
+ "desc": "raw(75)#ppey0zqj",
"hex": "75",
"type": "nonstandard"
}
diff --git a/test/util/data/txcreatescript2.json b/test/util/data/txcreatescript2.json
index 2cde70fdf7..1fbae62f4b 100644
--- a/test/util/data/txcreatescript2.json
+++ b/test/util/data/txcreatescript2.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL",
+ "desc": "addr(3C5QarEGh9feKbDJ3QbMf2YNjnMoiPDhNp)#5mx9waq3",
"hex": "a91471ed53322d470bb96657deb786b94f97dd46fb1587",
"address": "3C5QarEGh9feKbDJ3QbMf2YNjnMoiPDhNp",
"type": "scripthash"
diff --git a/test/util/data/txcreatescript3.json b/test/util/data/txcreatescript3.json
index 7a282faf4f..502fe91692 100644
--- a/test/util/data/txcreatescript3.json
+++ b/test/util/data/txcreatescript3.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",
+ "desc": "addr(bc1qp0lfxhnscvsu0j36l36uurgv5tuck4pzuqytkvwqp3kh78cupttqyf705v)#s4fdh9tu",
"hex": "00200bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",
"address": "bc1qp0lfxhnscvsu0j36l36uurgv5tuck4pzuqytkvwqp3kh78cupttqyf705v",
"type": "witness_v0_scripthash"
diff --git a/test/util/data/txcreatescript4.json b/test/util/data/txcreatescript4.json
index 298b37bb4a..1ed89dfff2 100644
--- a/test/util/data/txcreatescript4.json
+++ b/test/util/data/txcreatescript4.json
@@ -14,6 +14,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL",
+ "desc": "addr(3BNQbeFeJJGMAyDxPwWPuqxPMrjsFLjk3f)#fdleltnv",
"hex": "a9146a2c482f4985f57e702f325816c90e3723ca81ae87",
"address": "3BNQbeFeJJGMAyDxPwWPuqxPMrjsFLjk3f",
"type": "scripthash"
diff --git a/test/util/data/txcreatesignv1.json b/test/util/data/txcreatesignv1.json
index ca5e003110..56ef9b195e 100644
--- a/test/util/data/txcreatesignv1.json
+++ b/test/util/data/txcreatesignv1.json
@@ -23,6 +23,7 @@
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",
+ "desc": "addr(193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7)#nw04wh58",
"hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac",
"address": "193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7",
"type": "pubkeyhash"