Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace -upgradewallet startup option with upgradewallet RPC #15761

Merged
merged 6 commits into from
Apr 19, 2020

Conversation

achow101
Copy link
Member

@achow101 achow101 commented Apr 6, 2019

-upgradewallet is largely incompatible with many recent wallet features and versions. For example, it was disabled if multiple wallets were used and would not work with encrypted wallets that were being upgraded to HD.

This PR does away with the old method of upgrading upon startup and instead allows users to upgrade their wallets via an upgradewallet RPC. This does largely the same thing as the old -upgradewallet option but because the wallet is loaded, it can be unlocked to upgrade to HD. Furthermore it is compatible with multiwallet as it works on the individual wallet that is specified by the RPC.

@laanwj
Copy link
Member

laanwj commented Apr 6, 2019

No opposition to having this, but wouldn't bitcoin-wallet-tool be the designated place for this?

@achow101
Copy link
Member Author

achow101 commented Apr 6, 2019

No opposition to having this, but wouldn't bitcoin-wallet-tool be the designated place for this?

I'm not really a fan of putting things that users might actually use and want to use in a place that is less accessible. bitcoin-wallet-tool is command line only and many users won't know how to use it. With an RPC, most users will be able to use it since there is a RPC console in the GUI.

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some style nits

src/wallet/rpcwallet.cpp Outdated Show resolved Hide resolved
src/wallet/rpcwallet.cpp Outdated Show resolved Hide resolved
src/wallet/rpcwallet.cpp Outdated Show resolved Hide resolved
src/wallet/rpcwallet.cpp Outdated Show resolved Hide resolved
@maflcko
Copy link
Member

maflcko commented Apr 6, 2019

Related: #13044

@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 6, 2019

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

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.

@jnewbery
Copy link
Contributor

jnewbery commented Apr 6, 2019

Concept ACK although I agree with @laanwj that a utility function that does not require access to the chainstate or P2P rightly lives in the wallet tool.

I'm not really a fan of putting things that users might actually use and want to use in a place that is less accessible [...] With an RPC, most users will be able to use it since there is a RPC console in the GUI.

I'd disagree that RPC is accessible to users who aren't able to use the command line. We shouldn't encourage users to type commands into the debug command window if they're not able to use the command line. Besides, upgradewallet is currently command line only, so moving it to the wallet tool maintains exactly the same level of accessibility.

@sipa
Copy link
Member

sipa commented Apr 6, 2019

Is this something that we'd like to be accessible to wallets why they're loaded? If so, it needs to be an RPC (and possibly also in the wallet tool).

@achow101
Copy link
Member Author

achow101 commented Apr 6, 2019

Is this something that we'd like to be accessible to wallets why they're loaded?

I would like it to be.

@jnewbery
Copy link
Contributor

jnewbery commented Apr 7, 2019

Is this something that we'd like to be accessible to wallets while they're loaded?

This seems to me to potentially add complexity in future. I could imagine there may be some potential upgrade actions that would conflict badly when executed on a running wallet. Why not keep it simple and only allow upgrade when the wallet is not running?

EDIT: to be clear, I'm not NACKing this. I think an upgradewallet RPC is certainly an improvement over the command line option, and doesn't preclude also adding it to the wallet tool. I just think that the offline wallet tool would be an even better place for it.

@promag
Copy link
Member

promag commented Apr 8, 2019

Concept ACK removing the -upgradewallet argument.

Why not add upgrade option to loadwallet RPC?

@achow101
Copy link
Member Author

achow101 commented Apr 9, 2019

Why not add upgrade option to loadwallet RPC?

I think it makes more sense to have upgrading be separate from loading.

@jnewbery
Copy link
Contributor

jnewbery commented Apr 9, 2019

I think it makes more sense to have upgrading be separate from loading.

Can you justify that? Upgrading wallets is something that most users will very rarely (if ever) have to do. What's the benefit to adding the flexibility to upgrade wallets during runtime? The downsides seem pretty obvious to me (potential increased complexity and having to reason about interactions with other wallet operations) so I'd like to understand what you're weighing that against.

@achow101
Copy link
Member Author

I'd disagree that RPC is accessible to users who aren't able to use the command line. We shouldn't encourage users to type commands into the debug command window if they're not able to use the command line. Besides, upgradewallet is currently command line only, so moving it to the wallet tool maintains exactly the same level of accessibility.

I disagree. It is far easier for users to understand and use the RPC console than it is for them to use and understand the wallet tool. The instructions for opening up the RPC console and then entering a command are far simpler than the instructions for using the wallet tool. There is exactly one set of instructions that users have to follow with the only thing that they need to consider is their wallet name and making sure that that wallet is selected.

Conversely, with the wallet tool, the instructions for using it are dependent on how the user installed the software (i.e. they need to know the install location) and whether they changed the data directory. Then they have to specify the wallet in the command line which may involve escaping or quoting. All of these are extra options and information that users need to know which they may not. With the RPC console, all that stuff is already handled for them. The instructions are far simpler and easier to understand when using the RPC console than when using the command line wallet tool.

