Skip to content

Conversation

@meshcollider
Copy link
Contributor

@meshcollider meshcollider commented Sep 25, 2021

This PR makes two main changes:

  1. Adds a new RPC newkeypool which will entirely flush and refill the keypool.
  2. When upgradewallet is called on old, non-HD wallets upgrading them to HD, we now always flush the keypool and generate a new one, to immediately start using the HD generated keys.

This PR is motivated by a number of users with old, pre-compressed-key wallets upgrading them and being confused about why they still can't generate p2sh-segwit or bech32 addresses -- this is due to uncompressed keys remaining in the keypool post-upgrade and being illegal in these newer address formats. There is currently no easy way to flush the keypool other than to call getnewaddress a hundred/thousand times or an ugly hack of using a sethdseed call.

@achow101
Copy link
Member

achow101 commented Sep 25, 2021

I would really prefer that we just add a new parameter rather overloading newsize with special behavior for 0. newsize=0 should really just do nothing rather than be special behavior.

Instead of checking the versions and then calling NewKeyPool, it would be simpler and more robust to replace the TopUp call in LegacyScriptPubKeyMan::Upgrade with NewKeyPool(). Especially since that won't potentially throw away all of the newly generated HD keys.

IMO the automatic keypool flush should be optional behavior though. I think it would be better if that were an option to upgradewallet. Doing this defeats the purpose of having the pre-split keypool.

@meshcollider
Copy link
Contributor Author

@achow101 Sure, do you think the option should default to flushing or not though?

@achow101
Copy link
Member

achow101 commented Sep 25, 2021

I would prefer to keep the existing behavior as default, so default to not flushing.

Edit: Discussed briefly on IRC, flushing after upgrading to HD is fine. Flushing after every upgrade is not IMO.

@katesalazar
Copy link
Contributor

There is currently no easy way to flush the keypool other than to call getnewaddress a hundred times or an ugly hack of using a sethdseed call.

#10831

A thousand times.

@achow101
Copy link
Member

ACK 84fa19c

@laanwj
Copy link
Member

laanwj commented Sep 27, 2021

Edit: Discussed briefly on IRC, flushing after upgrading to HD is fine. Flushing after every upgrade is not IMO.

Agree; only once, so that users upgrading can use the new address tyeps. Definitely not for every upgrade.

@meshcollider
Copy link
Contributor Author

Agree; only once, so that users upgrading can use the new address tyeps. Definitely not for every upgrade.

👍 (note this is already the behaviour in this PR)

@laanwj
Copy link
Member

laanwj commented Sep 28, 2021

+1 (note this is already the behaviour in this PR)

Concept ACK then!

static RPCHelpMan newkeypool()
{
return RPCHelpMan{"newkeypool",
"\nEntirely clears and refills the keypool."+
Copy link
Member

Choose a reason for hiding this comment

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

We might want to be precise in documenting what "clears" means. I understand the keys will not be dealed out anymore by getnewaddress. But what happens to the keys in the old keypool? Are they deleted from the wallet, or still considered for incoming transactions? (I guess the latter)

Copy link
Contributor

Choose a reason for hiding this comment

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

what happens to the keys in the old keypool? Are they deleted from the wallet, or still considered for incoming transactions? (I guess the latter)

FWIW; if the keys in the pool, not extracted using getnewaddress, can be queried using some wallet software other than Core, then concept NACK to make it the default behavior (I think I've read that was going to be the topic of a different future PR).

OTOH, if they can't be queried, are somehow sealed and inaccessible, then why at all hold them (they are non-HD)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@laanwj they're marked as used and remain stored but won't be returned from getnewaddress. I'll try and improve the helptext.

@katesalazar I'm not sure what you mean about other software retrieving them - do you mean another piece of software that opens Core wallet.dat files? Otherwise no, without opening the wallet file there is no way an external program could "guess" what the addresses were going to be? Sorry if I'm misunderstanding your point but I don't see anything wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

do you mean another piece of software that opens Core wallet.dat files?

yea

Copy link
Member

@sipa sipa Sep 29, 2021

Choose a reason for hiding this comment

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

@katesalazar Perhaps I'm not understanding you, because I don't see the relevance.

For context, Bitcoin Core wallets distinguish between the set of addresses/keys that are considered part of the wallet (i.e., transactions to them will be treated as incoming payments), and addresses that are given out as new addresses for receiving.

What this PR does is permit refreshing the new addresses that will be given out, but the old ones remain valid for incoming transactions. They can also be queried still by various RPCs that dump things; they just won't be given out by getnewaddress and related procedures.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, I understand Samuel better now. Thanks.

Copy link
Member

Choose a reason for hiding this comment

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

I think "consumes" is clearer than "clears".

@laanwj
Copy link
Member

laanwj commented Oct 13, 2021

Code review ACK 84fa19c

re-ACK 6531599

@instagibbs
Copy link
Member

I'd like coverage of change addresses being flushed and the rewording, otherwise looks correct to me

@ghost
Copy link

ghost commented Oct 14, 2021

Concept ACK

@meshcollider
Copy link
Contributor Author

Added new commit 6531599 to avoid invalidating previous ACKs.

New commit adds test that newkeypool flushes change addresses too.

Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

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

ACK 6531599

@laanwj laanwj merged commit 6419bdf into bitcoin:master Oct 14, 2021
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Oct 14, 2021
@harding
Copy link
Contributor

harding commented Oct 18, 2021

Sorry for the late comment, but I'm curious about the impact of using the newkeypool RPC when it comes to wallet recovery. If Alice creates a new wallet, backs up the wallet, runs newkeypool, runs getnewaddress, receives a payment to that address, and then recovers from the earlier wallet backup, will rescanning find the previously received payment? What if she runs newkeypool twice in a row between backup and recovery?

If there's a possible footgun here, it might be worth documenting it in the RPC help.

@meshcollider
Copy link
Contributor Author

@harding added in #23341. Thanks for pointing this out.

@meshcollider meshcollider deleted the 202109_keypoolrefill branch December 20, 2021 07:53
achow101 added a commit to bitcoin-core/gui that referenced this pull request Dec 20, 2021
…nd and wallet backups

a2a9231 rpc: Add warning to user about newkeypool command (Samuel Dobson)

Pull request description:

  This PR prevents `newkeypool` from being run on non-HD wallets, because this would require a new backup every time, so it isn't very safe.

  David Harding also suggested [here](bitcoin/bitcoin#23093 (comment)) that the RPC help text should include a warning to the users about the interaction between newkeypool.

ACKs for top commit:
  achow101:
    ACK a2a9231

Tree-SHA512: 0aa497900f1d179764bce13ffce0bb081ba2ca354492bf2e04b21d0212e960b3ed13a386fbf65602b6b50461f4056a0285752ef707d312da28e82449cd8ea048
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Dec 20, 2021
…allet backups

a2a9231 rpc: Add warning to user about newkeypool command (Samuel Dobson)

Pull request description:

  This PR prevents `newkeypool` from being run on non-HD wallets, because this would require a new backup every time, so it isn't very safe.

  David Harding also suggested [here](bitcoin#23093 (comment)) that the RPC help text should include a warning to the users about the interaction between newkeypool.

ACKs for top commit:
  achow101:
    ACK a2a9231

Tree-SHA512: 0aa497900f1d179764bce13ffce0bb081ba2ca354492bf2e04b21d0212e960b3ed13a386fbf65602b6b50461f4056a0285752ef707d312da28e82449cd8ea048
@bitcoin bitcoin locked and limited conversation to collaborators Dec 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants