From e44ddee8ad27ecc68557cd7426cb5ef951b44598 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Thu, 29 Feb 2024 16:53:50 -0700 Subject: [PATCH 1/2] zcash_client_backend: Add documentation for the `data_api` module. Fixes #1209 --- zcash_client_backend/CHANGELOG.md | 4 ++ zcash_client_backend/src/data_api.rs | 57 ++++++++++++++++++- zcash_client_backend/src/data_api/scanning.rs | 2 + zcash_client_backend/src/data_api/wallet.rs | 33 ++++++++++- 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/zcash_client_backend/CHANGELOG.md b/zcash_client_backend/CHANGELOG.md index 90526e2de..95cc07d96 100644 --- a/zcash_client_backend/CHANGELOG.md +++ b/zcash_client_backend/CHANGELOG.md @@ -338,6 +338,10 @@ and this library adheres to Rust's notion of - `TransactionBalance::{fee_required, total}` - `zcash_client_backend::wallet::WalletTransparentOutput::value` +### Deprecated +- `zcash_client_backend::data_api::wallet`: + - `spend` (use `propose_transfer` and `create_proposed_transactions` instead). + ### Removed - `zcash_client_backend::wallet`: - `ReceivedSaplingNote` (use `zcash_client_backend::ReceivedNote` instead). diff --git a/zcash_client_backend/src/data_api.rs b/zcash_client_backend/src/data_api.rs index c999e45fb..7edf66513 100644 --- a/zcash_client_backend/src/data_api.rs +++ b/zcash_client_backend/src/data_api.rs @@ -1,4 +1,59 @@ -//! Interfaces for wallet data persistence & low-level wallet utilities. +//! # Utilities for Zcash wallet construction +//! +//! This module defines a set of APIs for wallet data persistence, and provides a suite of methods +//! based upon these APIs that can be used to implement a fully functional Zcash wallet. At +//! present, the interfaces provided here are built primarily around the use of a source of +//! [`CompactBlock`] data such as the Zcash Light Client Protocol as defined in +//! [ZIP 307](https://zips.z.cash/zip-0307) but they may be generalized to full-block use cases in +//! the future. +//! +//! ## Important Concepts +//! +//! There are several important operations that a Zcash wallet must perform that distinguish Zcash +//! wallet design from wallets for other cryptocurrencies. +//! +//! * Viewing Keys: Wallets based upon this module are built around the capabilities of Zcash +//! [`UnifiedFullViewingKey`]s; the wallet backend provides no facilities for the storage +//! of spending keys, and spending keys must be provided by the caller in order to perform +//! transaction creation operations. +//! * Blockchain Scanning: A Zcash wallet must download and trial-decrypt each transaction on the +//! Zcash blockchain using one or more Viewing Keys in order to find new shielded transaction +//! outputs (generally termed "notes") belonging to the wallet. The primary entrypoint for this +//! functionality is the [`scan_cached_blocks`] method. See the [`chain`] module for additional +//! details. +//! * Witness Updates: In order to spend a shielded note, the wallet must be able to compute the +//! Merkle path to that note in the global note commitment tree. When [`scan_cached_blocks`] is +//! used to process a range of blocks, the note commitment tree is updated with the note +//! commitments for the blocks in that range. +//! * Transaction Construction: The [`wallet`] module provides functions for creating Zcash +//! transactions that spend funds belonging to the wallet. +//! +//! ## Core Traits +//! +//! The utility functions described above depend upon four important traits defined in this +//! module, which between them encompass the data storage requirements of a light wallet. +//! The relevant traits are [`InputSource`], [`WalletRead`], [`WalletWrite`], and +//! [`WalletCommitmentTrees`]. A complete implementation of the data storage layer for a wallet +//! will include an implementation of all four of these traits. See the [`zcash_client_sqlite`] +//! crate for a complete example of the implementation of these traits. +//! +//! ## Accounts +//! +//! The operation of the [`InputSource`], [`WalletRead`] and [`WalletWrite`] traits is built around +//! the concept of a wallet having one or more accounts, with a unique `AccountId` for each +//! account. +//! +//! An account identifier corresponds to at most a single [`UnifiedSpendingKey`]'s worth of spend +//! authority, with the received and spent notes of that account tracked via the corresponding +//! [`UnifiedFullViewingKey`]. Both received notes and change spendable by that spending authority +//! (both the external and internal parts of that key, as defined by +//! [ZIP 316](https://zips.z.cash/zip-0316)) will be interpreted as belonging to that account. +//! +//! [`CompactBlock`]: crate::proto::compact_formats::CompactBlock +//! [`scan_cached_blocks`]: crate::data_api::chain::scan_cached_blocks +//! [`zcash_client_sqlite`]: https://crates.io/crates/zcash_client_sqlite +//! [`TransactionRequest`]: crate::zip321::TransactionRequest +//! [`propose_shielding`]: crate::data_api::wallet::propose_shielding use std::{ collections::HashMap, diff --git a/zcash_client_backend/src/data_api/scanning.rs b/zcash_client_backend/src/data_api/scanning.rs index 9f978025a..a03abd62f 100644 --- a/zcash_client_backend/src/data_api/scanning.rs +++ b/zcash_client_backend/src/data_api/scanning.rs @@ -1,3 +1,5 @@ +//! Common types used for managing a queue of scanning ranges. + use std::fmt; use std::ops::Range; diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index 96806d69b..6648810fd 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -1,3 +1,33 @@ +//! # Functions for creating Zcash transactions that spend funds belonging to the wallet +//! +//! This module contains several different ways of creating Zcash transactions. This module is +//! designed around the idea that a Zcash wallet holds its funds in notes in either the Orchard +//! or Sapling shielded pool. In order to better preserve users' privacy, it does not provide any +//! functionality that allows users to directly spend transparent funds except by sending them to a +//! shielded internal address belonging to their wallet. +//! +//! The important high-level operations provided by this module are [`propose_transfer`], +//! [`propose_shielding`], and [`create_proposed_transactions`]. +//! +//! [`propose_transfer`] takes a [`TransactionRequest`] object, selects inputs notes and +//! computes the fees required to satisfy that request, and returns a [`Proposal`] object that +//! describes the transaction to be made. +//! +//! [`propose_shielding`] takes a set of transparent source addresses, and constructs a +//! [`Proposal`] to send those funds to a wallet-internal shielded address, as described in +//! [ZIP 316](https://zips.z.cash/zip-0316). +//! +//! [`create_proposed_transactions`] constructs one or more Zcash [`Transaction`]s based upon a +//! provided [`Proposal`], stores them to the wallet database, and returns the [`TxId`] for each +//! constructed transaction to the caller. The caller can then use the +//! [`WalletRead::get_transaction`] method to retrieve the newly constructed transactions. It is +//! the responsibility of the caller to retrieve and serialize the transactions and submit them for +//! inclusion into the Zcash blockchain. +//! +//! [`TransactionRequest`]: crate::zip321::TransactionRequest +//! [`propose_transfer`]: crate::data_api::wallet::propose_transfer +//! [`propose_shielding`]: crate::data_api::wallet::propose_shielding + use nonempty::NonEmpty; use rand_core::OsRng; use sapling::{ @@ -195,7 +225,7 @@ where #[allow(clippy::too_many_arguments)] #[allow(clippy::type_complexity)] #[deprecated( - note = "Use `spend` instead. `create_spend_to_address` uses a fixed fee of 10000 zatoshis, which is not compliant with ZIP 317." + note = "Use `propose_transfer` and `create_proposed_transactions` instead. `create_spend_to_address` uses a fixed fee of 10000 zatoshis, which is not compliant with ZIP 317." )] pub fn create_spend_to_address( wallet_db: &mut DbT, @@ -311,6 +341,7 @@ where /// [`sapling::OutputProver`]: sapling::prover::OutputProver #[allow(clippy::too_many_arguments)] #[allow(clippy::type_complexity)] +#[deprecated(note = "Use `propose_transfer` and `create_proposed_transactions` instead.")] pub fn spend( wallet_db: &mut DbT, params: &ParamsT, From 9ea027150a38645616d942103d2b77f2a935411e Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Thu, 29 Feb 2024 17:57:24 -0700 Subject: [PATCH 2/2] zcash_client_sqlite: Allow use of `zcash_client_backend::data_api::wallet::spend` in tests --- zcash_client_sqlite/src/testing.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/zcash_client_sqlite/src/testing.rs b/zcash_client_sqlite/src/testing.rs index 4c164b3d1..50c98314f 100644 --- a/zcash_client_sqlite/src/testing.rs +++ b/zcash_client_sqlite/src/testing.rs @@ -494,6 +494,7 @@ impl TestState { where InputsT: InputSelector>, { + #![allow(deprecated)] let params = self.network(); let prover = test_prover(); spend(