-
Notifications
You must be signed in to change notification settings - Fork 38.2k
wallet: Add wallet method to detect if a key is "active" #27216
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
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code CoverageFor detailed information about the code coverage, see the test coverage report. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, 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. |
|
https://github.com/bitcoin/bitcoin/pull/27216/checks?check_run_id=11804958852 Assertion failed: lock cs_wallet not held in ./wallet/wallet.h:444; locks held:
'cs_KeyStore' in wallet/scriptpubkeyman.cpp:1185 (in thread 'test') |
87da692 to
1e4b0e8
Compare
c1bca08 to
4fec5fd
Compare
|
rebased on master and addressed some nits from follow-up PR bitcoin-core/gui#723 |
jonatack
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK, tested and reviewed each commit. Some thoughts and questions follow.
This PR also patches PKDescriptor from #22051 where matching public keys were not returned.
I didn't see where/how; can you help or explain?
|
@jonatack thanks so much for the great review, addressed comments (1 or 2 questions along the way) rebase on master and also rebased the GUI follow up |
|
rebase to: 58fba35e25c2b9dcdd5b3dd0aa8f412801a98146
|
jonatack
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK with some suggestions below.
The release note and added test coverage could optionally all be in separate commits, provided each commit is hygienic, i.e. builds and all tests pass. It's a bit easier for reviewers if updates needed for tests to pass with a change are in the same commit, while additional coverage is in separate commits.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 8139075 modulo eyes from someone more familiar with the wallet to validate the approach.
Commit 2a5774f should probably be renamed to something like test: cover ScriptPubKeyMan::IsKeyActive and IsDestinationActive
Re-reviewing this shuffled version was a little trickier due to the unneeded rebase. Please rebase only when you have to. Aside from that, the reorganized commits seem easier to review now.
src/wallet/scriptpubkeyman.h
Outdated
| virtual std::vector<WalletDestination> MarkUnusedAddresses(const CScript& script) { return {}; } | ||
|
|
||
| /* Determines if address is derived from active key manager */ | ||
| [[nodiscard]] virtual bool IsKeyActive(const CScript& script) const { return false; }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fb3d39a It may make sense to declare this base class member as a pure virtual function. The implementation here seems unused/unnecessary.
| [[nodiscard]] virtual bool IsKeyActive(const CScript& script) const { return false; }; | |
| virtual bool IsKeyActive(const CScript& script) const = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah thanks for the ack, I'll update this and the commit message you mentioned if I need to revise again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, both comments addressed with rebase
Following up on #27216 (comment) above, according to #20160 legacy wallet support may be dropped in the next couple releases. |
Github-Pull: bitcoin#27216 Rebased-From: 6765021
S3RK
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, we can't use "activeness" of a descriptor to determine if it was generated before encryption.
Descriptor wallets allow as many descriptors as you want, but only one descriptor per OutputType could be active at a time. The activeness only specifies which descriptor to use when generating new addresses for that type. Therefore, there are more scenarios, besides the two you've listed, in which a key will be NOT "active". The simplest one would be — I just imported two p2wpkh descriptors for two BIP-44 accounts that I have. And only one of these descriptors could be active at a time.
In general, I believe that the proper solution to "exposed" keys is to get a new wallet with new set of keys, rather than rotating keys in existing wallet. We don't have a good separation between UTXOs/addresses within a wallet. On the other hand we already support multiple wallets, which are completely isolated so there are no chances of leaking/mixing UTXOs and addresses.
You would have to set Even if you did do this (import with active:true), I still think it is useful for getaddrinfo to notify you if an address is derived from an inactive descriptor. The issue I am targeting with this PR is more about protecting less advanced users (particularly with the GUI) from giving out "risky" receive addresses. |
|
I have two concerns with the approach:
1/ The activeness indicates from which descriptor to derive new addresses. Based on the semantics of that field, It is incorrect to imply that addresses from inactive descriptors are less safe that addresses from active descriptors. Moreover, activeness of the descriptor is a user configurable parameter and we can't just reuse it to store information about "safety" of the descriptor. 2/ IIUC here's the use cases this PR tries to address: a user believes existing private keys are compromised and rotates the keys in the wallet. Since the keys are compromised it's unsafe to receive new and keep old funds. So after rotating the keys the user would have to sweep all the compromised keys. If I'm not mistaken, we currently don't support sweeping coins from a descriptor. However, we support the whole wallet sweeping with Separate wallet solution is also less error prone because it doesn't rely on a user to pay attention to the addresses to maintain safety. This approach (with optional sweeping) also works for privacy leaks, because it also prevents mixing UTXO histories. |
|
🐙 This pull request conflicts with the target branch and needs rebase. |
pablomartin4btc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
Interesting points of view from both @pinheadmz and @S3RK, regarding "activeness" concept for descriptor wallets, the use case scenario this PR tries to solve and safety related with rotating keys vs wallet sweeping.
I'll review this PR further.
|
I'm closing this to rethink the approach. Since 'active' descriptors can be imported it defeats the value of that field for this purpose. Really it seems the only property the wallet can really know for sure is if it generated keys into an encrypted wallet. I'll be back with a UI indicator for keys that we know have always been "safe". |
This new method returns true if the given CScript key is derived from the SPKM. For Legacy that means checking the hd_seed_id in the key's metadata. Also patches PKDescriptor to return associated public keys in MakeScripts() Github-Pull: bitcoin#27216 Rebased-From: f39957f
This connects SPKM.IsKeyActive() up to the wallet level. Github-Pull: bitcoin#27216 Rebased-From: d33f3bd
…ctive() Github-Pull: bitcoin#27216 Rebased-From: ba65d93
Github-Pull: bitcoin#27216 Rebased-From: 6765021
This new method returns true if the given CScript key is derived from the SPKM. For Legacy that means checking the hd_seed_id in the key's metadata. Also patches PKDescriptor to return associated public keys in MakeScripts() Github-Pull: bitcoin#27216 Rebased-From: f39957f
This connects SPKM.IsKeyActive() up to the wallet level. Github-Pull: bitcoin#27216 Rebased-From: d33f3bd
…ctive() Github-Pull: bitcoin#27216 Rebased-From: ba65d93
Github-Pull: bitcoin#27216 Rebased-From: 6765021
This new method returns true if the given CScript key is derived from the SPKM. For Legacy that means checking the hd_seed_id in the key's metadata. Also patches PKDescriptor to return associated public keys in MakeScripts() Github-Pull: bitcoin#27216 Rebased-From: f39957f
This connects SPKM.IsKeyActive() up to the wallet level. Github-Pull: bitcoin#27216 Rebased-From: d33f3bd
…ctive() Github-Pull: bitcoin#27216 Rebased-From: ba65d93
Github-Pull: bitcoin#27216 Rebased-From: 6765021
This is a first step towards closing #3314 by implementing functions in Wallet and ScriptPubKeyMan that determine if a key is "active" meaning "derived from a currently active scriptpubkey manager."
A key is NOT "active" if:
import{privkey, address, pubkey}rpcUsers should be informed that these keys may be compromised:
This PR adds a new field
isactiveto rpcgetaddressinfo, follow-up work will be adding this to the GUI address book as well, something like this. The original issue also recommends sweeping all value from keys in this category, I think that feature can be discussed in the future as a follow-up.This PR also patches
PKDescriptorfrom #22051 where matching public keys were not returned.Follow-up PR for the GUI: bitcoin-core/gui#723