Merge pull request #881 from zcash/zcash_client_backend-cache-ivks

zcash_client_backend: Precompute IVKs in `scan_cached_blocks`
This commit is contained in:
str4d 2023-07-25 17:00:14 +01:00 committed by GitHub
commit b2bb1b8716
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 4 deletions

View File

@ -23,7 +23,10 @@ and this library adheres to Rust's notion of
- `testing::MockWalletDb::new`
- `wallet::input_sellection::Proposal::{min_target_height, min_anchor_height}`:
- `zcash_client_backend::wallet::WalletSaplingOutput::note_commitment_tree_position`
- `zcash_client_backend::scanning::ScanError`
- `zcash_client_backend::scanning`:
- `ScanError`
- `impl<K: ScanningKey> ScanningKey for &K`
- `impl ScanningKey for (zip32::Scope, sapling::SaplingIvk, sapling::NullifierDerivingKey)`
### Changed
- MSRV is now 1.65.0.

View File

@ -155,7 +155,7 @@ use crate::{
data_api::{BlockMetadata, NullifierQuery, WalletWrite},
proto::compact_formats::CompactBlock,
scan::BatchRunner,
scanning::{add_block_to_runner, check_continuity, scan_block_with_runner},
scanning::{add_block_to_runner, check_continuity, scan_block_with_runner, ScanningKey},
};
pub mod error;
@ -254,6 +254,15 @@ where
.iter()
.filter_map(|(account, ufvk)| ufvk.sapling().map(move |k| (account, k)))
.collect();
// Precompute the IVKs instead of doing so per block.
let ivks = dfvks
.iter()
.flat_map(|(account, dfvk)| {
dfvk.to_sapling_keys()
.into_iter()
.map(|key| (*account, key))
})
.collect::<Vec<_>>();
// Get the nullifiers for the unspent notes we are tracking
let mut sapling_nullifiers = data_db
@ -337,7 +346,7 @@ where
let scanned_block = scan_block_with_runner(
params,
block,
&dfvks,
&ivks,
&sapling_nullifiers,
prior_block_metadata.as_ref(),
Some(&mut batch_runner),

View File

@ -66,6 +66,21 @@ pub trait ScanningKey {
-> Self::Nf;
}
impl<K: ScanningKey> ScanningKey for &K {
type Scope = K::Scope;
type SaplingNk = K::SaplingNk;
type SaplingKeys = K::SaplingKeys;
type Nf = K::Nf;
fn to_sapling_keys(&self) -> Self::SaplingKeys {
(*self).to_sapling_keys()
}
fn sapling_nf(key: &Self::SaplingNk, note: &sapling::Note, position: Position) -> Self::Nf {
K::sapling_nf(key, note, position)
}
}
impl ScanningKey for DiversifiableFullViewingKey {
type Scope = Scope;
type SaplingNk = sapling::NullifierDerivingKey;
@ -92,6 +107,21 @@ impl ScanningKey for DiversifiableFullViewingKey {
}
}
impl ScanningKey for (Scope, SaplingIvk, sapling::NullifierDerivingKey) {
type Scope = Scope;
type SaplingNk = sapling::NullifierDerivingKey;
type SaplingKeys = [(Self::Scope, SaplingIvk, Self::SaplingNk); 1];
type Nf = sapling::Nullifier;
fn to_sapling_keys(&self) -> Self::SaplingKeys {
[self.clone()]
}
fn sapling_nf(key: &Self::SaplingNk, note: &sapling::Note, position: Position) -> Self::Nf {
note.nf(key, position.into())
}
}
/// The [`ScanningKey`] implementation for [`SaplingIvk`]s.
/// Nullifiers cannot be derived when scanning with these keys.
///
@ -312,7 +342,7 @@ pub(crate) fn scan_block_with_runner<
>(
params: &P,
block: CompactBlock,
vks: &[(&AccountId, &K)],
vks: &[(&AccountId, K)],
nullifiers: &[(AccountId, sapling::Nullifier)],
prior_block_metadata: Option<&BlockMetadata>,
mut batch_runner: Option<&mut TaggedBatchRunner<P, K::Scope, T>>,