In a similar vein, I disagree with "We shouldn't encourage users to type commands into the debug command window if they're not able to use the command line." As I mentioned, using the RPC console is far easier than using the command line. While they are similar, the command line has so many extra rules and gotchas that the RPC console does not. A user can be fine and comfortable using the RPC console but not able to use the command line simply because the command line does many other things that can cause screwups.

Can you justify that? Upgrading wallets is something that most users will very rarely (if ever) have to do. What's the benefit to adding the flexibility to upgrade wallets during runtime?

Conceptually, loading and upgrading are two separate functions that should be defined separately. From a UX standpoint, it makes more sense to users to do an explicit upgrade as a separate command rather than as an argument to some other command. If bundled with loadwallet, I suspect that many users would miss the important step of unloading the wallet first and generally cause headaches all around as they complain and ask how to actually upgrade their wallets. Keep in mind that while upgrades may be infrequent, many users are still using non-HD wallets and have been waiting for an easy way to upgrade their non-HD wallets to HD; upgradewallet would provide that easy method.

The downsides seem pretty obvious to me (potential increased complexity and having to reason about interactions with other wallet operations) so I'd like to understand what you're weighing that against.

I really don't think that's a reason against this. By that logic we just shouldn't change anything because it increases complexity and we have to reason about interactions with other operations.

Moving upgrading to its own code will actually make it less complex and simpler. Currently I have it as largely a move-only, but it can actually be simplified. Keeping it as part of loading means that it has to distinguish between a new wallet and a wallet being upgraded. They follow largely the same codepaths but have just slightly different logic. The fact that these two are together in CreateWalletFromFile actually makes the upgrade logic hard to understand and reason about. I had a hard time determining whether the upgrade logic was actually upgrading correctly. By separating the upgrade logic into its own function, we can clean it up so that what it does is not confusing and can be followed. This actually reduces the complexity of the code.

@maflcko
Copy link
Member

maflcko commented Apr 10, 2019

Concept ACK moving it to either or both (tool and rpc)

@flack
Copy link
Contributor

flack commented Apr 12, 2019

The RPC variant probably has the advantage that the function could be added to the File menu later on (maybe right next to "Backup wallet..."), which would also alleviate the concerns about having users enter random stuff in the console

@luke-jr
Copy link
Member

luke-jr commented Apr 20, 2019

Nit: commit messages misspell upgrade multiple times

@@ -4064,67 +4064,6 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
}
}

int prev_version = walletInstance->GetVersion();
if (gArgs.GetBoolArg("-upgradewallet", fFirstRun))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is removed in the wrong commit.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Member

@luke-jr luke-jr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first commit is convoluted/difficult to review and broken (-upgradewallet no longer works).

@achow101
Copy link
Member Author

Nit: commit messages misspell upgrade multiple times

Fixed

The first commit is convoluted/difficult to review

How so? It's mostly just a move

broken (-upgradewallet no longer works).

Should be fixed

@luke-jr
Copy link
Member

luke-jr commented Apr 20, 2019

Re first commit: Since it's on the object, you drop the walletInstance-> everywhere. I'd suggest a minimal moveonly commit, then a subsequent one that makes the changes.

walletInstance->SetMaxVersion(nMaxVersion);
}

// Upgrade to HD if explicit upgrade
if (gArgs.GetBoolArg("-upgradewallet", false)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of this is supposed to run by default if fFirstRun.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That part is completely redundant. It just sets the wallet version but SetMinVersion is already called below in the if (fFirstRun) block. Furthermore, that call forces the wallet version to be the latest version so whatever version number specified for -upgradewallet that would have been set is overridden anyways.

@achow101
Copy link
Member Author

I've done some commit reorganization as suggested by @luke-jr so this should be easier to review now.

@maflcko
Copy link
Member

maflcko commented Apr 6, 2020

Maybe split out the first commit (move-only) as a separate pull, to cut down on the conflicts in the future?

Copy link
Contributor

@meshcollider meshcollider left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 0d32d66

I think this is definitely an improvement and do agree it should be an RPC not in the wallet tool. Tests? 🤔

Copy link
Member

@darosior darosior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 0d32d66

Tested and it fixes both #16091 and #14422.
(Used an encrypted pre-HD (0.11.1) wallet, and succesfully upgraded with upgradewallet, keypool refilled)

Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to merge this for 0.21.0

wen tests, sir?

ACK 0d32d66 🚵

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

ACK 0d32d661481f099af572e7a08a50e17bcc165c44 🚵
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUjK6gv/TC3347Yc0B3KJppRFbyvMZndV7FLINr0i6jsR6RlkeXC4tqTCGat8KRC
QKKRgJwpE8AYLmomgQlodds6OZ0NOxGDr+XkGfYcvZSXH8y8XPjrtgLgRVPpUeFg
F5tfZFGLttBnKhnL/n44vV+lGEbAIwDlTpKw+86vM9r8qf00KtKdLEwhhN1ZjZsk
3EM4NdZ7wxDzGTK8URF1egnFhaJayVLLQEXyWNiV4PQTDnnEr9SAr4N0B0khROML
ecpTlhzKGayQeYGYMNsvFJZl1FnSiuTosgjFbVRCyBHSeRvVhmEhSgGr3p9Ee9Pq
MycIK++P+r36bI/6uQo1L15mFDSITOPENPxBeRCar1btx0C/g0tK9TU0k5ji6OKH
cKueJdNsWxTnzJZJgNizVI/uY3UAk3MV5tN8oBkDKWXCU4kom8k5qbZKKWGBAh05
rUech6uc17vAPuk/XWk20dwVst50h5XdlwMd9EUzPn13Quk7xe06bDkJcD7RtfWd
g8IYq3zK
=LvtB
-----END PGP SIGNATURE-----

Timestamp of file with hash 7716a881705c80f791d9f508a2608fc565f0f69a935156d7ee952e846c5c6af2 -

@@ -3831,7 +3831,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
}

