Page MenuHomePhabricator

D10243.diff
No OneTemporary

D10243.diff

diff --git a/doc/release-notes/release-notes.md b/doc/release-notes/release-notes.md
--- a/doc/release-notes/release-notes.md
+++ b/doc/release-notes/release-notes.md
@@ -5,3 +5,10 @@
<https://download.bitcoinabc.org/0.24.4/>
This release includes the following features and fixes:
+
+- Bitcoin ABC will no longer create an unnamed `""` wallet by default when no wallet is
+ specified on the command line or in the configuration files. For backwards compatibility,
+ if an unnamed `""` wallet already exists and would have been loaded previously, then it
+ will still be loaded. Users without an unnamed `""` wallet and without any other wallets
+ to be loaded on startup will be prompted to either choose a wallet to load, or to
+ create a new wallet.
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -411,9 +411,7 @@
//! Return implementation of ChainClient interface for a wallet client. This
//! function will be undefined in builds where ENABLE_WALLET is false.
-std::unique_ptr<WalletClient>
-MakeWalletClient(Chain &chain, ArgsManager &args,
- std::vector<std::string> wallet_filenames);
+std::unique_ptr<WalletClient> MakeWalletClient(Chain &chain, ArgsManager &args);
} // namespace interfaces
diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -464,9 +464,7 @@
class WalletClientImpl : public WalletClient {
public:
- WalletClientImpl(Chain &chain, ArgsManager &args,
- std::vector<std::string> wallet_filenames)
- : m_wallet_filenames(std::move(wallet_filenames)) {
+ WalletClientImpl(Chain &chain, ArgsManager &args) {
m_context.chain = &chain;
m_context.args = &args;
}
@@ -493,12 +491,8 @@
registerRpcs(GetWalletRPCCommands());
registerRpcs(GetWalletDumpRPCCommands());
}
- bool verify() override {
- return VerifyWallets(*m_context.chain, m_wallet_filenames);
- }
- bool load() override {
- return LoadWallets(*m_context.chain, m_wallet_filenames);
- }
+ bool verify() override { return VerifyWallets(*m_context.chain); }
+ bool load() override { return LoadWallets(*m_context.chain); }
void start(CScheduler &scheduler) override {
return StartWallets(scheduler, *Assert(m_context.args));
}
@@ -565,11 +559,9 @@
return wallet ? std::make_unique<WalletImpl>(wallet) : nullptr;
}
-std::unique_ptr<WalletClient>
-MakeWalletClient(Chain &chain, ArgsManager &args,
- std::vector<std::string> wallet_filenames) {
- return std::make_unique<WalletClientImpl>(chain, args,
- std::move(wallet_filenames));
+std::unique_ptr<WalletClient> MakeWalletClient(Chain &chain,
+ ArgsManager &args) {
+ return std::make_unique<WalletClientImpl>(chain, args);
}
} // namespace interfaces
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -86,6 +86,7 @@
interfaces::BlockAndHeaderTipInfo *tip_info = nullptr);
#ifdef ENABLE_WALLET
void setWalletController(WalletController *wallet_controller);
+ WalletController *getWalletController();
#endif
#ifdef ENABLE_WALLET
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -750,6 +750,10 @@
}
}
+WalletController *BitcoinGUI::getWalletController() {
+ return m_wallet_controller;
+}
+
void BitcoinGUI::addWallet(WalletModel *walletModel) {
if (!walletFrame) {
return;
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -2,14 +2,19 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <qt/createwalletdialog.h>
+#include <qt/walletcontroller.h>
#include <qt/walletframe.h>
#include <qt/bitcoingui.h>
#include <qt/walletmodel.h>
#include <qt/walletview.h>
+#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
+#include <QPushButton>
+#include <QVBoxLayout>
#include <cassert>
@@ -22,9 +27,31 @@
walletFrameLayout->setContentsMargins(0, 0, 0, 0);
walletFrameLayout->addWidget(walletStack);
- QLabel *noWallet = new QLabel(tr("No wallet has been loaded."));
+ // hbox for no wallet
+ QGroupBox *no_wallet_group = new QGroupBox(walletStack);
+ QVBoxLayout *no_wallet_layout = new QVBoxLayout(no_wallet_group);
+
+ QLabel *noWallet = new QLabel(tr("No wallet has been loaded.\nGo to File > "
+ "Open Wallet to load a wallet.\n- OR -"));
noWallet->setAlignment(Qt::AlignCenter);
- walletStack->addWidget(noWallet);
+ no_wallet_layout->addWidget(noWallet, 0,
+ Qt::AlignHCenter | Qt::AlignBottom);
+
+ // A button for create wallet dialog
+ QPushButton *create_wallet_button =
+ new QPushButton(tr("Create a new wallet"), walletStack);
+ connect(create_wallet_button, &QPushButton::clicked, [this] {
+ auto activity =
+ new CreateWalletActivity(gui->getWalletController(), this);
+ connect(activity, &CreateWalletActivity::finished, activity,
+ &QObject::deleteLater);
+ activity->create();
+ });
+ no_wallet_layout->addWidget(create_wallet_button, 0,
+ Qt::AlignHCenter | Qt::AlignTop);
+ no_wallet_group->setLayout(no_wallet_layout);
+
+ walletStack->addWidget(no_wallet_group);
}
WalletFrame::~WalletFrame() {}
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -205,17 +205,7 @@
LogPrintf("Wallet disabled!\n");
return;
}
- // If there's no -wallet setting with a list of wallets to load, set it to
- // load the default "" wallet.
- if (!args.IsArgSet("wallet")) {
- args.LockSettings([&](util::Settings &settings) {
- util::SettingsValue wallets(util::SettingsValue::VARR);
- wallets.push_back(""); // Default wallet name is ""
- settings.rw_settings["wallet"] = wallets;
- });
- }
- auto wallet_client = interfaces::MakeWalletClient(*node.chain, args,
- args.GetArgs("-wallet"));
+ auto wallet_client = interfaces::MakeWalletClient(*node.chain, args);
node.wallet_client = wallet_client.get();
node.chain_clients.emplace_back(std::move(wallet_client));
}
diff --git a/src/wallet/load.h b/src/wallet/load.h
--- a/src/wallet/load.h
+++ b/src/wallet/load.h
@@ -18,12 +18,10 @@
//! Responsible for reading and validating the -wallet arguments and verifying
//! the wallet database.
-bool VerifyWallets(interfaces::Chain &chain,
- const std::vector<std::string> &wallet_files);
+bool VerifyWallets(interfaces::Chain &chain);
//! Load wallet databases.
-bool LoadWallets(interfaces::Chain &chain,
- const std::vector<std::string> &wallet_files);
+bool LoadWallets(interfaces::Chain &chain);
//! Complete startup of wallets.
void StartWallets(CScheduler &scheduler, const ArgsManager &args);
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -16,8 +16,7 @@
#include <univalue.h>
-bool VerifyWallets(interfaces::Chain &chain,
- const std::vector<std::string> &wallet_files) {
+bool VerifyWallets(interfaces::Chain &chain) {
if (gArgs.IsArgSet("-walletdir")) {
fs::path wallet_dir = gArgs.GetArg("-walletdir", "");
boost::system::error_code error;
@@ -49,10 +48,28 @@
chain.initMessage(_("Verifying wallet(s)...").translated);
+ // For backwards compatibility if an unnamed top level wallet exists in the
+ // wallets directory, include it in the default list of wallets to load.
+ if (!gArgs.IsArgSet("wallet")) {
+ DatabaseOptions options;
+ DatabaseStatus status;
+ bilingual_str error_string;
+ options.require_existing = true;
+ options.verify = false;
+ if (MakeWalletDatabase("", options, status, error_string)) {
+ gArgs.LockSettings([&](util::Settings &settings) {
+ util::SettingsValue wallets(util::SettingsValue::VARR);
+ // Default wallet name is ""
+ wallets.push_back("");
+ settings.rw_settings["wallet"] = wallets;
+ });
+ }
+ }
+
// Keep track of each wallet absolute path to detect duplicates.
std::set<fs::path> wallet_paths;
- for (const auto &wallet_file : wallet_files) {
+ for (const auto &wallet_file : gArgs.GetArgs("-wallet")) {
const fs::path path = fs::absolute(wallet_file, GetWalletDir());
if (!wallet_paths.insert(path).second) {
@@ -75,10 +92,9 @@
return true;
}
-bool LoadWallets(interfaces::Chain &chain,
- const std::vector<std::string> &wallet_files) {
+bool LoadWallets(interfaces::Chain &chain) {
try {
- for (const std::string &name : wallet_files) {
+ for (const std::string &name : gArgs.GetArgs("-wallet")) {
DatabaseOptions options;
DatabaseStatus status;
// No need to verify, assuming verified earlier in VerifyWallets()
diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
--- a/src/wallet/test/init_test_fixture.cpp
+++ b/src/wallet/test/init_test_fixture.cpp
@@ -13,7 +13,7 @@
const std::string &chainName)
: BasicTestingSetup(chainName) {
m_chain = interfaces::MakeChain(m_node, Params());
- m_wallet_client = MakeWalletClient(*m_chain, *Assert(m_node.args), {});
+ m_wallet_client = MakeWalletClient(*m_chain, *Assert(m_node.args));
std::string sep;
sep += fs::path::preferred_separator;
diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h
--- a/src/wallet/test/wallet_test_fixture.h
+++ b/src/wallet/test/wallet_test_fixture.h
@@ -24,7 +24,7 @@
std::unique_ptr<interfaces::Chain> m_chain;
std::unique_ptr<interfaces::WalletClient> m_wallet_client =
- interfaces::MakeWalletClient(*m_chain, *Assert(m_node.args), {});
+ interfaces::MakeWalletClient(*m_chain, *Assert(m_node.args));
CWallet m_wallet;
std::unique_ptr<interfaces::Handler> m_chain_notifications_handler;
};
diff --git a/test/functional/feature_dbcrash.py b/test/functional/feature_dbcrash.py
--- a/test/functional/feature_dbcrash.py
+++ b/test/functional/feature_dbcrash.py
@@ -56,7 +56,7 @@
# long-running test
self.base_args = ["-limitdescendantsize=0", "-maxmempool=0",
"-rpcservertimeout=900", "-dbbatchsize=200000",
- "-noparkdeepreorg"]
+ "-wallet=", "-noparkdeepreorg"]
# Set different crash ratios and cache sizes. Note that not all of
# -dbcache goes to the in-memory coins cache.
@@ -67,7 +67,8 @@
# Node3 is a normal node with default args, except will mine full blocks
# and non-standard txs (e.g. txs with "dust" outputs)
self.node3_args = [
- "-blockmaxsize={}".format(DEFAULT_MAX_BLOCK_SIZE), "-acceptnonstdtxn"]
+ "-blockmaxsize={}".format(DEFAULT_MAX_BLOCK_SIZE),
+ "-acceptnonstdtxn", "-wallet="]
self.extra_args = [self.node0_args, self.node1_args,
self.node2_args, self.node3_args]
diff --git a/test/functional/feature_filelock.py b/test/functional/feature_filelock.py
--- a/test/functional/feature_filelock.py
+++ b/test/functional/feature_filelock.py
@@ -16,7 +16,7 @@
def setup_network(self):
self.add_nodes(self.num_nodes, extra_args=None)
- self.nodes[0].start([])
+ self.nodes[0].start(['-wallet='])
self.nodes[0].wait_for_rpc_connection()
def run_test(self):
@@ -38,6 +38,7 @@
self.nodes[1].assert_start_raises_init_error(
extra_args=[
'-walletdir={}'.format(wallet_dir),
+ '-wallet=',
'-noserver'],
expected_msg=expected_msg,
match=ErrorMatch.PARTIAL_REGEX)
diff --git a/test/functional/feature_pruning.py b/test/functional/feature_pruning.py
--- a/test/functional/feature_pruning.py
+++ b/test/functional/feature_pruning.py
@@ -88,18 +88,19 @@
# Create nodes 0 and 1 to mine.
# Create node 2 to test pruning.
self.full_node_default_args = ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
- "-checkblocks=5", "-noparkdeepreorg", "-maxreorgdepth=-1"]
+ "-checkblocks=5", "-noparkdeepreorg", "-maxreorgdepth=-1",
+ "-wallet="]
# Create nodes 3 and 4 to test manual pruning (they will be re-started with manual pruning later)
# Create nodes 5 to test wallet in prune mode, but do not connect
self.extra_args = [self.full_node_default_args,
self.full_node_default_args,
- ["-maxreceivebuffer=20000", "-prune=550",
+ ["-wallet=", "-maxreceivebuffer=20000", "-prune=550",
"-noparkdeepreorg", "-maxreorgdepth=-1"],
- ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
+ ["-wallet=", "-maxreceivebuffer=20000", "-blockmaxsize=999000",
"-noparkdeepreorg", "-maxreorgdepth=-1"],
- ["-maxreceivebuffer=20000", "-blockmaxsize=999000",
+ ["-wallet=", "-maxreceivebuffer=20000", "-blockmaxsize=999000",
"-noparkdeepreorg", "-maxreorgdepth=-1"],
- ["-prune=550"]]
+ ["-wallet=", "-prune=550"]]
self.rpc_timeout = 120
def skip_test_if_missing_module(self):
diff --git a/test/functional/wallet_backup.py b/test/functional/wallet_backup.py
--- a/test/functional/wallet_backup.py
+++ b/test/functional/wallet_backup.py
@@ -50,10 +50,10 @@
# nodes 1, 2,3 are spenders, let's give them a keypool=100
# whitelist all peers to speed up tx relay / mempool sync
self.extra_args = [
- ["-whitelist=noban@127.0.0.1", "-keypool=100"],
- ["-whitelist=noban@127.0.0.1", "-keypool=100"],
- ["-whitelist=noban@127.0.0.1", "-keypool=100"],
- ["-whitelist=noban@127.0.0.1"],
+ ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="],
+ ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="],
+ ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="],
+ ["-whitelist=noban@127.0.0.1", "-wallet="],
]
self.rpc_timeout = 120
diff --git a/test/functional/wallet_dump.py b/test/functional/wallet_dump.py
--- a/test/functional/wallet_dump.py
+++ b/test/functional/wallet_dump.py
@@ -84,7 +84,7 @@
class WalletDumpTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
- self.extra_args = [["-keypool=90"]]
+ self.extra_args = [["-keypool=90", "-wallet=dump"]]
self.rpc_timeout = 120
def skip_test_if_missing_module(self):
diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py
--- a/test/functional/wallet_import_rescan.py
+++ b/test/functional/wallet_import_rescan.py
@@ -152,7 +152,7 @@
self.skip_if_no_wallet()
def setup_network(self):
- self.extra_args = [[] for _ in range(self.num_nodes)]
+ self.extra_args = [["-wallet="] for _ in range(self.num_nodes)]
for i, import_node in enumerate(IMPORT_NODES, 2):
if import_node.prune:
self.extra_args[i] += ["-prune=1"]
@@ -160,7 +160,7 @@
self.add_nodes(self.num_nodes, extra_args=self.extra_args)
# Import keys with pruning disabled
- self.start_nodes(extra_args=[[]] * self.num_nodes)
+ self.start_nodes(extra_args=[["-wallet="]] * self.num_nodes)
for n in self.nodes:
n.importprivkey(
privkey=n.get_deterministic_priv_key().key,
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -45,6 +45,7 @@
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
+ self.extra_args = [["-wallet="], ["-wallet="]]
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
@@ -91,7 +92,7 @@
os.rename(wallet_dir("wallet.dat"), wallet_dir("w8"))
# create another dummy wallet for use in testing backups later
- self.start_node(0, [])
+ self.start_node(0, ["-wallet="])
self.stop_nodes()
empty_wallet = os.path.join(self.options.tmpdir, 'empty.dat')
os.rename(wallet_dir("wallet.dat"), empty_wallet)
@@ -178,7 +179,8 @@
competing_wallet_dir = os.path.join(
self.options.tmpdir, 'competing_walletdir')
os.mkdir(competing_wallet_dir)
- self.restart_node(0, ['-walletdir=' + competing_wallet_dir])
+ self.restart_node(
+ 0, ['-walletdir=' + competing_wallet_dir, '-wallet='])
exp_stderr = r"Error: Error initializing wallet database environment \"\S+competing_walletdir\"!"
self.nodes[1].assert_start_raises_init_error(
['-walletdir=' + competing_wallet_dir], exp_stderr, match=ErrorMatch.PARTIAL_REGEX)
diff --git a/test/functional/wallet_startup.py b/test/functional/wallet_startup.py
--- a/test/functional/wallet_startup.py
+++ b/test/functional/wallet_startup.py
@@ -24,6 +24,17 @@
self.start_nodes()
def run_test(self):
+ self.log.info('Should start without any wallets')
+ assert_equal(self.nodes[0].listwallets(), [])
+ assert_equal(self.nodes[0].listwalletdir(), {'wallets': []})
+
+ self.log.info(
+ 'New default wallet should load by default when there are no other wallets')
+ self.nodes[0].createwallet(wallet_name='', load_on_startup=False)
+ self.restart_node(0)
+ assert_equal(self.nodes[0].listwallets(), [''])
+
+ self.log.info('Test load on startup behavior')
self.nodes[0].createwallet(wallet_name='w0', load_on_startup=True)
self.nodes[0].createwallet(wallet_name='w1', load_on_startup=False)
self.nodes[0].createwallet(wallet_name='w2', load_on_startup=True)

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 28, 19:43 (8 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4844986
Default Alt Text
D10243.diff (18 KB)

Event Timeline