zcash_client_backend: Add `WalletRead::get_seed_account`

This commit is contained in:
Kris Nuttycombe 2024-03-09 13:48:44 -07:00
parent 5e810d3689
commit 33e943d14a
4 changed files with 68 additions and 1 deletions

View File

@ -51,9 +51,10 @@ and this library adheres to Rust's notion of
- Arguments to `ScannedBlock::from_parts` have changed.
- Changes to the `WalletRead` trait:
- Added `Account` associated type.
- Added `get_orchard_nullifiers`
- Added `get_orchard_nullifiers` method.
- `get_account_for_ufvk` now returns an `Self::Account` instead of a bare
`AccountId`
- Added `get_seed_account` method.
- Changes to the `InputSource` trait:
- `select_spendable_notes` now takes its `target_value` argument as a
`NonNegativeAmount`. Also, the values of the returned map are also

View File

@ -66,6 +66,7 @@ use std::{
use incrementalmerkletree::{frontier::Frontier, Retention};
use secrecy::SecretVec;
use shardtree::{error::ShardTreeError, store::ShardStore, ShardTree};
use zcash_keys::keys::HdSeedFingerprint;
use self::{chain::CommitmentTreeRoot, scanning::ScanRange};
use crate::{
@ -655,6 +656,14 @@ pub trait WalletRead {
ufvk: &UnifiedFullViewingKey,
) -> Result<Option<Self::Account>, Self::Error>;
/// Returns the account corresponding to a given [`HdSeedFingerprint`] and
/// [`zip32::AccountId`], if any.
fn get_seed_account(
&self,
seed: &HdSeedFingerprint,
account_id: zip32::AccountId,
) -> Result<Option<Self::Account>, Self::Error>;
/// Returns the wallet balances and sync status for an account given the specified minimum
/// number of confirmations, or `Ok(None)` if the wallet has no balance data available.
fn get_wallet_summary(
@ -1416,6 +1425,7 @@ pub mod testing {
use secrecy::{ExposeSecret, SecretVec};
use shardtree::{error::ShardTreeError, store::memory::MemoryShardStore, ShardTree};
use std::{collections::HashMap, convert::Infallible, num::NonZeroU32};
use zcash_keys::keys::HdSeedFingerprint;
use zcash_primitives::{
block::BlockHash,
@ -1588,6 +1598,14 @@ pub mod testing {
Ok(None)
}
fn get_seed_account(
&self,
_seed: &HdSeedFingerprint,
_account_id: zip32::AccountId,
) -> Result<Option<Self::Account>, Self::Error> {
Ok(None)
}
fn get_wallet_summary(
&self,
_min_confirmations: u32,

View File

@ -405,6 +405,14 @@ impl<C: Borrow<rusqlite::Connection>, P: consensus::Parameters> WalletRead for W
wallet::get_account_for_ufvk(self.conn.borrow(), &self.params, ufvk)
}
fn get_seed_account(
&self,
seed: &HdSeedFingerprint,
account_id: zip32::AccountId,
) -> Result<Option<Self::Account>, Self::Error> {
wallet::get_seed_account(self.conn.borrow(), &self.params, seed, account_id)
}
fn get_wallet_summary(
&self,
min_confirmations: u32,

View File

@ -779,6 +779,46 @@ pub(crate) fn get_account_for_ufvk<P: consensus::Parameters>(
}
}
/// Returns the account id corresponding to a given [`HdSeedFingerprint`]
/// and [`zip32::AccountId`], if any.
pub(crate) fn get_seed_account<P: consensus::Parameters>(
conn: &rusqlite::Connection,
params: &P,
seed: &HdSeedFingerprint,
account_id: zip32::AccountId,
) -> Result<Option<(AccountId, Option<UnifiedFullViewingKey>)>, SqliteClientError> {
let mut stmt = conn.prepare(
"SELECT id, ufvk
FROM accounts
WHERE hd_seed_fingerprint = :hd_seed_fingerprint
AND hd_account_index = :account_id",
)?;
let mut accounts = stmt.query_and_then::<_, SqliteClientError, _, _>(
named_params![
":hd_seed_fingerprint": seed.as_bytes(),
":hd_account_index": u32::from(account_id),
],
|row| {
let account_id = row.get::<_, u32>(0).map(AccountId)?;
Ok((
account_id,
row.get::<_, Option<String>>(1)?
.map(|ufvk_str| UnifiedFullViewingKey::decode(params, &ufvk_str))
.transpose()
.map_err(|e| {
SqliteClientError::CorruptedData(format!(
"Could not decode unified full viewing key for account {:?}: {}",
account_id, e
))
})?,
))
},
)?;
accounts.next().transpose()
}
pub(crate) trait ScanProgress {
fn sapling_scan_progress(
&self,