Skip to content

Commit

Permalink
Merge pull request #363 from nuttycom/doc/zcash_client_sqlite
Browse files Browse the repository at this point in the history
Add docstrings for zcash_client_sqlite.
  • Loading branch information
str4d authored Mar 26, 2021
2 parents a80fd59 + 78f6432 commit 60ffeb7
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 8 deletions.
6 changes: 6 additions & 0 deletions zcash_client_sqlite/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ struct CompactBlockRow {
data: Vec<u8>,
}

/// Implements a traversal of `limit` blocks of the block cache database.
///
/// Starting at `from_height`, the `with_row` callback is invoked
/// with each block retrieved from the backing store. If the `limit`
/// value provided is `None`, all blocks are traversed up to the
/// maximum height.
pub fn with_blocks<F>(
cache: &BlockDB,
from_height: BlockHeight,
Expand Down
3 changes: 3 additions & 0 deletions zcash_client_sqlite/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
//! Error types for problems that may arise when reading or storing wallet data to SQLite.
use std::error;
use std::fmt;

use zcash_client_backend::data_api;

use crate::NoteId;

/// The primary error type for the SQLite wallet backend.
#[derive(Debug)]
pub enum SqliteClientError {
/// Decoding of a stored value from its serialized form has failed.
Expand Down
20 changes: 17 additions & 3 deletions zcash_client_sqlite/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! *An SQLite-based Zcash light client.*
//!
//! `zcash_client_backend` contains a set of APIs that collectively implement an
//! SQLite-based light client for the Zcash network.
//! `zcash_client_sqlite` contains complete SQLite-based implementations of the [`WalletRead`],
//! [`WalletWrite`], and [`BlockSource`] traits from the [`zcash_client_backend`] crate. In
//! combination with [`zcash_client_backend`], it provides a full implementation of a SQLite-backed
//! client for the Zcash network.
//!
//! # Design
//!
Expand All @@ -21,6 +23,9 @@
//! The `mainnet` feature configures the light client for use with the Zcash mainnet. By
//! default, the light client is configured for use with the Zcash testnet.
//!
//! [`WalletRead`]: zcash_client_backend::data_api::WalletRead
//! [`WalletWrite`]: zcash_client_backend::data_api::WalletWrite
//! [`BlockSource`]: zcash_client_backend::data_api::BlockSource
//! [`CompactBlock`]: zcash_client_backend::proto::compact_formats::CompactBlock
//! [`init_cache_database`]: crate::chain::init::init_cache_database
Expand Down Expand Up @@ -73,7 +78,7 @@ impl fmt::Display for NoteId {
}
}

/// A wrapper for the sqlite connection to the wallet database.
/// A wrapper for the SQLite connection to the wallet database.
pub struct WalletDB<P> {
conn: Connection,
params: P,
Expand Down Expand Up @@ -250,6 +255,13 @@ impl<P: consensus::Parameters> WalletRead for WalletDB<P> {
}
}

/// The primary type used to implement [`WalletWrite`] for the SQLite database.
///
/// A data structure that stores the SQLite prepared statements that are
/// required for the implementation of [`WalletWrite`] against the backing
/// store.
///
/// [`WalletWrite`]: zcash_client_backend::data_api::WalletWrite
pub struct DataConnStmtCache<'a, P> {
wallet_db: &'a WalletDB<P>,
stmt_insert_block: Statement<'a>,
Expand Down Expand Up @@ -499,9 +511,11 @@ impl<'a, P: consensus::Parameters> WalletWrite for DataConnStmtCache<'a, P> {
}
}

/// A wrapper for the SQLite connection to the block cache database.
pub struct BlockDB(Connection);

