mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-22 06:52:36 +01:00
Merge #20267: Disable and fix tests for when BDB is not compiled
49797c3ccf
tests: Disable bdb dump test when no bdb (Andrew Chow)1194cf9269
Fix wallet_send.py wallet setup to work with descriptors (Andrew Chow)fbaea7bfe4
Require legacy wallet for wallet_upgradewallet.py (Andrew Chow)b1b679e0ab
Explicitly mark legacy wallet tests as such (Andrew Chow)09514e1bef
Setup wallets for interface_zmq.py (Andrew Chow)4d03ef9a73
Use MiniWallet in rpc_net.py (Andrew Chow)4de23824b0
Setup wallets for interface_bitcoin_cli.py (Andrew Chow)7c71c627d2
Setup wallets with descriptors for feature_notifications (Andrew Chow)1f1bef8dba
Have feature_filelock.py test both bdb and sqlite, depending on compiled (Andrew Chow)c77975abc0
Disable upgrades tests that require BDB if BDB is not compiled (Andrew Chow)1f20cac9d4
Disable wallet_descriptor.py bdb format check if BDB is not compiled (Andrew Chow)3641597d7e
tests: Don't make any wallets unless wallet is required (Andrew Chow)b9b88f57a9
Skip legacy wallet reliant tests if BDB is not compiled (Andrew Chow)6f36242389
tests: Set descriptors default based on compilation (Andrew Chow) Pull request description: This PR fixes tests for when BDB is not compiled. Tests which rely on or test legacy wallet behavior are disabled and skipped when BDB is not compiled. For the components of some tests that are for legacy wallet things, those parts of the tests are skipped. For the majority of tests, changes are made so that they can be run with either legacy wallets or descriptor wallets without materially effecting the test. Most tests only need the wallet for balance and transactions, so the type of wallet is not an important part of those tests. Additionally, some tests are wallet agnostic and modified to instead use the test framework's MiniWallet. ACKs for top commit: laanwj: ACK49797c3ccf
ryanofsky: Code review ACK49797c3ccf
. Only change since last review is dropping last commit. Previous review w/ suggestions for future followup is https://github.com/bitcoin/bitcoin/pull/20267#pullrequestreview-581508843 Tree-SHA512: 69659f8a81fb437ecbca962f4082c12835282dbf1fba7d9952f727a49e01981d749af9b09feda1c8ca737516c7d7a08ef17e782795df3fa69892d5021b41c1ed
This commit is contained in:
commit
a6b1bf6439
12 changed files with 266 additions and 148 deletions
|
@ -354,73 +354,75 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|||
hdkeypath = v17_info["hdkeypath"]
|
||||
pubkey = v17_info["pubkey"]
|
||||
|
||||
# Copy the 0.16 wallet to the last Bitcoin Core version and open it:
|
||||
shutil.copyfile(
|
||||
os.path.join(node_v16_wallets_dir, "wallets/u1_v16"),
|
||||
os.path.join(node_master_wallets_dir, "u1_v16")
|
||||
)
|
||||
load_res = node_master.loadwallet("u1_v16")
|
||||
# Make sure this wallet opens without warnings. See https://github.com/bitcoin/bitcoin/pull/19054
|
||||
assert_equal(load_res['warning'], '')
|
||||
wallet = node_master.get_wallet_rpc("u1_v16")
|
||||
info = wallet.getaddressinfo(v16_addr)
|
||||
descriptor = "wpkh([" + info["hdmasterfingerprint"] + hdkeypath[1:] + "]" + v16_pubkey + ")"
|
||||
assert_equal(info["desc"], descsum_create(descriptor))
|
||||
if self.is_bdb_compiled():
|
||||
# Old wallets are BDB and will only work if BDB is compiled
|
||||
# Copy the 0.16 wallet to the last Bitcoin Core version and open it:
|
||||
shutil.copyfile(
|
||||
os.path.join(node_v16_wallets_dir, "wallets/u1_v16"),
|
||||
os.path.join(node_master_wallets_dir, "u1_v16")
|
||||
)
|
||||
load_res = node_master.loadwallet("u1_v16")
|
||||
# Make sure this wallet opens without warnings. See https://github.com/bitcoin/bitcoin/pull/19054
|
||||
assert_equal(load_res['warning'], '')
|
||||
wallet = node_master.get_wallet_rpc("u1_v16")
|
||||
info = wallet.getaddressinfo(v16_addr)
|
||||
descriptor = "wpkh([" + info["hdmasterfingerprint"] + hdkeypath[1:] + "]" + v16_pubkey + ")"
|
||||
assert_equal(info["desc"], descsum_create(descriptor))
|
||||
|
||||
# Now copy that same wallet back to 0.16 to make sure no automatic upgrade breaks it
|
||||
os.remove(os.path.join(node_v16_wallets_dir, "wallets/u1_v16"))
|
||||
shutil.copyfile(
|
||||
os.path.join(node_master_wallets_dir, "u1_v16"),
|
||||
os.path.join(node_v16_wallets_dir, "wallets/u1_v16")
|
||||
)
|
||||
self.start_node(-1, extra_args=["-wallet=u1_v16"])
|
||||
wallet = node_v16.get_wallet_rpc("u1_v16")
|
||||
info = wallet.validateaddress(v16_addr)
|
||||
assert_equal(info, v16_info)
|
||||
# Now copy that same wallet back to 0.16 to make sure no automatic upgrade breaks it
|
||||
os.remove(os.path.join(node_v16_wallets_dir, "wallets/u1_v16"))
|
||||
shutil.copyfile(
|
||||
os.path.join(node_master_wallets_dir, "u1_v16"),
|
||||
os.path.join(node_v16_wallets_dir, "wallets/u1_v16")
|
||||
)
|
||||
self.start_node(-1, extra_args=["-wallet=u1_v16"])
|
||||
wallet = node_v16.get_wallet_rpc("u1_v16")
|
||||
info = wallet.validateaddress(v16_addr)
|
||||
assert_equal(info, v16_info)
|
||||
|
||||
# Copy the 0.17 wallet to the last Bitcoin Core version and open it:
|
||||
node_v17.unloadwallet("u1_v17")
|
||||
shutil.copytree(
|
||||
os.path.join(node_v17_wallets_dir, "u1_v17"),
|
||||
os.path.join(node_master_wallets_dir, "u1_v17")
|
||||
)
|
||||
node_master.loadwallet("u1_v17")
|
||||
wallet = node_master.get_wallet_rpc("u1_v17")
|
||||
info = wallet.getaddressinfo(address)
|
||||
descriptor = "wpkh([" + info["hdmasterfingerprint"] + hdkeypath[1:] + "]" + pubkey + ")"
|
||||
assert_equal(info["desc"], descsum_create(descriptor))
|
||||
# Copy the 0.17 wallet to the last Bitcoin Core version and open it:
|
||||
node_v17.unloadwallet("u1_v17")
|
||||
shutil.copytree(
|
||||
os.path.join(node_v17_wallets_dir, "u1_v17"),
|
||||
os.path.join(node_master_wallets_dir, "u1_v17")
|
||||
)
|
||||
node_master.loadwallet("u1_v17")
|
||||
wallet = node_master.get_wallet_rpc("u1_v17")
|
||||
info = wallet.getaddressinfo(address)
|
||||
descriptor = "wpkh([" + info["hdmasterfingerprint"] + hdkeypath[1:] + "]" + pubkey + ")"
|
||||
assert_equal(info["desc"], descsum_create(descriptor))
|
||||
|
||||
# Now copy that same wallet back to 0.17 to make sure no automatic upgrade breaks it
|
||||
node_master.unloadwallet("u1_v17")
|
||||
shutil.rmtree(os.path.join(node_v17_wallets_dir, "u1_v17"))
|
||||
shutil.copytree(
|
||||
os.path.join(node_master_wallets_dir, "u1_v17"),
|
||||
os.path.join(node_v17_wallets_dir, "u1_v17")
|
||||
)
|
||||
node_v17.loadwallet("u1_v17")
|
||||
wallet = node_v17.get_wallet_rpc("u1_v17")
|
||||
info = wallet.getaddressinfo(address)
|
||||
assert_equal(info, v17_info)
|
||||
# Now copy that same wallet back to 0.17 to make sure no automatic upgrade breaks it
|
||||
node_master.unloadwallet("u1_v17")
|
||||
shutil.rmtree(os.path.join(node_v17_wallets_dir, "u1_v17"))
|
||||
shutil.copytree(
|
||||
os.path.join(node_master_wallets_dir, "u1_v17"),
|
||||
os.path.join(node_v17_wallets_dir, "u1_v17")
|
||||
)
|
||||
node_v17.loadwallet("u1_v17")
|
||||
wallet = node_v17.get_wallet_rpc("u1_v17")
|
||||
info = wallet.getaddressinfo(address)
|
||||
assert_equal(info, v17_info)
|
||||
|
||||
# Copy the 0.19 wallet to the last Bitcoin Core version and open it:
|
||||
shutil.copytree(
|
||||
os.path.join(node_v19_wallets_dir, "w1_v19"),
|
||||
os.path.join(node_master_wallets_dir, "w1_v19")
|
||||
)
|
||||
node_master.loadwallet("w1_v19")
|
||||
wallet = node_master.get_wallet_rpc("w1_v19")
|
||||
assert wallet.getaddressinfo(address_18075)["solvable"]
|
||||
# Copy the 0.19 wallet to the last Bitcoin Core version and open it:
|
||||
shutil.copytree(
|
||||
os.path.join(node_v19_wallets_dir, "w1_v19"),
|
||||
os.path.join(node_master_wallets_dir, "w1_v19")
|
||||
)
|
||||
node_master.loadwallet("w1_v19")
|
||||
wallet = node_master.get_wallet_rpc("w1_v19")
|
||||
assert wallet.getaddressinfo(address_18075)["solvable"]
|
||||
|
||||
# Now copy that same wallet back to 0.19 to make sure no automatic upgrade breaks it
|
||||
node_master.unloadwallet("w1_v19")
|
||||
shutil.rmtree(os.path.join(node_v19_wallets_dir, "w1_v19"))
|
||||
shutil.copytree(
|
||||
os.path.join(node_master_wallets_dir, "w1_v19"),
|
||||
os.path.join(node_v19_wallets_dir, "w1_v19")
|
||||
)
|
||||
node_v19.loadwallet("w1_v19")
|
||||
wallet = node_v19.get_wallet_rpc("w1_v19")
|
||||
assert wallet.getaddressinfo(address_18075)["solvable"]
|
||||
# Now copy that same wallet back to 0.19 to make sure no automatic upgrade breaks it
|
||||
node_master.unloadwallet("w1_v19")
|
||||
shutil.rmtree(os.path.join(node_v19_wallets_dir, "w1_v19"))
|
||||
shutil.copytree(
|
||||
os.path.join(node_master_wallets_dir, "w1_v19"),
|
||||
os.path.join(node_v19_wallets_dir, "w1_v19")
|
||||
)
|
||||
node_v19.loadwallet("w1_v19")
|
||||
wallet = node_v19.get_wallet_rpc("w1_v19")
|
||||
assert wallet.getaddressinfo(address_18075)["solvable"]
|
||||
|
||||
if __name__ == '__main__':
|
||||
BackwardsCompatibilityTest().main()
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Check that it's not possible to start a second bitcoind instance using the same datadir or wallet."""
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.test_node import ErrorMatch
|
||||
|
@ -27,11 +29,21 @@ class FilelockTest(BitcoinTestFramework):
|
|||
self.nodes[1].assert_start_raises_init_error(extra_args=['-datadir={}'.format(self.nodes[0].datadir), '-noserver'], expected_msg=expected_msg)
|
||||
|
||||
if self.is_wallet_compiled():
|
||||
self.nodes[0].createwallet(self.default_wallet_name)
|
||||
wallet_dir = os.path.join(datadir, 'wallets')
|
||||
self.log.info("Check that we can't start a second bitcoind instance using the same wallet")
|
||||
expected_msg = "Error: Error initializing wallet database environment"
|
||||
self.nodes[1].assert_start_raises_init_error(extra_args=['-walletdir={}'.format(wallet_dir), '-wallet=' + self.default_wallet_name, '-noserver'], expected_msg=expected_msg, match=ErrorMatch.PARTIAL_REGEX)
|
||||
def check_wallet_filelock(descriptors):
|
||||
wallet_name = ''.join([random.choice(string.ascii_lowercase) for _ in range(6)])
|
||||
self.nodes[0].createwallet(wallet_name=wallet_name, descriptors=descriptors)
|
||||
wallet_dir = os.path.join(datadir, 'wallets')
|
||||
self.log.info("Check that we can't start a second bitcoind instance using the same wallet")
|
||||
if descriptors:
|
||||
expected_msg = "Error: SQLiteDatabase: Unable to obtain an exclusive lock on the database, is it being used by another bitcoind?"
|
||||
else:
|
||||
expected_msg = "Error: Error initializing wallet database environment"
|
||||
self.nodes[1].assert_start_raises_init_error(extra_args=['-walletdir={}'.format(wallet_dir), '-wallet=' + wallet_name, '-noserver'], expected_msg=expected_msg, match=ErrorMatch.PARTIAL_REGEX)
|
||||
|
||||
if self.is_bdb_compiled():
|
||||
check_wallet_filelock(False)
|
||||
if self.is_sqlite_compiled():
|
||||
check_wallet_filelock(True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
FilelockTest().main()
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
"""Test the -alertnotify, -blocknotify and -walletnotify options."""
|
||||
import os
|
||||
|
||||
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE, keyhash_to_p2pkh
|
||||
from test_framework.address import ADDRESS_BCRT1_UNSPENDABLE
|
||||
from test_framework.descriptors import descsum_create
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
hex_str_to_bytes,
|
||||
)
|
||||
|
||||
# Linux allow all characters other than \x00
|
||||
|
@ -49,6 +49,31 @@ class NotificationsTest(BitcoinTestFramework):
|
|||
super().setup_network()
|
||||
|
||||
def run_test(self):
|
||||
if self.is_wallet_compiled():
|
||||
# Setup the descriptors to be imported to the wallet
|
||||
seed = "cTdGmKFWpbvpKQ7ejrdzqYT2hhjyb3GPHnLAK7wdi5Em67YLwSm9"
|
||||
xpriv = "tprv8ZgxMBicQKsPfHCsTwkiM1KT56RXbGGTqvc2hgqzycpwbHqqpcajQeMRZoBD35kW4RtyCemu6j34Ku5DEspmgjKdt2qe4SvRch5Kk8B8A2v"
|
||||
desc_imports = [{
|
||||
"desc": descsum_create("wpkh(" + xpriv + "/0/*)"),
|
||||
"timestamp": 0,
|
||||
"active": True,
|
||||
"keypool": True,
|
||||
},{
|
||||
"desc": descsum_create("wpkh(" + xpriv + "/1/*)"),
|
||||
"timestamp": 0,
|
||||
"active": True,
|
||||
"keypool": True,
|
||||
"internal": True,
|
||||
}]
|
||||
# Make the wallets and import the descriptors
|
||||
# Ensures that node 0 and node 1 share the same wallet for the conflicting transaction tests below.
|
||||
for i, name in enumerate(self.wallet_names):
|
||||
self.nodes[i].createwallet(wallet_name=name, descriptors=self.options.descriptors, blank=True, load_on_startup=True)
|
||||
if self.options.descriptors:
|
||||
self.nodes[i].importdescriptors(desc_imports)
|
||||
else:
|
||||
self.nodes[i].sethdseed(True, seed)
|
||||
|
||||
self.log.info("test -blocknotify")
|
||||
block_count = 10
|
||||
blocks = self.nodes[1].generatetoaddress(block_count, self.nodes[1].getnewaddress() if self.is_wallet_compiled() else ADDRESS_BCRT1_UNSPENDABLE)
|
||||
|
@ -84,11 +109,10 @@ class NotificationsTest(BitcoinTestFramework):
|
|||
for tx_file in os.listdir(self.walletnotify_dir):
|
||||
os.remove(os.path.join(self.walletnotify_dir, tx_file))
|
||||
|
||||
# Conflicting transactions tests. Give node 0 same wallet seed as
|
||||
# node 1, generate spends from node 0, and check notifications
|
||||
# Conflicting transactions tests.
|
||||
# Generate spends from node 0, and check notifications
|
||||
# triggered by node 1
|
||||
self.log.info("test -walletnotify with conflicting transactions")
|
||||
self.nodes[0].sethdseed(seed=self.nodes[1].dumpprivkey(keyhash_to_p2pkh(hex_str_to_bytes(self.nodes[1].getwalletinfo()['hdseedid'])[::-1])))
|
||||
self.nodes[0].rescanblockchain()
|
||||
self.nodes[0].generatetoaddress(100, ADDRESS_BCRT1_UNSPENDABLE)
|
||||
self.sync_blocks()
|
||||
|
|
|
@ -29,6 +29,8 @@ class TestBitcoinCli(BitcoinTestFramework):
|
|||
def set_test_params(self):
|
||||
self.setup_clean_chain = True
|
||||
self.num_nodes = 1
|
||||
if self.is_wallet_compiled():
|
||||
self.requires_wallet = True
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_cli()
|
||||
|
|
|
@ -62,6 +62,8 @@ class ZMQSubscriber:
|
|||
class ZMQTest (BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
if self.is_wallet_compiled():
|
||||
self.requires_wallet = True
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_py3_zmq()
|
||||
|
|
|
@ -25,6 +25,7 @@ from test_framework.util import (
|
|||
assert_raises_rpc_error,
|
||||
p2p_port,
|
||||
)
|
||||
from test_framework.wallet import MiniWallet
|
||||
|
||||
|
||||
def assert_net_servicesnames(servicesflag, servicenames):
|
||||
|
@ -48,6 +49,9 @@ class NetTest(BitcoinTestFramework):
|
|||
self.supports_cli = False
|
||||
|
||||
def run_test(self):
|
||||
# We need miniwallet to make a transaction
|
||||
self.wallet = MiniWallet(self.nodes[0])
|
||||
self.wallet.generate(1)
|
||||
# Get out of IBD for the minfeefilter and getpeerinfo tests.
|
||||
self.nodes[0].generate(101)
|
||||
|
||||
|
@ -74,8 +78,7 @@ class NetTest(BitcoinTestFramework):
|
|||
def test_getpeerinfo(self):
|
||||
self.log.info("Test getpeerinfo")
|
||||
# Create a few getpeerinfo last_block/last_transaction values.
|
||||
if self.is_wallet_compiled():
|
||||
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
|
||||
self.wallet.send_self_transfer(from_node=self.nodes[0]) # Make a transaction so we can see it in the getpeerinfo results
|
||||
self.nodes[1].generate(1)
|
||||
self.sync_all()
|
||||
time_now = int(time.time())
|
||||
|
|
|
@ -108,6 +108,9 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
|||
# skipped. If list is truncated, wallet creation is skipped and keys
|
||||
# are not imported.
|
||||
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.set_test_params()
|
||||
assert self.wallet_names is None or len(self.wallet_names) <= self.num_nodes
|
||||
if self.options.timeout_factor == 0 :
|
||||
|
@ -184,15 +187,30 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
|||
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", default=False, action="store_true",
|
||||
group.add_argument("--descriptors", action='store_const', const=True,
|
||||
help="Run test using a descriptor wallet", dest='descriptors')
|
||||
group.add_argument("--legacy-wallet", default=False, action="store_false",
|
||||
group.add_argument("--legacy-wallet", action='store_const', const=False,
|
||||
help="Run test using legacy wallets", dest='descriptors')
|
||||
|
||||
self.add_options(parser)
|
||||
self.options = parser.parse_args()
|
||||
self.options.previous_releases_path = previous_releases_path
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read_file(open(self.options.configfile))
|
||||
self.config = config
|
||||
|
||||
if self.options.descriptors is None:
|
||||
# Prefer BDB unless it isn't available
|
||||
if self.is_bdb_compiled():
|
||||
self.options.descriptors = False
|
||||
elif self.is_sqlite_compiled():
|
||||
self.options.descriptors = True
|
||||
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.
|
||||
self.options.descriptors = None
|
||||
|
||||
def setup(self):
|
||||
"""Call this method to start up the test framework object with options set."""
|
||||
|
||||
|
@ -202,9 +220,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
|||
|
||||
self.options.cachedir = os.path.abspath(self.options.cachedir)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read_file(open(self.options.configfile))
|
||||
self.config = config
|
||||
config = self.config
|
||||
|
||||
fname_bitcoind = os.path.join(
|
||||
config["environment"]["BUILDDIR"],
|
||||
"src",
|
||||
|
@ -377,7 +394,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
|||
extra_args = self.extra_args
|
||||
self.add_nodes(self.num_nodes, extra_args)
|
||||
self.start_nodes()
|
||||
if self.is_wallet_compiled():
|
||||
if self.requires_wallet:
|
||||
self.import_deterministic_coinbase_privkeys()
|
||||
if not self.setup_clean_chain:
|
||||
for n in self.nodes:
|
||||
|
@ -769,10 +786,13 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
|||
|
||||
def skip_if_no_wallet(self):
|
||||
"""Skip the running test if wallet has not been compiled."""
|
||||
self.requires_wallet = True
|
||||
if not self.is_wallet_compiled():
|
||||
raise SkipTest("wallet has not been compiled.")
|
||||
if self.options.descriptors:
|
||||
self.skip_if_no_sqlite()
|
||||
else:
|
||||
self.skip_if_no_bdb()
|
||||
|
||||
def skip_if_no_sqlite(self):
|
||||
"""Skip the running test if sqlite has not been compiled."""
|
||||
|
|
|
@ -86,29 +86,29 @@ EXTENDED_SCRIPTS = [
|
|||
BASE_SCRIPTS = [
|
||||
# Scripts that are run by default.
|
||||
# Longest test should go first, to favor running tests in parallel
|
||||
'wallet_hd.py',
|
||||
'wallet_hd.py --legacy-wallet',
|
||||
'wallet_hd.py --descriptors',
|
||||
'wallet_backup.py',
|
||||
'wallet_backup.py --legacy-wallet',
|
||||
'wallet_backup.py --descriptors',
|
||||
# vv Tests less than 5m vv
|
||||
'mining_getblocktemplate_longpoll.py',
|
||||
'feature_maxuploadtarget.py',
|
||||
'feature_block.py',
|
||||
'rpc_fundrawtransaction.py',
|
||||
'rpc_fundrawtransaction.py --legacy-wallet',
|
||||
'rpc_fundrawtransaction.py --descriptors',
|
||||
'p2p_compactblocks.py',
|
||||
'feature_segwit.py --legacy-wallet',
|
||||
# vv Tests less than 2m vv
|
||||
'wallet_basic.py',
|
||||
'wallet_basic.py --legacy-wallet',
|
||||
'wallet_basic.py --descriptors',
|
||||
'wallet_labels.py',
|
||||
'wallet_labels.py --legacy-wallet',
|
||||
'wallet_labels.py --descriptors',
|
||||
'p2p_segwit.py',
|
||||
'p2p_timeouts.py',
|
||||
'p2p_tx_download.py',
|
||||
'mempool_updatefromblock.py',
|
||||
'wallet_dump.py --legacy-wallet',
|
||||
'wallet_listtransactions.py',
|
||||
'wallet_listtransactions.py --legacy-wallet',
|
||||
'wallet_listtransactions.py --descriptors',
|
||||
'feature_taproot.py',
|
||||
# vv Tests less than 60s vv
|
||||
|
@ -116,21 +116,21 @@ BASE_SCRIPTS = [
|
|||
'wallet_importmulti.py --legacy-wallet',
|
||||
'mempool_limit.py',
|
||||
'rpc_txoutproof.py',
|
||||
'wallet_listreceivedby.py',
|
||||
'wallet_listreceivedby.py --legacy-wallet',
|
||||
'wallet_listreceivedby.py --descriptors',
|
||||
'wallet_abandonconflict.py',
|
||||
'wallet_abandonconflict.py --legacy-wallet',
|
||||
'wallet_abandonconflict.py --descriptors',
|
||||
'feature_csv_activation.py',
|
||||
'rpc_rawtransaction.py',
|
||||
'rpc_rawtransaction.py --legacy-wallet',
|
||||
'rpc_rawtransaction.py --descriptors',
|
||||
'wallet_address_types.py',
|
||||
'wallet_address_types.py --legacy-wallet',
|
||||
'wallet_address_types.py --descriptors',
|
||||
'feature_bip68_sequence.py',
|
||||
'p2p_feefilter.py',
|
||||
'feature_reindex.py',
|
||||
'feature_abortnode.py',
|
||||
# vv Tests less than 30s vv
|
||||
'wallet_keypool_topup.py',
|
||||
'wallet_keypool_topup.py --legacy-wallet',
|
||||
'wallet_keypool_topup.py --descriptors',
|
||||
'feature_fee_estimation.py',
|
||||
'interface_zmq.py',
|
||||
|
@ -138,7 +138,7 @@ BASE_SCRIPTS = [
|
|||
'interface_bitcoin_cli.py',
|
||||
'mempool_resurrect.py',
|
||||
'wallet_txn_doublespend.py --mineblock',
|
||||
'tool_wallet.py',
|
||||
'tool_wallet.py --legacy-wallet',
|
||||
'tool_wallet.py --descriptors',
|
||||
'wallet_txn_clone.py',
|
||||
'wallet_txn_clone.py --segwit',
|
||||
|
@ -146,14 +146,14 @@ BASE_SCRIPTS = [
|
|||
'rpc_misc.py',
|
||||
'interface_rest.py',
|
||||
'mempool_spend_coinbase.py',
|
||||
'wallet_avoidreuse.py',
|
||||
'wallet_avoidreuse.py --legacy-wallet',
|
||||
'wallet_avoidreuse.py --descriptors',
|
||||
'mempool_reorg.py',
|
||||
'mempool_persist.py',
|
||||
'wallet_multiwallet.py',
|
||||
'wallet_multiwallet.py --legacy-wallet',
|
||||
'wallet_multiwallet.py --descriptors',
|
||||
'wallet_multiwallet.py --usecli',
|
||||
'wallet_createwallet.py',
|
||||
'wallet_createwallet.py --legacy-wallet',
|
||||
'wallet_createwallet.py --usecli',
|
||||
'wallet_createwallet.py --descriptors',
|
||||
'wallet_watchonly.py --legacy-wallet',
|
||||
|
@ -161,27 +161,27 @@ BASE_SCRIPTS = [
|
|||
'wallet_reorgsrestore.py',
|
||||
'interface_http.py',
|
||||
'interface_rpc.py',
|
||||
'rpc_psbt.py',
|
||||
'rpc_psbt.py --legacy-wallet',
|
||||
'rpc_psbt.py --descriptors',
|
||||
'rpc_users.py',
|
||||
'rpc_whitelist.py',
|
||||
'feature_proxy.py',
|
||||
'rpc_signrawtransaction.py',
|
||||
'rpc_signrawtransaction.py --legacy-wallet',
|
||||
'rpc_signrawtransaction.py --descriptors',
|
||||
'wallet_groups.py',
|
||||
'wallet_groups.py --legacy-wallet',
|
||||
'p2p_addrv2_relay.py',
|
||||
'wallet_groups.py --descriptors',
|
||||
'p2p_disconnect_ban.py',
|
||||
'rpc_decodescript.py',
|
||||
'rpc_blockchain.py',
|
||||
'rpc_deprecated.py',
|
||||
'wallet_disable.py',
|
||||
'wallet_disable.py --legacy-wallet',
|
||||
'wallet_disable.py --descriptors',
|
||||
'p2p_addr_relay.py',
|
||||
'p2p_getaddr_caching.py',
|
||||
'p2p_getdata.py',
|
||||
'rpc_net.py',
|
||||
'wallet_keypool.py',
|
||||
'wallet_keypool.py --legacy-wallet',
|
||||
'wallet_keypool.py --descriptors',
|
||||
'wallet_descriptor.py --descriptors',
|
||||
'p2p_nobloomfilter_messages.py',
|
||||
|
@ -195,9 +195,9 @@ BASE_SCRIPTS = [
|
|||
'p2p_invalid_tx.py',
|
||||
'feature_assumevalid.py',
|
||||
'example_test.py',
|
||||
'wallet_txn_doublespend.py',
|
||||
'wallet_txn_doublespend.py --legacy-wallet',
|
||||
'wallet_txn_doublespend.py --descriptors',
|
||||
'feature_backwards_compatibility.py',
|
||||
'feature_backwards_compatibility.py --legacy-wallet',
|
||||
'feature_backwards_compatibility.py --descriptors',
|
||||
'wallet_txn_clone.py --mineblock',
|
||||
'feature_notifications.py',
|
||||
|
@ -206,59 +206,60 @@ BASE_SCRIPTS = [
|
|||
'feature_rbf.py',
|
||||
'mempool_packages.py',
|
||||
'mempool_package_onemore.py',
|
||||
'rpc_createmultisig.py',
|
||||
'rpc_createmultisig.py --legacy-wallet',
|
||||
'rpc_createmultisig.py --descriptors',
|
||||
'feature_versionbits_warning.py',
|
||||
'rpc_preciousblock.py',
|
||||
'wallet_importprunedfunds.py',
|
||||
'wallet_importprunedfunds.py --legacy-wallet',
|
||||
'wallet_importprunedfunds.py --descriptors',
|
||||
'p2p_leak_tx.py',
|
||||
'p2p_eviction.py',
|
||||
'rpc_signmessage.py',
|
||||
'rpc_generateblock.py',
|
||||
'rpc_generate.py',
|
||||
'wallet_balance.py',
|
||||
'wallet_balance.py --legacy-wallet',
|
||||
'wallet_balance.py --descriptors',
|
||||
'feature_nulldummy.py',
|
||||
'feature_nulldummy.py --legacy-wallet',
|
||||
'feature_nulldummy.py --descriptors',
|
||||
'mempool_accept.py',
|
||||
'mempool_expiry.py',
|
||||
'wallet_import_rescan.py --legacy-wallet',
|
||||
'wallet_import_with_label.py --legacy-wallet',
|
||||
'wallet_importdescriptors.py --descriptors',
|
||||
'wallet_upgradewallet.py',
|
||||
'wallet_upgradewallet.py --legacy-wallet',
|
||||
'rpc_bind.py --ipv4',
|
||||
'rpc_bind.py --ipv6',
|
||||
'rpc_bind.py --nonloopback',
|
||||
'mining_basic.py',
|
||||
'feature_signet.py',
|
||||
'wallet_bumpfee.py',
|
||||
'wallet_bumpfee.py --legacy-wallet',
|
||||
'wallet_bumpfee.py --descriptors',
|
||||
'wallet_implicitsegwit.py --legacy-wallet',
|
||||
'rpc_named_arguments.py',
|
||||
'wallet_listsinceblock.py',
|
||||
'wallet_listsinceblock.py --legacy-wallet',
|
||||
'wallet_listsinceblock.py --descriptors',
|
||||
'wallet_listdescriptors.py --descriptors',
|
||||
'p2p_leak.py',
|
||||
'wallet_encryption.py',
|
||||
'wallet_encryption.py --legacy-wallet',
|
||||
'wallet_encryption.py --descriptors',
|
||||
'feature_dersig.py',
|
||||
'feature_cltv.py',
|
||||
'rpc_uptime.py',
|
||||
'wallet_resendwallettransactions.py',
|
||||
'wallet_resendwallettransactions.py --legacy-wallet',
|
||||
'wallet_resendwallettransactions.py --descriptors',
|
||||
'wallet_fallbackfee.py',
|
||||
'wallet_fallbackfee.py --legacy-wallet',
|
||||
'wallet_fallbackfee.py --descriptors',
|
||||
'rpc_dumptxoutset.py',
|
||||
'feature_minchainwork.py',
|
||||
'rpc_estimatefee.py',
|
||||
'rpc_getblockstats.py',
|
||||
'wallet_create_tx.py',
|
||||
'wallet_send.py',
|
||||
'wallet_create_tx.py --legacy-wallet',
|
||||
'wallet_send.py --legacy-wallet',
|
||||
'wallet_send.py --descriptors',
|
||||
'wallet_create_tx.py --descriptors',
|
||||
'p2p_fingerprint.py',
|
||||
'feature_uacomment.py',
|
||||
'wallet_coinbase_category.py',
|
||||
'wallet_coinbase_category.py --legacy-wallet',
|
||||
'wallet_coinbase_category.py --descriptors',
|
||||
'feature_filelock.py',
|
||||
'feature_loadblock.py',
|
||||
|
|
|
@ -350,7 +350,8 @@ class ToolWalletTest(BitcoinTestFramework):
|
|||
|
||||
self.log.info('Checking createfromdump')
|
||||
self.do_tool_createfromdump("load", "wallet.dump")
|
||||
self.do_tool_createfromdump("load-bdb", "wallet.dump", "bdb")
|
||||
if self.is_bdb_compiled():
|
||||
self.do_tool_createfromdump("load-bdb", "wallet.dump", "bdb")
|
||||
if self.is_sqlite_compiled():
|
||||
self.do_tool_createfromdump("load-sqlite", "wallet.dump", "sqlite")
|
||||
|
||||
|
|
|
@ -23,11 +23,14 @@ class WalletDescriptorTest(BitcoinTestFramework):
|
|||
self.skip_if_no_sqlite()
|
||||
|
||||
def run_test(self):
|
||||
# Make a legacy wallet and check it is BDB
|
||||
self.nodes[0].createwallet(wallet_name="legacy1", descriptors=False)
|
||||
wallet_info = self.nodes[0].getwalletinfo()
|
||||
assert_equal(wallet_info['format'], 'bdb')
|
||||
self.nodes[0].unloadwallet("legacy1")
|
||||
if self.is_bdb_compiled():
|
||||
# Make a legacy wallet and check it is BDB
|
||||
self.nodes[0].createwallet(wallet_name="legacy1", descriptors=False)
|
||||
wallet_info = self.nodes[0].getwalletinfo()
|
||||
assert_equal(wallet_info['format'], 'bdb')
|
||||
self.nodes[0].unloadwallet("legacy1")
|
||||
else:
|
||||
self.log.warning("Skipping BDB test")
|
||||
|
||||
# Make a descriptor wallet
|
||||
self.log.info("Making a descriptor wallet")
|
||||
|
|
|
@ -8,6 +8,7 @@ from decimal import Decimal, getcontext
|
|||
from itertools import product
|
||||
|
||||
from test_framework.authproxy import JSONRPCException
|
||||
from test_framework.descriptors import descsum_create
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import (
|
||||
assert_equal,
|
||||
|
@ -168,48 +169,90 @@ class WalletSendTest(BitcoinTestFramework):
|
|||
self.nodes[1].createwallet(wallet_name="w1")
|
||||
w1 = self.nodes[1].get_wallet_rpc("w1")
|
||||
# w2 contains the private keys for w3
|
||||
self.nodes[1].createwallet(wallet_name="w2")
|
||||
self.nodes[1].createwallet(wallet_name="w2", blank=True)
|
||||
w2 = self.nodes[1].get_wallet_rpc("w2")
|
||||
xpriv = "tprv8ZgxMBicQKsPfHCsTwkiM1KT56RXbGGTqvc2hgqzycpwbHqqpcajQeMRZoBD35kW4RtyCemu6j34Ku5DEspmgjKdt2qe4SvRch5Kk8B8A2v"
|
||||
xpub = "tpubD6NzVbkrYhZ4YkEfMbRJkQyZe7wTkbTNRECozCtJPtdLRn6cT1QKb8yHjwAPcAr26eHBFYs5iLiFFnCbwPRsncCKUKCfubHDMGKzMVcN1Jg"
|
||||
if self.options.descriptors:
|
||||
w2.importdescriptors([{
|
||||
"desc": descsum_create("wpkh(" + xpriv + "/0/0/*)"),
|
||||
"timestamp": "now",
|
||||
"range": [0, 100],
|
||||
"active": True
|
||||
},{
|
||||
"desc": descsum_create("wpkh(" + xpriv + "/0/1/*)"),
|
||||
"timestamp": "now",
|
||||
"range": [0, 100],
|
||||
"active": True,
|
||||
"internal": True
|
||||
}])
|
||||
else:
|
||||
w2.sethdseed(True)
|
||||
|
||||
# w3 is a watch-only wallet, based on w2
|
||||
self.nodes[1].createwallet(wallet_name="w3", disable_private_keys=True)
|
||||
w3 = self.nodes[1].get_wallet_rpc("w3")
|
||||
for _ in range(3):
|
||||
a2_receive = w2.getnewaddress()
|
||||
a2_change = w2.getrawchangeaddress() # doesn't actually use change derivation
|
||||
res = w3.importmulti([{
|
||||
"desc": w2.getaddressinfo(a2_receive)["desc"],
|
||||
if self.options.descriptors:
|
||||
# Match the privkeys in w2 for descriptors
|
||||
res = w3.importdescriptors([{
|
||||
"desc": descsum_create("wpkh(" + xpub + "/0/0/*)"),
|
||||
"timestamp": "now",
|
||||
"range": [0, 100],
|
||||
"keypool": True,
|
||||
"active": True,
|
||||
"watchonly": True
|
||||
},{
|
||||
"desc": w2.getaddressinfo(a2_change)["desc"],
|
||||
"desc": descsum_create("wpkh(" + xpub + "/0/1/*)"),
|
||||
"timestamp": "now",
|
||||
"range": [0, 100],
|
||||
"keypool": True,
|
||||
"active": True,
|
||||
"internal": True,
|
||||
"watchonly": True
|
||||
}])
|
||||
assert_equal(res, [{"success": True}, {"success": True}])
|
||||
|
||||
for _ in range(3):
|
||||
a2_receive = w2.getnewaddress()
|
||||
if not self.options.descriptors:
|
||||
# Because legacy wallets use exclusively hardened derivation, we can't do a ranged import like we do for descriptors
|
||||
a2_change = w2.getrawchangeaddress() # doesn't actually use change derivation
|
||||
res = w3.importmulti([{
|
||||
"desc": w2.getaddressinfo(a2_receive)["desc"],
|
||||
"timestamp": "now",
|
||||
"keypool": True,
|
||||
"watchonly": True
|
||||
},{
|
||||
"desc": w2.getaddressinfo(a2_change)["desc"],
|
||||
"timestamp": "now",
|
||||
"keypool": True,
|
||||
"internal": True,
|
||||
"watchonly": True
|
||||
}])
|
||||
assert_equal(res, [{"success": True}, {"success": True}])
|
||||
|
||||
w0.sendtoaddress(a2_receive, 10) # fund w3
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_blocks()
|
||||
|
||||
# w4 has private keys enabled, but only contains watch-only keys (from w2)
|
||||
self.nodes[1].createwallet(wallet_name="w4", disable_private_keys=False)
|
||||
w4 = self.nodes[1].get_wallet_rpc("w4")
|
||||
for _ in range(3):
|
||||
a2_receive = w2.getnewaddress()
|
||||
res = w4.importmulti([{
|
||||
"desc": w2.getaddressinfo(a2_receive)["desc"],
|
||||
"timestamp": "now",
|
||||
"keypool": False,
|
||||
"watchonly": True
|
||||
}])
|
||||
assert_equal(res, [{"success": True}])
|
||||
if not self.options.descriptors:
|
||||
# w4 has private keys enabled, but only contains watch-only keys (from w2)
|
||||
# This is legacy wallet behavior only as descriptor wallets don't allow watchonly and non-watchonly things in the same wallet.
|
||||
self.nodes[1].createwallet(wallet_name="w4", disable_private_keys=False)
|
||||
w4 = self.nodes[1].get_wallet_rpc("w4")
|
||||
for _ in range(3):
|
||||
a2_receive = w2.getnewaddress()
|
||||
res = w4.importmulti([{
|
||||
"desc": w2.getaddressinfo(a2_receive)["desc"],
|
||||
"timestamp": "now",
|
||||
"keypool": False,
|
||||
"watchonly": True
|
||||
}])
|
||||
assert_equal(res, [{"success": True}])
|
||||
|
||||
w0.sendtoaddress(a2_receive, 10) # fund w4
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_blocks()
|
||||
w0.sendtoaddress(a2_receive, 10) # fund w4
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_blocks()
|
||||
|
||||
self.log.info("Send to address...")
|
||||
self.test_send(from_wallet=w0, to_wallet=w1, amount=1)
|
||||
|
@ -241,11 +284,15 @@ class WalletSendTest(BitcoinTestFramework):
|
|||
res = w2.walletprocesspsbt(res["psbt"])
|
||||
assert res["complete"]
|
||||
|
||||
self.log.info("Create PSBT from wallet w4 with watch-only keys, sign with w2...")
|
||||
self.test_send(from_wallet=w4, to_wallet=w1, amount=1, expect_error=(-4, "Insufficient funds"))
|
||||
res = self.test_send(from_wallet=w4, to_wallet=w1, amount=1, include_watching=True, add_to_wallet=False)
|
||||
res = w2.walletprocesspsbt(res["psbt"])
|
||||
assert res["complete"]
|
||||
if not self.options.descriptors:
|
||||
# Descriptor wallets do not allow mixed watch-only and non-watch-only things in the same wallet.
|
||||
# This is specifically testing that w4 ignores its own private keys and creates a psbt with send
|
||||
# which is not something that needs to be tested in descriptor wallets.
|
||||
self.log.info("Create PSBT from wallet w4 with watch-only keys, sign with w2...")
|
||||
self.test_send(from_wallet=w4, to_wallet=w1, amount=1, expect_error=(-4, "Insufficient funds"))
|
||||
res = self.test_send(from_wallet=w4, to_wallet=w1, amount=1, include_watching=True, add_to_wallet=False)
|
||||
res = w2.walletprocesspsbt(res["psbt"])
|
||||
assert res["complete"]
|
||||
|
||||
self.log.info("Create OP_RETURN...")
|
||||
self.test_send(from_wallet=w0, to_wallet=w1, amount=1)
|
||||
|
|
|
@ -57,6 +57,7 @@ class UpgradeWalletTest(BitcoinTestFramework):
|
|||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
self.skip_if_no_bdb()
|
||||
self.skip_if_no_previous_releases()
|
||||
|
||||
def setup_network(self):
|
||||
|
|
Loading…
Add table
Reference in a new issue