Skip to content

Commit

Permalink
zcash_client_backend: Generalize ScanningKey
Browse files Browse the repository at this point in the history
This change allows the `ScanningKey` type to represent Orchard
keys as well as Sapling keys.
  • Loading branch information
nuttycom committed Feb 22, 2024
1 parent 04343e1 commit 386b860
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 110 deletions.
63 changes: 23 additions & 40 deletions zcash_client_backend/src/data_api/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,7 @@
use std::ops::Range;

use sapling::note_encryption::PreparedIncomingViewingKey;
use zcash_primitives::{
consensus::{self, BlockHeight},
zip32::Scope,
};
use zcash_primitives::consensus::{self, BlockHeight};

use crate::{
data_api::{NullifierQuery, WalletWrite},
Expand Down Expand Up @@ -284,57 +281,43 @@ where
.map_err(Error::Wallet)?;
// TODO: Change `scan_block` to also scan Orchard.
// https://github.com/zcash/librustzcash/issues/403
let dfvks: Vec<_> = ufvks
let ivks: Vec<_> = ufvks
.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))
})
.flat_map(|(account, dfvk)| dfvk.to_ivks().into_iter().map(move |key| (account, key)))
.collect::<Vec<_>>();

// Get the nullifiers for the unspent notes we are tracking
let mut sapling_nullifiers = data_db
.get_sapling_nullifiers(NullifierQuery::Unspent)
.map_err(Error::Wallet)?;

let mut batch_runner = BatchRunner::<_, _, _, _, ()>::new(
let mut sapling_runner = BatchRunner::<_, _, _, _, ()>::new(
100,
dfvks
.iter()
.flat_map(|(account, dfvk)| {
[
((**account, Scope::External), dfvk.to_ivk(Scope::External)),
((**account, Scope::Internal), dfvk.to_ivk(Scope::Internal)),
]
})
.map(|(tag, ivk)| (tag, PreparedIncomingViewingKey::new(&ivk))),
ivks.iter().map(|(account, (scope, ivk, _))| {
((**account, *scope), PreparedIncomingViewingKey::new(ivk))
}),
);

let mut prior_block_metadata = if from_height > BlockHeight::from(0) {
data_db
.block_metadata(from_height - 1)
.map_err(Error::Wallet)?
} else {
None
};

block_source.with_blocks::<_, DbT::Error>(
Some(from_height),
Some(limit),
|block: CompactBlock| {
add_block_to_runner(params, block, &mut batch_runner);
add_block_to_runner(params, block, &mut sapling_runner);

Ok(())
},
)?;

batch_runner.flush();
sapling_runner.flush();

let mut prior_block_metadata = if from_height > BlockHeight::from(0) {
data_db
.block_metadata(from_height - 1)
.map_err(Error::Wallet)?
} else {
None
};

// Get the nullifiers for the unspent notes we are tracking
let mut sapling_nullifiers = data_db
.get_sapling_nullifiers(NullifierQuery::Unspent)
.map_err(Error::Wallet)?;

let mut scanned_blocks = vec![];
let mut scan_end_height = from_height;
Expand All @@ -351,7 +334,7 @@ where
&ivks,
&sapling_nullifiers,
prior_block_metadata.as_ref(),
Some(&mut batch_runner),
Some(&mut sapling_runner),
)
.map_err(Error::Scan)?;

Expand Down
Loading

0 comments on commit 386b860

Please sign in to comment.