Factor out `get_commitment_tree` from scan.
This commit is contained in:
parent
d16c74725e
commit
56e6091876
|
@ -1,9 +1,9 @@
|
|||
use zcash_primitives::{
|
||||
block::BlockHash,
|
||||
consensus::{self, BlockHeight},
|
||||
merkle_tree::CommitmentTree,
|
||||
primitives::PaymentAddress,
|
||||
//merkle_tree::{CommitmentTree, IncrementalWitness},
|
||||
//sapling::Node,
|
||||
sapling::Node,
|
||||
transaction::components::Amount,
|
||||
zip32::ExtendedFullViewingKey,
|
||||
};
|
||||
|
@ -66,8 +66,11 @@ pub trait DBOps {
|
|||
params: &P,
|
||||
) -> Result<Vec<ExtendedFullViewingKey>, Self::Error>;
|
||||
|
||||
// fn get_commitment_tree(block_height: BlockHeight) -> Result<Option<CommitmentTree<Node>>, Self::Error>;
|
||||
//
|
||||
fn get_commitment_tree(
|
||||
&self,
|
||||
block_height: BlockHeight,
|
||||
) -> Result<Option<CommitmentTree<Node>>, Self::Error>;
|
||||
|
||||
// fn get_witnesses(block_height: BlockHeight) -> Result<Box<dyn Iterator<Item = IncrementalWitness<Node>>>, Self::Error>;
|
||||
//
|
||||
// fn get_nullifiers() -> Result<(Vec<u8>, Account), Self::Error>;
|
||||
|
|
|
@ -30,7 +30,9 @@ use std::path::Path;
|
|||
use zcash_primitives::{
|
||||
block::BlockHash,
|
||||
consensus::{self, BlockHeight},
|
||||
merkle_tree::CommitmentTree,
|
||||
primitives::PaymentAddress,
|
||||
sapling::Node,
|
||||
transaction::components::Amount,
|
||||
zip32::ExtendedFullViewingKey,
|
||||
};
|
||||
|
@ -133,6 +135,13 @@ impl DBOps for DataConnection {
|
|||
) -> Result<Vec<ExtendedFullViewingKey>, Self::Error> {
|
||||
query::get_extended_full_viewing_keys(self, params)
|
||||
}
|
||||
|
||||
fn get_commitment_tree(
|
||||
&self,
|
||||
block_height: BlockHeight,
|
||||
) -> Result<Option<CommitmentTree<Node>>, Self::Error> {
|
||||
query::get_commitment_tree(self, block_height)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CacheConnection(Connection);
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
//! Functions for querying information in the data database.
|
||||
|
||||
use rusqlite::NO_PARAMS;
|
||||
use rusqlite::{OptionalExtension, NO_PARAMS};
|
||||
|
||||
use zcash_primitives::{
|
||||
consensus::{self},
|
||||
consensus::{self, BlockHeight},
|
||||
merkle_tree::CommitmentTree,
|
||||
note_encryption::Memo,
|
||||
primitives::PaymentAddress,
|
||||
sapling::Node,
|
||||
transaction::components::Amount,
|
||||
zip32::ExtendedFullViewingKey,
|
||||
};
|
||||
|
@ -236,6 +238,29 @@ pub fn get_extended_full_viewing_keys<P: consensus::Parameters>(
|
|||
rows.collect::<Result<Result<_, _>, _>>()?
|
||||
}
|
||||
|
||||
pub fn get_commitment_tree(
|
||||
data: &DataConnection,
|
||||
block_height: BlockHeight,
|
||||
) -> Result<Option<CommitmentTree<Node>>, SqliteClientError> {
|
||||
data.0
|
||||
.query_row_and_then(
|
||||
"SELECT sapling_tree FROM blocks WHERE height = ?",
|
||||
&[u32::from(block_height)],
|
||||
|row| {
|
||||
let row_data: Vec<u8> = row.get(0)?;
|
||||
CommitmentTree::read(&row_data[..]).map_err(|e| {
|
||||
rusqlite::Error::FromSqlConversionFailure(
|
||||
row_data.len(),
|
||||
rusqlite::types::Type::Blob,
|
||||
Box::new(e),
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
.optional()
|
||||
.map_err(SqliteClientError::from)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rusqlite::Connection;
|
||||
|
|
|
@ -7,7 +7,10 @@ use rusqlite::{types::ToSql, OptionalExtension, NO_PARAMS};
|
|||
|
||||
use zcash_client_backend::{
|
||||
address::RecipientAddress,
|
||||
data_api::error::{ChainInvalid, Error},
|
||||
data_api::{
|
||||
error::{ChainInvalid, Error},
|
||||
DBOps,
|
||||
},
|
||||
decrypt_transaction,
|
||||
encoding::decode_extended_full_viewing_key,
|
||||
proto::compact_formats::CompactBlock,
|
||||
|
@ -88,56 +91,18 @@ pub fn scan_cached_blocks<P: consensus::Parameters>(
|
|||
|
||||
// Recall where we synced up to previously.
|
||||
// If we have never synced, use sapling activation height to select all cached CompactBlocks.
|
||||
let mut last_height: BlockHeight =
|
||||
data.0
|
||||
.query_row("SELECT MAX(height) FROM blocks", NO_PARAMS, |row| {
|
||||
row.get::<_, u32>(0)
|
||||
.map(BlockHeight::from)
|
||||
.or(Ok(sapling_activation_height - 1))
|
||||
})?;
|
||||
|
||||
// Fetch the CompactBlocks we need to scan
|
||||
let mut stmt_blocks = cache.0.prepare(
|
||||
"SELECT height, data FROM compactblocks WHERE height > ? ORDER BY height ASC LIMIT ?",
|
||||
)?;
|
||||
let rows = stmt_blocks.query_map(
|
||||
&[u32::from(last_height), limit.unwrap_or(u32::max_value())],
|
||||
|row| {
|
||||
Ok(CompactBlockRow {
|
||||
height: row.get::<_, u32>(0).map(BlockHeight::from)?,
|
||||
data: row.get(1)?,
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
// Fetch the ExtendedFullViewingKeys we are tracking
|
||||
let mut stmt_fetch_accounts = data
|
||||
.0
|
||||
.prepare("SELECT extfvk FROM accounts ORDER BY account ASC")?;
|
||||
let extfvks = stmt_fetch_accounts.query_map(NO_PARAMS, |row| {
|
||||
row.get(0).map(|extfvk: String| {
|
||||
decode_extended_full_viewing_key(
|
||||
params.hrp_sapling_extended_full_viewing_key(),
|
||||
&extfvk,
|
||||
)
|
||||
})
|
||||
let mut last_height = data.block_height_extrema().map(|opt| {
|
||||
opt.map(|(_, max)| max)
|
||||
.unwrap_or(sapling_activation_height - 1)
|
||||
})?;
|
||||
|
||||
// Raise SQL errors from the query, IO errors from parsing, and incorrect HRP errors.
|
||||
let extfvks: Vec<_> = extfvks
|
||||
.collect::<Result<Result<Option<_>, _>, _>>()??
|
||||
.ok_or(Error::IncorrectHRPExtFVK)?;
|
||||
let extfvks = data.get_extended_full_viewing_keys(params)?;
|
||||
|
||||
// Get the most recent CommitmentTree
|
||||
let mut stmt_fetch_tree = data
|
||||
.0
|
||||
.prepare("SELECT sapling_tree FROM blocks WHERE height = ?")?;
|
||||
let mut tree = stmt_fetch_tree
|
||||
.query_row(&[u32::from(last_height)], |row| {
|
||||
row.get(0).map(|data: Vec<_>| {
|
||||
CommitmentTree::read(&data[..]).unwrap_or_else(|_| CommitmentTree::new())
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|_| CommitmentTree::new());
|
||||
let mut tree = data
|
||||
.get_commitment_tree(last_height)
|
||||
.map(|t| t.unwrap_or(CommitmentTree::new()))?;
|
||||
|
||||
// Get most recent incremental witnesses for the notes we are tracking
|
||||
let mut stmt_fetch_witnesses = data
|
||||
|
@ -206,6 +171,23 @@ pub fn scan_cached_blocks<P: consensus::Parameters>(
|
|||
)",
|
||||
)?;
|
||||
|
||||
// Fetch the CompactBlocks we need to scan
|
||||
let mut stmt_blocks = cache.0.prepare(
|
||||
"SELECT height, data FROM compactblocks WHERE height > ? ORDER BY height ASC LIMIT ?",
|
||||
)?;
|
||||
let rows = stmt_blocks.query_map(
|
||||
&[
|
||||
u32::from(last_height).to_sql()?,
|
||||
limit.unwrap_or(u32::max_value()).to_sql()?,
|
||||
],
|
||||
|row| {
|
||||
Ok(CompactBlockRow {
|
||||
height: BlockHeight::from_u32(row.get(0)?),
|
||||
data: row.get(1)?,
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
for row in rows {
|
||||
let row = row?;
|
||||
|
||||
|
|
Loading…
Reference in New Issue