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:
|
/// TODO:
|
||||||
/// - Remove the `sapling_tree_size` parameter or turn it into an `Option` once we have access to
|
/// - 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,
|
network: Network,
|
||||||
block: Arc<Block>,
|
block: Arc<Block>,
|
||||||
sapling_tree_size: u32,
|
sapling_tree_size: u32,
|
||||||
scanning_keys: &[&K],
|
scanning_key: &K,
|
||||||
) -> Result<ScannedBlock<K::Nf>, ScanError> {
|
) -> Result<ScannedBlock<K::Nf>, ScanError> {
|
||||||
// TODO: Implement a check that returns early when the block height is below the Sapling
|
// TODO: Implement a check that returns early when the block height is below the Sapling
|
||||||
// activation height.
|
// activation height.
|
||||||
|
@ -96,10 +96,8 @@ pub fn scan_block<K: ScanningKey>(
|
||||||
// Use a dummy `AccountId` as we don't use accounts yet.
|
// Use a dummy `AccountId` as we don't use accounts yet.
|
||||||
let dummy_account = AccountId::from(0);
|
let dummy_account = AccountId::from(0);
|
||||||
|
|
||||||
let scanning_keys: Vec<_> = scanning_keys
|
// We only support scanning one key and one block per function call for now.
|
||||||
.iter()
|
let scanning_keys = vec![(&dummy_account, scanning_key)];
|
||||||
.map(|key| (&dummy_account, key))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
zcash_client_backend::scanning::scan_block(
|
zcash_client_backend::scanning::scan_block(
|
||||||
&network,
|
&network,
|
||||||
|
|
|
@ -32,80 +32,11 @@ use zcash_primitives::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use zebra_chain::{
|
use zebra_chain::{
|
||||||
block::Block, chain_tip::ChainTip, parameters::Network, serialization::ZcashDeserializeInto,
|
block::Block, chain_tip::ChainTip, serialization::ZcashDeserializeInto, transaction::Hash,
|
||||||
transaction::Hash,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::scan::{block_to_compact, scan_block};
|
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
|
/// Prove that we can create fake blocks with fake notes and scan them using the
|
||||||
/// `zcash_client_backend::scanning::scan_block` function:
|
/// `zcash_client_backend::scanning::scan_block` function:
|
||||||
/// - Function `fake_compact_block` will generate 1 block with one pre created fake nullifier in
|
/// - 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 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");
|
.expect("scanning block for the ZECpages viewing key should work");
|
||||||
|
|
||||||
transactions_found += res.transactions().len();
|
transactions_found += res.transactions().len();
|
||||||
|
|
Loading…
Reference in New Issue