Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_multiwallet.py
Show First 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
def data_dir(*p): return os.path.join(node.datadir, self.chain, *p) | def data_dir(*p): return os.path.join(node.datadir, self.chain, *p) | ||||
def wallet_dir(*p): return data_dir('wallets', *p) | def wallet_dir(*p): return data_dir('wallets', *p) | ||||
def wallet(name): return node.get_wallet_rpc(name) | def wallet(name): return node.get_wallet_rpc(name) | ||||
def wallet_file(name): | def wallet_file(name): | ||||
if name == self.default_wallet_name: | |||||
return wallet_dir(self.default_wallet_name, | |||||
self.wallet_data_filename) | |||||
if os.path.isdir(wallet_dir(name)): | if os.path.isdir(wallet_dir(name)): | ||||
return wallet_dir(name, self.wallet_data_filename) | return wallet_dir(name, "wallet.dat") | ||||
return wallet_dir(name) | return wallet_dir(name) | ||||
assert_equal(self.nodes[0].listwalletdir(), | assert_equal(self.nodes[0].listwalletdir(), | ||||
{'wallets': [{'name': self.default_wallet_name}]}) | {'wallets': [{'name': self.default_wallet_name}]}) | ||||
# check wallet.dat is created | # check wallet.dat is created | ||||
self.stop_nodes() | self.stop_nodes() | ||||
assert_equal(os.path.isfile(wallet_dir(self.default_wallet_name, | assert_equal(os.path.isfile(wallet_dir(self.default_wallet_name, | ||||
self.wallet_data_filename)), | self.wallet_data_filename)), | ||||
True) | True) | ||||
# create symlink to verify wallet directory path can be referenced | # create symlink to verify wallet directory path can be referenced | ||||
# through symlink | # through symlink | ||||
if os.name != 'nt': | if os.name != 'nt': | ||||
os.mkdir(wallet_dir('w7')) | os.mkdir(wallet_dir('w7')) | ||||
os.symlink('w7', wallet_dir('w7_symlink')) | os.symlink('w7', wallet_dir('w7_symlink')) | ||||
# rename wallet.dat to make sure plain wallet file paths (as opposed to | # rename wallet.dat to make sure plain wallet file paths (as opposed to | ||||
# directory paths) can be loaded | # directory paths) can be loaded | ||||
os.rename(wallet_dir(self.default_wallet_name, self.wallet_data_filename), | |||||
wallet_dir("w8")) | |||||
# create another dummy wallet for use in testing backups later | # create another dummy wallet for use in testing backups later | ||||
self.start_node( | self.start_node(0, ["-nowallet", "-wallet=empty", "-wallet=plain"]) | ||||
0, ["-nowallet", "-wallet=" + self.default_wallet_name]) | node.createwallet("created") | ||||
self.stop_nodes() | self.stop_nodes() | ||||
empty_wallet = os.path.join(self.options.tmpdir, 'empty.dat') | empty_wallet = os.path.join(self.options.tmpdir, 'empty.dat') | ||||
os.rename(wallet_dir(self.default_wallet_name, self.wallet_data_filename), | os.rename(wallet_file("empty"), empty_wallet) | ||||
empty_wallet) | shutil.rmtree(wallet_dir("empty")) | ||||
empty_created_wallet = os.path.join(self.options.tmpdir, | |||||
'empty.created.dat') | |||||
os.rename(wallet_dir("created", self.wallet_data_filename), | |||||
empty_created_wallet) | |||||
shutil.rmtree(wallet_dir("created")) | |||||
os.rename(wallet_file("plain"), wallet_dir("w8")) | |||||
shutil.rmtree(wallet_dir("plain")) | |||||
# restart node with a mix of wallet names: | # restart node with a mix of wallet names: | ||||
# w1, w2, w3 - to verify new wallets created when non-existing paths specified | # w1, w2, w3 - to verify new wallets created when non-existing paths specified | ||||
# w - to verify wallet name matching works when one wallet path is prefix of another | # w - to verify wallet name matching works when one wallet path is prefix of another | ||||
# sub/w5 - to verify relative wallet path is created correctly | # sub/w5 - to verify relative wallet path is created correctly | ||||
# extern/w6 - to verify absolute wallet path is created correctly | # extern/w6 - to verify absolute wallet path is created correctly | ||||
# w7_symlink - to verify symlinked wallet path is initialized correctly | # w7_symlink - to verify symlinked wallet path is initialized correctly | ||||
# w8 - to verify existing wallet file is loaded correctly | # w8 - to verify existing wallet file is loaded correctly | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
w5 = wallet("w5") | w5 = wallet("w5") | ||||
w5_info = w5.getwalletinfo() | w5_info = w5.getwalletinfo() | ||||
assert_equal(w5_info['immature_balance'], 50000000) | assert_equal(w5_info['immature_balance'], 50000000) | ||||
competing_wallet_dir = os.path.join( | competing_wallet_dir = os.path.join( | ||||
self.options.tmpdir, 'competing_walletdir') | self.options.tmpdir, 'competing_walletdir') | ||||
os.mkdir(competing_wallet_dir) | os.mkdir(competing_wallet_dir) | ||||
self.restart_node(0, ['-walletdir=' + competing_wallet_dir]) | self.restart_node(0, ['-walletdir=' + competing_wallet_dir]) | ||||
exp_stderr = r"Error: Error initializing wallet database environment \"\S+competing_walletdir\"!" | exp_stderr = r"Error: Error initializing wallet database environment \"\S+competing_walletdir\S*\"!" | ||||
self.nodes[1].assert_start_raises_init_error( | self.nodes[1].assert_start_raises_init_error( | ||||
['-walletdir=' + competing_wallet_dir], exp_stderr, match=ErrorMatch.PARTIAL_REGEX) | ['-walletdir=' + competing_wallet_dir], exp_stderr, match=ErrorMatch.PARTIAL_REGEX) | ||||
self.restart_node(0, extra_args) | self.restart_node(0, extra_args) | ||||
assert_equal(sorted(map(lambda w: w['name'], | assert_equal(sorted(map(lambda w: w['name'], | ||||
self.nodes[0].listwalletdir()['wallets'])), | self.nodes[0].listwalletdir()['wallets'])), | ||||
[self.default_wallet_name, os.path.join('sub', 'w5'), 'w', | [self.default_wallet_name, os.path.join('sub', 'w5'), 'w', | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
# Fail to load duplicate wallets | # Fail to load duplicate wallets | ||||
path = os.path.join( | path = os.path.join( | ||||
self.options.tmpdir, | self.options.tmpdir, | ||||
"node0", | "node0", | ||||
"regtest", | "regtest", | ||||
"wallets", | "wallets", | ||||
"w1", | "w1", | ||||
self.wallet_data_filename) | "wallet.dat") | ||||
assert_raises_rpc_error( | assert_raises_rpc_error( | ||||
-4, | -4, | ||||
"Wallet file verification failed. Refusing to load database. Data file '{}' is already loaded.".format( | "Wallet file verification failed. Refusing to load database. Data file '{}' is already loaded.".format( | ||||
path), | path), | ||||
self.nodes[0].loadwallet, | self.nodes[0].loadwallet, | ||||
wallet_names[0]) | wallet_names[0]) | ||||
# Fail to load duplicate wallets by different ways (directory and | # Fail to load duplicate wallets by different ways (directory and | ||||
# filepath) | # filepath) | ||||
path = os.path.join( | if not self.options.descriptors: | ||||
self.options.tmpdir, | path = os.path.join(self.options.tmpdir, "node0", "regtest", | ||||
"node0", | "wallets", "wallet.dat") | ||||
"regtest", | |||||
"wallets", | |||||
self.wallet_data_filename) | |||||
assert_raises_rpc_error( | assert_raises_rpc_error( | ||||
-4, | -4, | ||||
"Wallet file verification failed. Refusing to load database. Data file '{}' is already loaded.".format( | "Wallet file verification failed. Refusing to load database. " | ||||
path), | "Data file '{}' is already loaded.".format(path), | ||||
self.nodes[0].loadwallet, | self.nodes[0].loadwallet, 'wallet.dat') | ||||
self.wallet_data_filename) | |||||
# Fail to load if one wallet is a copy of another | # Fail to load if one wallet is a copy of another | ||||
assert_raises_rpc_error(-4, "BerkeleyDatabase: Can't open database w8_copy (duplicates fileid", | assert_raises_rpc_error(-4, "BerkeleyDatabase: Can't open database w8_copy (duplicates fileid", | ||||
self.nodes[0].loadwallet, 'w8_copy') | self.nodes[0].loadwallet, 'w8_copy') | ||||
# Fail to load if one wallet is a copy of another. | # Fail to load if one wallet is a copy of another. | ||||
# Test this twice to make sure that we don't re-introduce | # Test this twice to make sure that we don't re-introduce | ||||
# https://github.com/bitcoin/bitcoin/issues/14304 | # https://github.com/bitcoin/bitcoin/issues/14304 | ||||
▲ Show 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
self.log.info("Test wallet backup") | self.log.info("Test wallet backup") | ||||
self.restart_node(0, ['-nowallet']) | self.restart_node(0, ['-nowallet']) | ||||
for wallet_name in wallet_names: | for wallet_name in wallet_names: | ||||
self.nodes[0].loadwallet(wallet_name) | self.nodes[0].loadwallet(wallet_name) | ||||
for wallet_name in wallet_names: | for wallet_name in wallet_names: | ||||
rpc = self.nodes[0].get_wallet_rpc(wallet_name) | rpc = self.nodes[0].get_wallet_rpc(wallet_name) | ||||
addr = rpc.getnewaddress() | addr = rpc.getnewaddress() | ||||
backup = os.path.join(self.options.tmpdir, 'backup.dat') | backup = os.path.join(self.options.tmpdir, 'backup.dat') | ||||
if os.path.exists(backup): | |||||
os.unlink(backup) | |||||
rpc.backupwallet(backup) | rpc.backupwallet(backup) | ||||
self.nodes[0].unloadwallet(wallet_name) | self.nodes[0].unloadwallet(wallet_name) | ||||
shutil.copyfile(empty_wallet, wallet_file(wallet_name)) | shutil.copyfile( | ||||
empty_created_wallet if wallet_name == self.default_wallet_name else empty_wallet, | |||||
wallet_file(wallet_name)) | |||||
self.nodes[0].loadwallet(wallet_name) | self.nodes[0].loadwallet(wallet_name) | ||||
assert_equal(rpc.getaddressinfo(addr)['ismine'], False) | assert_equal(rpc.getaddressinfo(addr)['ismine'], False) | ||||
self.nodes[0].unloadwallet(wallet_name) | self.nodes[0].unloadwallet(wallet_name) | ||||
shutil.copyfile(backup, wallet_file(wallet_name)) | shutil.copyfile(backup, wallet_file(wallet_name)) | ||||
self.nodes[0].loadwallet(wallet_name) | self.nodes[0].loadwallet(wallet_name) | ||||
assert_equal(rpc.getaddressinfo(addr)['ismine'], True) | assert_equal(rpc.getaddressinfo(addr)['ismine'], True) | ||||
# Test .walletlock file is closed | # Test .walletlock file is closed | ||||
self.start_node(1) | self.start_node(1) | ||||
wallet = os.path.join(self.options.tmpdir, 'my_wallet') | wallet = os.path.join(self.options.tmpdir, 'my_wallet') | ||||
self.nodes[0].createwallet(wallet) | self.nodes[0].createwallet(wallet) | ||||
assert_raises_rpc_error(-4, "Error initializing wallet database environment", | if self.options.descriptors: | ||||
assert_raises_rpc_error(-4, "Unable to obtain an exclusive lock", | |||||
self.nodes[1].loadwallet, wallet) | |||||
else: | |||||
assert_raises_rpc_error( | |||||
-4, "Error initializing wallet database environment", | |||||
self.nodes[1].loadwallet, wallet) | self.nodes[1].loadwallet, wallet) | ||||
self.nodes[0].unloadwallet(wallet) | self.nodes[0].unloadwallet(wallet) | ||||
self.nodes[1].loadwallet(wallet) | self.nodes[1].loadwallet(wallet) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
MultiWalletTest().main() | MultiWalletTest().main() |