change(zebra-scan): Scan only one key per backend call (#8034)
* scan one key per backend call * fix docs
This commit is contained in:
parent
cb9452c5e3
commit
1708f9d946
|
@ -70,7 +70,7 @@ pub async fn start(mut state: State, storage: Storage) -> Result<(), Report> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns transactions belonging to any of the given [`ScanningKey`]s.
|
||||
/// Returns transactions belonging to the given `ScanningKey`.
|
||||
///
|
||||
/// TODO:
|
||||
/// - Remove the `sapling_tree_size` parameter or turn it into an `Option` once we have access to
|
||||
|
@ -80,7 +80,7 @@ pub fn scan_block<K: ScanningKey>(
|
|||
network: Network,
|
||||
block: Arc<Block>,
|
||||
sapling_tree_size: u32,
|
||||
scanning_keys: &[&K],
|
||||
scanning_key: &K,
|
||||
) -> Result<ScannedBlock<K::Nf>, ScanError> {
|
||||
// TODO: Implement a check that returns early when the block height is below the Sapling
|
||||
// activation height.
|
||||
|
@ -96,10 +96,8 @@ pub fn scan_block<K: ScanningKey>(
|
|||
// Use a dummy `AccountId` as we don't use accounts yet.
|
||||
let dummy_account = AccountId::from(0);
|
||||
|
||||
let scanning_keys: Vec<_> = scanning_keys
|
||||
.iter()
|
||||
.map(|key| (&dummy_account, key))
|
||||
.collect();
|
||||
// We only support scanning one key and one block per function call for now.
|
||||
let scanning_keys = vec![(&dummy_account, scanning_key)];
|
||||
|
||||
zcash_client_backend::scanning::scan_block(
|
||||
&network,
|
||||
|
|
|
@ -32,80 +32,11 @@ use zcash_primitives::{
|
|||
};
|
||||
|
||||
use zebra_chain::{
|
||||
block::Block, chain_tip::ChainTip, parameters::Network, serialization::ZcashDeserializeInto,
|
||||
transaction::Hash,
|
||||
block::Block, chain_tip::ChainTip, serialization::ZcashDeserializeInto, transaction::Hash,
|
||||
};
|
||||
|
||||
use crate::scan::{block_to_compact, scan_block};
|
||||
|
||||
/// Scans a continuous chain of Mainnet blocks from tip to genesis.
|
||||
///
|
||||
/// Also verifies that no relevant transaction is found in the chain when scanning for a fake
|
||||
/// account's nullifier.
|
||||
#[tokio::test]
|
||||
async fn scanning_from_populated_zebra_state() -> Result<()> {
|
||||
let network = Network::default();
|
||||
|
||||
// Create a continuous chain of mainnet blocks from genesis
|
||||
let blocks: Vec<Arc<Block>> = zebra_test::vectors::CONTINUOUS_MAINNET_BLOCKS
|
||||
.iter()
|
||||
.map(|(_height, block_bytes)| block_bytes.zcash_deserialize_into().unwrap())
|
||||
.collect();
|
||||
|
||||
// Create a populated state service.
|
||||
let (_state_service, read_only_state_service, latest_chain_tip, _chain_tip_change) =
|
||||
zebra_state::populated_state(blocks.clone(), network).await;
|
||||
|
||||
let db = read_only_state_service.db();
|
||||
|
||||
// use the tip as starting height
|
||||
let mut height = latest_chain_tip.best_tip_height().unwrap();
|
||||
|
||||
let mut transactions_found = 0;
|
||||
let mut transactions_scanned = 0;
|
||||
let mut blocks_scanned = 0;
|
||||
// TODO: Accessing the state database directly is ok in the tests, but not in production code.
|
||||
// Use `Request::Block` if the code is copied to production.
|
||||
while let Some(block) = db.block(height.into()) {
|
||||
// We use a dummy size of the Sapling note commitment tree. We can't set the size to zero
|
||||
// because the underlying scanning function would return
|
||||
// `zcash_client_backeng::scanning::ScanError::TreeSizeUnknown`.
|
||||
let sapling_commitment_tree_size = 1;
|
||||
|
||||
let orchard_commitment_tree_size = 0;
|
||||
|
||||
let chain_metadata = ChainMetadata {
|
||||
sapling_commitment_tree_size,
|
||||
orchard_commitment_tree_size,
|
||||
};
|
||||
|
||||
let compact_block = block_to_compact(block.clone(), chain_metadata);
|
||||
|
||||
let res =
|
||||
scan_block::<SaplingIvk>(network, block, sapling_commitment_tree_size, &[]).unwrap();
|
||||
|
||||
transactions_found += res.transactions().len();
|
||||
transactions_scanned += compact_block.vtx.len();
|
||||
blocks_scanned += 1;
|
||||
|
||||
if height.is_min() {
|
||||
break;
|
||||
}
|
||||
|
||||
// scan backwards
|
||||
height = height.previous()?;
|
||||
}
|
||||
|
||||
// make sure all blocks and transactions were scanned
|
||||
assert_eq!(blocks_scanned, 11);
|
||||
assert_eq!(transactions_scanned, 11);
|
||||
|
||||
// no relevant transactions should be found
|
||||
assert_eq!(transactions_found, 0);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Prove that we can create fake blocks with fake notes and scan them using the
|
||||
/// `zcash_client_backend::scanning::scan_block` function:
|
||||
/// - Function `fake_compact_block` will generate 1 block with one pre created fake nullifier in
|
||||
|
@ -207,7 +138,7 @@ async fn scanning_zecpages_from_populated_zebra_state() -> Result<()> {
|
|||
|
||||
let compact_block = block_to_compact(block.clone(), chain_metadata);
|
||||
|
||||
let res = scan_block(network, block, sapling_commitment_tree_size, &[&ivk])
|
||||
let res = scan_block(network, block, sapling_commitment_tree_size, &ivk)
|
||||
.expect("scanning block for the ZECpages viewing key should work");
|
||||
|
||||
transactions_found += res.transactions().len();
|
||||
|
|
Loading…
Reference in New Issue