Skip to content
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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

str4d
Copy link
Contributor

@str4d str4d commented Nov 21, 2024

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.

Copy link

codecov bot commented Nov 21, 2024

Codecov Report

Attention: Patch coverage is 72.94833% with 89 lines in your changes missing coverage. Please review.

Project coverage is 56.41%. Comparing base (2df4497) to head (6e1933b).

Files with missing lines Patch % Lines
zcash_client_sqlite/src/wallet.rs 71.30% 33 Missing ⚠️
...e/src/wallet/init/migrations/tx_retrieval_queue.rs 56.86% 22 Missing ⚠️
zcash_client_sqlite/src/wallet/transparent.rs 64.70% 12 Missing ⚠️
zcash_client_sqlite/src/lib.rs 61.11% 7 Missing ⚠️
...te/src/wallet/init/migrations/add_account_uuids.rs 92.18% 5 Missing ⚠️
zcash_client_sqlite/src/wallet/orchard.rs 0.00% 5 Missing ⚠️
zcash_client_sqlite/src/error.rs 0.00% 1 Missing ⚠️
zcash_client_sqlite/src/wallet/common.rs 83.33% 1 Missing ⚠️
.../src/wallet/init/migrations/ephemeral_addresses.rs 80.00% 1 Missing ⚠️
zcash_client_sqlite/src/wallet/sapling.rs 85.71% 1 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1631      +/-   ##
==========================================
+ Coverage   56.39%   56.41%   +0.02%     
==========================================
  Files         148      149       +1     
  Lines       19232    19404     +172     
==========================================
+ Hits        10845    10947     +102     
- Misses       8387     8457      +70     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@str4d str4d marked this pull request as ready for review November 22, 2024 02:48
@str4d
Copy link
Contributor Author

str4d commented Nov 22, 2024

I discovered that the Android SDK is misusing v_tx_outputs by putting to_account_id into a type that actually stores a ZIP 32 account index. These previously were indeed the same type, until #1235 was merged. I think we need to alter the views to expose the account UUIDs instead of the account IDs, particularly as after this PR the account IDs cannot be extracted from AccountId and are intended to be entirely internal.

daira
daira previously approved these changes Nov 22, 2024
Copy link
Contributor

@daira daira left a comment

Choose a reason for hiding this comment

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

utACK with comments.

@str4d
Copy link
Contributor Author

str4d commented Nov 23, 2024

Force-pushed to replace account_id in the views with account_uuid (because account_id is now intended to be an internal-only value). cc @AArnott for awareness (though I've also documented it in the changelogs).

daira
daira previously approved these changes Nov 24, 2024
Copy link
Contributor

@daira daira left a comment

Choose a reason for hiding this comment

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

Copy link
Contributor

@nuttycom nuttycom left a comment

Choose a reason for hiding this comment

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

If we're going to make this change, we should do so wholesale: replace the contents of the AccountId type with the UUID, and change all the queries to take the UUID (and join to the accounts table if necessary).

zcash_client_sqlite/src/lib.rs Outdated Show resolved Hide resolved
zcash_client_sqlite/src/lib.rs Outdated Show resolved Hide resolved

st.reset();

// Account creation and DFVK derivation should be deterministic.
let (_, restored_usk) = st.wallet_mut().create_account(&seed, &birthday).unwrap();
let (account1, restored_usk) = st.wallet_mut().create_account(&seed, &birthday).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

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

This change is necessary because we get new account UUIDs when we regenerate the wallet.

…`AccountUuid`

This requires a few annoying changes to migrations in order to avoid
hitting cases where account UUIDs are expected before they exist in the
database schema.
This is now consistent with how we name other internal primary key type
wrappers.
@@ -129,7 +124,7 @@ pub enum SqliteClientError {
/// ephemeral address outputs have been mined. The parameters are the account id and
Copy link
Contributor

@daira daira Nov 28, 2024

Choose a reason for hiding this comment

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

Suggested change
/// ephemeral address outputs have been mined. The parameters are the account id and
/// ephemeral address outputs have been mined. The parameters are the account UUID and

Also s/account_id/account_uuid/ on lines 190 and 192.

@@ -181,8 +176,7 @@ impl fmt::Display for SqliteClientError {
SqliteClientError::UnknownZip32Derivation => write!(f, "ZIP-32 derivation information is not known for this account."),
SqliteClientError::KeyDerivationError(acct_id) => write!(f, "Key derivation failed for account {}", u32::from(*acct_id)),
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
SqliteClientError::KeyDerivationError(acct_id) => write!(f, "Key derivation failed for account {}", u32::from(*acct_id)),
SqliteClientError::KeyDerivationError(zip32_index) => write!(f, "Key derivation failed for ZIP 32 account index {}", u32::from(*zip32_index)),

@@ -181,8 +176,7 @@ impl fmt::Display for SqliteClientError {
SqliteClientError::UnknownZip32Derivation => write!(f, "ZIP-32 derivation information is not known for this account."),
SqliteClientError::KeyDerivationError(acct_id) => write!(f, "Key derivation failed for account {}", u32::from(*acct_id)),
SqliteClientError::BadAccountData(e) => write!(f, "Failed to add account: {}", e),
SqliteClientError::AccountIdDiscontinuity => write!(f, "Wallet account identifiers must be sequential."),
SqliteClientError::AccountIdOutOfRange => write!(f, "Wallet account identifiers must be less than 0x7FFFFFFF."),
SqliteClientError::Zip32AccountIndexOutOfRange => write!(f, "ZIP 32 account identifiers must be less than 0x7FFFFFFF."),
SqliteClientError::AccountCollision(id) => write!(f, "An account corresponding to the data provided already exists in the wallet with internal identifier {}.", id.0),
Copy link
Contributor

@daira daira Nov 28, 2024

Choose a reason for hiding this comment

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

Suggested change
SqliteClientError::AccountCollision(id) => write!(f, "An account corresponding to the data provided already exists in the wallet with internal identifier {}.", id.0),
SqliteClientError::AccountCollision(account_uuid) => write!(f, "An account corresponding to the data provided already exists in the wallet with UUID {account_uuid:?}."),

(probably needs a rustfmt)

@@ -818,7 +848,10 @@ impl<P: consensus::Parameters> WalletWrite for WalletDb<rusqlite::Connection, P>
)
})?;
let account_index = wallet::max_zip32_account_index(wdb.conn.0, &seed_fingerprint)?
Copy link
Contributor

Choose a reason for hiding this comment

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

Rename to zip32_account_index.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

zcash_client_sqlite: Implement the new multi-seed-compatible account ID
3 participants