dash/test/functional/wallet_multiwallet.py

268 lines
14 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
# Copyright (c) 2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test multiwallet.
Verify that a dashd node can load multiple wallet files
"""
import os
import re
import shutil
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
)
class MultiWalletTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
self.supports_cli = True
def run_test(self):
node = self.nodes[0]
data_dir = lambda *p: os.path.join(node.datadir, self.chain, *p)
wallet_dir = lambda *p: data_dir('wallets', *p)
wallet = lambda name: node.get_wallet_rpc(name)
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
# check wallet.dat is created
self.stop_nodes()
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
assert_equal(os.path.isfile(wallet_dir('wallet.dat')), True)
# create symlink to verify wallet directory path can be referenced
# through symlink
os.mkdir(wallet_dir('w7'))
os.symlink('w7', wallet_dir('w7_symlink'))
# rename wallet.dat to make sure plain wallet file paths (as opposed to
# directory paths) can be loaded
os.rename(wallet_dir("wallet.dat"), wallet_dir("w8"))
# restart node with a mix of wallet names:
# 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
# sub/w5 - to verify relative 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
# w8 - to verify existing wallet file is loaded correctly
# '' - to verify default wallet file is created correctly
wallet_names = ['w1', 'w2', 'w3', 'w', 'sub/w5', os.path.join(self.options.tmpdir, 'extern/w6'), 'w7_symlink', 'w8', '']
extra_args = ['-wallet={}'.format(n) for n in wallet_names]
self.start_node(0, extra_args)
assert_equal(set(node.listwallets()), set(wallet_names))
# check that all requested wallets were created
self.stop_node(0)
for wallet_name in wallet_names:
if os.path.isdir(wallet_dir(wallet_name)):
assert_equal(os.path.isfile(wallet_dir(wallet_name, "wallet.dat")), True)
else:
assert_equal(os.path.isfile(wallet_dir(wallet_name)), True)
# should not initialize if wallet path can't be created
exp_stderr = "boost::filesystem::create_directory: (The system cannot find the path specified|Not a directory):"
self.nodes[0].assert_start_raises_init_error(['-wallet=wallet.dat/bad'], exp_stderr, partial_match=True)
self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" does not exist')
self.nodes[0].assert_start_raises_init_error(['-walletdir=wallets'], 'Error: Specified -walletdir "wallets" is a relative path', cwd=data_dir())
self.nodes[0].assert_start_raises_init_error(['-walletdir=debug.log'], 'Error: Specified -walletdir "debug.log" is not a directory', cwd=data_dir())
# should not initialize if there are duplicate wallets
self.nodes[0].assert_start_raises_init_error(['-wallet=w1', '-wallet=w1'], 'Error: Error loading wallet w1. Duplicate -wallet filename specified.')
# should not initialize if one wallet is a copy of another
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
shutil.copyfile(wallet_dir('w8'), wallet_dir('w8_copy'))
exp_stderr = "Can't open database w8_copy \(duplicates fileid \w+ from w8\)"
self.nodes[0].assert_start_raises_init_error(['-wallet=w8', '-wallet=w8_copy'], exp_stderr, partial_match=True)
# should not initialize if wallet file is a symlink
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
os.symlink('w8', wallet_dir('w8_symlink'))
self.nodes[0].assert_start_raises_init_error(['-wallet=w8_symlink'], 'Error: Invalid -wallet path \'w8_symlink\'\. .*')
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
# should not initialize if the specified walletdir does not exist
self.nodes[0].assert_start_raises_init_error(['-walletdir=bad'], 'Error: Specified -walletdir "bad" does not exist')
# should not initialize if the specified walletdir is not a directory
not_a_dir = wallet_dir('notadir')
open(not_a_dir, 'a', encoding="utf8").close()
self.nodes[0].assert_start_raises_init_error(['-walletdir=' + not_a_dir], 'Error: Specified -walletdir "' + re.escape(not_a_dir) + '" is not a directory')
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
self.log.info("Do not allow -zapwallettxes with multiwallet")
self.nodes[0].assert_start_raises_init_error(['-zapwallettxes', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file")
self.nodes[0].assert_start_raises_init_error(['-zapwallettxes=1', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file")
self.nodes[0].assert_start_raises_init_error(['-zapwallettxes=2', '-wallet=w1', '-wallet=w2'], "Error: -zapwallettxes is only allowed with a single wallet file")
self.log.info("Do not allow -salvagewallet with multiwallet")
self.nodes[0].assert_start_raises_init_error(['-salvagewallet', '-wallet=w1', '-wallet=w2'], "Error: -salvagewallet is only allowed with a single wallet file")
self.nodes[0].assert_start_raises_init_error(['-salvagewallet=1', '-wallet=w1', '-wallet=w2'], "Error: -salvagewallet is only allowed with a single wallet file")
self.log.info("Do not allow -upgradewallet with multiwallet")
self.nodes[0].assert_start_raises_init_error(['-upgradewallet', '-wallet=w1', '-wallet=w2'], "Error: -upgradewallet is only allowed with a single wallet file")
self.nodes[0].assert_start_raises_init_error(['-upgradewallet=1', '-wallet=w1', '-wallet=w2'], "Error: -upgradewallet is only allowed with a single wallet file")
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
# if wallets/ doesn't exist, datadir should be the default wallet dir
wallet_dir2 = data_dir('walletdir')
os.rename(wallet_dir(), wallet_dir2)
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
self.start_node(0, ['-wallet=w4', '-wallet=w5'])
assert_equal(set(node.listwallets()), {"w4", "w5"})
w5 = wallet("w5")
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
w5.generate(1)
# now if wallets/ exists again, but the rootdir is specified as the walletdir, w4 and w5 should still be loaded
os.rename(wallet_dir2, wallet_dir())
self.restart_node(0, ['-wallet=w4', '-wallet=w5', '-walletdir=' + data_dir()])
assert_equal(set(node.listwallets()), {"w4", "w5"})
w5 = wallet("w5")
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
w5_info = w5.getwalletinfo()
assert_equal(w5_info['immature_balance'], 500)
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
competing_wallet_dir = os.path.join(self.options.tmpdir, 'competing_walletdir')
os.mkdir(competing_wallet_dir)
self.restart_node(0, ['-walletdir=' + competing_wallet_dir])
exp_stderr = "Error: Error initializing wallet database environment \"\S+competing_walletdir\"!"
self.nodes[1].assert_start_raises_init_error(['-walletdir=' + competing_wallet_dir], exp_stderr, partial_match=True)
Merge #11466: Specify custom wallet directory with -walletdir param c1e5d40 Make debugging test crash easier (MeshCollider) 8263f6a Create walletdir if datadir doesn't exist and fix tests (MeshCollider) 9587a9c Default walletdir is wallets/ if it exists (MeshCollider) d987889 Add release notes for -walletdir and wallets/ dir (MeshCollider) 80c5cbc Add test for -walletdir (MeshCollider) 0530ba0 Add -walletdir parameter to specify custom wallet dir (MeshCollider) Pull request description: Closes #11348 Adds a `-walletdir` parameter which specifies a directory to use for wallets, allowing them to be stored separately from the 'main' data directory. Creates a new `wallets/` directory in datadir if this is the first time running, and defaults to using it if it exists. Includes tests and release notes. Things which might need to be considered more: - there is no 'lock' on the wallets directory, which might be needed? - because this uses a new wallets/ directory by default, downgrading to an earlier version won't see the wallets in that directory (not a big deal though, users can just copy them up to the main dir) - jnewbery suggested putting each wallet in its own directory, which is a good idea, but out of scope for this PR IMO. EDIT: this is being done in https://github.com/bitcoin/bitcoin/pull/11687 - doc/files.md needs updating (will do soon) I also considered including a cleanup by removing caching of data directory paths and instead just initialise them once on startup (c.f. #3073), but decided it wasn't super relevant here will just complicate review. Tree-SHA512: c8ac04bfe9a810c32055f2c8b8fa0d535e56125ceb8d96f12447dd3538bf3e5ee992b60b1cd2173bf5f3fa023a9feab12c9963593bf27ed419df929bb413398d
2017-11-18 14:32:50 +01:00
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
self.restart_node(0, extra_args)
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
wallets = [wallet(w) for w in wallet_names]
wallet_bad = wallet("bad")
Merge #10711: [tests] Introduce TestNode 789733891 [tests] Introduce TestNode (John Newbery) Pull request description: Continues #10082 TestNode is a class responsible for all state related to a bitcoind node under test. It stores local state, is responsible for tracking the bitcoind process and delegates unrecognised messages to the RPC connection. This commit changes start_nodes and stop_nodes to start and stop the bitcoind nodes in parallel, making test setup and teardown much faster. On my vm, this changeset reduces total test_runner runtime for the base set of tests (including building the cache) from 263s to 195s (a 25% speedup). Note that the time reported by test_runner does not include time spent building the cache: *with TestNode*: ``` → date +"%T" ; ./test_runner.py -q ; date +"%T" 12:48:04 .................................................................................................................................................................................................................................................................................................................................. TEST | STATUS | DURATION abandonconflict.py | ✓ Passed | 12 s bip68-112-113-p2p.py | ✓ Passed | 19 s blockchain.py | ✓ Passed | 8 s bumpfee.py | ✓ Passed | 13 s decodescript.py | ✓ Passed | 3 s disablewallet.py | ✓ Passed | 3 s disconnect_ban.py | ✓ Passed | 6 s fundrawtransaction.py | ✓ Passed | 37 s getchaintips.py | ✓ Passed | 4 s httpbasics.py | ✓ Passed | 3 s import-rescan.py | ✓ Passed | 4 s importmulti.py | ✓ Passed | 6 s importprunedfunds.py | ✓ Passed | 3 s invalidblockrequest.py | ✓ Passed | 4 s invalidtxrequest.py | ✓ Passed | 4 s keypool.py | ✓ Passed | 7 s listsinceblock.py | ✓ Passed | 4 s listtransactions.py | ✓ Passed | 33 s mempool_limit.py | ✓ Passed | 4 s mempool_persist.py | ✓ Passed | 15 s mempool_reorg.py | ✓ Passed | 4 s mempool_resurrect_test.py | ✓ Passed | 3 s mempool_spendcoinbase.py | ✓ Passed | 3 s merkle_blocks.py | ✓ Passed | 3 s multi_rpc.py | ✓ Passed | 4 s net.py | ✓ Passed | 3 s nulldummy.py | ✓ Passed | 3 s p2p-compactblocks.py | ✓ Passed | 28 s p2p-fullblocktest.py | ✓ Passed | 126 s p2p-leaktests.py | ✓ Passed | 8 s p2p-mempool.py | ✓ Passed | 3 s p2p-segwit.py | ✓ Passed | 59 s p2p-versionbits-warning.py | ✓ Passed | 8 s preciousblock.py | ✓ Passed | 3 s prioritise_transaction.py | ✓ Passed | 5 s proxy_test.py | ✓ Passed | 3 s rawtransactions.py | ✓ Passed | 9 s receivedby.py | ✓ Passed | 19 s reindex.py | ✓ Passed | 12 s rest.py | ✓ Passed | 9 s rpcnamedargs.py | ✓ Passed | 3 s segwit.py | ✓ Passed | 7 s sendheaders.py | ✓ Passed | 24 s signmessages.py | ✓ Passed | 3 s signrawtransactions.py | ✓ Passed | 3 s txn_clone.py | ✓ Passed | 4 s txn_doublespend.py --mineblock | ✓ Passed | 4 s uptime.py | ✓ Passed | 3 s wallet-accounts.py | ✓ Passed | 3 s wallet-dump.py | ✓ Passed | 7 s wallet-encryption.py | ✓ Passed | 8 s wallet-hd.py | ✓ Passed | 15 s wallet.py | ✓ Passed | 31 s walletbackup.py | ✓ Passed | 104 s zapwallettxes.py | ✓ Passed | 9 s zmq_test.py | ○ Skipped | 0 s ALL | ✓ Passed | 735 s (accumulated) Runtime: 189 s 12:51:19 ``` *master*: ``` → date +"%T" ; ./test_runner.py -q ; date +"%T" 12:40:13 .......................................................................................................................................................................................................................................................................................................................................................................................................................................... TEST | STATUS | DURATION abandonconflict.py | ✓ Passed | 15 s bip68-112-113-p2p.py | ✓ Passed | 19 s blockchain.py | ✓ Passed | 8 s bumpfee.py | ✓ Passed | 20 s decodescript.py | ✓ Passed | 3 s disablewallet.py | ✓ Passed | 3 s disconnect_ban.py | ✓ Passed | 8 s fundrawtransaction.py | ✓ Passed | 36 s getchaintips.py | ✓ Passed | 11 s httpbasics.py | ✓ Passed | 7 s import-rescan.py | ✓ Passed | 16 s importmulti.py | ✓ Passed | 10 s importprunedfunds.py | ✓ Passed | 5 s invalidblockrequest.py | ✓ Passed | 4 s invalidtxrequest.py | ✓ Passed | 3 s keypool.py | ✓ Passed | 7 s listsinceblock.py | ✓ Passed | 11 s listtransactions.py | ✓ Passed | 37 s mempool_limit.py | ✓ Passed | 4 s mempool_persist.py | ✓ Passed | 23 s mempool_reorg.py | ✓ Passed | 7 s mempool_resurrect_test.py | ✓ Passed | 3 s mempool_spendcoinbase.py | ✓ Passed | 3 s merkle_blocks.py | ✓ Passed | 10 s multi_rpc.py | ✓ Passed | 6 s net.py | ✓ Passed | 6 s nulldummy.py | ✓ Passed | 3 s p2p-compactblocks.py | ✓ Passed | 30 s p2p-fullblocktest.py | ✓ Passed | 126 s p2p-leaktests.py | ✓ Passed | 8 s p2p-mempool.py | ✓ Passed | 3 s p2p-segwit.py | ✓ Passed | 62 s p2p-versionbits-warning.py | ✓ Passed | 8 s preciousblock.py | ✓ Passed | 8 s prioritise_transaction.py | ✓ Passed | 7 s proxy_test.py | ✓ Passed | 10 s rawtransactions.py | ✓ Passed | 15 s receivedby.py | ✓ Passed | 28 s reindex.py | ✓ Passed | 12 s rest.py | ✓ Passed | 12 s rpcnamedargs.py | ✓ Passed | 3 s segwit.py | ✓ Passed | 12 s sendheaders.py | ✓ Passed | 26 s signmessages.py | ✓ Passed | 3 s signrawtransactions.py | ✓ Passed | 3 s txn_clone.py | ✓ Passed | 10 s txn_doublespend.py --mineblock | ✓ Passed | 10 s uptime.py | ✓ Passed | 3 s wallet-accounts.py | ✓ Passed | 3 s wallet-dump.py | ✓ Passed | 6 s wallet-encryption.py | ✓ Passed | 8 s wallet-hd.py | ✓ Passed | 18 s wallet.py | ✓ Passed | 69 s walletbackup.py | ✓ Passed | 130 s zapwallettxes.py | ✓ Passed | 15 s zmq_test.py | ○ Skipped | 0 s ALL | ✓ Passed | 936 s (accumulated) Runtime: 242 s 12:44:36 ``` Tree-SHA512: 6dfc4c11fd0caf7de6954c93679cf22c3df0acc6f432e616d1151062a61f456faa8ae2fe670b427868af55bb564802df84c8fd76e90b4b338750dbc23f46ad88
2017-08-15 23:34:07 +02:00
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
# check wallet names and balances
wallets[0].generate(1)
for wallet_name, wallet in zip(wallet_names, wallets):
info = wallet.getwalletinfo()
assert_equal(info['immature_balance'], 500 if wallet is wallets[0] else 0)
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
assert_equal(info['walletname'], wallet_name)
# accessing invalid wallet fails
assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", wallet_bad.getwalletinfo)
# accessing wallet RPC without using wallet endpoint fails
assert_raises_rpc_error(-19, "Wallet file not specified", node.getwalletinfo)
Merge #11687: External wallet files be8ab7d08 Create new wallet databases as directories rather than files (Russell Yanofsky) 26c06f24e Allow wallet files not in -walletdir directory (Russell Yanofsky) d8a99f65e Allow wallet files in multiple directories (Russell Yanofsky) Pull request description: This change consists of three commits: * The first commit is a pure refactoring that removes the restriction that two wallets can only be opened at the same time if they are contained in the same directory. * The second commit removes the restriction that `-wallet` filenames can only refer to files in the `-walletdir` directory. * The third commit makes second commit a little safer by changing bitcoin to create wallet databases as directories rather than files, so they can be safely backed up. All three commits should be straightforward: * The first commit adds around 20 lines of new code and then updates a bunch of function signatures (generally updating them to take plain fs::path parameters, instead of combinations of strings, fs::paths, and objects like CDBEnv and CWalletDBWrapper). * The second commit removes two `-wallet` filename checks and adds some test cases to the multiwallet unit test. * The third commit just changes the mapping from specified wallet paths to bdb environment & data paths. --- **Note:** For anybody looking at this PR for the first time, I think you can skip the comments before _20 Nov_ and start reading at https://github.com/bitcoin/bitcoin/pull/11687#issuecomment-345625565. Comments before _20 Nov_ were about an earlier version of the PR that didn't include the third commit, and then confusion from not seeing the first commit. Tree-SHA512: 00bbb120fe0df847cf57014f75f1f7f1f58b0b62fa0b3adab4560163ebdfe06ccdfff33b4231693f03c5dc23601cb41954a07bcea9a4919c8d42f7d62bcf6024
2018-03-07 17:05:08 +01:00
w1, w2, w3, w4, *_ = wallets
w1.generate(101)
assert_equal(w1.getbalance(), 1000)
assert_equal(w2.getbalance(), 0)
assert_equal(w3.getbalance(), 0)
assert_equal(w4.getbalance(), 0)
w1.sendtoaddress(w2.getnewaddress(), 1)
w1.sendtoaddress(w3.getnewaddress(), 2)
w1.sendtoaddress(w4.getnewaddress(), 3)
w1.generate(1)
assert_equal(w2.getbalance(), 1)
assert_equal(w3.getbalance(), 2)
assert_equal(w4.getbalance(), 3)
batch = w1.batch([w1.getblockchaininfo.get_request(), w1.getwalletinfo.get_request()])
assert_equal(batch[0]["result"]["chain"], self.chain)
assert_equal(batch[1]["result"]["walletname"], "w1")
self.log.info("Test dynamic wallet loading")
self.restart_node(0, ['-nowallet'])
assert_equal(node.listwallets(), [])
assert_raises_rpc_error(-32601, "Method not found", node.getwalletinfo)
self.log.info("Load first wallet")
loadwallet_name = node.loadwallet(wallet_names[0])
assert_equal(loadwallet_name['name'], wallet_names[0])
assert_equal(node.listwallets(), wallet_names[0:1])
node.getwalletinfo()
w1 = node.get_wallet_rpc(wallet_names[0])
w1.getwalletinfo()
self.log.info("Load second wallet")
loadwallet_name = node.loadwallet(wallet_names[1])
assert_equal(loadwallet_name['name'], wallet_names[1])
assert_equal(node.listwallets(), wallet_names[0:2])
assert_raises_rpc_error(-19, "Wallet file not specified", node.getwalletinfo)
w2 = node.get_wallet_rpc(wallet_names[1])
w2.getwalletinfo()
self.log.info("Load remaining wallets")
for wallet_name in wallet_names[2:]:
loadwallet_name = self.nodes[0].loadwallet(wallet_name)
assert_equal(loadwallet_name['name'], wallet_name)
assert_equal(set(self.nodes[0].listwallets()), set(wallet_names))
# Fail to load if wallet doesn't exist
assert_raises_rpc_error(-18, 'Wallet wallets not found.', self.nodes[0].loadwallet, 'wallets')
# Fail to load duplicate wallets
assert_raises_rpc_error(-4, 'Wallet file verification failed: Error loading wallet w1. Duplicate -wallet filename specified.', self.nodes[0].loadwallet, wallet_names[0])
# Fail to load if one wallet is a copy of another
assert_raises_rpc_error(-1, "BerkeleyBatch: Can't open database w8_copy (duplicates fileid", self.nodes[0].loadwallet, 'w8_copy')
# Fail to load if one wallet is a copy of another, test this twice to make sure that we don't re-introduce #14304
assert_raises_rpc_error(-1, "BerkeleyBatch: Can't open database w8_copy (duplicates fileid", self.nodes[0].loadwallet, 'w8_copy')
# Fail to load if wallet file is a symlink
assert_raises_rpc_error(-4, "Wallet file verification failed: Invalid -wallet path 'w8_symlink'", self.nodes[0].loadwallet, 'w8_symlink')
self.log.info("Test dynamic wallet creation.")
# Fail to create a wallet if it already exists.
assert_raises_rpc_error(-4, "Wallet w2 already exists.", self.nodes[0].createwallet, 'w2')
# Successfully create a wallet with a new name
loadwallet_name = self.nodes[0].createwallet('w9')
assert_equal(loadwallet_name['name'], 'w9')
w9 = node.get_wallet_rpc('w9')
assert_equal(w9.getwalletinfo()['walletname'], 'w9')
assert 'w9' in self.nodes[0].listwallets()
# Successfully create a wallet using a full path
new_wallet_dir = os.path.join(self.options.tmpdir, 'new_walletdir')
new_wallet_name = os.path.join(new_wallet_dir, 'w10')
loadwallet_name = self.nodes[0].createwallet(new_wallet_name)
assert_equal(loadwallet_name['name'], new_wallet_name)
w10 = node.get_wallet_rpc(new_wallet_name)
assert_equal(w10.getwalletinfo()['walletname'], new_wallet_name)
assert new_wallet_name in self.nodes[0].listwallets()
# Fail to load if a directory is specified that doesn't contain a wallet
os.mkdir(wallet_dir('empty_wallet_dir'))
assert_raises_rpc_error(-18, "Directory empty_wallet_dir does not contain a wallet.dat file", self.nodes[0].loadwallet, 'empty_wallet_dir')
self.log.info("Test dynamic wallet unloading")
# Test `unloadwallet` errors
assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[0].unloadwallet)
assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", self.nodes[0].unloadwallet, "dummy")
assert_raises_rpc_error(-18, "Requested wallet does not exist or is not loaded", node.get_wallet_rpc("dummy").unloadwallet)
assert_raises_rpc_error(-8, "Cannot unload the requested wallet", w1.unloadwallet, "w2"),
# Successfully unload the specified wallet name
self.nodes[0].unloadwallet("w1")
assert 'w1' not in self.nodes[0].listwallets()
# Successfully unload the wallet referenced by the request endpoint
w2.unloadwallet()
assert 'w2' not in self.nodes[0].listwallets()
# Successfully unload all wallets
for wallet_name in self.nodes[0].listwallets():
self.nodes[0].unloadwallet(wallet_name)
assert_equal(self.nodes[0].listwallets(), [])
assert_raises_rpc_error(-32601, "Method not found (wallet method is disabled because no wallet is loaded)", self.nodes[0].getwalletinfo)
# Successfully load a previously unloaded wallet
self.nodes[0].loadwallet('w1')
assert_equal(self.nodes[0].listwallets(), ['w1'])
assert_equal(w1.getwalletinfo()['walletname'], 'w1')
if __name__ == '__main__':
MultiWalletTest().main()