From d3dc7d0f0ef91fe2c6dbae4b0cf284070cabb3a8 Mon Sep 17 00:00:00 2001 From: Marek Date: Tue, 5 Dec 2023 23:49:39 +0100 Subject: [PATCH] change(scan): Store scanned TXIDs in "display order" (#8057) * Store scanned TXIDs in "display order" * Unrelated: Remove a redundant `Arc` --------- Co-authored-by: teor --- zebra-scan/src/scan.rs | 14 +++----- zebra-scan/src/tests.rs | 20 +++++------ .../finalized_state/disk_format/scan.rs | 34 +++++++++++++++++-- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/zebra-scan/src/scan.rs b/zebra-scan/src/scan.rs index 907036933fa..f951c9f91e4 100644 --- a/zebra-scan/src/scan.rs +++ b/zebra-scan/src/scan.rs @@ -22,12 +22,8 @@ use zcash_primitives::{ }; use zebra_chain::{ - block::Block, - chain_tip::ChainTip, - diagnostic::task::WaitForPanics, - parameters::Network, - serialization::ZcashSerialize, - transaction::{self, Transaction}, + block::Block, chain_tip::ChainTip, diagnostic::task::WaitForPanics, parameters::Network, + serialization::ZcashSerialize, transaction::Transaction, }; use zebra_state::{ChainTipChange, SaplingScannedResult}; @@ -191,7 +187,7 @@ pub async fn start( /// - Add prior block metadata once we have access to Zebra's state. pub fn scan_block( network: Network, - block: &Arc, + block: &Block, sapling_tree_size: u32, scanning_keys: &[K], ) -> Result, ScanError> { @@ -255,7 +251,7 @@ pub fn sapling_key_to_scan_block_keys( } /// Converts a zebra block and meta data into a compact block. -pub fn block_to_compact(block: &Arc, chain_metadata: ChainMetadata) -> CompactBlock { +pub fn block_to_compact(block: &Block, chain_metadata: ChainMetadata) -> CompactBlock { CompactBlock { height: block .coinbase_height() @@ -344,6 +340,6 @@ fn scanned_block_to_db_result(scanned_block: ScannedBlock) -> Vec Result<()> { Some(0), ); - // Scan with our key - let res = zcash_client_backend::scanning::scan_block( + let result = zcash_client_backend::scanning::scan_block( &zcash_primitives::consensus::MainNetwork, cb.clone(), &vks[..], @@ -221,21 +220,18 @@ fn scanning_fake_blocks_store_key_and_results() -> Result<()> { ) .unwrap(); - // Get transaction hash - let found_transaction = res.transactions()[0].txid.as_ref(); - let found_transaction_hash = Hash::from_bytes_in_display_order(found_transaction); + // The response should have one transaction relevant to the key we provided. + assert_eq!(result.transactions().len(), 1); + + let result = SaplingScannedResult::from(result.transactions()[0].txid.as_ref()); // Add result to database - s.add_sapling_result( - key_to_be_stored.clone(), - Height(1), - vec![found_transaction_hash], - ); + s.add_sapling_result(key_to_be_stored.clone(), Height(1), vec![result]); // Check the result was added assert_eq!( s.sapling_results(&key_to_be_stored).get(&Height(1)), - Some(&vec![found_transaction_hash]) + Some(&vec![result]) ); Ok(()) diff --git a/zebra-state/src/service/finalized_state/disk_format/scan.rs b/zebra-state/src/service/finalized_state/disk_format/scan.rs index 2a866b69164..479cce771f0 100644 --- a/zebra-state/src/service/finalized_state/disk_format/scan.rs +++ b/zebra-state/src/service/finalized_state/disk_format/scan.rs @@ -26,8 +26,24 @@ pub const SAPLING_SCANNING_RESULT_LENGTH: usize = 32; /// It can represent a full viewing key or an individual viewing key. pub type SaplingScanningKey = String; -/// The type used in Zebra to store Sapling scanning results. -pub type SaplingScannedResult = transaction::Hash; +/// Stores a scanning result. +/// +/// Currently contains a TXID in "display order", which is big-endian byte order following the u256 +/// convention set by Bitcoin and zcashd. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct SaplingScannedResult([u8; 32]); + +impl From for transaction::Hash { + fn from(scanned_result: SaplingScannedResult) -> Self { + transaction::Hash::from_bytes_in_display_order(&scanned_result.0) + } +} + +impl From<&[u8; 32]> for SaplingScannedResult { + fn from(bytes: &[u8; 32]) -> Self { + Self(*bytes) + } +} /// A database column family entry for a block scanned with a Sapling vieweing key. #[derive(Clone, Debug, Eq, PartialEq)] @@ -123,6 +139,20 @@ impl FromDisk for SaplingScannedDatabaseIndex { } } +impl IntoDisk for SaplingScannedResult { + type Bytes = [u8; 32]; + + fn as_bytes(&self) -> Self::Bytes { + self.0 + } +} + +impl FromDisk for SaplingScannedResult { + fn from_bytes(bytes: impl AsRef<[u8]>) -> Self { + SaplingScannedResult(bytes.as_ref().try_into().unwrap()) + } +} + impl IntoDisk for Vec { type Bytes = Vec;