-
Notifications
You must be signed in to change notification settings - Fork 252
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
zcash_client_sqlite: Assign UUIDs to each account #1631
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1631 +/- ##
==========================================
+ Coverage 56.39% 56.46% +0.07%
==========================================
Files 148 149 +1
Lines 19232 19319 +87
==========================================
+ Hits 10845 10908 +63
- Misses 8387 8411 +24 ☔ View full report in Codecov by Sentry. 🚨 Try these New Features:
|
I discovered that the Android SDK is misusing |
/// This is an ephemeral value for efficiently and generically working with accounts in a | ||
/// [`WalletDb`]. To reference accounts in external contexts, use [`AccountUuid`]. | ||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Default)] | ||
pub struct AccountId(u32); |
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.
Would it be useful to rename this to LocalAccountId
? Doing so is obviously a more disruptive change, but it would force all code currently using AccountId
[directly as a type] to explicitly choose between AccountUuid
and LocalAccountId
. It would also, I think, reduce the chance of confusing these with ZIP 32 account indices (which is something I've found to be a hazard on several occasions).
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.
Such a rename serves little purpose, because it is named directly for the WalletRead::AccountId
associated type that it gets set to, and the associated type is what actually gets used in most places.
I'm somewhat annoyed that we now have this split where our local account ID that needs to be in WalletRead
is infallible concretely but fallible in the trait API, which was in part due to #1235 getting rushed into a crate release (something I expressed disagreement with at the time). As it is, we'd need Yet Another Large Refactor to fix it, and I explicitly do not want to do that at the same time as these changes; our changelogs get large enough as it is.
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.
Confusion with the associated type is one reason I want to do this change, actually. It makes no sense to me to have the associated type be named the same as one particular possible instantiation of it. They are conceptually not the same thing. (See also https://github.com/Electric-Coin-Company/zcash-swift-wallet-sdk/pull/1515/files#r1855209493 .)
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.
utACK with comments.
c8aff5b
to
bf42ec2
Compare
Force-pushed to replace |
@@ -779,8 +794,9 @@ pub(crate) fn get_derived_account<P: consensus::Parameters>( | |||
":hd_account_index": u32::from(account_index), |
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.
I'm confused: stmt
uses :account_id
as a named parameter, but the name specified here is :hd_account_index
. How was this working?
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.
Hmm. https://docs.rs/rusqlite/latest/rusqlite/trait.Params.html#named-parameters :
Note: Unbound named parameters will be left to the value they previously were bound with, falling back to NULL for parameters which have never been bound.
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.
That's a bug, and we've had that kind of bug before. It would be nice to figure out a way to lint for this.
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.
I'd settle for a runtime error. Substituting NULL is just terrible. 😭
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.
I guess you could have a macro to generate a struct and an impl rusqlite::Params for that struct from the query string. Then you could pass an instance of the struct rather than named_params!
, and the compiler would check whether you'd missed out fields or included undefined fields. It could be made completely typesafe; you would have the statement type returned from the macro be parameterized by the struct type, so that it will only accept the right parameters. Sounds like a lot of effort to get working, though, unless someone has already done something like it.
@@ -767,7 +782,7 @@ pub(crate) fn get_derived_account<P: consensus::Parameters>( | |||
account_index: zip32::AccountId, | |||
) -> Result<Option<Account>, SqliteClientError> { | |||
let mut stmt = conn.prepare( | |||
"SELECT id, ufvk | |||
"SELECT id, uuid, ufvk | |||
FROM accounts | |||
WHERE hd_seed_fingerprint = :hd_seed_fingerprint | |||
AND hd_account_index = :account_id", |
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.
AND hd_account_index = :account_id", | |
AND hd_account_index = :hd_account_index", |
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.
utACK with this suggestion: https://github.com/zcash/librustzcash/pull/1631/files#r1855319372
This provides equivalent uniqueness to the
accounts
table primary key, but avoids collisions across wallet recreation events (to defend against downstream crate users who don't flush any persisted account IDs at those events).Closes #1629.