wallet: Add importdescriptors interface#34861
Conversation
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. Code Coverage & BenchmarksFor details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34861. ReviewsSee the guideline and AI policy for information on the review process.
If your review is incorrectly listed, please copy-paste 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. |
a3582a2 to
5e9dab4
Compare
Why can a GUI not use the RPC interface? |
Sorry, a GUI can. I ment Bitcoin Core GUI needs it because it doesn't use RPC. |
|
Concept ACK We'll eventually want a way to import descriptors in the GUI, and moving this code out of Let's update the PR description to make it clear this isn't an IPC change. Until #10102 |
|
Concept ACK Makes sense to move this into the wallet interface, but this does indeed have nothing to do with ipc for now. |
|
Updated the title and description to avoid confusion |
|
Thanks for the clarification, Concept ACK. |
|
Approach ACK |
5e9dab4 to
b88462d
Compare
|
Concept ACK, this refactor is a nice win for maintainability, and makes adding importdescriptors to the GUI and/or to an IPC interface or any other interface trivial. I could be mistaken as I haven't tried yet to make this change myself, but I think that the RPC code should consume the interface you are adding, because it deduplicates code and increases confidence that the interface added in this PR (which in the current branch is untested) works correctly since we reuse all of our functional tests on it. If that's not feasible, the interface commit should probably be held off until the PR that introduces its consumer in the GUI. |
That is not how RPCs access the wallet, and making RPCs access the wallet through this interface is a pretty significant change that is massively outside of the scope of this PR. It would also mean that a bunch of things use the interface, while other things access I think the layout of the commits could be changed to make this easier to review. In general, making a new function that is mostly a copy of another function that will end up replacing the other function makes review more difficult as it does not allow git to show reviewers where things are moved. It also runs the risk of things that are added to the original function not making it into the copy when the PR is rebased, although this is less likely to be an issue for this PR. Since the difference between the 2 functions is primarily in the data types, I would suggest having a first commit that separates |
| INVALID_DESCRIPTOR, | ||
| INVALID_PARAMETER, | ||
| WALLET_ERROR, | ||
| WALLET_UNLOCK_NEEDED, |
There was a problem hiding this comment.
65886aa to
4b93797
Compare
|
|
||
| namespace wallet { | ||
|
|
||
| struct ImportDescriptorResult { |
There was a problem hiding this comment.
In 28cce72 "wallet: Add ImportDescriptorRequest and ImportDescriptorResult structs"
Since the structs introduced here are used by the interface, they should live in wallet/types.h as that is where wallet internal structs that get passed across the interface live.
But also, as is being discussed in #35436, it would be preferable to avoid having single function specific structs and enums, especially for error codes.
|
@pseudoramdom
I am not sure, in the proposed code both items |
Introduce WalletError as a generic wallet-layer error type that can carry a machine-readable WalletErrorCode and a translated user-facing message. The generic `WALLET_ERROR` code is intended for failures that callers should only display to the user. More specific codes should only be added when callers can handle the condition differently.
Timestamp 0 is allowed and it does not seem a reason to have a minimum timestamp > 0 other than some carried value from legacy wallet. Lowering simplifies importdescriptors because, before this change, if a timestamp 0 was set by the user it would be overwritten by the minimum timestamp, but error messages should still report timestamp 0.
ImportDescriptorRquest will replace the UniValue-based interface of ProcessDescriptorImport(), which will allow to extract the functionality to other interfaces such as the GUI, etc, in a subsequent commit.
…ptorImport Adds a new function ProcessUniValueDescriptor that translates from UniValue to ImportDescriptorRequest. Refactors ProcessDescriptorImport to work with ImportDescriptorRequest objects instead of UniValue. Refactors RPCMethod importdescriptors() to use ProcessUniValueDescriptor.
ImportError struct will substitute the UniValue based response of ProcessDescriptorImport in a subsequent commit. This will allow other interfaces such as the GUI to consume those function. Also add new error codes to the WalletError codes enum, this is necessary in order to propagate error codes to the new interfaces and to translate errors to the rpc wallet error codes.
…orResult Make ProcessDescriptorImport return a ImportDescriptorResult object instead of a UniValue. This commit gets rid of a try-catch that generates a big diff of identation changes, it is recommended to review it with --ignore-space-change
4b93797 to
4c076bd
Compare
|
Last force push https://github.com/bitcoin/bitcoin/compare/4b9379723e07c46266cc0f8c29bcb9befeed816e..4c076bd0ff55c46ceb21c1530c8ae2d61520cd7c Rebased it on top of #35690 The location and names of the three new errors does not need to be there, I have just added them there temporary so we can discuss. Also simplified a lot the result struct and removed the |
|
🚧 At least one of the CI tasks failed. HintsTry to run the tests locally, according to the documentation. However, a CI failure may still
Leave a comment here, if you need help tracking down a confusing failure. |
…ocessDescriptorsImport Rename ProcessDescriptorImport() to ImportDescriptor(). ImportDescriptor() takes a single descriptor request and imports it into the wallet. Add ProcessDescriptorsImport() (descriptors in plural) to handle wallet locking and rescanning over a vector of ImportDescriptorRequest items. It is also in charge of collecting all responses of imports from ImportDescriptor. This allows a next commit to extract ImportDescriptor() and ProcessDescriptorsImport() out of the RPC code so they can be used by other future interfaces.
….cpp Extract ImportDescriptor() and ProcessDescriptorsImport() out of backup.cpp and move them into imports.cpp so other future interfaces can use them without needing to know about RPC code. The commit can be reviewed with the --color-moved=dimmed-zebra option for an easier review.
|
@achow101 re: #35690 (comment)
We consider those breaking change acceptable in this case? |
|
🐙 This pull request conflicts with the target branch and needs rebase. |
This PR adds an interface for importing descriptors.
The motivation behind this is that currently, importing descriptors is only possible via RPC. Bitcoin Core GUI doesn't use the RPC interface so it cannot offer descriptor import functionality, which is needed to support more complex wallet setups such as multisig.
This PR also adds a refactor by moving the
importdescriptorslogic from the RPC layer intoCWallet::ImportDescriptor, making it reusable by both the RPC and this new interface.The main changes are:
CWallet::ImportDescriptor()containing the core import logic, previously embedded in the RPCProcessDescriptorImportfunction.wallet::ImportDescriptorResult, a new result struct that carries success status, error message, warnings, and aFailureReasonenum. The RPC layer usesFailureReasonto map results back to the appropriate JSON-RPC error codes, keeping RPC concerns out ofCWallet.ProcessDescriptorImportinrpc/backup.cppto delegate toCWallet::ImportDescriptor.interfaces::Wallet::importDescriptors()as a new interface method, allowing the GUI to import descriptors without going through RPC.I have a vibe coded PoC commit for how the GUI could consume it here: polespinasa@d1cb120
It might be useful to cherry-pick the commit to test the interface.