diff options
Diffstat (limited to 'test')
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 = [] |