aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/example_test.py3
-rwxr-xr-xtest/functional/feature_backwards_compatibility.py3
-rwxr-xr-xtest/functional/feature_bip68_sequence.py3
-rwxr-xr-xtest/functional/feature_cltv.py3
-rwxr-xr-xtest/functional/feature_config_args.py3
-rwxr-xr-xtest/functional/feature_filelock.py3
-rwxr-xr-xtest/functional/feature_init.py3
-rwxr-xr-xtest/functional/feature_notifications.py3
-rwxr-xr-xtest/functional/feature_pruning.py3
-rwxr-xr-xtest/functional/feature_rbf.py3
-rwxr-xr-xtest/functional/feature_segwit.py3
-rwxr-xr-xtest/functional/feature_taproot.py1
-rwxr-xr-xtest/functional/interface_bitcoin_cli.py11
-rwxr-xr-xtest/functional/interface_usdt_coinselection.py3
-rwxr-xr-xtest/functional/mempool_compatibility.py3
-rwxr-xr-xtest/functional/mempool_packages.py3
-rwxr-xr-xtest/functional/mempool_persist.py3
-rwxr-xr-xtest/functional/mempool_unbroadcast.py6
-rwxr-xr-xtest/functional/p2p_sendtxrcncl.py151
-rwxr-xr-xtest/functional/rpc_createmultisig.py6
-rwxr-xr-xtest/functional/rpc_fundrawtransaction.py3
-rwxr-xr-xtest/functional/rpc_help.py3
-rwxr-xr-xtest/functional/rpc_invalid_address_message.py3
-rwxr-xr-xtest/functional/rpc_named_arguments.py3
-rwxr-xr-xtest/functional/rpc_packages.py270
-rwxr-xr-xtest/functional/rpc_psbt.py3
-rwxr-xr-xtest/functional/rpc_rawtransaction.py8
-rw-r--r--test/functional/test_framework/authproxy.py6
-rwxr-xr-xtest/functional/test_framework/messages.py12
-rwxr-xr-xtest/functional/test_framework/test_framework.py42
-rwxr-xr-xtest/functional/test_framework/test_node.py4
-rw-r--r--test/functional/test_framework/wallet.py76
-rwxr-xr-xtest/functional/test_runner.py12
-rwxr-xr-xtest/functional/tool_signet_miner.py3
-rwxr-xr-xtest/functional/tool_wallet.py3
-rwxr-xr-xtest/functional/wallet_abandonconflict.py3
-rwxr-xr-xtest/functional/wallet_address_types.py3
-rwxr-xr-xtest/functional/wallet_avoid_mixing_output_types.py3
-rwxr-xr-xtest/functional/wallet_avoidreuse.py2
-rwxr-xr-xtest/functional/wallet_backup.py3
-rwxr-xr-xtest/functional/wallet_balance.py3
-rwxr-xr-xtest/functional/wallet_basic.py3
-rwxr-xr-xtest/functional/wallet_bumpfee.py34
-rwxr-xr-xtest/functional/wallet_coinbase_category.py3
-rwxr-xr-xtest/functional/wallet_create_tx.py3
-rwxr-xr-xtest/functional/wallet_createwallet.py3
-rwxr-xr-xtest/functional/wallet_crosschain.py3
-rwxr-xr-xtest/functional/wallet_descriptor.py3
-rwxr-xr-xtest/functional/wallet_dump.py3
-rwxr-xr-xtest/functional/wallet_encryption.py3
-rwxr-xr-xtest/functional/wallet_fallbackfee.py3
-rwxr-xr-xtest/functional/wallet_fast_rescan.py3
-rwxr-xr-xtest/functional/wallet_groups.py3
-rwxr-xr-xtest/functional/wallet_hd.py3
-rwxr-xr-xtest/functional/wallet_implicitsegwit.py3
-rwxr-xr-xtest/functional/wallet_import_rescan.py3
-rwxr-xr-xtest/functional/wallet_import_with_label.py3
-rwxr-xr-xtest/functional/wallet_importdescriptors.py3
-rwxr-xr-xtest/functional/wallet_importmulti.py3
-rwxr-xr-xtest/functional/wallet_importprunedfunds.py3
-rwxr-xr-xtest/functional/wallet_inactive_hdchains.py3
-rwxr-xr-xtest/functional/wallet_keypool.py3
-rwxr-xr-xtest/functional/wallet_keypool_topup.py3
-rwxr-xr-xtest/functional/wallet_labels.py3
-rwxr-xr-xtest/functional/wallet_listdescriptors.py20
-rwxr-xr-xtest/functional/wallet_listreceivedby.py3
-rwxr-xr-xtest/functional/wallet_listsinceblock.py3
-rwxr-xr-xtest/functional/wallet_listtransactions.py3
-rwxr-xr-xtest/functional/wallet_migration.py13
-rwxr-xr-xtest/functional/wallet_miniscript.py3
-rwxr-xr-xtest/functional/wallet_multisig_descriptor_psbt.py3
-rwxr-xr-xtest/functional/wallet_multiwallet.py1
-rwxr-xr-xtest/functional/wallet_orphanedreward.py3
-rwxr-xr-xtest/functional/wallet_reorgsrestore.py3
-rwxr-xr-xtest/functional/wallet_resendwallettransactions.py3
-rwxr-xr-xtest/functional/wallet_send.py3
-rwxr-xr-xtest/functional/wallet_sendall.py3
-rwxr-xr-xtest/functional/wallet_signer.py3
-rwxr-xr-xtest/functional/wallet_signmessagewithaddress.py3
-rwxr-xr-xtest/functional/wallet_signrawtransactionwithwallet.py3
-rwxr-xr-xtest/functional/wallet_simulaterawtx.py3
-rwxr-xr-xtest/functional/wallet_startup.py3
-rwxr-xr-xtest/functional/wallet_taproot.py3
-rwxr-xr-xtest/functional/wallet_timelock.py3
-rwxr-xr-xtest/functional/wallet_transactiontime_rescan.py3
-rwxr-xr-xtest/functional/wallet_txn_clone.py1
-rwxr-xr-xtest/functional/wallet_txn_doublespend.py1
-rwxr-xr-xtest/functional/wallet_upgradewallet.py3
-rwxr-xr-xtest/functional/wallet_watchonly.py3
-rwxr-xr-xtest/get_previous_releases.py9
-rwxr-xr-xtest/lint/lint-git-commit-check.py2
-rwxr-xr-xtest/lint/lint-whitespace.py2
92 files changed, 534 insertions, 363 deletions
diff --git a/test/functional/example_test.py b/test/functional/example_test.py
index 9cf756060e..3ea7614661 100755
--- a/test/functional/example_test.py
+++ b/test/functional/example_test.py
@@ -79,6 +79,9 @@ class ExampleTest(BitcoinTestFramework):
# Override the set_test_params(), skip_test_if_missing_module(), add_options(), setup_chain(), setup_network()
# and setup_nodes() methods to customize the test setup as required.
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
"""Override test parameters for your individual test.
diff --git a/test/functional/feature_backwards_compatibility.py b/test/functional/feature_backwards_compatibility.py
index 59a12193fd..5fe4a95f6f 100755
--- a/test/functional/feature_backwards_compatibility.py
+++ b/test/functional/feature_backwards_compatibility.py
@@ -32,6 +32,9 @@ from test_framework.util import (
class BackwardsCompatibilityTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 10
diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py
index 5b43fe4f8e..f8854d0e8d 100755
--- a/test/functional/feature_bip68_sequence.py
+++ b/test/functional/feature_bip68_sequence.py
@@ -44,6 +44,9 @@ SEQUENCE_LOCKTIME_MASK = 0x0000ffff
NOT_FINAL_ERROR = "non-BIP68-final"
class BIP68Test(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index 9d32749a08..44725ad85e 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -8,6 +8,7 @@ Test that the CHECKLOCKTIMEVERIFY soft-fork activates.
"""
from test_framework.blocktools import (
+ TIME_GENESIS_BLOCK,
create_block,
create_coinbase,
)
@@ -61,7 +62,7 @@ def cltv_invalidate(tx, failure_reason):
# +-------------------------------------------------+------------+--------------+
[[OP_CHECKLOCKTIMEVERIFY], None, None],
[[OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP], None, None],
- [[CScriptNum(100), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, 1296688602], # timestamp of genesis block
+ [[CScriptNum(100), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, TIME_GENESIS_BLOCK],
[[CScriptNum(100), OP_CHECKLOCKTIMEVERIFY, OP_DROP], 0, 50],
[[CScriptNum(50), OP_CHECKLOCKTIMEVERIFY, OP_DROP], SEQUENCE_FINAL, 50],
][failure_reason]
diff --git a/test/functional/feature_config_args.py b/test/functional/feature_config_args.py
index 112dbb9e6a..fbaf93bac4 100755
--- a/test/functional/feature_config_args.py
+++ b/test/functional/feature_config_args.py
@@ -12,6 +12,9 @@ from test_framework import util
class ConfArgsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/feature_filelock.py b/test/functional/feature_filelock.py
index 945ece6a33..025fe38d30 100755
--- a/test/functional/feature_filelock.py
+++ b/test/functional/feature_filelock.py
@@ -11,6 +11,9 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.test_node import ErrorMatch
class FilelockTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/feature_init.py b/test/functional/feature_init.py
index 56d093c396..cf626bc7c6 100755
--- a/test/functional/feature_init.py
+++ b/test/functional/feature_init.py
@@ -17,6 +17,9 @@ class InitStressTest(BitcoinTestFramework):
subsequent starts.
"""
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = False
self.num_nodes = 1
diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py
index e038afa1ad..8e821295b8 100755
--- a/test/functional/feature_notifications.py
+++ b/test/functional/feature_notifications.py
@@ -24,6 +24,9 @@ def notify_outputname(walletname, txid):
class NotificationsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
index 7dbeccbc09..58bc6ca67c 100755
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -76,6 +76,9 @@ def calc_usage(blockdir):
return sum(os.path.getsize(blockdir + f) for f in os.listdir(blockdir) if os.path.isfile(os.path.join(blockdir, f))) / (1024. * 1024.)
class PruneTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 6
diff --git a/test/functional/feature_rbf.py b/test/functional/feature_rbf.py
index 7603248ae5..1d46959a4d 100755
--- a/test/functional/feature_rbf.py
+++ b/test/functional/feature_rbf.py
@@ -21,6 +21,9 @@ from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE
MAX_REPLACEMENT_LIMIT = 100
class ReplaceByFeeTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index 7f2a615be1..34eca32c11 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -78,6 +78,9 @@ txs_mined = {} # txindex from txid to blockhash
class SegWitTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 3
diff --git a/test/functional/feature_taproot.py b/test/functional/feature_taproot.py
index 31a6b31225..dbe51f8f54 100755
--- a/test/functional/feature_taproot.py
+++ b/test/functional/feature_taproot.py
@@ -1274,6 +1274,7 @@ UTXOData = namedtuple('UTXOData', 'outpoint,output,spender')
class TaprootTest(BitcoinTestFramework):
def add_options(self, parser):
+ self.add_wallet_options(parser)
parser.add_argument("--dumptests", dest="dump_tests", default=False, action="store_true",
help="Dump generated test cases to directory set by TEST_DUMP_DIR environment variable")
diff --git a/test/functional/interface_bitcoin_cli.py b/test/functional/interface_bitcoin_cli.py
index db5564ac50..b1369c2615 100755
--- a/test/functional/interface_bitcoin_cli.py
+++ b/test/functional/interface_bitcoin_cli.py
@@ -66,11 +66,12 @@ def cli_get_info_string_to_dict(cli_get_info_string):
class TestBitcoinCli(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
- if self.is_specified_wallet_compiled():
- self.requires_wallet = True
def skip_test_if_missing_module(self):
self.skip_if_no_cli()
@@ -84,6 +85,11 @@ class TestBitcoinCli(BitcoinTestFramework):
rpc_response = self.nodes[0].getblockchaininfo()
assert_equal(cli_response, rpc_response)
+ self.log.info("Test named arguments")
+ assert_equal(self.nodes[0].cli.echo(0, 1, arg3=3, arg5=5), ['0', '1', None, '3', None, '5'])
+ assert_raises_rpc_error(-8, "Parameter arg1 specified twice both as positional and named argument", self.nodes[0].cli.echo, 0, 1, arg1=1)
+ assert_raises_rpc_error(-8, "Parameter arg1 specified twice both as positional and named argument", self.nodes[0].cli.echo, 0, None, 2, arg1=1)
+
user, password = get_auth_cookie(self.nodes[0].datadir, self.chain)
self.log.info("Test -stdinrpcpass option")
@@ -114,6 +120,7 @@ class TestBitcoinCli(BitcoinTestFramework):
self.log.info("Test -getinfo returns expected network and blockchain info")
if self.is_specified_wallet_compiled():
+ self.import_deterministic_coinbase_privkeys()
self.nodes[0].encryptwallet(password)
cli_get_info_string = self.nodes[0].cli('-getinfo').send_cli()
cli_get_info = cli_get_info_string_to_dict(cli_get_info_string)
diff --git a/test/functional/interface_usdt_coinselection.py b/test/functional/interface_usdt_coinselection.py
index ef32feda99..a3c830bb51 100755
--- a/test/functional/interface_usdt_coinselection.py
+++ b/test/functional/interface_usdt_coinselection.py
@@ -97,6 +97,9 @@ int trace_aps_create_tx(struct pt_regs *ctx) {
class CoinSelectionTracepointTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
diff --git a/test/functional/mempool_compatibility.py b/test/functional/mempool_compatibility.py
index c545a7f68d..7f03a215b2 100755
--- a/test/functional/mempool_compatibility.py
+++ b/test/functional/mempool_compatibility.py
@@ -21,6 +21,9 @@ from test_framework.wallet import (
class MempoolCompatibilityTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.wallet_names = [None]
diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py
index def0b1fce4..a8ebcd875b 100755
--- a/test/functional/mempool_packages.py
+++ b/test/functional/mempool_packages.py
@@ -28,6 +28,9 @@ assert CUSTOM_DESCENDANT_LIMIT >= CUSTOM_ANCESTOR_LIMIT
class MempoolPackagesTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [
diff --git a/test/functional/mempool_persist.py b/test/functional/mempool_persist.py
index b6fa7fbd91..1c06426256 100755
--- a/test/functional/mempool_persist.py
+++ b/test/functional/mempool_persist.py
@@ -50,6 +50,9 @@ from test_framework.wallet import MiniWallet
class MempoolPersistTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.num_nodes = 3
self.extra_args = [[], ["-persistmempool=0"], []]
diff --git a/test/functional/mempool_unbroadcast.py b/test/functional/mempool_unbroadcast.py
index 7587adc257..5487ca40c1 100755
--- a/test/functional/mempool_unbroadcast.py
+++ b/test/functional/mempool_unbroadcast.py
@@ -15,10 +15,11 @@ from test_framework.wallet import MiniWallet
MAX_INITIAL_BROADCAST_DELAY = 15 * 60 # 15 minutes in seconds
class MempoolUnbroadcastTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
- if self.is_wallet_compiled():
- self.requires_wallet = True
def run_test(self):
self.wallet = MiniWallet(self.nodes[0])
@@ -35,6 +36,7 @@ class MempoolUnbroadcastTest(BitcoinTestFramework):
self.log.info("Generate transactions that only node 0 knows about")
if self.is_wallet_compiled():
+ self.import_deterministic_coinbase_privkeys()
# generate a wallet txn
addr = node.getnewaddress()
wallet_tx_hsh = node.sendtoaddress(addr, 0.0001)
diff --git a/test/functional/p2p_sendtxrcncl.py b/test/functional/p2p_sendtxrcncl.py
index fed9832a7d..0e349ef70c 100755
--- a/test/functional/p2p_sendtxrcncl.py
+++ b/test/functional/p2p_sendtxrcncl.py
@@ -10,6 +10,7 @@ from test_framework.messages import (
msg_verack,
msg_version,
msg_wtxidrelay,
+ NODE_BLOOM,
)
from test_framework.p2p import (
P2PInterface,
@@ -54,10 +55,8 @@ class PeerTrackMsgOrder(P2PInterface):
super().on_message(message)
self.messages.append(message)
-def create_sendtxrcncl_msg(initiator=True):
+def create_sendtxrcncl_msg():
sendtxrcncl_msg = msg_sendtxrcncl()
- sendtxrcncl_msg.initiator = initiator
- sendtxrcncl_msg.responder = not initiator
sendtxrcncl_msg.version = 1
sendtxrcncl_msg.salt = 2
return sendtxrcncl_msg
@@ -68,11 +67,11 @@ class SendTxRcnclTest(BitcoinTestFramework):
self.extra_args = [['-txreconciliation']]
def run_test(self):
+ # Check everything concerning *sending* SENDTXRCNCL
+ # First, *sending* to *inbound*.
self.log.info('SENDTXRCNCL sent to an inbound')
peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=True, wait_for_verack=True)
assert peer.sendtxrcncl_msg_received
- assert not peer.sendtxrcncl_msg_received.initiator
- assert peer.sendtxrcncl_msg_received.responder
assert_equal(peer.sendtxrcncl_msg_received.version, 1)
self.nodes[0].disconnect_p2ps()
@@ -81,7 +80,7 @@ class SendTxRcnclTest(BitcoinTestFramework):
peer.wait_for_verack()
verack_index = [i for i, msg in enumerate(peer.messages) if msg.msgtype == b'verack'][0]
sendtxrcncl_index = [i for i, msg in enumerate(peer.messages) if msg.msgtype == b'sendtxrcncl'][0]
- assert(sendtxrcncl_index < verack_index)
+ assert sendtxrcncl_index < verack_index
self.nodes[0].disconnect_p2ps()
self.log.info('SENDTXRCNCL on pre-WTXID version should not be sent')
@@ -108,30 +107,77 @@ class SendTxRcnclTest(BitcoinTestFramework):
assert not peer.sendtxrcncl_msg_received
self.nodes[0].disconnect_p2ps()
+ self.log.info('SENDTXRCNCL for fRelay=false should not be sent (with NODE_BLOOM offered)')
+ self.restart_node(0, ["-peerbloomfilters", "-txreconciliation"])
+ peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=False, wait_for_verack=False)
+ no_txrelay_version_msg = msg_version()
+ no_txrelay_version_msg.nVersion = P2P_VERSION
+ no_txrelay_version_msg.strSubVer = P2P_SUBVERSION
+ no_txrelay_version_msg.nServices = P2P_SERVICES
+ no_txrelay_version_msg.relay = 0
+ peer.send_message(no_txrelay_version_msg)
+ peer.wait_for_verack()
+ assert peer.nServices & NODE_BLOOM != 0
+ assert not peer.sendtxrcncl_msg_received
+ self.nodes[0].disconnect_p2ps()
+
+ # Now, *sending* to *outbound*.
+ self.log.info('SENDTXRCNCL sent to an outbound')
+ peer = self.nodes[0].add_outbound_p2p_connection(
+ SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="outbound-full-relay")
+ assert peer.sendtxrcncl_msg_received
+ assert_equal(peer.sendtxrcncl_msg_received.version, 1)
+ self.nodes[0].disconnect_p2ps()
+
+ self.log.info('SENDTXRCNCL should not be sent if block-relay-only')
+ peer = self.nodes[0].add_outbound_p2p_connection(
+ SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="block-relay-only")
+ assert not peer.sendtxrcncl_msg_received
+ self.nodes[0].disconnect_p2ps()
+
+ self.log.info("SENDTXRCNCL should not be sent if feeler")
+ peer = self.nodes[0].add_outbound_p2p_connection(P2PFeelerReceiver(), p2p_idx=0, connection_type="feeler")
+ assert not peer.sendtxrcncl_msg_received
+ self.nodes[0].disconnect_p2ps()
+
+ self.log.info("SENDTXRCNCL should not be sent if addrfetch")
+ peer = self.nodes[0].add_outbound_p2p_connection(
+ SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="addr-fetch")
+ assert not peer.sendtxrcncl_msg_received
+ self.nodes[0].disconnect_p2ps()
+
+ self.log.info('SENDTXRCNCL not sent if -txreconciliation flag is not set')
+ self.restart_node(0, [])
+ peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=True, wait_for_verack=True)
+ assert not peer.sendtxrcncl_msg_received
+ self.nodes[0].disconnect_p2ps()
+
+ self.log.info('SENDTXRCNCL not sent if blocksonly is set')
+ self.restart_node(0, ["-txreconciliation", "-blocksonly"])
+ peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=True, wait_for_verack=True)
+ assert not peer.sendtxrcncl_msg_received
+ self.nodes[0].disconnect_p2ps()
+
+ # Check everything concerning *receiving* SENDTXRCNCL
+ # First, receiving from *inbound*.
+ self.restart_node(0, ["-txreconciliation"])
self.log.info('valid SENDTXRCNCL received')
peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
- peer.send_message(create_sendtxrcncl_msg())
- self.wait_until(lambda : "sendtxrcncl" in self.nodes[0].getpeerinfo()[-1]["bytesrecv_per_msg"])
+ with self.nodes[0].assert_debug_log(["received: sendtxrcncl"]):
+ peer.send_message(create_sendtxrcncl_msg())
self.log.info('second SENDTXRCNCL triggers a disconnect')
with self.nodes[0].assert_debug_log(["(sendtxrcncl received from already registered peer); disconnecting"]):
peer.send_message(create_sendtxrcncl_msg())
peer.wait_for_disconnect()
- self.log.info('SENDTXRCNCL with initiator=responder=0 triggers a disconnect')
- sendtxrcncl_no_role = create_sendtxrcncl_msg()
- sendtxrcncl_no_role.initiator = False
- sendtxrcncl_no_role.responder = False
+ self.restart_node(0, [])
+ self.log.info('SENDTXRCNCL if no txreconciliation supported is ignored')
peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
- with self.nodes[0].assert_debug_log(["txreconciliation protocol violation"]):
- peer.send_message(sendtxrcncl_no_role)
- peer.wait_for_disconnect()
+ with self.nodes[0].assert_debug_log(['ignored, as our node does not have txreconciliation enabled']):
+ peer.send_message(create_sendtxrcncl_msg())
+ self.nodes[0].disconnect_p2ps()
- self.log.info('SENDTXRCNCL with initiator=0 and responder=1 from inbound triggers a disconnect')
- sendtxrcncl_wrong_role = create_sendtxrcncl_msg(initiator=False)
- peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
- with self.nodes[0].assert_debug_log(["txreconciliation protocol violation"]):
- peer.send_message(sendtxrcncl_wrong_role)
- peer.wait_for_disconnect()
+ self.restart_node(0, ["-txreconciliation"])
self.log.info('SENDTXRCNCL with version=0 triggers a disconnect')
sendtxrcncl_low_version = create_sendtxrcncl_msg()
@@ -141,6 +187,26 @@ class SendTxRcnclTest(BitcoinTestFramework):
peer.send_message(sendtxrcncl_low_version)
peer.wait_for_disconnect()
+ self.log.info('SENDTXRCNCL with version=2 is valid')
+ sendtxrcncl_higher_version = create_sendtxrcncl_msg()
+ sendtxrcncl_higher_version.version = 2
+ peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=True, wait_for_verack=False)
+ with self.nodes[0].assert_debug_log(['Register peer=1']):
+ peer.send_message(sendtxrcncl_higher_version)
+ self.nodes[0].disconnect_p2ps()
+
+ self.log.info('unexpected SENDTXRCNCL is ignored')
+ peer = self.nodes[0].add_p2p_connection(PeerNoVerack(), send_version=False, wait_for_verack=False)
+ old_version_msg = msg_version()
+ old_version_msg.nVersion = 70015
+ old_version_msg.strSubVer = P2P_SUBVERSION
+ old_version_msg.nServices = P2P_SERVICES
+ old_version_msg.relay = 1
+ peer.send_message(old_version_msg)
+ with self.nodes[0].assert_debug_log(['Ignore unexpected txreconciliation signal']):
+ peer.send_message(create_sendtxrcncl_msg())
+ self.nodes[0].disconnect_p2ps()
+
self.log.info('sending SENDTXRCNCL after sending VERACK triggers a disconnect')
peer = self.nodes[0].add_p2p_connection(P2PInterface())
with self.nodes[0].assert_debug_log(["sendtxrcncl received after verack"]):
@@ -154,53 +220,14 @@ class SendTxRcnclTest(BitcoinTestFramework):
peer.send_message(msg_verack())
self.nodes[0].disconnect_p2ps()
- self.log.info('SENDTXRCNCL sent to an outbound')
- peer = self.nodes[0].add_outbound_p2p_connection(
- SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="outbound-full-relay")
- assert peer.sendtxrcncl_msg_received
- assert peer.sendtxrcncl_msg_received.initiator
- assert not peer.sendtxrcncl_msg_received.responder
- assert_equal(peer.sendtxrcncl_msg_received.version, 1)
- self.nodes[0].disconnect_p2ps()
-
- self.log.info('SENDTXRCNCL should not be sent if block-relay-only')
- peer = self.nodes[0].add_outbound_p2p_connection(
- SendTxrcnclReceiver(), wait_for_verack=True, p2p_idx=0, connection_type="block-relay-only")
- assert not peer.sendtxrcncl_msg_received
- self.nodes[0].disconnect_p2ps()
-
- self.log.info("SENDTXRCNCL should not be sent if feeler")
- peer = self.nodes[0].add_outbound_p2p_connection(P2PFeelerReceiver(), p2p_idx=0, connection_type="feeler")
- assert not peer.sendtxrcncl_msg_received
- self.nodes[0].disconnect_p2ps()
-
+ # Now, *receiving* from *outbound*.
self.log.info('SENDTXRCNCL if block-relay-only triggers a disconnect')
peer = self.nodes[0].add_outbound_p2p_connection(
PeerNoVerack(), wait_for_verack=False, p2p_idx=0, connection_type="block-relay-only")
with self.nodes[0].assert_debug_log(["we indicated no tx relay; disconnecting"]):
- peer.send_message(create_sendtxrcncl_msg(initiator=False))
- peer.wait_for_disconnect()
-
- self.log.info('SENDTXRCNCL with initiator=1 and responder=0 from outbound triggers a disconnect')
- sendtxrcncl_wrong_role = create_sendtxrcncl_msg(initiator=True)
- peer = self.nodes[0].add_outbound_p2p_connection(
- PeerNoVerack(), wait_for_verack=False, p2p_idx=0, connection_type="outbound-full-relay")
- with self.nodes[0].assert_debug_log(["txreconciliation protocol violation"]):
- peer.send_message(sendtxrcncl_wrong_role)
+ peer.send_message(create_sendtxrcncl_msg())
peer.wait_for_disconnect()
- self.log.info('SENDTXRCNCL not sent if -txreconciliation flag is not set')
- self.restart_node(0, [])
- peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=True, wait_for_verack=True)
- assert not peer.sendtxrcncl_msg_received
- self.nodes[0].disconnect_p2ps()
-
- self.log.info('SENDTXRCNCL not sent if blocksonly is set')
- self.restart_node(0, ["-txreconciliation", "-blocksonly"])
- peer = self.nodes[0].add_p2p_connection(SendTxrcnclReceiver(), send_version=True, wait_for_verack=True)
- assert not peer.sendtxrcncl_msg_received
- self.nodes[0].disconnect_p2ps()
-
if __name__ == '__main__':
SendTxRcnclTest().main()
diff --git a/test/functional/rpc_createmultisig.py b/test/functional/rpc_createmultisig.py
index 1ad3fc24c9..5b6eb2d22c 100755
--- a/test/functional/rpc_createmultisig.py
+++ b/test/functional/rpc_createmultisig.py
@@ -24,12 +24,13 @@ from test_framework.wallet import (
)
class RpcCreateMultiSigTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 3
self.supports_cli = False
- if self.is_bdb_compiled():
- self.requires_wallet = True
def get_keys(self):
self.pub = []
@@ -50,6 +51,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
self.wallet = MiniWallet(test_node=node0)
if self.is_bdb_compiled():
+ self.import_deterministic_coinbase_privkeys()
self.check_addmultisigaddress_errors()
self.log.info('Generating blocks ...')
diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py
index 1152995ac9..0f77d6ad30 100755
--- a/test/functional/rpc_fundrawtransaction.py
+++ b/test/functional/rpc_fundrawtransaction.py
@@ -35,6 +35,9 @@ def get_unspent(listunspent, amount):
raise AssertionError('Could not find unspent with amount={}'.format(amount))
class RawTransactionsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 4
self.setup_clean_chain = True
diff --git a/test/functional/rpc_help.py b/test/functional/rpc_help.py
index f683577c47..a2de8e3ef5 100755
--- a/test/functional/rpc_help.py
+++ b/test/functional/rpc_help.py
@@ -43,6 +43,9 @@ def process_mapping(fname):
class HelpRpcTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
self.supports_cli = False
diff --git a/test/functional/rpc_invalid_address_message.py b/test/functional/rpc_invalid_address_message.py
index fcc49d0a75..1694020663 100755
--- a/test/functional/rpc_invalid_address_message.py
+++ b/test/functional/rpc_invalid_address_message.py
@@ -39,6 +39,9 @@ INVALID_ADDRESS = 'asfah14i8fajz0123f'
INVALID_ADDRESS_2 = '1q049ldschfnwystcqnsvyfpj23mpsg3jcedq9xv'
class InvalidAddressErrorMessageTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/rpc_named_arguments.py b/test/functional/rpc_named_arguments.py
index 41b9312969..cc3ee9efd5 100755
--- a/test/functional/rpc_named_arguments.py
+++ b/test/functional/rpc_named_arguments.py
@@ -30,6 +30,9 @@ class NamedArgumentTest(BitcoinTestFramework):
assert_equal(node.echo(arg1=1), [None, 1])
assert_equal(node.echo(arg9=None), [None]*10)
assert_equal(node.echo(arg0=0,arg3=3,arg9=9), [0] + [None]*2 + [3] + [None]*5 + [9])
+ assert_equal(node.echo(0, 1, arg3=3, arg5=5), [0, 1, None, 3, None, 5])
+ assert_raises_rpc_error(-8, "Parameter arg1 specified twice both as positional and named argument", node.echo, 0, 1, arg1=1)
+ assert_raises_rpc_error(-8, "Parameter arg1 specified twice both as positional and named argument", node.echo, 0, None, 2, arg1=1)
if __name__ == '__main__':
NamedArgumentTest().main()
diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py
index 9a563cbf5f..a512a6b675 100755
--- a/test/functional/rpc_packages.py
+++ b/test/functional/rpc_packages.py
@@ -7,31 +7,24 @@
from decimal import Decimal
import random
-from test_framework.address import ADDRESS_BCRT1_P2WSH_OP_TRUE
-from test_framework.test_framework import BitcoinTestFramework
+from test_framework.blocktools import COINBASE_MATURITY
from test_framework.messages import (
MAX_BIP125_RBF_SEQUENCE,
- COIN,
- CTxInWitness,
tx_from_hex,
)
from test_framework.p2p import P2PTxInvStore
-from test_framework.script import (
- CScript,
- OP_TRUE,
-)
+from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_fee_amount,
assert_raises_rpc_error,
)
from test_framework.wallet import (
- create_child_with_parents,
- create_raw_chain,
DEFAULT_FEE,
- make_chain,
+ MiniWallet,
)
+
class RPCPackagesTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
@@ -49,38 +42,38 @@ class RPCPackagesTest(BitcoinTestFramework):
assert_equal(shuffled_testres, self.nodes[0].testmempoolaccept(shuffled_package))
def run_test(self):
- self.log.info("Generate blocks to create UTXOs")
node = self.nodes[0]
- self.privkeys = [node.get_deterministic_priv_key().key]
- self.address = node.get_deterministic_priv_key().address
- self.coins = []
- # The last 100 coinbase transactions are premature
- for b in self.generatetoaddress(node, 220, self.address)[:-100]:
- coinbase = node.getblock(blockhash=b, verbosity=2)["tx"][0]
- self.coins.append({
+
+ # get an UTXO that requires signature to be spent
+ deterministic_address = node.get_deterministic_priv_key().address
+ blockhash = self.generatetoaddress(node, 1, deterministic_address)[0]
+ coinbase = node.getblock(blockhash=blockhash, verbosity=2)["tx"][0]
+ coin = {
"txid": coinbase["txid"],
"amount": coinbase["vout"][0]["value"],
"scriptPubKey": coinbase["vout"][0]["scriptPubKey"],
- })
+ "vout": 0,
+ "height": 0
+ }
+ self.wallet = MiniWallet(self.nodes[0])
+ self.generate(self.wallet, COINBASE_MATURITY + 100) # blocks generated for inputs
+
+ self.log.info("Create some transactions")
# Create some transactions that can be reused throughout the test. Never submit these to mempool.
self.independent_txns_hex = []
self.independent_txns_testres = []
for _ in range(3):
- coin = self.coins.pop()
- rawtx = node.createrawtransaction([{"txid": coin["txid"], "vout": 0}],
- {self.address : coin["amount"] - Decimal("0.0001")})
- signedtx = node.signrawtransactionwithkey(hexstring=rawtx, privkeys=self.privkeys)
- assert signedtx["complete"]
- testres = node.testmempoolaccept([signedtx["hex"]])
+ tx_hex = self.wallet.create_self_transfer(fee_rate=Decimal("0.0001"))["hex"]
+ testres = self.nodes[0].testmempoolaccept([tx_hex])
assert testres[0]["allowed"]
- self.independent_txns_hex.append(signedtx["hex"])
+ self.independent_txns_hex.append(tx_hex)
# testmempoolaccept returns a list of length one, avoid creating a 2D list
self.independent_txns_testres.append(testres[0])
self.independent_txns_testres_blank = [{
"txid": res["txid"], "wtxid": res["wtxid"]} for res in self.independent_txns_testres]
- self.test_independent()
+ self.test_independent(coin)
self.test_chain()
self.test_multiple_children()
self.test_multiple_parents()
@@ -88,14 +81,15 @@ class RPCPackagesTest(BitcoinTestFramework):
self.test_rbf()
self.test_submitpackage()
- def test_independent(self):
+ def test_independent(self, coin):
self.log.info("Test multiple independent transactions in a package")
node = self.nodes[0]
# For independent transactions, order doesn't matter.
self.assert_testres_equal(self.independent_txns_hex, self.independent_txns_testres)
self.log.info("Test an otherwise valid package with an extra garbage tx appended")
- garbage_tx = node.createrawtransaction([{"txid": "00" * 32, "vout": 5}], {self.address: 1})
+ address = node.get_deterministic_priv_key().address
+ garbage_tx = node.createrawtransaction([{"txid": "00" * 32, "vout": 5}], {address: 1})
tx = tx_from_hex(garbage_tx)
# Only the txid and wtxids are returned because validation is incomplete for the independent txns.
# Package validation is atomic: if the node cannot find a UTXO for any single tx in the package,
@@ -105,9 +99,8 @@ class RPCPackagesTest(BitcoinTestFramework):
self.assert_testres_equal(package_bad, testres_bad)
self.log.info("Check testmempoolaccept tells us when some transactions completed validation successfully")
- coin = self.coins.pop()
tx_bad_sig_hex = node.createrawtransaction([{"txid": coin["txid"], "vout": 0}],
- {self.address : coin["amount"] - Decimal("0.0001")})
+ {address : coin["amount"] - Decimal("0.0001")})
tx_bad_sig = tx_from_hex(tx_bad_sig_hex)
testres_bad_sig = node.testmempoolaccept(self.independent_txns_hex + [tx_bad_sig_hex])
# By the time the signature for the last transaction is checked, all the other transactions
@@ -120,23 +113,22 @@ class RPCPackagesTest(BitcoinTestFramework):
}])
self.log.info("Check testmempoolaccept reports txns in packages that exceed max feerate")
- coin = self.coins.pop()
- tx_high_fee_raw = node.createrawtransaction([{"txid": coin["txid"], "vout": 0}],
- {self.address : coin["amount"] - Decimal("0.999")})
- tx_high_fee_signed = node.signrawtransactionwithkey(hexstring=tx_high_fee_raw, privkeys=self.privkeys)
- assert tx_high_fee_signed["complete"]
- tx_high_fee = tx_from_hex(tx_high_fee_signed["hex"])
- testres_high_fee = node.testmempoolaccept([tx_high_fee_signed["hex"]])
+ tx_high_fee = self.wallet.create_self_transfer(fee=Decimal("0.999"))
+ testres_high_fee = node.testmempoolaccept([tx_high_fee["hex"]])
assert_equal(testres_high_fee, [
- {"txid": tx_high_fee.rehash(), "wtxid": tx_high_fee.getwtxid(), "allowed": False, "reject-reason": "max-fee-exceeded"}
+ {"txid": tx_high_fee["txid"], "wtxid": tx_high_fee["wtxid"], "allowed": False, "reject-reason": "max-fee-exceeded"}
])
- package_high_fee = [tx_high_fee_signed["hex"]] + self.independent_txns_hex
+ package_high_fee = [tx_high_fee["hex"]] + self.independent_txns_hex
testres_package_high_fee = node.testmempoolaccept(package_high_fee)
assert_equal(testres_package_high_fee, testres_high_fee + self.independent_txns_testres_blank)
def test_chain(self):
node = self.nodes[0]
- (chain_hex, chain_txns) = create_raw_chain(node, self.coins.pop(), self.address, self.privkeys)
+
+ chain = self.wallet.create_self_transfer_chain(chain_length=25)
+ chain_hex = chain["chain_hex"]
+ chain_txns = chain["chain_txns"]
+
self.log.info("Check that testmempoolaccept requires packages to be sorted by dependency")
assert_equal(node.testmempoolaccept(rawtxs=chain_hex[::-1]),
[{"txid": tx.rehash(), "wtxid": tx.getwtxid(), "package-error": "package-not-sorted"} for tx in chain_txns[::-1]])
@@ -158,78 +150,57 @@ class RPCPackagesTest(BitcoinTestFramework):
def test_multiple_children(self):
node = self.nodes[0]
-
self.log.info("Testmempoolaccept a package in which a transaction has two children within the package")
- first_coin = self.coins.pop()
- value = (first_coin["amount"] - Decimal("0.0002")) / 2 # Deduct reasonable fee and make 2 outputs
- inputs = [{"txid": first_coin["txid"], "vout": 0}]
- outputs = [{self.address : value}, {ADDRESS_BCRT1_P2WSH_OP_TRUE : value}]
- rawtx = node.createrawtransaction(inputs, outputs)
-
- parent_signed = node.signrawtransactionwithkey(hexstring=rawtx, privkeys=self.privkeys)
- assert parent_signed["complete"]
- parent_tx = tx_from_hex(parent_signed["hex"])
- parent_txid = parent_tx.rehash()
- assert node.testmempoolaccept([parent_signed["hex"]])[0]["allowed"]
- parent_locking_script_a = parent_tx.vout[0].scriptPubKey.hex()
- child_value = value - Decimal("0.0001")
+ parent_tx = self.wallet.create_self_transfer_multi(num_outputs=2)
+ assert node.testmempoolaccept([parent_tx["hex"]])[0]["allowed"]
# Child A
- (_, tx_child_a_hex, _, _) = make_chain(node, self.address, self.privkeys, parent_txid, child_value, 0, parent_locking_script_a)
- assert not node.testmempoolaccept([tx_child_a_hex])[0]["allowed"]
+ child_a_tx = self.wallet.create_self_transfer(utxo_to_spend=parent_tx["new_utxos"][0])
+ assert not node.testmempoolaccept([child_a_tx["hex"]])[0]["allowed"]
# Child B
- rawtx_b = node.createrawtransaction([{"txid": parent_txid, "vout": 1}], {self.address : child_value})
- tx_child_b = tx_from_hex(rawtx_b)
- tx_child_b.wit.vtxinwit = [CTxInWitness()]
- tx_child_b.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
- tx_child_b_hex = tx_child_b.serialize().hex()
- assert not node.testmempoolaccept([tx_child_b_hex])[0]["allowed"]
+ child_b_tx = self.wallet.create_self_transfer(utxo_to_spend=parent_tx["new_utxos"][1])
+ assert not node.testmempoolaccept([child_b_tx["hex"]])[0]["allowed"]
self.log.info("Testmempoolaccept with entire package, should work with children in either order")
- testres_multiple_ab = node.testmempoolaccept(rawtxs=[parent_signed["hex"], tx_child_a_hex, tx_child_b_hex])
- testres_multiple_ba = node.testmempoolaccept(rawtxs=[parent_signed["hex"], tx_child_b_hex, tx_child_a_hex])
+ testres_multiple_ab = node.testmempoolaccept(rawtxs=[parent_tx["hex"], child_a_tx["hex"], child_b_tx["hex"]])
+ testres_multiple_ba = node.testmempoolaccept(rawtxs=[parent_tx["hex"], child_b_tx["hex"], child_a_tx["hex"]])
assert all([testres["allowed"] for testres in testres_multiple_ab + testres_multiple_ba])
testres_single = []
# Test accept and then submit each one individually, which should be identical to package testaccept
- for rawtx in [parent_signed["hex"], tx_child_a_hex, tx_child_b_hex]:
+ for rawtx in [parent_tx["hex"], child_a_tx["hex"], child_b_tx["hex"]]:
testres = node.testmempoolaccept([rawtx])
testres_single.append(testres[0])
# Submit the transaction now so its child should have no problem validating
node.sendrawtransaction(rawtx)
assert_equal(testres_single, testres_multiple_ab)
-
def test_multiple_parents(self):
node = self.nodes[0]
-
self.log.info("Testmempoolaccept a package in which a transaction has multiple parents within the package")
+
for num_parents in [2, 10, 24]:
# Test a package with num_parents parents and 1 child transaction.
+ parent_coins = []
package_hex = []
- parents_tx = []
- values = []
- parent_locking_scripts = []
+
for _ in range(num_parents):
- parent_coin = self.coins.pop()
- value = parent_coin["amount"]
- (tx, txhex, value, parent_locking_script) = make_chain(node, self.address, self.privkeys, parent_coin["txid"], value)
- package_hex.append(txhex)
- parents_tx.append(tx)
- values.append(value)
- parent_locking_scripts.append(parent_locking_script)
- child_hex = create_child_with_parents(node, self.address, self.privkeys, parents_tx, values, parent_locking_scripts)
- # Package accept should work with the parents in any order (as long as parents come before child)
+ # Package accept should work with the parents in any order (as long as parents come before child)
+ parent_tx = self.wallet.create_self_transfer()
+ parent_coins.append(parent_tx["new_utxo"])
+ package_hex.append(parent_tx["hex"])
+
+ child_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=parent_coins, fee_per_output=2000)
for _ in range(10):
random.shuffle(package_hex)
- testres_multiple = node.testmempoolaccept(rawtxs=package_hex + [child_hex])
+ testres_multiple = node.testmempoolaccept(rawtxs=package_hex + [child_tx['hex']])
assert all([testres["allowed"] for testres in testres_multiple])
testres_single = []
# Test accept and then submit each one individually, which should be identical to package testaccept
- for rawtx in package_hex + [child_hex]:
+ for rawtx in package_hex + [child_tx["hex"]]:
testres_single.append(node.testmempoolaccept([rawtx])[0])
# Submit the transaction now so its child should have no problem validating
node.sendrawtransaction(rawtx)
@@ -237,77 +208,60 @@ class RPCPackagesTest(BitcoinTestFramework):
def test_conflicting(self):
node = self.nodes[0]
- prevtx = self.coins.pop()
- inputs = [{"txid": prevtx["txid"], "vout": 0}]
- output1 = {node.get_deterministic_priv_key().address: 50 - 0.00125}
- output2 = {ADDRESS_BCRT1_P2WSH_OP_TRUE: 50 - 0.00125}
+ coin = self.wallet.get_utxo()
# tx1 and tx2 share the same inputs
- rawtx1 = node.createrawtransaction(inputs, output1)
- rawtx2 = node.createrawtransaction(inputs, output2)
- signedtx1 = node.signrawtransactionwithkey(hexstring=rawtx1, privkeys=self.privkeys)
- signedtx2 = node.signrawtransactionwithkey(hexstring=rawtx2, privkeys=self.privkeys)
- tx1 = tx_from_hex(signedtx1["hex"])
- tx2 = tx_from_hex(signedtx2["hex"])
- assert signedtx1["complete"]
- assert signedtx2["complete"]
+ tx1 = self.wallet.create_self_transfer(utxo_to_spend=coin)
+ tx2 = self.wallet.create_self_transfer(utxo_to_spend=coin)
# Ensure tx1 and tx2 are valid by themselves
- assert node.testmempoolaccept([signedtx1["hex"]])[0]["allowed"]
- assert node.testmempoolaccept([signedtx2["hex"]])[0]["allowed"]
+ assert node.testmempoolaccept([tx1["hex"]])[0]["allowed"]
+ assert node.testmempoolaccept([tx2["hex"]])[0]["allowed"]
self.log.info("Test duplicate transactions in the same package")
- testres = node.testmempoolaccept([signedtx1["hex"], signedtx1["hex"]])
+ testres = node.testmempoolaccept([tx1["hex"], tx1["hex"]])
assert_equal(testres, [
- {"txid": tx1.rehash(), "wtxid": tx1.getwtxid(), "package-error": "conflict-in-package"},
- {"txid": tx1.rehash(), "wtxid": tx1.getwtxid(), "package-error": "conflict-in-package"}
+ {"txid": tx1["txid"], "wtxid": tx1["wtxid"], "package-error": "conflict-in-package"},
+ {"txid": tx1["txid"], "wtxid": tx1["wtxid"], "package-error": "conflict-in-package"}
])
self.log.info("Test conflicting transactions in the same package")
- testres = node.testmempoolaccept([signedtx1["hex"], signedtx2["hex"]])
+ testres = node.testmempoolaccept([tx1["hex"], tx2["hex"]])
assert_equal(testres, [
- {"txid": tx1.rehash(), "wtxid": tx1.getwtxid(), "package-error": "conflict-in-package"},
- {"txid": tx2.rehash(), "wtxid": tx2.getwtxid(), "package-error": "conflict-in-package"}
+ {"txid": tx1["txid"], "wtxid": tx1["wtxid"], "package-error": "conflict-in-package"},
+ {"txid": tx2["txid"], "wtxid": tx2["wtxid"], "package-error": "conflict-in-package"}
])
def test_rbf(self):
node = self.nodes[0]
- coin = self.coins.pop()
- inputs = [{"txid": coin["txid"], "vout": 0, "sequence": MAX_BIP125_RBF_SEQUENCE}]
- fee = Decimal('0.00125000')
- output = {node.get_deterministic_priv_key().address: 50 - fee}
- raw_replaceable_tx = node.createrawtransaction(inputs, output)
- signed_replaceable_tx = node.signrawtransactionwithkey(hexstring=raw_replaceable_tx, privkeys=self.privkeys)
- testres_replaceable = node.testmempoolaccept([signed_replaceable_tx["hex"]])
- replaceable_tx = tx_from_hex(signed_replaceable_tx["hex"])
+
+ coin = self.wallet.get_utxo()
+ fee = Decimal("0.00125000")
+ replaceable_tx = self.wallet.create_self_transfer(utxo_to_spend=coin, sequence=MAX_BIP125_RBF_SEQUENCE, fee = fee)
+ testres_replaceable = node.testmempoolaccept([replaceable_tx["hex"]])
assert_equal(testres_replaceable, [
- {"txid": replaceable_tx.rehash(), "wtxid": replaceable_tx.getwtxid(),
- "allowed": True, "vsize": replaceable_tx.get_vsize(), "fees": { "base": fee }}
+ {"txid": replaceable_tx["txid"], "wtxid": replaceable_tx["wtxid"],
+ "allowed": True, "vsize": replaceable_tx["tx"].get_vsize(), "fees": { "base": fee }}
])
# Replacement transaction is identical except has double the fee
- replacement_tx = tx_from_hex(signed_replaceable_tx["hex"])
- replacement_tx.vout[0].nValue -= int(fee * COIN) # Doubled fee
- signed_replacement_tx = node.signrawtransactionwithkey(replacement_tx.serialize().hex(), self.privkeys)
- replacement_tx = tx_from_hex(signed_replacement_tx["hex"])
-
- self.log.info("Test that transactions within a package cannot replace each other")
- testres_rbf_conflicting = node.testmempoolaccept([signed_replaceable_tx["hex"], signed_replacement_tx["hex"]])
+ replacement_tx = self.wallet.create_self_transfer(utxo_to_spend=coin, sequence=MAX_BIP125_RBF_SEQUENCE, fee = 2 * fee)
+ testres_rbf_conflicting = node.testmempoolaccept([replaceable_tx["hex"], replacement_tx["hex"]])
assert_equal(testres_rbf_conflicting, [
- {"txid": replaceable_tx.rehash(), "wtxid": replaceable_tx.getwtxid(), "package-error": "conflict-in-package"},
- {"txid": replacement_tx.rehash(), "wtxid": replacement_tx.getwtxid(), "package-error": "conflict-in-package"}
+ {"txid": replaceable_tx["txid"], "wtxid": replaceable_tx["wtxid"], "package-error": "conflict-in-package"},
+ {"txid": replacement_tx["txid"], "wtxid": replacement_tx["wtxid"], "package-error": "conflict-in-package"}
])
self.log.info("Test that packages cannot conflict with mempool transactions, even if a valid BIP125 RBF")
- node.sendrawtransaction(signed_replaceable_tx["hex"])
- testres_rbf_single = node.testmempoolaccept([signed_replacement_tx["hex"]])
# This transaction is a valid BIP125 replace-by-fee
+ self.wallet.sendrawtransaction(from_node=node, tx_hex=replaceable_tx["hex"])
+ testres_rbf_single = node.testmempoolaccept([replacement_tx["hex"]])
assert testres_rbf_single[0]["allowed"]
testres_rbf_package = self.independent_txns_testres_blank + [{
- "txid": replacement_tx.rehash(), "wtxid": replacement_tx.getwtxid(), "allowed": False,
+ "txid": replacement_tx["txid"], "wtxid": replacement_tx["wtxid"], "allowed": False,
"reject-reason": "bip125-replacement-disallowed"
}]
- self.assert_testres_equal(self.independent_txns_hex + [signed_replacement_tx["hex"]], testres_rbf_package)
+ self.assert_testres_equal(self.independent_txns_hex + [replacement_tx["hex"]], testres_rbf_package)
def assert_equal_package_results(self, node, testmempoolaccept_result, submitpackage_result):
"""Assert that a successful submitpackage result is consistent with testmempoolaccept
@@ -330,36 +284,26 @@ class RPCPackagesTest(BitcoinTestFramework):
def test_submit_child_with_parents(self, num_parents, partial_submit):
node = self.nodes[0]
peer = node.add_p2p_connection(P2PTxInvStore())
- # Test a package with num_parents parents and 1 child transaction.
- package_hex = []
+
package_txns = []
- values = []
- scripts = []
for _ in range(num_parents):
- parent_coin = self.coins.pop()
- value = parent_coin["amount"]
- (tx, txhex, value, spk) = make_chain(node, self.address, self.privkeys, parent_coin["txid"], value)
- package_hex.append(txhex)
- package_txns.append(tx)
- values.append(value)
- scripts.append(spk)
+ parent_tx = self.wallet.create_self_transfer(fee=DEFAULT_FEE)
+ package_txns.append(parent_tx)
if partial_submit and random.choice([True, False]):
- node.sendrawtransaction(txhex)
- child_hex = create_child_with_parents(node, self.address, self.privkeys, package_txns, values, scripts)
- package_hex.append(child_hex)
- package_txns.append(tx_from_hex(child_hex))
+ node.sendrawtransaction(parent_tx["hex"])
+ child_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=[tx["new_utxo"] for tx in package_txns], fee_per_output=10000) #DEFAULT_FEE
+ package_txns.append(child_tx)
- testmempoolaccept_result = node.testmempoolaccept(rawtxs=package_hex)
- submitpackage_result = node.submitpackage(package=package_hex)
+ testmempoolaccept_result = node.testmempoolaccept(rawtxs=[tx["hex"] for tx in package_txns])
+ submitpackage_result = node.submitpackage(package=[tx["hex"] for tx in package_txns])
# Check that each result is present, with the correct size and fees
- for i in range(num_parents + 1):
- tx = package_txns[i]
- wtxid = tx.getwtxid()
- assert wtxid in submitpackage_result["tx-results"]
- tx_result = submitpackage_result["tx-results"][wtxid]
+ for package_txn in package_txns:
+ tx = package_txn["tx"]
+ assert tx.getwtxid() in submitpackage_result["tx-results"]
+ tx_result = submitpackage_result["tx-results"][tx.getwtxid()]
assert_equal(tx_result, {
- "txid": tx.rehash(),
+ "txid": package_txn["txid"],
"vsize": tx.get_vsize(),
"fees": {
"base": DEFAULT_FEE,
@@ -376,30 +320,25 @@ class RPCPackagesTest(BitcoinTestFramework):
assert "package-feerate" not in submitpackage_result
# The node should announce each transaction. No guarantees for propagation.
- peer.wait_for_broadcast([tx.getwtxid() for tx in package_txns])
+ peer.wait_for_broadcast([tx["tx"].getwtxid() for tx in package_txns])
self.generate(node, 1)
-
def test_submit_cpfp(self):
node = self.nodes[0]
peer = node.add_p2p_connection(P2PTxInvStore())
- # 2 parent 1 child CPFP. First parent pays high fees, second parent pays 0 fees and is
- # fee-bumped by the child.
- coin_rich = self.coins.pop()
- coin_poor = self.coins.pop()
- tx_rich, hex_rich, value_rich, spk_rich = make_chain(node, self.address, self.privkeys, coin_rich["txid"], coin_rich["amount"])
- tx_poor, hex_poor, value_poor, spk_poor = make_chain(node, self.address, self.privkeys, coin_poor["txid"], coin_poor["amount"], fee=0)
+ tx_poor = self.wallet.create_self_transfer(fee=0, fee_rate=0)
+ tx_rich = self.wallet.create_self_transfer(fee=DEFAULT_FEE)
package_txns = [tx_rich, tx_poor]
- hex_child = create_child_with_parents(node, self.address, self.privkeys, package_txns, [value_rich, value_poor], [spk_rich, spk_poor])
- tx_child = tx_from_hex(hex_child)
+ coins = [tx["new_utxo"] for tx in package_txns]
+ tx_child = self.wallet.create_self_transfer_multi(utxos_to_spend=coins, fee_per_output=10000) #DEFAULT_FEE
package_txns.append(tx_child)
- submitpackage_result = node.submitpackage([hex_rich, hex_poor, hex_child])
+ submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns])
- rich_parent_result = submitpackage_result["tx-results"][tx_rich.getwtxid()]
- poor_parent_result = submitpackage_result["tx-results"][tx_poor.getwtxid()]
- child_result = submitpackage_result["tx-results"][tx_child.getwtxid()]
+ rich_parent_result = submitpackage_result["tx-results"][tx_rich["wtxid"]]
+ poor_parent_result = submitpackage_result["tx-results"][tx_poor["wtxid"]]
+ child_result = submitpackage_result["tx-results"][tx_child["tx"].getwtxid()]
assert_equal(rich_parent_result["fees"]["base"], DEFAULT_FEE)
assert_equal(poor_parent_result["fees"]["base"], 0)
assert_equal(child_result["fees"]["base"], DEFAULT_FEE)
@@ -410,10 +349,9 @@ class RPCPackagesTest(BitcoinTestFramework):
assert_fee_amount(DEFAULT_FEE, rich_parent_result["vsize"] + child_result["vsize"], submitpackage_result["package-feerate"])
# The node will broadcast each transaction, still abiding by its peer's fee filter
- peer.wait_for_broadcast([tx.getwtxid() for tx in package_txns])
+ peer.wait_for_broadcast([tx["tx"].getwtxid() for tx in package_txns])
self.generate(node, 1)
-
def test_submitpackage(self):
node = self.nodes[0]
@@ -427,7 +365,7 @@ class RPCPackagesTest(BitcoinTestFramework):
self.log.info("Submitpackage only allows packages of 1 child with its parents")
# Chain of 3 transactions has too many generations
- chain_hex, _ = create_raw_chain(node, self.coins.pop(), self.address, self.privkeys, 3)
+ chain_hex = self.wallet.create_self_transfer_chain(chain_length=25)["chain_hex"]
assert_raises_rpc_error(-25, "not-child-with-parents", node.submitpackage, chain_hex)
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index 8243f43736..f6a697438a 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -47,8 +47,9 @@ import json
import os
-# Create one-input, one-output, no-fee transaction:
class PSBTTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
def set_test_params(self):
self.num_nodes = 3
diff --git a/test/functional/rpc_rawtransaction.py b/test/functional/rpc_rawtransaction.py
index 930aaaa897..15fc947eef 100755
--- a/test/functional/rpc_rawtransaction.py
+++ b/test/functional/rpc_rawtransaction.py
@@ -54,6 +54,9 @@ class multidict(dict):
class RawTransactionsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 3
@@ -65,8 +68,6 @@ class RawTransactionsTest(BitcoinTestFramework):
# whitelist all peers to speed up tx relay / mempool sync
for args in self.extra_args:
args.append("-whitelist=noban@127.0.0.1")
- self.requires_wallet = self.is_specified_wallet_compiled()
-
self.supports_cli = False
def setup_network(self):
@@ -85,7 +86,8 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sendrawtransaction_testmempoolaccept_tests()
self.decoderawtransaction_tests()
self.transaction_version_number_tests()
- if self.requires_wallet and not self.options.descriptors:
+ if self.is_specified_wallet_compiled() and not self.options.descriptors:
+ self.import_deterministic_coinbase_privkeys()
self.raw_multisig_transaction_legacy_tests()
def getrawtransaction_tests(self):
diff --git a/test/functional/test_framework/authproxy.py b/test/functional/test_framework/authproxy.py
index c4ffd1fbf6..dd20b28550 100644
--- a/test/functional/test_framework/authproxy.py
+++ b/test/functional/test_framework/authproxy.py
@@ -131,10 +131,12 @@ class AuthServiceProxy():
json.dumps(args or argsn, default=EncodeDecimal, ensure_ascii=self.ensure_ascii),
))
if args and argsn:
- raise ValueError('Cannot handle both named and positional arguments')
+ params = dict(args=args, **argsn)
+ else:
+ params = args or argsn
return {'version': '1.1',
'method': self._service_name,
- 'params': args or argsn,
+ 'params': params,
'id': AuthServiceProxy.__id_count}
def __call__(self, *args, **argsn):
diff --git a/test/functional/test_framework/messages.py b/test/functional/test_framework/messages.py
index 252b49cc6d..7389b1624e 100755
--- a/test/functional/test_framework/messages.py
+++ b/test/functional/test_framework/messages.py
@@ -1840,29 +1840,23 @@ class msg_cfcheckpt:
self.filter_type, self.stop_hash)
class msg_sendtxrcncl:
- __slots__ = ("initiator", "responder", "version", "salt")
+ __slots__ = ("version", "salt")
msgtype = b"sendtxrcncl"
def __init__(self):
- self.initiator = False
- self.responder = False
self.version = 0
self.salt = 0
def deserialize(self, f):
- self.initiator = struct.unpack("<?", f.read(1))[0]
- self.responder = struct.unpack("<?", f.read(1))[0]
self.version = struct.unpack("<I", f.read(4))[0]
self.salt = struct.unpack("<Q", f.read(8))[0]
def serialize(self):
r = b""
- r += struct.pack("<?", self.initiator)
- r += struct.pack("<?", self.responder)
r += struct.pack("<I", self.version)
r += struct.pack("<Q", self.salt)
return r
def __repr__(self):
- return "msg_sendtxrcncl(initiator=%i, responder=%i, version=%lu, salt=%lu)" %\
- (self.initiator, self.responder, self.version, self.salt)
+ return "msg_sendtxrcncl(version=%lu, salt=%lu)" %\
+ (self.version, self.salt)
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index b1164b98fd..7cfeae3ff6 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -97,6 +97,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.chain: str = 'regtest'
self.setup_clean_chain: bool = False
self.nodes: List[TestNode] = []
+ self.extra_args = None
self.network_thread = None
self.rpc_timeout = 60 # Wait for up to 60 seconds for the RPC server to respond
self.supports_cli = True
@@ -113,7 +114,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.wallet_names = None
# By default the wallet is not required. Set to true by skip_if_no_wallet().
# When False, we ignore wallet_names regardless of what it is.
- self.requires_wallet = False
+ self._requires_wallet = False
# Disable ThreadOpenConnections by default, so that adding entries to
# addrman will not result in automatic connections to them.
self.disable_autoconnect = True
@@ -194,12 +195,6 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
help="set a random seed for deterministically reproducing a previous test run")
parser.add_argument('--timeout-factor', dest="timeout_factor", type=float, default=1.0, help='adjust test timeouts by a factor. Setting it to 0 disables all timeouts')
- group = parser.add_mutually_exclusive_group()
- group.add_argument("--descriptors", action='store_const', const=True,
- help="Run test using a descriptor wallet", dest='descriptors')
- group.add_argument("--legacy-wallet", action='store_const', const=False,
- help="Run test using legacy wallets", dest='descriptors')
-
self.add_options(parser)
# Running TestShell in a Jupyter notebook causes an additional -f argument
# To keep TestShell from failing with an "unrecognized argument" error, we add a dummy "-f" argument
@@ -212,7 +207,13 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
config.read_file(open(self.options.configfile))
self.config = config
- if self.options.descriptors is None:
+ if "descriptors" not in self.options:
+ # Wallet is not required by the test at all and the value of self.options.descriptors won't matter.
+ # It still needs to exist and be None in order for tests to work however.
+ # So set it to None to force -disablewallet, because the wallet is not needed.
+ self.options.descriptors = None
+ elif self.options.descriptors is None:
+ # Some wallet is either required or optionally used by the test.
# Prefer BDB unless it isn't available
if self.is_bdb_compiled():
self.options.descriptors = False
@@ -221,6 +222,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
else:
# If neither are compiled, tests requiring a wallet will be skipped and the value of self.options.descriptors won't matter
# It still needs to exist and be None in order for tests to work however.
+ # So set it to None, which will also set -disablewallet.
self.options.descriptors = None
PortSeed.n = self.options.port_seed
@@ -407,12 +409,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
def setup_nodes(self):
"""Override this method to customize test node setup"""
- extra_args = [[]] * self.num_nodes
- if hasattr(self, "extra_args"):
- extra_args = self.extra_args
- self.add_nodes(self.num_nodes, extra_args)
+ self.add_nodes(self.num_nodes, self.extra_args)
self.start_nodes()
- if self.requires_wallet:
+ if self._requires_wallet:
self.import_deterministic_coinbase_privkeys()
if not self.setup_clean_chain:
for n in self.nodes:
@@ -446,6 +445,21 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
# Public helper methods. These can be accessed by the subclass test scripts.
+ def add_wallet_options(self, parser, *, descriptors=True, legacy=True):
+ kwargs = {}
+ if descriptors + legacy == 1:
+ # If only one type can be chosen, set it as default
+ kwargs["default"] = descriptors
+ group = parser.add_mutually_exclusive_group(
+ # If only one type is allowed, require it to be set in test_runner.py
+ required=os.getenv("REQUIRE_WALLET_TYPE_SET") == "1" and "default" in kwargs)
+ if descriptors:
+ group.add_argument("--descriptors", action='store_const', const=True, **kwargs,
+ help="Run test using a descriptor wallet", dest='descriptors')
+ if legacy:
+ group.add_argument("--legacy-wallet", action='store_const', const=False, **kwargs,
+ help="Run test using legacy wallets", dest='descriptors')
+
def add_nodes(self, num_nodes: int, extra_args=None, *, rpchost=None, binary=None, binary_cli=None, versions=None):
"""Instantiate TestNode objects.
@@ -866,7 +880,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
def skip_if_no_wallet(self):
"""Skip the running test if wallet has not been compiled."""
- self.requires_wallet = True
+ self._requires_wallet = True
if not self.is_wallet_compiled():
raise SkipTest("wallet has not been compiled.")
if self.options.descriptors:
diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py
index 64edff15ae..fc93940b63 100755
--- a/test/functional/test_framework/test_node.py
+++ b/test/functional/test_framework/test_node.py
@@ -105,6 +105,9 @@ class TestNode():
"-debugexclude=rand",
"-uacomment=testnode%d" % i,
]
+ if self.descriptors is None:
+ self.args.append("-disablewallet")
+
if use_valgrind:
default_suppressions_file = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
@@ -720,7 +723,6 @@ class TestNodeCLI():
"""Run bitcoin-cli command. Deserializes returned string as python object."""
pos_args = [arg_to_cli(arg) for arg in args]
named_args = [str(key) + "=" + arg_to_cli(value) for (key, value) in kwargs.items()]
- assert not (pos_args and named_args), "Cannot use positional arguments and named arguments in the same bitcoin-cli call"
p_args = [self.binary, "-datadir=" + self.datadir] + self.options
if named_args:
p_args += ["-named"]
diff --git a/test/functional/test_framework/wallet.py b/test/functional/test_framework/wallet.py
index 374fda5c23..2b31fe7c87 100644
--- a/test/functional/test_framework/wallet.py
+++ b/test/functional/test_framework/wallet.py
@@ -32,7 +32,6 @@ from test_framework.messages import (
CTxIn,
CTxInWitness,
CTxOut,
- tx_from_hex,
)
from test_framework.script import (
CScript,
@@ -338,6 +337,28 @@ class MiniWallet:
self.scan_tx(from_node.decoderawtransaction(tx_hex))
return txid
+ def create_self_transfer_chain(self, *, chain_length):
+ """
+ Create a "chain" of chain_length transactions. The nth transaction in
+ the chain is a child of the n-1th transaction and parent of the n+1th transaction.
+
+ Returns a dic {"chain_hex": chain_hex, "chain_txns" : chain_txns}
+
+ "chain_hex" is a list representing the chain's transactions in hexadecimal.
+ "chain_txns" is a list representing the chain's transactions in the CTransaction object.
+ """
+ chaintip_utxo = self.get_utxo()
+ chain_hex = []
+ chain_txns = []
+
+ for _ in range(chain_length):
+ tx = self.create_self_transfer(utxo_to_spend=chaintip_utxo)
+ chaintip_utxo = tx["new_utxo"]
+ chain_hex.append(tx["hex"])
+ chain_txns.append(tx["tx"])
+
+ return {"chain_hex": chain_hex, "chain_txns" : chain_txns}
+
def send_self_transfer_chain(self, *, from_node, chain_length, utxo_to_spend=None):
"""Create and send a "chain" of chain_length transactions. The nth transaction in
the chain is a child of the n-1th transaction and parent of the n+1th transaction.
@@ -388,56 +409,3 @@ def address_to_scriptpubkey(address):
# TODO: also support other address formats
else:
assert False
-
-
-def make_chain(node, address, privkeys, parent_txid, parent_value, n=0, parent_locking_script=None, fee=DEFAULT_FEE):
- """Build a transaction that spends parent_txid.vout[n] and produces one output with
- amount = parent_value with a fee deducted.
- Return tuple (CTransaction object, raw hex, nValue, scriptPubKey of the output created).
- """
- inputs = [{"txid": parent_txid, "vout": n}]
- my_value = parent_value - fee
- outputs = {address : my_value}
- rawtx = node.createrawtransaction(inputs, outputs)
- prevtxs = [{
- "txid": parent_txid,
- "vout": n,
- "scriptPubKey": parent_locking_script,
- "amount": parent_value,
- }] if parent_locking_script else None
- signedtx = node.signrawtransactionwithkey(hexstring=rawtx, privkeys=privkeys, prevtxs=prevtxs)
- assert signedtx["complete"]
- tx = tx_from_hex(signedtx["hex"])
- return (tx, signedtx["hex"], my_value, tx.vout[0].scriptPubKey.hex())
-
-def create_child_with_parents(node, address, privkeys, parents_tx, values, locking_scripts, fee=DEFAULT_FEE):
- """Creates a transaction that spends the first output of each parent in parents_tx."""
- num_parents = len(parents_tx)
- total_value = sum(values)
- inputs = [{"txid": tx.rehash(), "vout": 0} for tx in parents_tx]
- outputs = {address : total_value - fee}
- rawtx_child = node.createrawtransaction(inputs, outputs)
- prevtxs = []
- for i in range(num_parents):
- prevtxs.append({"txid": parents_tx[i].rehash(), "vout": 0, "scriptPubKey": locking_scripts[i], "amount": values[i]})
- signedtx_child = node.signrawtransactionwithkey(hexstring=rawtx_child, privkeys=privkeys, prevtxs=prevtxs)
- assert signedtx_child["complete"]
- return signedtx_child["hex"]
-
-def create_raw_chain(node, first_coin, address, privkeys, chain_length=25):
- """Helper function: create a "chain" of chain_length transactions. The nth transaction in the
- chain is a child of the n-1th transaction and parent of the n+1th transaction.
- """
- parent_locking_script = None
- txid = first_coin["txid"]
- chain_hex = []
- chain_txns = []
- value = first_coin["amount"]
-
- for _ in range(chain_length):
- (tx, txhex, value, parent_locking_script) = make_chain(node, address, privkeys, txid, value, 0, parent_locking_script)
- txid = tx.rehash()
- chain_hex.append(txhex)
- chain_txns.append(tx)
-
- return (chain_hex, chain_txns)
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 785a97a48b..b9adb5dcb5 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -27,6 +27,8 @@ import re
import logging
import unittest
+os.environ["REQUIRE_WALLET_TYPE_SET"] = "1"
+
# Formatting. Default colors to empty strings.
DEFAULT, BOLD, GREEN, RED = ("", ""), ("", ""), ("", ""), ("", "")
try:
@@ -159,7 +161,7 @@ BASE_SCRIPTS = [
'wallet_avoidreuse.py --descriptors',
'wallet_avoid_mixing_output_types.py --descriptors',
'mempool_reorg.py',
- 'mempool_persist.py',
+ 'mempool_persist.py --descriptors',
'p2p_block_sync.py',
'wallet_multiwallet.py --legacy-wallet',
'wallet_multiwallet.py --descriptors',
@@ -208,7 +210,7 @@ BASE_SCRIPTS = [
'wallet_keypool.py --legacy-wallet',
'wallet_keypool.py --descriptors',
'wallet_descriptor.py --descriptors',
- 'wallet_miniscript.py',
+ 'wallet_miniscript.py --descriptors',
'feature_maxtipage.py',
'p2p_nobloomfilter_messages.py',
'p2p_filter.py',
@@ -222,7 +224,7 @@ BASE_SCRIPTS = [
'feature_assumevalid.py',
'example_test.py',
'wallet_txn_doublespend.py --legacy-wallet',
- 'wallet_multisig_descriptor_psbt.py',
+ 'wallet_multisig_descriptor_psbt.py --descriptors',
'wallet_txn_doublespend.py --descriptors',
'feature_backwards_compatibility.py --legacy-wallet',
'feature_backwards_compatibility.py --descriptors',
@@ -294,8 +296,8 @@ BASE_SCRIPTS = [
'wallet_sendall.py --legacy-wallet',
'wallet_sendall.py --descriptors',
'wallet_create_tx.py --descriptors',
- 'wallet_taproot.py',
- 'wallet_inactive_hdchains.py',
+ 'wallet_taproot.py --descriptors',
+ 'wallet_inactive_hdchains.py --legacy-wallet',
'p2p_fingerprint.py',
'feature_uacomment.py',
'feature_init.py',
diff --git a/test/functional/tool_signet_miner.py b/test/functional/tool_signet_miner.py
index e6fc9072ab..1ad2a579bf 100755
--- a/test/functional/tool_signet_miner.py
+++ b/test/functional/tool_signet_miner.py
@@ -20,6 +20,9 @@ CHALLENGE_PRIVATE_KEY = (42).to_bytes(32, 'big')
class SignetMinerTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.chain = "signet"
self.setup_clean_chain = True
diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py
index 1e5ce513cb..076288293c 100755
--- a/test/functional/tool_wallet.py
+++ b/test/functional/tool_wallet.py
@@ -19,6 +19,9 @@ BUFFER_SIZE = 16 * 1024
class ToolWalletTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
diff --git a/test/functional/wallet_abandonconflict.py b/test/functional/wallet_abandonconflict.py
index d7850b41ac..d7bfe08437 100755
--- a/test/functional/wallet_abandonconflict.py
+++ b/test/functional/wallet_abandonconflict.py
@@ -21,6 +21,9 @@ from test_framework.util import (
class AbandonConflictTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [["-minrelaytxfee=0.00001"], []]
diff --git a/test/functional/wallet_address_types.py b/test/functional/wallet_address_types.py
index 5b836f693f..497795409e 100755
--- a/test/functional/wallet_address_types.py
+++ b/test/functional/wallet_address_types.py
@@ -66,6 +66,9 @@ from test_framework.util import (
)
class AddressTypeTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 6
self.extra_args = [
diff --git a/test/functional/wallet_avoid_mixing_output_types.py b/test/functional/wallet_avoid_mixing_output_types.py
index cad9d02808..861765f452 100755
--- a/test/functional/wallet_avoid_mixing_output_types.py
+++ b/test/functional/wallet_avoid_mixing_output_types.py
@@ -106,6 +106,9 @@ def generate_payment_values(n, m):
class AddressInputTypeGrouping(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/wallet_avoidreuse.py b/test/functional/wallet_avoidreuse.py
index f663666f57..474270cf80 100755
--- a/test/functional/wallet_avoidreuse.py
+++ b/test/functional/wallet_avoidreuse.py
@@ -63,6 +63,8 @@ def assert_balances(node, mine, margin=0.001):
assert_approx(got[k], v, margin)
class AvoidReuseTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
def set_test_params(self):
self.num_nodes = 2
diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py
index 292fe3a310..eb36673b8a 100755
--- a/test/functional/wallet_backup.py
+++ b/test/functional/wallet_backup.py
@@ -44,6 +44,9 @@ from test_framework.util import (
class WalletBackupTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 4
self.setup_clean_chain = True
diff --git a/test/functional/wallet_balance.py b/test/functional/wallet_balance.py
index 60da22ca26..e8c09e4c1a 100755
--- a/test/functional/wallet_balance.py
+++ b/test/functional/wallet_balance.py
@@ -46,6 +46,9 @@ def create_transactions(node, address, amt, fees):
return txs
class WalletTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 20c577ceb3..bbda771e18 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -23,6 +23,9 @@ OUT_OF_RANGE = "Amount out of range"
class WalletTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 4
self.extra_args = [[
diff --git a/test/functional/wallet_bumpfee.py b/test/functional/wallet_bumpfee.py
index 2ee3e00a7b..07ec55f8f3 100755
--- a/test/functional/wallet_bumpfee.py
+++ b/test/functional/wallet_bumpfee.py
@@ -17,10 +17,6 @@ from decimal import Decimal
from test_framework.blocktools import (
COINBASE_MATURITY,
- add_witness_commitment,
- create_block,
- create_coinbase,
- send_to_witness,
)
from test_framework.messages import (
MAX_BIP125_RBF_SEQUENCE,
@@ -46,6 +42,9 @@ TOO_HIGH = 100000
class BumpFeeTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
@@ -200,16 +199,8 @@ def test_segwit_bumpfee_succeeds(self, rbf_node, dest_address):
# Create a transaction with segwit output, then create an RBF transaction
# which spends it, and make sure bumpfee can be called on it.
- segwit_in = next(u for u in rbf_node.listunspent() if u["amount"] == Decimal("0.001"))
- segwit_out = rbf_node.getaddressinfo(rbf_node.getnewaddress(address_type='bech32'))
- segwitid = send_to_witness(
- use_p2wsh=False,
- node=rbf_node,
- utxo=segwit_in,
- pubkey=segwit_out["pubkey"],
- encode_p2sh=False,
- amount=Decimal("0.0009"),
- sign=True)
+ segwit_out = rbf_node.getnewaddress(address_type='bech32')
+ segwitid = rbf_node.send({segwit_out: "0.0009"}, options={"change_position": 1})["txid"]
rbfraw = rbf_node.createrawtransaction([{
'txid': segwitid,
@@ -541,10 +532,10 @@ def test_unconfirmed_not_spendable(self, rbf_node, rbf_node_address):
# then invalidate the block so the rbf tx will be put back in the mempool.
# This makes it possible to check whether the rbf tx outputs are
# spendable before the rbf tx is confirmed.
- block = submit_block_with_tx(rbf_node, rbftx)
+ block = self.generateblock(rbf_node, output="raw(51)", transactions=[rbftx])
# Can not abandon conflicted tx
assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', lambda: rbf_node.abandontransaction(txid=bumpid))
- rbf_node.invalidateblock(block.hash)
+ rbf_node.invalidateblock(block["hash"])
# Call abandon to make sure the wallet doesn't attempt to resubmit
# the bump tx and hope the wallet does not rebroadcast before we call.
rbf_node.abandontransaction(bumpid)
@@ -619,17 +610,6 @@ def spend_one_input(node, dest_address, change_size=Decimal("0.00049000")):
return txid
-def submit_block_with_tx(node, tx):
- tip = node.getbestblockhash()
- height = node.getblockcount() + 1
- block_time = node.getblockheader(tip)["mediantime"] + 1
- block = create_block(int(tip, 16), create_coinbase(height), block_time, txlist=[tx])
- add_witness_commitment(block)
- block.solve()
- node.submitblock(block.serialize().hex())
- return block
-
-
def test_no_more_inputs_fails(self, rbf_node, dest_address):
self.log.info('Test that bumpfee fails when there are no available confirmed outputs')
# feerate rbf requires confirmed outputs when change output doesn't exist or is insufficient
diff --git a/test/functional/wallet_coinbase_category.py b/test/functional/wallet_coinbase_category.py
index c2a8e612cf..06cafd62f9 100755
--- a/test/functional/wallet_coinbase_category.py
+++ b/test/functional/wallet_coinbase_category.py
@@ -13,6 +13,9 @@ from test_framework.util import (
)
class CoinbaseCategoryTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py
index a213a261ef..2415172c74 100755
--- a/test/functional/wallet_create_tx.py
+++ b/test/functional/wallet_create_tx.py
@@ -14,6 +14,9 @@ from test_framework.blocktools import (
class CreateTxWalletTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/wallet_createwallet.py b/test/functional/wallet_createwallet.py
index 12480d4d1e..95aa40720d 100755
--- a/test/functional/wallet_createwallet.py
+++ b/test/functional/wallet_createwallet.py
@@ -16,6 +16,9 @@ from test_framework.util import (
from test_framework.wallet_util import bytes_to_wif, generate_wif_key
class CreateWalletTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
diff --git a/test/functional/wallet_crosschain.py b/test/functional/wallet_crosschain.py
index c0047542ed..549eec34c3 100755
--- a/test/functional/wallet_crosschain.py
+++ b/test/functional/wallet_crosschain.py
@@ -9,6 +9,9 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_raises_rpc_error
class WalletCrossChain(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
diff --git a/test/functional/wallet_descriptor.py b/test/functional/wallet_descriptor.py
index e7cfa56c46..4b305106f1 100755
--- a/test/functional/wallet_descriptor.py
+++ b/test/functional/wallet_descriptor.py
@@ -13,6 +13,9 @@ from test_framework.util import (
class WalletDescriptorTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py
index 9f0d666270..20b91fc523 100755
--- a/test/functional/wallet_dump.py
+++ b/test/functional/wallet_dump.py
@@ -93,6 +93,9 @@ def read_dump(file_name, addrs, script_addrs, hd_master_addr_old):
class WalletDumpTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.num_nodes = 1
self.extra_args = [["-keypool=90", "-addresstype=legacy"]]
diff --git a/test/functional/wallet_encryption.py b/test/functional/wallet_encryption.py
index 37c1c4bff3..abf6bc6393 100755
--- a/test/functional/wallet_encryption.py
+++ b/test/functional/wallet_encryption.py
@@ -14,6 +14,9 @@ from test_framework.util import (
class WalletEncryptionTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/wallet_fallbackfee.py b/test/functional/wallet_fallbackfee.py
index acd92097ff..4aa8eb466e 100755
--- a/test/functional/wallet_fallbackfee.py
+++ b/test/functional/wallet_fallbackfee.py
@@ -9,6 +9,9 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_raises_rpc_error
class WalletRBFTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
diff --git a/test/functional/wallet_fast_rescan.py b/test/functional/wallet_fast_rescan.py
index 3b8ae8eb92..52e33acb24 100755
--- a/test/functional/wallet_fast_rescan.py
+++ b/test/functional/wallet_fast_rescan.py
@@ -21,6 +21,9 @@ NUM_BLOCKS = 6 # number of blocks to mine
class WalletFastRescanTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.num_nodes = 1
self.extra_args = [[f'-keypool={KEYPOOL_SIZE}', '-blockfilterindex=1']]
diff --git a/test/functional/wallet_groups.py b/test/functional/wallet_groups.py
index e5e4cf03bf..5da4c1e462 100755
--- a/test/functional/wallet_groups.py
+++ b/test/functional/wallet_groups.py
@@ -16,6 +16,9 @@ from test_framework.util import (
class WalletGroupTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 5
diff --git a/test/functional/wallet_hd.py b/test/functional/wallet_hd.py
index 220c856498..05d1ac132d 100755
--- a/test/functional/wallet_hd.py
+++ b/test/functional/wallet_hd.py
@@ -16,6 +16,9 @@ from test_framework.util import (
class WalletHDTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/wallet_implicitsegwit.py b/test/functional/wallet_implicitsegwit.py
index a8583e2879..59f11ae9d7 100755
--- a/test/functional/wallet_implicitsegwit.py
+++ b/test/functional/wallet_implicitsegwit.py
@@ -39,6 +39,9 @@ def check_implicit_transactions(implicit_keys, implicit_node):
assert(('receive', b_address) in tuple((tx['category'], tx['address']) for tx in txs))
class ImplicitSegwitTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.num_nodes = 2
self.supports_cli = False
diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py
index 085ad51c79..64f8f2eb6e 100755
--- a/test/functional/wallet_import_rescan.py
+++ b/test/functional/wallet_import_rescan.py
@@ -147,6 +147,9 @@ def get_rand_amount():
class ImportRescanTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.num_nodes = 2 + len(IMPORT_NODES)
self.supports_cli = False
diff --git a/test/functional/wallet_import_with_label.py b/test/functional/wallet_import_with_label.py
index 6a9d2e8290..0c18448473 100755
--- a/test/functional/wallet_import_with_label.py
+++ b/test/functional/wallet_import_with_label.py
@@ -15,6 +15,9 @@ from test_framework.wallet_util import test_address
class ImportWithLabel(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
diff --git a/test/functional/wallet_importdescriptors.py b/test/functional/wallet_importdescriptors.py
index 9744009af8..f70b83cc5b 100755
--- a/test/functional/wallet_importdescriptors.py
+++ b/test/functional/wallet_importdescriptors.py
@@ -30,6 +30,9 @@ from test_framework.wallet_util import (
)
class ImportDescriptorsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [["-addresstype=legacy"],
diff --git a/test/functional/wallet_importmulti.py b/test/functional/wallet_importmulti.py
index 62a1a3341d..78f33c0ac4 100755
--- a/test/functional/wallet_importmulti.py
+++ b/test/functional/wallet_importmulti.py
@@ -35,6 +35,9 @@ from test_framework.wallet_util import (
class ImportMultiTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.num_nodes = 2
self.extra_args = [["-addresstype=legacy"], ["-addresstype=legacy"]]
diff --git a/test/functional/wallet_importprunedfunds.py b/test/functional/wallet_importprunedfunds.py
index 2a4d0981c7..a912856198 100755
--- a/test/functional/wallet_importprunedfunds.py
+++ b/test/functional/wallet_importprunedfunds.py
@@ -21,6 +21,9 @@ from test_framework.wallet_util import bytes_to_wif
class ImportPrunedFundsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/wallet_inactive_hdchains.py b/test/functional/wallet_inactive_hdchains.py
index e1dad00876..43a0fa7c55 100755
--- a/test/functional/wallet_inactive_hdchains.py
+++ b/test/functional/wallet_inactive_hdchains.py
@@ -17,6 +17,9 @@ from test_framework.wallet_util import (
class InactiveHDChainsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/wallet_keypool.py b/test/functional/wallet_keypool.py
index 54c47511a9..aa31757f35 100755
--- a/test/functional/wallet_keypool.py
+++ b/test/functional/wallet_keypool.py
@@ -11,6 +11,9 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error
class KeyPoolTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
diff --git a/test/functional/wallet_keypool_topup.py b/test/functional/wallet_keypool_topup.py
index 4c965b7160..d57e1b5aff 100755
--- a/test/functional/wallet_keypool_topup.py
+++ b/test/functional/wallet_keypool_topup.py
@@ -21,6 +21,9 @@ from test_framework.util import (
class KeypoolRestoreTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 4
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
index c29b02e661..c92b6f2c2a 100755
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -18,6 +18,9 @@ from test_framework.wallet_util import test_address
class WalletLabelsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/wallet_listdescriptors.py b/test/functional/wallet_listdescriptors.py
index d5372f5aee..39217dd0f1 100755
--- a/test/functional/wallet_listdescriptors.py
+++ b/test/functional/wallet_listdescriptors.py
@@ -4,8 +4,11 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the listdescriptors RPC."""
+from test_framework.blocktools import (
+ TIME_GENESIS_BLOCK,
+)
from test_framework.descriptors import (
- descsum_create
+ descsum_create,
)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
@@ -15,6 +18,9 @@ from test_framework.util import (
class ListDescriptorsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.num_nodes = 1
@@ -63,13 +69,13 @@ class ListDescriptorsTest(BitcoinTestFramework):
wallet = node.get_wallet_rpc('w2')
wallet.importdescriptors([{
'desc': descsum_create('wpkh(' + xprv + hardened_path + '/0/*)'),
- 'timestamp': 1296688602,
+ 'timestamp': TIME_GENESIS_BLOCK,
}])
expected = {
'wallet_name': 'w2',
'descriptors': [
{'desc': descsum_create('wpkh([80002067' + hardened_path + ']' + xpub_acc + '/0/*)'),
- 'timestamp': 1296688602,
+ 'timestamp': TIME_GENESIS_BLOCK,
'active': False,
'range': [0, 0],
'next': 0},
@@ -83,7 +89,7 @@ class ListDescriptorsTest(BitcoinTestFramework):
'wallet_name': 'w2',
'descriptors': [
{'desc': descsum_create('wpkh(' + xprv + hardened_path + '/0/*)'),
- 'timestamp': 1296688602,
+ 'timestamp': TIME_GENESIS_BLOCK,
'active': False,
'range': [0, 0],
'next': 0},
@@ -105,7 +111,7 @@ class ListDescriptorsTest(BitcoinTestFramework):
watch_only_wallet = node.get_wallet_rpc('watch-only')
watch_only_wallet.importdescriptors([{
'desc': descsum_create('wpkh(' + xpub_acc + ')'),
- 'timestamp': 1296688602,
+ 'timestamp': TIME_GENESIS_BLOCK,
}])
assert_raises_rpc_error(-4, 'Can\'t get descriptor string', watch_only_wallet.listdescriptors, True)
@@ -114,14 +120,14 @@ class ListDescriptorsTest(BitcoinTestFramework):
wallet = node.get_wallet_rpc('w4')
wallet.importdescriptors([{
'desc': descsum_create('combo(' + node.get_deterministic_priv_key().key + ')'),
- 'timestamp': 1296688602,
+ 'timestamp': TIME_GENESIS_BLOCK,
}])
expected = {
'wallet_name': 'w4',
'descriptors': [
{'active': False,
'desc': 'combo(0227d85ba011276cf25b51df6a188b75e604b38770a462b2d0e9fb2fc839ef5d3f)#np574htj',
- 'timestamp': 1296688602},
+ 'timestamp': TIME_GENESIS_BLOCK},
]
}
assert_equal(expected, wallet.listdescriptors())
diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py
index f1d7de2f27..04f1e87fe1 100755
--- a/test/functional/wallet_listreceivedby.py
+++ b/test/functional/wallet_listreceivedby.py
@@ -16,6 +16,9 @@ from test_framework.wallet_util import test_address
class ReceivedByTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
# whitelist peers to speed up tx relay / mempool sync
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
index aff408ceb1..ecdfb7d0e3 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -20,6 +20,9 @@ from test_framework.wallet_util import bytes_to_wif
from decimal import Decimal
class ListSinceBlockTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 4
self.setup_clean_chain = True
diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py
index 9bb06774a5..27246e3902 100755
--- a/test/functional/wallet_listtransactions.py
+++ b/test/functional/wallet_listtransactions.py
@@ -21,6 +21,9 @@ from test_framework.util import (
class ListTransactionsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 3
# This test isn't testing txn relay/timing, so set whitelist on the
diff --git a/test/functional/wallet_migration.py b/test/functional/wallet_migration.py
index 3c1cb6ac32..37625e50d8 100755
--- a/test/functional/wallet_migration.py
+++ b/test/functional/wallet_migration.py
@@ -19,6 +19,9 @@ from test_framework.wallet_util import (
class WalletMigrationTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
@@ -393,6 +396,15 @@ class WalletMigrationTest(BitcoinTestFramework):
assert_equal(bals, wallet.getbalances())
+ def test_encrypted(self):
+ self.log.info("Test migration of an encrypted wallet")
+ wallet = self.create_legacy_wallet("encrypted")
+
+ wallet.encryptwallet("pass")
+
+ assert_raises_rpc_error(-15, "Error: migratewallet on encrypted wallets is currently unsupported.", wallet.migratewallet)
+ # TODO: Fix migratewallet so that we can actually migrate encrypted wallets
+
def run_test(self):
self.generate(self.nodes[0], 101)
@@ -402,6 +414,7 @@ class WalletMigrationTest(BitcoinTestFramework):
self.test_other_watchonly()
self.test_no_privkeys()
self.test_pk_coinbases()
+ self.test_encrypted()
if __name__ == '__main__':
WalletMigrationTest().main()
diff --git a/test/functional/wallet_miniscript.py b/test/functional/wallet_miniscript.py
index 2252f1e424..cefcaf4dc7 100755
--- a/test/functional/wallet_miniscript.py
+++ b/test/functional/wallet_miniscript.py
@@ -22,6 +22,9 @@ MINISCRIPTS = [
class WalletMiniscriptTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.num_nodes = 1
diff --git a/test/functional/wallet_multisig_descriptor_psbt.py b/test/functional/wallet_multisig_descriptor_psbt.py
index 2b565db137..f741eac9f3 100755
--- a/test/functional/wallet_multisig_descriptor_psbt.py
+++ b/test/functional/wallet_multisig_descriptor_psbt.py
@@ -16,6 +16,9 @@ from test_framework.util import (
class WalletMultisigDescriptorPSBTTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.num_nodes = 3
self.setup_clean_chain = True
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 1c890d7207..1d0bb5a9b3 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -52,6 +52,7 @@ class MultiWalletTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def add_options(self, parser):
+ self.add_wallet_options(parser)
parser.add_argument(
'--data_wallets_dir',
default=os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/wallets/'),
diff --git a/test/functional/wallet_orphanedreward.py b/test/functional/wallet_orphanedreward.py
index 7295db4653..06a96754cf 100755
--- a/test/functional/wallet_orphanedreward.py
+++ b/test/functional/wallet_orphanedreward.py
@@ -8,6 +8,9 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
class OrphanedBlockRewardTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/wallet_reorgsrestore.py b/test/functional/wallet_reorgsrestore.py
index f2bdb114b7..5350c73abb 100755
--- a/test/functional/wallet_reorgsrestore.py
+++ b/test/functional/wallet_reorgsrestore.py
@@ -23,6 +23,9 @@ from test_framework.util import (
)
class ReorgsRestoreTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 3
diff --git a/test/functional/wallet_resendwallettransactions.py b/test/functional/wallet_resendwallettransactions.py
index b3d02fbfc9..fb8d1215f8 100755
--- a/test/functional/wallet_resendwallettransactions.py
+++ b/test/functional/wallet_resendwallettransactions.py
@@ -18,6 +18,9 @@ from test_framework.util import (
)
class ResendWalletTransactionsTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py
index 83b8332c4d..eb7d9616a1 100755
--- a/test/functional/wallet_send.py
+++ b/test/functional/wallet_send.py
@@ -25,6 +25,9 @@ from test_framework.util import (
from test_framework.wallet_util import bytes_to_wif
class WalletSendTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 2
# whitelist all peers to speed up tx relay / mempool sync
diff --git a/test/functional/wallet_sendall.py b/test/functional/wallet_sendall.py
index 4fe11455b1..042b5dbf79 100755
--- a/test/functional/wallet_sendall.py
+++ b/test/functional/wallet_sendall.py
@@ -26,6 +26,9 @@ def cleanup(func):
class SendallTest(BitcoinTestFramework):
# Setup and helpers
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
diff --git a/test/functional/wallet_signer.py b/test/functional/wallet_signer.py
index db3a8a2efa..9ab7154424 100755
--- a/test/functional/wallet_signer.py
+++ b/test/functional/wallet_signer.py
@@ -18,6 +18,9 @@ from test_framework.util import (
class WalletSignerTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def mock_signer_path(self):
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mocks', 'signer.py')
if platform.system() == "Windows":
diff --git a/test/functional/wallet_signmessagewithaddress.py b/test/functional/wallet_signmessagewithaddress.py
index 74a8f2eef2..be43bab501 100755
--- a/test/functional/wallet_signmessagewithaddress.py
+++ b/test/functional/wallet_signmessagewithaddress.py
@@ -10,6 +10,9 @@ from test_framework.util import (
)
class SignMessagesWithAddressTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/wallet_signrawtransactionwithwallet.py b/test/functional/wallet_signrawtransactionwithwallet.py
index 6b30386b7e..247269ce2a 100755
--- a/test/functional/wallet_signrawtransactionwithwallet.py
+++ b/test/functional/wallet_signrawtransactionwithwallet.py
@@ -34,6 +34,9 @@ from decimal import (
)
class SignRawTransactionWithWalletTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
diff --git a/test/functional/wallet_simulaterawtx.py b/test/functional/wallet_simulaterawtx.py
index a408b99515..b7c64f3a93 100755
--- a/test/functional/wallet_simulaterawtx.py
+++ b/test/functional/wallet_simulaterawtx.py
@@ -15,6 +15,9 @@ from test_framework.util import (
)
class SimulateTxTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/wallet_startup.py b/test/functional/wallet_startup.py
index d96c2da686..fefd5798f7 100755
--- a/test/functional/wallet_startup.py
+++ b/test/functional/wallet_startup.py
@@ -13,6 +13,9 @@ from test_framework.util import (
class WalletStartupTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
diff --git a/test/functional/wallet_taproot.py b/test/functional/wallet_taproot.py
index 4c28958982..dde83269fa 100755
--- a/test/functional/wallet_taproot.py
+++ b/test/functional/wallet_taproot.py
@@ -187,6 +187,9 @@ def compute_raw_taproot_address(pubkey):
class WalletTaprootTest(BitcoinTestFramework):
"""Test generation and spending of P2TR address outputs."""
+ def add_options(self, parser):
+ self.add_wallet_options(parser, legacy=False)
+
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
diff --git a/test/functional/wallet_timelock.py b/test/functional/wallet_timelock.py
index a71cec6607..57a7c3907a 100755
--- a/test/functional/wallet_timelock.py
+++ b/test/functional/wallet_timelock.py
@@ -8,6 +8,9 @@ from test_framework.util import assert_equal
class WalletLocktimeTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
diff --git a/test/functional/wallet_transactiontime_rescan.py b/test/functional/wallet_transactiontime_rescan.py
index 9caa1fa3d0..c8f4e260da 100755
--- a/test/functional/wallet_transactiontime_rescan.py
+++ b/test/functional/wallet_transactiontime_rescan.py
@@ -17,6 +17,9 @@ from test_framework.util import (
class TransactionTimeRescanTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.setup_clean_chain = False
self.num_nodes = 3
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index 5bdde13aa4..a06f094610 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -24,6 +24,7 @@ class TxnMallTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def add_options(self, parser):
+ self.add_wallet_options(parser)
parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true",
help="Test double-spend of 1-confirmed transaction")
parser.add_argument("--segwit", dest="segwit", default=False, action="store_true",
diff --git a/test/functional/wallet_txn_doublespend.py b/test/functional/wallet_txn_doublespend.py
index 206187fb61..bfb29ae773 100755
--- a/test/functional/wallet_txn_doublespend.py
+++ b/test/functional/wallet_txn_doublespend.py
@@ -22,6 +22,7 @@ class TxnMallTest(BitcoinTestFramework):
self.skip_if_no_wallet()
def add_options(self, parser):
+ self.add_wallet_options(parser)
parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true",
help="Test double-spend of 1-confirmed transaction")
diff --git a/test/functional/wallet_upgradewallet.py b/test/functional/wallet_upgradewallet.py
index c452e1eafd..97df320464 100755
--- a/test/functional/wallet_upgradewallet.py
+++ b/test/functional/wallet_upgradewallet.py
@@ -45,6 +45,9 @@ def deser_keymeta(f):
return ver, create_time, kp_str, seed_id, fpr, path_len, path, has_key_orig
class UpgradeWalletTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser, descriptors=False)
+
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 3
diff --git a/test/functional/wallet_watchonly.py b/test/functional/wallet_watchonly.py
index 69c32ba54c..f5bccb14c0 100755
--- a/test/functional/wallet_watchonly.py
+++ b/test/functional/wallet_watchonly.py
@@ -14,6 +14,9 @@ from test_framework.util import (
class CreateWalletWatchonlyTest(BitcoinTestFramework):
+ def add_options(self, parser):
+ self.add_wallet_options(parser)
+
def set_test_params(self):
self.num_nodes = 1
diff --git a/test/get_previous_releases.py b/test/get_previous_releases.py
index c983dce619..ca06d7b8f8 100755
--- a/test/get_previous_releases.py
+++ b/test/get_previous_releases.py
@@ -136,7 +136,7 @@ def download_binary(tag, args) -> int:
tarballHash = hasher.hexdigest()
if tarballHash not in SHA256_SUMS or SHA256_SUMS[tarballHash]['tarball'] != tarball:
- if tarball in SHA256_SUMS.values():
+ if tarball in [v['tarball'] for v in SHA256_SUMS.values()]:
print("Checksum did not match")
return 1
@@ -260,11 +260,10 @@ if __name__ == '__main__':
help='download release binary.')
parser.add_argument('-t', '--target-dir', action='store',
help='target directory.', default='releases')
- parser.add_argument('tags', nargs='*', default=set(
- [v['tag'] for v in SHA256_SUMS.values()]
- ),
+ all_tags = sorted([*set([v['tag'] for v in SHA256_SUMS.values()])])
+ parser.add_argument('tags', nargs='*', default=all_tags,
help='release tags. e.g.: v0.18.1 v0.20.0rc2 '
- '(if not specified, the full list needed for'
+ '(if not specified, the full list needed for '
'backwards compatibility tests will be used)'
)
args = parser.parse_args()
diff --git a/test/lint/lint-git-commit-check.py b/test/lint/lint-git-commit-check.py
index a1d03370e8..049104398a 100755
--- a/test/lint/lint-git-commit-check.py
+++ b/test/lint/lint-git-commit-check.py
@@ -46,6 +46,8 @@ def main():
commit_range = merge_base + "..HEAD"
else:
commit_range = os.getenv("COMMIT_RANGE")
+ if commit_range == "SKIP_EMPTY_NOT_A_PR":
+ sys.exit(0)
commit_hashes = check_output(["git", "log", commit_range, "--format=%H"], universal_newlines=True, encoding="utf8").splitlines()
diff --git a/test/lint/lint-whitespace.py b/test/lint/lint-whitespace.py
index 3fb5b80013..72b7ebc394 100755
--- a/test/lint/lint-whitespace.py
+++ b/test/lint/lint-whitespace.py
@@ -97,6 +97,8 @@ def main():
commit_range = merge_base + "..HEAD"
else:
commit_range = os.getenv("COMMIT_RANGE")
+ if commit_range == "SKIP_EMPTY_NOT_A_PR":
+ sys.exit(0)
whitespace_selection = []
tab_selection = []