change(scan): Store scanned TXIDs in "display order" (#8057)

* Store scanned TXIDs in "display order"

* Unrelated: Remove a redundant `Arc`

---------

Co-authored-by: teor <teor@riseup.net>
This commit is contained in:
Marek 2023-12-05 23:49:39 +01:00 committed by GitHub
parent ba58d637d9
commit d3dc7d0f0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 23 deletions

View File

@ -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<K: ScanningKey>(
network: Network,
block: &Arc<Block>,
block: &Block,
sapling_tree_size: u32,
scanning_keys: &[K],
) -> Result<ScannedBlock<K::Nf>, 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<Block>, 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<Nf>(scanned_block: ScannedBlock<Nf>) -> Vec<Saplin
scanned_block
.transactions()
.iter()
.map(|tx| transaction::Hash::from_bytes_in_display_order(tx.txid.as_ref()))
.map(|tx| SaplingScannedResult::from(tx.txid.as_ref()))
.collect()
}

View File

@ -36,8 +36,8 @@ use zebra_chain::{
chain_tip::ChainTip,
parameters::Network,
serialization::ZcashDeserializeInto,
transaction::Hash,
};
use zebra_state::SaplingScannedResult;
use crate::{
config::Config,
@ -211,8 +211,7 @@ fn scanning_fake_blocks_store_key_and_results() -> 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(())

View File

@ -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<SaplingScannedResult> 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<SaplingScannedResult> {
type Bytes = Vec<u8>;