impl BlockDB {
/// Opens a connection to the wallet database stored at the specified path.
pub fn for_path<P: AsRef<Path>>(path: P) -> Result<Self, rusqlite::Error> {
Connection::open(path).map(BlockDB)
}
Expand Down
121 changes: 116 additions & 5 deletions zcash_client_sqlite/src/wallet.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
//! Functions for querying information in the wdb database.
//!
//! These functions should generally not be used directly; instead,
//! their functionality is available via the [`WalletRead`] and
//! [`WalletWrite`] traits.
//!
//! [`WalletRead`]: zcash_client_backend::data_api::WalletRead
//! [`WalletWrite`]: zcash_client_backend::data_api::WalletWrite
use ff::PrimeField;
use rusqlite::{params, OptionalExtension, ToSql, NO_PARAMS};
Expand Down Expand Up @@ -32,11 +39,7 @@ use crate::{error::SqliteClientError, DataConnStmtCache, NoteId, WalletDB};
pub mod init;
pub mod transact;

/// This trait provides a generalization over shielded output representations
/// that allows a wallet to avoid coupling to a specific one.
// TODO: it'd probably be better not to unify the definitions of
// `WalletShieldedOutput` and `DecryptedOutput` via a compositional
// approach, if possible.
/// This trait provides a generalization over shielded output representations.
pub trait ShieldedOutput {
fn index(&self) -> usize;
fn account(&self) -> AccountId;
Expand Down Expand Up @@ -130,6 +133,9 @@ pub fn get_address<P: consensus::Parameters>(
.map_err(SqliteClientError::Bech32)
}

/// Returns the [`ExtendedFullViewingKey`]s for the wallet.
///
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
pub fn get_extended_full_viewing_keys<P: consensus::Parameters>(
wdb: &WalletDB<P>,
) -> Result<HashMap<AccountId, ExtendedFullViewingKey>, SqliteClientError> {
Expand Down Expand Up @@ -163,6 +169,10 @@ pub fn get_extended_full_viewing_keys<P: consensus::Parameters>(
Ok(res)
}

/// Checks whether the specified [`ExtendedFullViewingKey`] is valid and corresponds to the
/// specified account.
///
/// [`ExtendedFullViewingKey`]: zcash_primitives::zip32::ExtendedFullViewingKey
pub fn is_valid_account_extfvk<P: consensus::Parameters>(
wdb: &WalletDB<P>,
account: AccountId,
Expand Down Expand Up @@ -327,6 +337,22 @@ pub fn get_sent_memo<P>(wdb: &WalletDB<P>, id_note: i64) -> Result<Memo, SqliteC
.map_err(SqliteClientError::from)
}

/// Returns the minimum and maximum heights for blocks stored in the wallet database.
///
/// # Examples
///
/// ```
/// use tempfile::NamedTempFile;
/// use zcash_primitives::consensus::Network;
/// use zcash_client_sqlite::{
/// WalletDB,
/// wallet::block_height_extrema,
/// };
///
/// let data_file = NamedTempFile::new().unwrap();
/// let db = WalletDB::for_path(data_file, Network::TestNetwork).unwrap();
/// let bounds = block_height_extrema(&db);
/// ```
pub fn block_height_extrema<P>(
wdb: &WalletDB<P>,
) -> Result<Option<(BlockHeight, BlockHeight)>, rusqlite::Error> {
Expand All @@ -348,6 +374,24 @@ pub fn block_height_extrema<P>(
.or(Ok(None))
}

/// Returns the block height at which the specified transaction was mined,
/// if any.
///
/// # Examples
///
/// ```
/// use tempfile::NamedTempFile;
/// use zcash_primitives::consensus::Network;
/// use zcash_primitives::transaction::TxId;
/// use zcash_client_sqlite::{
/// WalletDB,
/// wallet::get_tx_height,
/// };
///
/// let data_file = NamedTempFile::new().unwrap();
/// let db = WalletDB::for_path(data_file, Network::TestNetwork).unwrap();
/// let height = get_tx_height(&db, TxId([0u8; 32]));
/// ```
pub fn get_tx_height<P>(
wdb: &WalletDB<P>,
txid: TxId,
Expand All @@ -361,6 +405,23 @@ pub fn get_tx_height<P>(
.optional()
}

/// Returns the block hash for the block at the specified height,
/// if any.
///
/// # Examples
///
/// ```
/// use tempfile::NamedTempFile;
/// use zcash_primitives::consensus::{H0, Network};
/// use zcash_client_sqlite::{
/// WalletDB,
/// wallet::get_block_hash,
/// };
///
/// let data_file = NamedTempFile::new().unwrap();
/// let db = WalletDB::for_path(data_file, Network::TestNetwork).unwrap();
/// let hash = get_block_hash(&db, H0);
/// ```
pub fn get_block_hash<P>(
wdb: &WalletDB<P>,
block_height: BlockHeight,
Expand Down Expand Up @@ -427,6 +488,23 @@ pub fn rewind_to_height<P: consensus::Parameters>(
}
}

/// Returns the commitment tree for the block at the specified height,
/// if any.
///
/// # Examples
///
/// ```
/// use tempfile::NamedTempFile;
/// use zcash_primitives::consensus::{Network, H0};
/// use zcash_client_sqlite::{
/// WalletDB,
/// wallet::get_commitment_tree,
/// };
///
/// let data_file = NamedTempFile::new().unwrap();
/// let db = WalletDB::for_path(data_file, Network::TestNetwork).unwrap();
/// let tree = get_commitment_tree(&db, H0);
/// ```
pub fn get_commitment_tree<P>(
wdb: &WalletDB<P>,
block_height: BlockHeight,
Expand All @@ -450,6 +528,23 @@ pub fn get_commitment_tree<P>(
.map_err(SqliteClientError::from)
}

/// Returns the incremental witnesses for the block at the specified height,
/// if any.
///
/// # Examples
///
/// ```
/// use tempfile::NamedTempFile;
/// use zcash_primitives::consensus::{Network, H0};
/// use zcash_client_sqlite::{
/// WalletDB,
/// wallet::get_witnesses,
/// };
///
/// let data_file = NamedTempFile::new().unwrap();
/// let db = WalletDB::for_path(data_file, Network::TestNetwork).unwrap();
/// let witnesses = get_witnesses(&db, H0);
/// ```
pub fn get_witnesses<P>(
wdb: &WalletDB<P>,
block_height: BlockHeight,
Expand Down Expand Up @@ -494,6 +589,7 @@ pub fn get_nullifiers<P>(
Ok(res)
}

/// Inserts information about a scanned block into the database.
pub fn insert_block<'a, P>(
stmts: &mut DataConnStmtCache<'a, P>,
block_height: BlockHeight,
Expand All @@ -514,6 +610,8 @@ pub fn insert_block<'a, P>(
Ok(())
}

/// Inserts information about a mined transaction that was observed to
/// contain a note related to this wallet into the database.
pub fn put_tx_meta<'a, P, N>(
stmts: &mut DataConnStmtCache<'a, P>,
tx: &WalletTx<N>,
Expand All @@ -540,6 +638,7 @@ pub fn put_tx_meta<'a, P, N>(
}
}

/// Inserts full transaction data into the database.
pub fn put_tx_data<'a, P>(
stmts: &mut DataConnStmtCache<'a, P>,
tx: &Transaction,
Expand Down Expand Up @@ -573,6 +672,11 @@ pub fn put_tx_data<'a, P>(
}
}

/// Marks a given nullifier as having been revealed in the construction
/// of the specified transaction.
///
/// Marking a note spent in this fashion does NOT imply that the
/// spending transaction has been mined.
pub fn mark_spent<'a, P>(
stmts: &mut DataConnStmtCache<'a, P>,
tx_ref: i64,
Expand All @@ -584,6 +688,7 @@ pub fn mark_spent<'a, P>(
Ok(())
}

/// Records the specified shielded output as having been received.
// Assumptions:
// - A transaction will not contain more than 2^63 shielded outputs.
// - A note value will never exceed 2^63 zatoshis.
Expand Down Expand Up @@ -634,6 +739,8 @@ pub fn put_received_note<'a, P, T: ShieldedOutput>(
}
}

/// Records the incremental witness for the specified note,
/// as of the given block height.
pub fn insert_witness<'a, P>(
stmts: &mut DataConnStmtCache<'a, P>,
note_id: i64,
Expand All @@ -650,6 +757,7 @@ pub fn insert_witness<'a, P>(
Ok(())
}

/// Removes old incremental witnesses up to the given block height.
pub fn prune_witnesses<'a, P>(
stmts: &mut DataConnStmtCache<'a, P>,
below_height: BlockHeight,
Expand All @@ -660,6 +768,8 @@ pub fn prune_witnesses<'a, P>(
Ok(())
}

/// Marks notes that have not been mined in transactions
/// as expired, up to the given block height.
pub fn update_expired_notes<'a, P>(
stmts: &mut DataConnStmtCache<'a, P>,
height: BlockHeight,
Expand All @@ -668,6 +778,7 @@ pub fn update_expired_notes<'a, P>(
Ok(())
}

/// Records information about a note that your wallet created.
pub fn put_sent_note<'a, P: consensus::Parameters>(
stmts: &mut DataConnStmtCache<'a, P>,
output: &DecryptedOutput,
Expand Down

0 comments on commit 60ffeb7

Please sign in to comment.