Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrations & data storage for pre-DAG-sync #831

Merged
merged 27 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
32e2991
zcash_client_backend: Add note commitment tree sizes to `CompactBlock…
nuttycom Apr 3, 2023
3e358bc
zcash_client_backend: Use `shardtree` for note commitments in block s…
nuttycom Apr 3, 2023
ed2e22b
zcash_client_sqlite: Add shard serialization & parsing
nuttycom May 25, 2023
9f2bb94
zcash_client_sqlite: Add shard persistence to wallet migration.
nuttycom Apr 3, 2023
ade882d
zcash_client_sqlite: Add shard & checkpoint insertion.
nuttycom Jun 2, 2023
d11f3d2
zcash_client_sqlite: Add shardtree truncation & checkpoint operations.
nuttycom Jun 13, 2023
c42cffe
zcash_client_backend: Replace `WalletWrite::advance_by_block` with `W…
nuttycom Jun 14, 2023
425b5e0
zcash_client_sqlite: Support shardtree checkpoint functionality
nuttycom Jun 14, 2023
0a4236f
zcash_client_sqlite: Add tests for sqlite-backed ShardTree & fix reve…
nuttycom Jun 15, 2023
106669d
zcash_client_sqlite: Generalize SQLite-backed ShardStore impl to make…
nuttycom Jun 16, 2023
547634e
zcash_client_sqlite: Move the SqliteShardStore implementation out of …
nuttycom Jun 16, 2023
ba70917
Reorganize Sapling and Orchard note commitment tree sizes in CompactB…
nuttycom Jun 29, 2023
d65b129
Apply changelog, documentation & style suggestions from code review
nuttycom Jun 29, 2023
8fa3a08
Fix indexing error in checkpoint determination.
nuttycom Jun 30, 2023
c05b3d0
Add a test demonstrating off-by-one error in `scan_block_with_runner`
nuttycom Jun 30, 2023
45177a5
Fix off-by-one error in scan_block_with_runner.
nuttycom Jun 30, 2023
95745dd
Use ruqlite::Rows::mapped to allow `collect`
nuttycom Jun 30, 2023
cd939f9
Ensure that checkpoints are ordered by position when querying for pru…
nuttycom Jun 30, 2023
70497a2
Only store z->t transaction data once, not once per Sapling output.
nuttycom Jun 30, 2023
8625e9a
Handle parsing of the not-present `CommitmentTree` sentinel.
nuttycom Jun 30, 2023
e225a54
Use `NonZeroU32` for all `min_confirmations` values.
nuttycom Jun 30, 2023
77b6380
Remove `zcash_client_backend::data_api::chain::validate_chain`
nuttycom Jul 1, 2023
e3aafda
Move chain continuity checks into `scan_block_with_runner`
nuttycom Jul 2, 2023
09a0096
Use valid serialized CommitmentTree values for migration tests.
nuttycom Jul 2, 2023
42ed6ba
Rename `zcash_client_backend::welding_rig` to `zcash_client_backend::…
nuttycom Jul 2, 2023
c363e71
Rename proto::compact::{BlockMetadata => ChainMetadata}
nuttycom Jul 3, 2023
c13c8c6
Address comments from code review.
nuttycom Jul 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions zcash_client_backend/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ and this library adheres to Rust's notion of
- `impl Eq for zcash_client_backend::zip321::{Payment, TransactionRequest}`
- `impl Debug` for `zcash_client_backend::{data_api::wallet::input_selection::Proposal, wallet::ReceivedSaplingNote}`
- `zcash_client_backend::data_api`:
- `WalletRead::{fully_scanned_height, suggest_scan_ranges}`
- `WalletRead::{block_metadata, block_fully_scanned, suggest_scan_ranges}`
- `WalletWrite::put_block`
- `WalletCommitmentTrees`
- `testing::MockWalletDb::new`
- `NullifierQuery` for use with `WalletRead::get_sapling_nullifiers`
- `BlockMetadata`
- `ScannedBlock`
- `wallet::input_sellection::Proposal::{min_target_height, min_anchor_height}`:
- `zcash_client_backend::wallet::WalletSaplingOutput::note_commitment_tree_position`
- `zcash_client_backend::welding_rig::SyncError`
- `zcash_client_backend::welding_rig::ScanError`

### Changed
- MSRV is now 1.65.0.
Expand Down Expand Up @@ -56,27 +58,28 @@ and this library adheres to Rust's notion of
- `zcash_client_backend::welding_rig::ScanningKey::sapling_nf` has been changed to
take a note position instead of an incremental witness for the note.
- Arguments to `zcash_client_backend::welding_rig::scan_block` have changed. This
method now takes an optional `CommitmentTreeMeta` argument instead of a base commitment
tree and incremental witnesses for each previously-known note.
method now takes an optional `BlockMetadata` argument instead of a base commitment
tree and incremental witnesses for each previously-known note. In addition, the
return type has now been updated to return a `Result<ScannedBlock, ScanError>`
in the case of scan failure.
nuttycom marked this conversation as resolved.
Show resolved Hide resolved


### Removed
- `zcash_client_backend::data_api`:
- `WalletRead::get_all_nullifiers`
- `WalletRead::{get_commitment_tree, get_witnesses}` (use
`WalletRead::fully_scanned_height` instead).
- `WalletRead::{get_commitment_tree, get_witnesses}` have been removed
without replacement. The utility of these methods is now subsumed
by those available from the `WalletCommitmentTrees` trait.
- `WalletWrite::advance_by_block` (use `WalletWrite::put_block` instead).
- The `commitment_tree` and `transactions` properties of the `PrunedBlock`
struct are now owned values instead of references, making this a fully owned type.
It is now parameterized by the nullifier type instead of by a lifetime for the
fields that were previously references. In addition, two new properties,
`sapling_commitment_tree_size` and `sapling_commitments` have been added.
- `PrunedBlock` has been replaced by `ScannedBlock`
- `testing::MockWalletDb`, which is available under the `test-dependencies`
feature flag, has been modified by the addition of a `sapling_tree` property.
- `wallet::input_selection`:
- `Proposal::target_height` (use `Proposal::min_target_height` instead).
- `zcash_client_backend::data_api::chain::validate_chain` TODO: document how
to handle validation given out-of-order blocks.
- `zcash_client_backend::data_api::chain::error::{ChainError, Cause}` have been
replaced by `zcash_client_backend::welding_rig::ScanError`
- `zcash_client_backend::wallet::WalletSaplingOutput::{witness, witness_mut}`
have been removed as individual incremental witnesses are no longer tracked on a
per-note basis. The global note commitment tree for the wallet should be used
Expand Down
121 changes: 105 additions & 16 deletions zcash_client_backend/src/data_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,17 @@ pub trait WalletRead {
/// This will return `Ok(None)` if no block data is present in the database.
fn block_height_extrema(&self) -> Result<Option<(BlockHeight, BlockHeight)>, Self::Error>;

/// Returns the height to which the wallet has been fully scanned.
/// Returns the available block metadata for the block at the specified height, if any.
fn block_metadata(&self, height: BlockHeight) -> Result<Option<BlockMetadata>, Self::Error>;

/// Returns the metadata for the block at the height to which the wallet has been fully
/// scanned.
///
/// This is the height for which the wallet has fully trial-decrypted this and all preceding
/// blocks above the wallet's birthday height. Along with this height, this method returns
/// metadata describing the state of the wallet's note commitment trees as of the end of that
/// block.
fn fully_scanned_height(
&self,
) -> Result<Option<(BlockHeight, chain::CommitmentTreeMeta)>, Self::Error>;
fn block_fully_scanned(&self) -> Result<Option<BlockMetadata>, Self::Error>;

/// Returns a vector of suggested scan ranges based upon the current wallet state.
///
Expand Down Expand Up @@ -248,17 +250,99 @@ pub trait WalletRead {
) -> Result<HashMap<TransparentAddress, Amount>, Self::Error>;
}

/// Metadata describing the sizes of the zcash note commitment trees as of a particular block.
#[derive(Debug, Clone, Copy)]
pub struct BlockMetadata {
block_height: BlockHeight,
block_hash: BlockHash,
sapling_tree_size: u32,
//TODO: orchard_tree_size: u32
}

impl BlockMetadata {
/// Constructs a new [`BlockMetadata`] value from its constituent parts.
pub fn from_parts(
block_height: BlockHeight,
block_hash: BlockHash,
sapling_tree_size: u32,
) -> Self {
Self {
block_height,
block_hash,
sapling_tree_size,
}
}

/// Returns the block height.
pub fn block_height(&self) -> BlockHeight {
self.block_height
}

/// Returns the hash of the block
pub fn block_hash(&self) -> BlockHash {
self.block_hash
}

/// Returns the size of the Sapling note commitment tree as of the block that this
/// [`BlockMetadata`] describes.
pub fn sapling_tree_size(&self) -> u32 {
self.sapling_tree_size
}
}

/// The subset of information that is relevant to this wallet that has been
/// decrypted and extracted from a [`CompactBlock`].
///
/// [`CompactBlock`]: crate::proto::compact_formats::CompactBlock
pub struct PrunedBlock<Nf> {
pub block_height: BlockHeight,
pub block_hash: BlockHash,
pub block_time: u32,
pub transactions: Vec<WalletTx<Nf>>,
pub sapling_commitment_tree_size: Option<u32>,
pub sapling_commitments: Vec<(sapling::Node, Retention<BlockHeight>)>,
pub struct ScannedBlock<Nf> {
metadata: BlockMetadata,
block_time: u32,
transactions: Vec<WalletTx<Nf>>,
sapling_commitments: Vec<(sapling::Node, Retention<BlockHeight>)>,
}

impl<Nf> ScannedBlock<Nf> {
pub fn from_parts(
metadata: BlockMetadata,
block_time: u32,
transactions: Vec<WalletTx<Nf>>,
sapling_commitments: Vec<(sapling::Node, Retention<BlockHeight>)>,
) -> Self {
Self {
metadata,
block_time,
transactions,
sapling_commitments,
}
}

pub fn height(&self) -> BlockHeight {
self.metadata.block_height
}

pub fn block_hash(&self) -> BlockHash {
self.metadata.block_hash
}

pub fn block_time(&self) -> u32 {
self.block_time
}

pub fn metadata(&self) -> &BlockMetadata {
&self.metadata
}

pub fn transactions(&self) -> &[WalletTx<Nf>] {
&self.transactions
}

pub fn sapling_commitments(&self) -> &[(sapling::Node, Retention<BlockHeight>)] {
&self.sapling_commitments
}

pub fn take_sapling_commitments(self) -> Vec<(sapling::Node, Retention<BlockHeight>)> {
nuttycom marked this conversation as resolved.
Show resolved Hide resolved
self.sapling_commitments
}
}

/// A transaction that was detected during scanning of the blockchain,
Expand Down Expand Up @@ -404,7 +488,7 @@ pub trait WalletWrite: WalletRead {
#[allow(clippy::type_complexity)]
fn put_block(
&mut self,
block: PrunedBlock<sapling::Nullifier>,
block: ScannedBlock<sapling::Nullifier>,
) -> Result<Vec<Self::NoteRef>, Self::Error>;

/// Caches a decrypted transaction in the persistent wallet store.
Expand Down Expand Up @@ -489,7 +573,7 @@ pub mod testing {
};

use super::{
chain, DecryptedTransaction, NullifierQuery, PrunedBlock, SentTransaction,
BlockMetadata, DecryptedTransaction, NullifierQuery, ScannedBlock, SentTransaction,
WalletCommitmentTrees, WalletRead, WalletWrite, SAPLING_SHARD_HEIGHT,
};

Expand Down Expand Up @@ -520,9 +604,14 @@ pub mod testing {
Ok(None)
}

fn fully_scanned_height(
fn block_metadata(
&self,
) -> Result<Option<(BlockHeight, chain::CommitmentTreeMeta)>, Self::Error> {
_height: BlockHeight,
) -> Result<Option<BlockMetadata>, Self::Error> {
Ok(None)
}

fn block_fully_scanned(&self) -> Result<Option<BlockMetadata>, Self::Error> {
Ok(None)
}

Expand Down Expand Up @@ -667,7 +756,7 @@ pub mod testing {
#[allow(clippy::type_complexity)]
fn put_block(
&mut self,
_block: PrunedBlock<sapling::Nullifier>,
_block: ScannedBlock<sapling::Nullifier>,
) -> Result<Vec<Self::NoteRef>, Self::Error> {
Ok(vec![])
}
Expand Down
Loading