if (gArgs.GetBoolArg("-upgradewallet", false)) {
if (!UpgradeWallet(walletInstance, gArgs.GetBoolArg("-upgradewallet", 0), error, warnings)) {
if (!UpgradeWallet(gArgs.GetBoolArg("-upgradewallet", 0), error, warnings)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in commit 1e48796

This is a bug and it needs to call walletInstance->UpgradeWallet, but I see the code is removed in the next commit anyway

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Luckily it doesn't compile:

wallet/wallet.cpp:3831:14: error: call to non-static member function without an object argument
        if (!UpgradeWallet(gArgs.GetBoolArg("-upgradewallet", 0), error, warnings)) {
             ^~~~~~~~~~~~~
1 error generated.

"\nUpgrade the wallet. Upgrades to the latest version if no version number is specified\n"
"New keys may be generated and a new wallet backup will need to be made.",
{
{"version", RPCArg::Type::NUM, /* default */ strprintf("%d", FEATURE_LATEST), "The version number to upgrade to. Default is the latest wallet version"}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{"version", RPCArg::Type::NUM, /* default */ strprintf("%d", FEATURE_LATEST), "The version number to upgrade to. Default is the latest wallet version"}
{"version", RPCArg::Type::NUM, /* default */ strprintf("%d", WalletFeature::LATEST), "The version number to upgrade to. Default is the latest wallet version"}

Unrelated nit for future cleanup: This should probably be scoped and not in the global namespace

@maflcko maflcko merged commit b470c75 into bitcoin:master Apr 19, 2020
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Apr 20, 2020
…dewallet RPC

0d32d66 Remove -upgradewallet startup option (Andrew Chow)
92263cc Add upgradewallet RPC (Andrew Chow)
1e48796 Make UpgradeWallet a member function of CWallet (Andrew Chow)
c988f27 Have UpgradeWallet take the version to upgrade to and an error message out parameter (Andrew Chow)
1833237 Only run UpgradeWallet if the wallet needs to be upgraded (Andrew Chow)
9c16b17 Move wallet upgrading to its own function (Andrew Chow)

Pull request description:

  `-upgradewallet` is largely incompatible with many recent wallet features and versions. For example, it was disabled if multiple wallets were used and would not work with encrypted wallets that were being upgraded to HD.

  This PR does away with the old method of upgrading upon startup and instead allows users to upgrade their wallets via an `upgradewallet` RPC. This does largely the same thing as the old `-upgradewallet` option but because the wallet is loaded, it can be unlocked to upgrade to HD. Furthermore it is compatible with multiwallet as it works on the individual wallet that is specified by the RPC.

ACKs for top commit:
  meshcollider:
    Code review ACK 0d32d66
  darosior:
    ACK 0d32d66
  MarcoFalke:
    ACK 0d32d66 🚵

Tree-SHA512: b425bf6f5d605e26506889d63c780895482f07cbc086193218e031e8504d3072d41e90d65cd41bcc98ee4c1eb048954bc5d4ac85435f7394892373aac89a3b0a
deadalnix pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 15, 2020
Summary: Backport of Core [[bitcoin/bitcoin#15761 | PR15761]] [1/6] : bitcoin/bitcoin@9c16b17

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7922
deadalnix pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 15, 2020
Summary:
Backport of Core [[bitcoin/bitcoin#15761 | PR15761]] [2/6] : bitcoin/bitcoin@1833237

Depends on D7922

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7923
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 15, 2020
…e out parameter

Summary:
Backport of Core [[bitcoin/bitcoin#15761 | PR15761]] [3/6] : bitcoin/bitcoin@c988f27

Depends on D7923

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7924
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 15, 2020
Summary:
Backport of Core [[bitcoin/bitcoin#15761 | PR15761]] [4/6] : bitcoin/bitcoin@1e48796

Depends on D7924

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7925
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 15, 2020
Summary:
 Backport of Core [[bitcoin/bitcoin#15761 | PR15761]] [5/6] : bitcoin/bitcoin@92263cc

Depends on D7925

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7926
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Oct 15, 2020
Summary:
Backport of Core [[bitcoin/bitcoin#15761 | PR15761]] [6/6] : bitcoin/bitcoin@0d32d66

Depends on D7926

Test Plan:
  ninja all check-all

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D7927
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.