Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F12428786
D10243.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Subscribers
None
D10243.diff
View Options
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
Details
Attached
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)
Attached To
D10243: Remove the automatic creation and loading of the default wallet
Event Timeline
Log In to Comment