Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Declare and use NonHardenedChildIndex for transparent #1185
Declare and use NonHardenedChildIndex for transparent #1185
Changes from 4 commits
1733af8
918f5cc
8003a39
9f221f8
8f6afb2
f1b6dd0
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
If all we wanted to return from this API is the transparent address and the child index it was derived from, then I argue that
NonHardenedChildIndex
should be the key: it is trivial to derive the address from the full viewing key given the index (and providing the address is thus only an optimization), whereas the reverse requires brute forcing, so logically the child index is the unique key here.However, given the existing usage of this API, the child index is being treated as metadata, so we should keep
AddressMetadata
as the return type here. This would allow for e.g. marking whether a receiver is external or internal (currently this API only returns external receivers becausezcash_client_backend
wallets never create transparent change, but if a third party wallet seed phrase is imported that did, we'd need to support scanning at least the default internal transparent receiver to detect it). If we keepAddressMetadata
removed then in future we'd also need to change the map to beHashMap<(zip32::Scope, NonHardenedChildIndex), TransparentAddress>
.Separately, I note that
AddressMetadata
is currently only used for transparent addresses, and is really a detail of this specificWalletRead
method. It should probably not have been moved intozcash_keys
, and should be moved back intozcash_client_backend
(and maybe renamed to be specific to transparent addresses, since we do not expose internal addresses for shielded keys).After a rather deep rabbit-hole session with @nuttycom, our conclusion is we should:
AddressMetadata
back intozcash_client_backend::address
.AddressMetadata
to replacediversifier_index
withNonHardenedChildIndex
, removeaccount_id
, and addzip32::Scope
.These changes don't need to happen in this PR, however this PR should be changed to not remove
AddressMetadata
from the return type of this method. So if you do want to make the other changes here, you are welcome to.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.
More specifically, we realized as part of the discussion that there is probably an existing bug related to the import of seeds from transparent-only wallets, where we are not at present scanning any of the internal key tree (which is where Bitcoin wallets regularly send change) so if you import a seed that was previously used with a transparent-only wallet, you're likely to be missing funds.
Then again, if you do that, then you're also not doing gap limit scanning at the moment, so both of these should be addressed at once. I'll open an issue for that and it can get stuck in the backlog somewhere.
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.
AddressMetadata
includesDiversifierIndex
and the ZIP-32AccountId
. Both are problematic because we may not know the address index at all for a given receiver, and similarly we may not know the AccountId. At least, we won't be guaranteed to know these things after #1175 merges. And it is in preparation for that PR that I created this PR in the first place. Although now that I think about it, I guess we're not even guaranteed to know theNonHardenedChildIndex
. So what do we do about a function whose primary purpose (based on its name, anyway) is to produce the transparent addresses for a given account, when it also provides metadata for that address which may or may not be available?What about changing it to return a vector of tuples, where the first element is the address, and the second element is an
Option<T>
whereT
is whatever makes the most sense given what we may know?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.
Is it all of the metadata that may be known or unknown, or is it each field of
AddressMetadata
somewhat independently? If the former then useOption<AddressMetadata>
, otherwise make the relevant accessors onAddressMetadata
returnOption
s.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.
Addressed. Please take another look.
I left the key=value order as it was because in the future when we support importing transparent private keys, we won't have derivation data.
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.
If we can't even guarantee that, then we cannot spend any funds received to that address, because:
We do not import raw transparent spending keys; everything needs to be at a minimum tied back to a transparent full viewing key (which we define in ZIP 316 as a particular node in the BIP 44 key derivation path).
Importing arbitrary non-HD transparent private keys will break a bunch of assumptions the current wallet architecture makes, and no one has committed to supporting and maintaining that use case in the long term. From a user perspective, it is only necessary in the context of a full node wallet that explicitly supports importing an arbitrary
zcashd
wallet, and even in that case we should preferably instead have a migration pathway away from those transparent keys. Transparent-only mobile wallets have for basically all of Zcash's existence used HD-derived keys.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.
While I am strongly opposed to trait changes that point us in the direction of adding support for long-since-deprecated
zcashd
behaviours, I am not going to block this PR being merged. I have not fully re-reviewed the PR after the recent changes, but the trait returningOption<Metadata>
is the least intrusive thing that could be done, and I will almost certainly just be.unwrap()
ing everywhere downstream.Check warning on line 389 in zcash_client_sqlite/src/wallet.rs
Codecov / codecov/patch
zcash_client_sqlite/src/wallet.rs#L388-L389
Check warning on line 395 in zcash_client_sqlite/src/wallet.rs
Codecov / codecov/patch
zcash_client_sqlite/src/wallet.rs#L394-L395