Skip to content

Commit

Permalink
poc(scanner): add a populated state test for ZECpages viewing key (#7916
Browse files Browse the repository at this point in the history
)

* get started with the blockchain scanner poc

* rustfmt

* fix the tests

* Reads blocks from db

* Adds conversion functions

* scans blocks and counts transactions

* fix bug

* split into 2 tests

* add duplicated dependencies to deny.toml

* upgrade zebra-scanner version

* try removing ecc duplicated dependencies

* try fix deny.toml

* remove unintended paste from deny.toml

* remove duplicated code from the other test

* remove strict version of `zcash_primitives` crate

* change description

* remove feture

* remove tokio features

* change lib doc

* add more documentation

* change expect

* do not use default in compact block creation

* more docs

* add more checks to test

* remove zebra-consensus dependency

* move all deps to dev-deps

* change crate version

* rename crate to zebra-scan

* lock file

* add test for zecpages populated state

* scans all cached blocks for zecpages viewing key expecting Ok results.

* use test blocks

* fixes test

* fix expect messages

* Discard changes to Cargo.lock

* Discard changes to deny.toml

---------

Co-authored-by: arya2 <[email protected]>
Co-authored-by: teor <[email protected]>
  • Loading branch information
3 people authored Nov 8, 2023
1 parent 2fad357 commit e5e89ec
Showing 1 changed file with 116 additions and 1 deletion.
117 changes: 116 additions & 1 deletion zebra-scan/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use std::sync::Arc;

use zcash_client_backend::{
data_api::BlockMetadata,
encoding::decode_extended_full_viewing_key,
proto::compact_formats::{
self as compact, ChainMetadata, CompactBlock, CompactSaplingOutput, CompactSaplingSpend,
CompactTx,
Expand All @@ -16,7 +18,7 @@ use zcash_note_encryption::Domain;
use zcash_primitives::{
block::BlockHash,
consensus::{BlockHeight, Network},
constants::SPENDING_KEY_GENERATOR,
constants::{mainnet::HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, SPENDING_KEY_GENERATOR},
memo::MemoBytes,
sapling::{
note_encryption::{sapling_note_encryption, SaplingDomain},
Expand Down Expand Up @@ -168,6 +170,119 @@ async fn scanning_from_fake_generated_blocks() -> Result<()> {
Ok(())
}

/// Scan a populated state for the ZECpages viewing key.
/// This test is very similar to `scanning_from_populated_zebra_state` but with the ZECpages key.
/// There are no zechub transactions in the test data so we should get empty related transactions.
#[tokio::test]
async fn scanning_zecpages_from_populated_zebra_state() -> Result<()> {
/// The extended Sapling viewing key of [ZECpages](https://zecpages.com/boardinfo)
const ZECPAGES_VIEWING_KEY: &str = "zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz";

// Parse the key from ZECpages
let efvk = decode_extended_full_viewing_key(
HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
ZECPAGES_VIEWING_KEY,
)
.unwrap();

let account = AccountId::from(1);

// Build a vector of viewing keys `vks` to scan for.
let fvk = efvk.fvk;
let ivk = fvk.vk.ivk();
let vks: Vec<(&AccountId, &SaplingIvk)> = vec![(&account, &ivk)];

let network = zebra_chain::parameters::Network::Mainnet;

// 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;
while let Some(block) = db.block(height.into()) {
// zcash_client_backend doesn't support scanning the genesis block, but that's ok, because
// Sapling activates at height 419,200. So we'll never scan these blocks in production code.
let sapling_tree_size = if height.is_min() {
1
} else {
db.sapling_tree_by_hash_or_height(height.into())
.expect("each state block must have a sapling tree")
.count()
};

let orchard_tree_size = db
.orchard_tree_by_hash_or_height(height.into())
.expect("each state block must have a orchard tree")
.count();

let chain_metadata = ChainMetadata {
sapling_commitment_tree_size: sapling_tree_size
.try_into()
.expect("sapling position is limited to u32::MAX"),
orchard_commitment_tree_size: orchard_tree_size
.try_into()
.expect("orchard position is limited to u32::MAX"),
};

let block_metadata = if height.is_min() {
None
} else {
Some(BlockMetadata::from_parts(
height.previous()?.0.into(),
BlockHash(block.header.previous_block_hash.0),
db.sapling_tree_by_hash_or_height(block.header.previous_block_hash.into())
.expect("each state block must have a sapling tree")
.count()
.try_into()
.expect("sapling position is limited to u32::MAX"),
))
};

let compact_block = block_to_compact(block, chain_metadata);

let res = scan_block(
&zcash_primitives::consensus::MainNetwork,
compact_block.clone(),
&vks[..],
&[],
block_metadata.as_ref(),
)
.expect("scanning block for the ZECpages viewing key should work");

transactions_found += res.transactions().len();
transactions_scanned += compact_block.vtx.len();
blocks_scanned += 1;

// scan backwards
if height.is_min() {
break;
}
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(())
}

/// Convert a zebra block and meta data into a compact block.
fn block_to_compact(block: Arc<Block>, chain_metadata: ChainMetadata) -> CompactBlock {
CompactBlock {
Expand Down

0 comments on commit e5e89ec

Please sign in to comment.