Instead of automatically creating and loading a default wallet, users should instead explicitly create their wallet or load it on start.
Builds on #19754 which provides the load_on_startup
behavior for the GUI.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
183@@ -184,8 +184,16 @@ void WalletInit::Construct(InitInterfaces& interfaces) const
184 LogPrintf("Wallet disabled!\n");
185 return;
186 }
187- gArgs.SoftSetArg("-wallet", "");
createwallet
in RPC.
Partial Concept ACK on:
bitcoind
bitcoin_rw.conf
(QT only)Concept On The Fence about making this a breaking change for bitcoind
. I.e. maybe we should still load an existing <datadir>/wallet.dat
and <datadir>/wallet.dat
, but not create one.
Concept NACK on:
I think the best solution is here is to pull the create wallet UI into the startup wizard, as an additional section. The user can then just click next and it creates the default wallet.
Since it takes at least a few seconds, this gives the RNG a bit more bit time too (I assume the IBD network traffic should generate some extra entropy). (Although that requires starting IBD while the wizard is open.)
An easier but still acceptable solution is a big Create Wallet button in the Overview tab (when no wallet is loaded), as well as point out that they can load an existing wallet (less likely for first time users).
Some issues:
bitcoin_rw.conf
, which is good but:
loadedwallet
? adding and removing wallet=
entries seems cleaner. It won’t work for wallets already in bitcoin.conf, but that’s fine (we can warn the user in that case).An easier but still acceptable solution is a big Create Wallet button in the Overview tab (when no wallet is loaded), as well as point out that they can load an existing wallet (less likely for first time users).
I’ve done this.
not loading the default wallet in QT after upgrading: that’s a guarantee for user heart attacks
I’ve changed that back to the original behavior except that it only loads the default wallet if it is available. It will not create it.
- why use a new field
loadedwallet
? adding and removingwallet=
entries seems cleaner. It won’t work for wallets already in bitcoin.conf, but that’s fine (we can warn the user in that case).
#11082 doesn’t let me set the multiple of the same argument.
Much better, thanks. Both bitcoind and QT now load the default wallet if it exists, and the QT create button is more clear.
Can you add screenshots of the UX to the PR description?
The initial download overlay actually hides the wallet functionality, which has the nice side-effect of collecting some entropy. Although I’d rather work on making the initial experience such that users can get started more quickly, that’s a whole different story.
When the user hides the sync they see this:
A bit ugly, but I think the button makes it super clear what to do. Nit: reverse the order, i.e. suggest creating a wallet and then point out that the user can also load an existing wallet.
Regarding the wallet creation dialog, that can be discussed in #15450, but it’s important that we don’t overwhelm a first time user with advanced options. One thing though: what to do with the default name, at the risk of bike shedding…
I suggest we hide the wallet name field for the first wallet, or make it really clear that it’s totally optional and that you can’t (easily) change it (yet).
As for rw_config, which has been in limbo for quite a long time, let’s start with reviewing #14866 by @AkioNak which makes the evaluation of bitcoin.conf
(includes) a bit more sane. We should expand the functional test suite to more thoroughly cover the expected behavior. That in turn should make it easier to merge rw_config.
Found a small bug:
0src/bitcoin-cli -testnet listwallets
1[
2]
3
4src/bitcoin-cli -testnet createwallet ""
5error code: -4
6error message:
7Wallet already exists
239@@ -228,10 +240,19 @@ void StopWallets()
240 void UnloadWallets()
241 {
242 auto wallets = GetWallets();
243+ std::string loaded_wallets = "";
115+
116+ // Write the wallet name to rw conf
117+ if (!loaded_wallets.empty()) {
118+ loaded_wallets += ",";
119+ }
120+ loaded_wallets += wallet->GetName();
wallet=
fields…
122 wallets.pop_back();
123 RemoveWallet(wallet);
124 UnloadWallet(std::move(wallet));
125 }
126+ if (gArgs.HaveRWConfigFile()) {
127+ gArgs.ModifyRWConfigFile("loadedwallet", loaded_wallets);
wallet=
?
wallet=
.
115@@ -116,6 +116,9 @@ void WalletInit::Construct(NodeContext& node) const
116 LogPrintf("Wallet disabled!\n");
117 return;
118 }
119- gArgs.SoftSetArg("-wallet", "");
120+ WalletLocation default_wallet("wallet.dat");
121+ if (default_wallet.Exists()) {
122+ gArgs.SoftSetArg("-wallet", "");
In commit “Do not create default wallet” (6feed9508a225276cc2264b7d19b151a62deecea)
Was experimenting with this PR and would suggest the following fixup: 973bb7e652c4ce10ee536e9967a88c80f6dbe2e0 (tag). SoftSet doesn’t really work here for a persistent setting. I’ll backport this fixup to #15937 so the diff here will be smaller, and the only code change this should have to make is adding && WalletLocation("").Exists()
re: #15454 (review)
Was experimenting with this PR and would suggest the following fixup: 973bb7e (tag)
Feel free to steal updated version of this PR with fix above squashed and newer changes from 15937: https://github.com/ryanofsky/bitcoin/commits/review.15454.2-edit
Could use a fresh rebase in light of discussion in bitcoin-core/gui#26
Waiting on #15937 rebase
29@@ -25,9 +30,25 @@ WalletFrame::WalletFrame(const PlatformStyle *_platformStyle, BitcoinGUI *_gui)
30 walletFrameLayout->setContentsMargins(0,0,0,0);
31 walletFrameLayout->addWidget(walletStack);
32
33- QLabel *noWallet = new QLabel(tr("No wallet has been loaded."));
34+ // hbox for no wallet
35+ QGroupBox* no_wallet_group = new QGroupBox(walletStack);
36+ QVBoxLayout* no_wallet_layout = new QVBoxLayout(no_wallet_group);
37+
38+ QLabel *noWallet = new QLabel(tr("No wallet has been loaded.\nGo to File > Open Wallet to load a wallet.\n- OR -"));
open_wallet_button
here like it is done below for the create button? That would save the user a bit of mousing around. Also, it would remove the headache of making sure that File > Open Wallet
stays consistent with how the menu items are actually called
It would, but the way that opening wallets works now would require more extensive changes with code that I’m not too familiar with.
Someone who is more familiar with the GUI can make this nicer in the future.
Code review ACK a386fcd605509767b20a90719cf966e093bfa5dd. Only change since last review is rebasing and replacing bbda06f9cd1345aa80301bfc98b1cae4ec231f6d with e8bfa09b1c1888c33acfd5dcebbe136bf0d6fe82 from #19754.
re: #15454#issue-254819021
Instead of automatically creating and loading a default wallet, users should instead explicitly create their wallet or load it on start.
This makes use of the
load_on_start
feature provided by #15937. The GUI is also changed to always do load on start for all loaded and created wallets.
It would probably be good to update PR description to mention #19754 instead of #15937
I guess we can leave #19754 (comment) for another PR. But I wonder what the best approach would be. Currently we have:
0auto wallet_client = interfaces::MakeWalletClient(*node.chain, args, args.GetArgs("-wallet"));
Which then calls
0std::shared_ptr<CWallet> pwallet = CWallet::CreateWalletFromFile(chain, WalletLocation(walletFile), error, warnings);
So, for this code path, we should add some sort of flag to “create if exists”/“just load”.
Alternatively we could filter settings -wallet
, but I think that’s the best approach.
I guess we can leave #19754 (comment) for another PR. But I wonder what the best approach would be. Currently we have:
Ideally, I don’t think it should be handled in the wallet/init.cpp Construct method. That method was only meant to construct WalletClient object early on startup, not to access the filesystem or do anything slow or blocking. Also with #10102, that function runs in the node process, not the wallet process.
More ideally, handling not existing wallets would be done in wallet/load.cpp VerifyWallets function. With #19619 all that would be required is setting the DatabaseOptions::require_existing
option and handling DatabaseStatus::FAILED_NOT_FOUND
return code. It would be easy to implement by permanently removing non-existing wallets from settings.json there, or by just temporarily ignoring them.
More difficult but nicer, I think, would be to have non-existing wallets not removed from settings.json, and shown in the GUI in a disabled state, grayed out with “Wallet path was not accessible” message. That way user could be informed that wallet wasn’t accessible and decide whether or not they want to keep trying to load it in the future.
and shown in the GUI in a disabled state
IMO more appropriate is to show a modal dialog on start (for each non existing wallet) asking if it should be removed/forgotten from settings, and if he chooses to keep it then it could be disabled.
How would you drop disabled wallets (from settings)?
The same way you drop an enabled wallet from settings. Switch to wallet in drop-down, go to File -> Close Wallet…
Error building after #19619 was merged:
0wallet/init.cpp: In member function ‘virtual void WalletInit::Construct(NodeContext&) const’:
1wallet/init.cpp:112:37: error: ‘WalletLocation’ was not declared in this scope
2 if (!args.IsArgSet("wallet") && WalletLocation("").Exists()) {
3 ^~~~~~~~~~~~~~
4wallet/init.cpp:112:37: note: suggested alternative: ‘WalletBatch’
5 if (!args.IsArgSet("wallet") && WalletLocation("").Exists()) {
6 ^~~~~~~~~~~~~~
7 WalletBatch
8Makefile:11482: recipe for target 'wallet/libbitcoin_server_a-init.o' failed
Code review ACK c24bb1a09cc608b499fefba2402a497cf504217d, but I think it would be good to fix up the first commit to not do file I/O in WalletInit::Construct and not hardcode “wallet.dat” berkeley wallet name outside of bdb.cpp
, and to call existing MakeWalletDatabase
function instead of adding a new HasDefaultWallet
function. Suggested changes that I think would be to squash are: 421a5502ec71dff3e2d26c7f63cbd3d8da10a706 (branch) +32/-33 lines.
Also would also be good if the change had release notes. Off the top of my head something like “Bitcoin Core will no longer create an unnamed ""
wallet by default when no -wallet=<name>
command line or wallet=<name>
configuration options are used, but for backwards compatibility if a ""
wallet already exists and would have been loaded previously, it will still be loaded. Instead of automatically creating an unnamed unencrypted wallet, the GUI now prompts to create a named, encrypted wallet. Instead of only loading the unnamed ""
wallet on startup the GUI loads previously loaded wallets.”
No longer create a default wallet. The default wallet will still be
loaded if it exists and not other wallets were specified (anywhere,
including settings.json, bitcoin.conf, and command line).
Tests are updated to be started with -wallet= if they need the default
wallet.
Added test to wallet_startup.py testing that no default wallet is
created and that it is loaded if it exists and no other wallets were
specified.
I would really like to see this merged, because I think it’s a significant interface change (or at least a notable one) that a lot of other changes can build on:
settings.json
wallet list recreating removed wallets #19754 (comment)createwallet
call or gui interaction. jb55 reported problems caused by this yesterday in IRC: http://www.erisian.com.au/bitcoin-core-dev/log-2020-09-14.html#l-355""
wallet reliance in in test framework, and switching to explicit named creates. 5d2e85c5d33c3b65c79673cad5d7bc0e5875b107 starts down this roadManual test and very light code review ACK d26f0648f1c0d1115dcb8d76e57195032b88f400
I manually tested:
ACK d26f0648f1c0d1115dcb8d76e57195032b88f400 light code review, debug build, ran tests, did manual testing with testnet, rebased on master, on linux debian.
One edge case seen: If I load a wallet (default or no), shutdown without unloading it, then rm wallet.dat
or rm -rf
the wallet folder, then restart, a new wallet is created in its place.
It seems possible to remove the additional “-wallet=” extra_arg from a number of the changed tests before finding a couple that fail without it. Passing -wallet
without a value also seems fine:
0- ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="],
1- ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="],
2- ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="],
3- ["-whitelist=noban@127.0.0.1", "-wallet="],
4+ ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet"],
5+ ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet"],
6+ ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet"],
7+ ["-whitelist=noban@127.0.0.1", "-wallet"],
40@@ -41,10 +41,27 @@ bool VerifyWallets(interfaces::Chain& chain, const std::vector<std::string>& wal
41
42 chain.initMessage(_("Verifying wallet(s)...").translated);
43
44+ // For backwards compatibility if an unnamed top level wallet exists in the
45+ // wallets directory, include it in the default list of wallets to load.
46+ if (!gArgs.IsArgSet("wallet")) {
Would it better to do:
0- if (!gArgs.IsArgSet("wallet")) {
1+ if (!(gArgs.GetBoolArg("wallet", false)) {
re: #15454 (review)
Would it better to do:
0- if (!gArgs.IsArgSet("wallet")) { 1+ if (!(gArgs.GetBoolArg("wallet", false)) {
This would be bad because it would cause a -nowallet
setting to load the default wallet.
re: #15454 (comment)
Passing
-wallet
without a value also seems fine?
Would not suggest this because that syntax more typically is used to set a boolean setting to true than to set a string setting to empty. #16545 would actually make it an error to use -string
syntax for future string-only settings and would require -string=
or -string=""
I think both versions of:
0- ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet="],
1+ ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet"],
are less clear than they could be, which is why the the followup https://github.com/ryanofsky/bitcoin/commit/5d2e85c5d33c3b65c79673cad5d7bc0e5875b107 I mentioned in #15454 (comment) would change these to:
0 ["-whitelist=noban@127.0.0.1", "-keypool=100", "-wallet=" + self.default_wallet_name],
0@@ -0,0 +1,6 @@
1+Wallet
2+------
3+
4+Bitcoin Core will no longer create an unnamed `""` wallet by default when no wallet is specified on the command line or in the configuration files.
Bitcoin Core will no longer create an unnamed
""
wallet by default.
Just stop here. It won’t make a default wallet of any kind, whether or not you specify one specifically.
createwallet
by default
is the key phrase here. It makes nothing by default.
re: #15454 (comment) & #15454#pullrequestreview-490569662
It seems possible to remove the additional “-wallet=” extra_arg from a number of the changed tests
#20034 follows this PR up and removes all of these. It also goes further and removes the test framework -wallet
extra_args mangling, which is no longer necessary thanks to this PR and #15937