From 3206255b8afd3d12ea6cb9f5c8003e45604c6a68 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 3 Jan 2024 20:15:26 +0000 Subject: [PATCH] Various documentation improvements --- Cargo.lock | 4 +- .../proto/compact_formats.proto | 28 +++++---- .../src/proto/compact_formats.rs | 28 +++++---- zcash_client_backend/src/wallet.rs | 4 +- zcash_keys/src/encoding.rs | 4 +- zcash_primitives/src/block.rs | 4 ++ zcash_primitives/src/consensus.rs | 13 +++- zcash_primitives/src/constants.rs | 2 +- zcash_primitives/src/legacy/keys.rs | 59 +++++++++++++------ zcash_primitives/src/merkle_tree.rs | 2 +- zcash_primitives/src/transaction/mod.rs | 22 +++++++ 11 files changed, 118 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5610310a..acbf272d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2474,9 +2474,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", diff --git a/zcash_client_backend/proto/compact_formats.proto b/zcash_client_backend/proto/compact_formats.proto index 1db1ecf69..e39e5225d 100644 --- a/zcash_client_backend/proto/compact_formats.proto +++ b/zcash_client_backend/proto/compact_formats.proto @@ -10,12 +10,14 @@ option swift_prefix = ""; // Remember that proto3 fields are all optional. A field that is not present will be set to its zero value. // bytes fields of hashes are in canonical little-endian format. -// ChainMetadata represents information about the state of the chain as of a given block. +// Information about the state of the chain as of a given block. message ChainMetadata { uint32 saplingCommitmentTreeSize = 1; // the size of the Sapling note commitment tree as of the end of this block uint32 orchardCommitmentTreeSize = 2; // the size of the Orchard note commitment tree as of the end of this block } +// A compact representation of the shielded data in a Zcash block. +// // CompactBlock is a packaging of ONLY the data from a block that's needed to: // 1. Detect a payment to your shielded Sapling address // 2. Detect a spend of your shielded Sapling notes @@ -31,6 +33,8 @@ message CompactBlock { ChainMetadata chainMetadata = 8; // information about the state of the chain as of this block } +// A compact representation of the shielded data in a Zcash transaction. +// // CompactTx contains the minimum information for a wallet to know if this transaction // is relevant to it (either pays to it or spends from it) via shielded elements // only. This message will not encode a transparent-to-transparent transaction. @@ -53,25 +57,25 @@ message CompactTx { repeated CompactOrchardAction actions = 6; } +// A compact representation of a [Sapling Spend](https://zips.z.cash/protocol/protocol.pdf#spendencodingandconsensus). +// // CompactSaplingSpend is a Sapling Spend Description as described in 7.3 of the Zcash // protocol specification. message CompactSaplingSpend { - bytes nf = 1; // nullifier (see the Zcash protocol specification) + bytes nf = 1; // Nullifier (see the Zcash protocol specification) } -// output encodes the `cmu` field, `ephemeralKey` field, and a 52-byte prefix of the -// `encCiphertext` field of a Sapling Output Description. These fields are described in -// section 7.4 of the Zcash protocol spec: -// https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus -// Total size is 116 bytes. +// A compact representation of a [Sapling Output](https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus). +// +// It encodes the `cmu` field, `ephemeralKey` field, and a 52-byte prefix of the +// `encCiphertext` field of a Sapling Output Description. Total size is 116 bytes. message CompactSaplingOutput { - bytes cmu = 1; // note commitment u-coordinate - bytes ephemeralKey = 2; // ephemeral public key - bytes ciphertext = 3; // first 52 bytes of ciphertext + bytes cmu = 1; // Note commitment u-coordinate. + bytes ephemeralKey = 2; // Ephemeral public key. + bytes ciphertext = 3; // First 52 bytes of ciphertext. } -// https://github.com/zcash/zips/blob/main/zip-0225.rst#orchard-action-description-orchardaction -// (but not all fields are needed) +// A compact representation of an [Orchard Action](https://zips.z.cash/protocol/protocol.pdf#actionencodingandconsensus). message CompactOrchardAction { bytes nullifier = 1; // [32] The nullifier of the input note bytes cmx = 2; // [32] The x-coordinate of the note commitment for the output note diff --git a/zcash_client_backend/src/proto/compact_formats.rs b/zcash_client_backend/src/proto/compact_formats.rs index 2e8a435db..44455378f 100644 --- a/zcash_client_backend/src/proto/compact_formats.rs +++ b/zcash_client_backend/src/proto/compact_formats.rs @@ -1,4 +1,4 @@ -/// ChainMetadata represents information about the state of the chain as of a given block. +/// Information about the state of the chain as of a given block. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ChainMetadata { @@ -9,6 +9,8 @@ pub struct ChainMetadata { #[prost(uint32, tag = "2")] pub orchard_commitment_tree_size: u32, } +/// A compact representation of the shielded data in a Zcash block. +/// /// CompactBlock is a packaging of ONLY the data from a block that's needed to: /// 1. Detect a payment to your shielded Sapling address /// 2. Detect a spend of your shielded Sapling notes @@ -41,6 +43,8 @@ pub struct CompactBlock { #[prost(message, optional, tag = "8")] pub chain_metadata: ::core::option::Option, } +/// A compact representation of the shielded data in a Zcash transaction. +/// /// CompactTx contains the minimum information for a wallet to know if this transaction /// is relevant to it (either pays to it or spends from it) via shielded elements /// only. This message will not encode a transparent-to-transparent transaction. @@ -71,35 +75,35 @@ pub struct CompactTx { #[prost(message, repeated, tag = "6")] pub actions: ::prost::alloc::vec::Vec, } +/// A compact representation of a [Sapling Spend](). +/// /// CompactSaplingSpend is a Sapling Spend Description as described in 7.3 of the Zcash /// protocol specification. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CompactSaplingSpend { - /// nullifier (see the Zcash protocol specification) + /// Nullifier (see the Zcash protocol specification) #[prost(bytes = "vec", tag = "1")] pub nf: ::prost::alloc::vec::Vec, } -/// output encodes the `cmu` field, `ephemeralKey` field, and a 52-byte prefix of the -/// `encCiphertext` field of a Sapling Output Description. These fields are described in -/// section 7.4 of the Zcash protocol spec: -/// -/// Total size is 116 bytes. +/// A compact representation of a [Sapling Output](). +/// +/// It encodes the `cmu` field, `ephemeralKey` field, and a 52-byte prefix of the +/// `encCiphertext` field of a Sapling Output Description. Total size is 116 bytes. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CompactSaplingOutput { - /// note commitment u-coordinate + /// Note commitment u-coordinate. #[prost(bytes = "vec", tag = "1")] pub cmu: ::prost::alloc::vec::Vec, - /// ephemeral public key + /// Ephemeral public key. #[prost(bytes = "vec", tag = "2")] pub ephemeral_key: ::prost::alloc::vec::Vec, - /// first 52 bytes of ciphertext + /// First 52 bytes of ciphertext. #[prost(bytes = "vec", tag = "3")] pub ciphertext: ::prost::alloc::vec::Vec, } -/// -/// (but not all fields are needed) +/// A compact representation of an [Orchard Action](). #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CompactOrchardAction { diff --git a/zcash_client_backend/src/wallet.rs b/zcash_client_backend/src/wallet.rs index 851bc31ad..8cfb3a48d 100644 --- a/zcash_client_backend/src/wallet.rs +++ b/zcash_client_backend/src/wallet.rs @@ -135,7 +135,7 @@ impl transparent_fees::InputView for WalletTransparentOutput { /// A subset of a [`SpendDescription`] relevant to wallets and light clients. /// -/// [`SpendDescription`]: zcash_primitives::transaction::components::SpendDescription +/// [`SpendDescription`]: sapling::bundle::SpendDescription pub struct WalletSaplingSpend { index: usize, nf: sapling::Nullifier, @@ -169,7 +169,7 @@ impl WalletSaplingSpend { /// this output; this will usually be [`zcash_primitives::zip32::Scope`] for received notes, and /// `()` for sent notes. /// -/// [`OutputDescription`]: zcash_primitives::transaction::components::OutputDescription +/// [`OutputDescription`]: sapling::bundle::OutputDescription pub struct WalletSaplingOutput { index: usize, cmu: sapling::note::ExtractedNoteCommitment, diff --git a/zcash_keys/src/encoding.rs b/zcash_keys/src/encoding.rs index a64970cda..1e8626cb0 100644 --- a/zcash_keys/src/encoding.rs +++ b/zcash_keys/src/encoding.rs @@ -1,9 +1,7 @@ //! Encoding and decoding functions for Zcash key and address structs. //! //! Human-Readable Prefixes (HRPs) for Bech32 encodings are located in the -//! [zcash_primitives::constants][constants] module. -//! -//! [constants]: zcash_primitives::constants +//! [zcash_primitives::constants] module. use crate::address::UnifiedAddress; use bech32::{self, Error, FromBase32, ToBase32, Variant}; diff --git a/zcash_primitives/src/block.rs b/zcash_primitives/src/block.rs index b9ef9a5ca..2b332016a 100644 --- a/zcash_primitives/src/block.rs +++ b/zcash_primitives/src/block.rs @@ -10,6 +10,9 @@ use zcash_encoding::Vector; pub use equihash; +/// The identifier for a Zcash block. +/// +/// Derived from a [`BlockHeader`]. #[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct BlockHash(pub [u8; 32]); @@ -70,6 +73,7 @@ impl Deref for BlockHeader { } } +/// The information contained in a Zcash block header. pub struct BlockHeaderData { pub version: i32, pub prev_block: BlockHash, diff --git a/zcash_primitives/src/consensus.rs b/zcash_primitives/src/consensus.rs index f6a734ec4..d9dafc5ce 100644 --- a/zcash_primitives/src/consensus.rs +++ b/zcash_primitives/src/consensus.rs @@ -9,14 +9,17 @@ use zcash_address; use crate::{constants, sapling::note_encryption::Zip212Enforcement}; -/// A wrapper type representing blockchain heights. Safe conversion from -/// various integer types, as well as addition and subtraction, are provided. +/// A wrapper type representing blockchain heights. +/// +/// Safe conversion from various integer types, as well as addition and subtraction, are +/// provided. #[repr(transparent)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct BlockHeight(u32); memuse::impl_no_dynamic_usage!(BlockHeight); +/// The height of the genesis block on a network. pub const H0: BlockHeight = BlockHeight(0); impl BlockHeight { @@ -201,6 +204,7 @@ pub struct MainNetwork; memuse::impl_no_dynamic_usage!(MainNetwork); +/// The production network. pub const MAIN_NETWORK: MainNetwork = MainNetwork; impl Parameters for MainNetwork { @@ -254,6 +258,7 @@ pub struct TestNetwork; memuse::impl_no_dynamic_usage!(TestNetwork); +/// The test network. pub const TEST_NETWORK: TestNetwork = TestNetwork; impl Parameters for TestNetwork { @@ -301,6 +306,7 @@ impl Parameters for TestNetwork { } } +/// Marker enum for the deployed Zcash consensus networks. #[derive(PartialEq, Eq, Copy, Clone, Debug)] pub enum Network { MainNetwork, @@ -462,6 +468,9 @@ const UPGRADES_IN_ORDER: &[NetworkUpgrade] = &[ NetworkUpgrade::Nu6, ]; +/// The "grace period" defined in [ZIP 212]. +/// +/// [ZIP 212]: https://zips.z.cash/zip-0212#changes-to-the-process-of-receiving-sapling-or-orchard-notes pub const ZIP212_GRACE_PERIOD: u32 = 32256; /// A globally-unique identifier for a set of consensus rules within the Zcash chain. diff --git a/zcash_primitives/src/constants.rs b/zcash_primitives/src/constants.rs index 2643d912b..fc56eca93 100644 --- a/zcash_primitives/src/constants.rs +++ b/zcash_primitives/src/constants.rs @@ -1,4 +1,4 @@ -//! Various constants used by the Zcash primitives. +//! Network-specific Zcash constants. pub mod mainnet; pub mod regtest; diff --git a/zcash_primitives/src/legacy/keys.rs b/zcash_primitives/src/legacy/keys.rs index 026ba6bf6..9614e3ce8 100644 --- a/zcash_primitives/src/legacy/keys.rs +++ b/zcash_primitives/src/legacy/keys.rs @@ -1,3 +1,5 @@ +//! Transparent key components. + use hdwallet::{ traits::{Deserialize, Serialize}, ExtendedPrivKey, ExtendedPubKey, KeyIndex, @@ -12,13 +14,14 @@ use super::TransparentAddress; const MAX_TRANSPARENT_CHILD_INDEX: u32 = 0x7FFFFFFF; -/// A type representing a BIP-44 private key at the account path level -/// `m/44'/'/' +/// A [BIP44] private key at the account path level `m/44'/'/'`. +/// +/// [BIP44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki #[derive(Clone, Debug)] pub struct AccountPrivKey(ExtendedPrivKey); impl AccountPrivKey { - /// Performs derivation of the extended private key for the BIP-44 path: + /// Performs derivation of the extended private key for the BIP44 path: /// `m/44'/'/'`. /// /// This produces the root of the derivation tree for transparent @@ -43,7 +46,7 @@ impl AccountPrivKey { AccountPubKey(ExtendedPubKey::from_private_key(&self.0)) } - /// Derives the BIP-44 private spending key for the external (incoming payment) child path + /// Derives the BIP44 private spending key for the external (incoming payment) child path /// `m/44'/'/'/0/`. pub fn derive_external_secret_key( &self, @@ -55,7 +58,7 @@ impl AccountPrivKey { .map(|k| k.private_key) } - /// Derives the BIP-44 private spending key for the internal (change) child path + /// Derives the BIP44 private spending key for the internal (change) child path /// `m/44'/'/'/1/`. pub fn derive_internal_secret_key( &self, @@ -82,16 +85,17 @@ impl AccountPrivKey { } } -/// A type representing a BIP-44 public key at the account path level -/// `m/44'/'/'`. +/// A [BIP44] public key at the account path level `m/44'/'/'`. /// /// This provides the necessary derivation capability for the transparent component of a unified /// full viewing key. +/// +/// [BIP44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki #[derive(Clone, Debug)] pub struct AccountPubKey(ExtendedPubKey); impl AccountPubKey { - /// Derives the BIP-44 public key at the external "change level" path + /// Derives the BIP44 public key at the external "change level" path /// `m/44'/'/'/0`. pub fn derive_external_ivk(&self) -> Result { self.0 @@ -99,7 +103,7 @@ impl AccountPubKey { .map(ExternalIvk) } - /// Derives the BIP-44 public key at the internal "change level" path + /// Derives the BIP44 public key at the internal "change level" path /// `m/44'/'/'/1`. pub fn derive_internal_ivk(&self) -> Result { self.0 @@ -162,6 +166,21 @@ pub(crate) mod private { } } +/// Trait representing a transparent "incoming viewing key". +/// +/// Unlike the Sapling and Orchard shielded protocols (which have viewing keys built into +/// their key trees and bound to specific spending keys), the transparent protocol has no +/// "viewing key" concept. Transparent viewing keys are instead emulated by making two +/// observations: +/// +/// - [BIP32] hierarchical derivation is structured as a tree. +/// - The [BIP44] key paths use non-hardened derivation below the account level. +/// +/// A transparent viewing key for an account is thus defined as the root of a specific +/// non-hardened subtree underneath the account's path. +/// +/// [BIP32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki +/// [BIP44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki pub trait IncomingViewingKey: private::SealedChangeLevelKey + std::marker::Sized { /// Derives a transparent address at the provided child index. #[allow(deprecated)] @@ -210,9 +229,12 @@ pub trait IncomingViewingKey: private::SealedChangeLevelKey + std::marker::Sized } } -/// A type representing an incoming viewing key at the BIP-44 "external" -/// path `m/44'/'/'/0`. This allows derivation -/// of child addresses that may be provided to external parties. +/// An incoming viewing key at the [BIP44] "external" path +/// `m/44'/'/'/0`. +/// +/// This allows derivation of child addresses that may be provided to external parties. +/// +/// [BIP44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki #[derive(Clone, Debug)] pub struct ExternalIvk(ExtendedPubKey); @@ -228,10 +250,13 @@ impl private::SealedChangeLevelKey for ExternalIvk { impl IncomingViewingKey for ExternalIvk {} -/// A type representing an incoming viewing key at the BIP-44 "internal" -/// path `m/44'/'/'/1`. This allows derivation -/// of change addresses for use within the wallet, but which should +/// An incoming viewing key at the [BIP44] "internal" path +/// `m/44'/'/'/1`. +/// +/// This allows derivation of change addresses for use within the wallet, but which should /// not be shared with external parties. +/// +/// [BIP44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki #[derive(Clone, Debug)] pub struct InternalIvk(ExtendedPubKey); @@ -247,7 +272,7 @@ impl private::SealedChangeLevelKey for InternalIvk { impl IncomingViewingKey for InternalIvk {} -/// Internal ovk used for autoshielding. +/// Internal outgoing viewing key used for autoshielding. pub struct InternalOvk([u8; 32]); impl InternalOvk { @@ -256,7 +281,7 @@ impl InternalOvk { } } -/// External ovk used by zcashd for transparent -> shielded spends to +/// External outgoing viewing key used by `zcashd` for transparent-to-shielded spends to /// external receivers. pub struct ExternalOvk([u8; 32]); diff --git a/zcash_primitives/src/merkle_tree.rs b/zcash_primitives/src/merkle_tree.rs index 21a6a1f3f..e365b9062 100644 --- a/zcash_primitives/src/merkle_tree.rs +++ b/zcash_primitives/src/merkle_tree.rs @@ -1,4 +1,4 @@ -//! Implementation of a Merkle tree of commitments used to prove the existence of notes. +//! Parsers and serializers for Zcash Merkle trees. use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use incrementalmerkletree::{ diff --git a/zcash_primitives/src/transaction/mod.rs b/zcash_primitives/src/transaction/mod.rs index 6c121d73d..7e3802a18 100644 --- a/zcash_primitives/src/transaction/mod.rs +++ b/zcash_primitives/src/transaction/mod.rs @@ -60,6 +60,13 @@ const ZFUTURE_VERSION_GROUP_ID: u32 = 0xFFFFFFFF; #[cfg(feature = "zfuture")] const ZFUTURE_TX_VERSION: u32 = 0x0000FFFF; +/// The identifier for a Zcash transaction. +/// +/// - For v1-4 transactions, this is a double-SHA-256 hash of the encoded transaction. +/// This means that it is malleable, and only a reliable identifier for transactions +/// that have been mined. +/// - For v5 transactions onwards, this identifier is derived only from "effecting" data, +/// and is non-malleable in all contexts. #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)] pub struct TxId([u8; 32]); @@ -193,6 +200,7 @@ impl TxVersion { } } + /// Returns `true` if this transaction version supports the Sprout protocol. pub fn has_sprout(&self) -> bool { match self { TxVersion::Sprout(v) => *v >= 2u32, @@ -207,6 +215,7 @@ impl TxVersion { !matches!(self, TxVersion::Sprout(_)) } + /// Returns `true` if this transaction version supports the Sapling protocol. pub fn has_sapling(&self) -> bool { match self { TxVersion::Sprout(_) | TxVersion::Overwinter => false, @@ -217,6 +226,7 @@ impl TxVersion { } } + /// Returns `true` if this transaction version supports the Orchard protocol. pub fn has_orchard(&self) -> bool { match self { TxVersion::Sprout(_) | TxVersion::Overwinter | TxVersion::Sapling => false, @@ -231,6 +241,7 @@ impl TxVersion { matches!(self, TxVersion::ZFuture) } + /// Suggests the transaction version that should be used in the given Zcash epoch. pub fn suggested_for_branch(consensus_branch_id: BranchId) -> Self { match consensus_branch_id { BranchId::Sprout => TxVersion::Sprout(2), @@ -257,6 +268,7 @@ pub trait Authorization { type TzeAuth: tze::Authorization; } +/// [`Authorization`] marker type for fully-authorized transactions. #[derive(Debug)] pub struct Authorized; @@ -269,6 +281,10 @@ impl Authorization for Authorized { type TzeAuth = tze::Authorized; } +/// [`Authorization`] marker type for transactions without authorization data. +/// +/// Currently this includes Sapling proofs because the types in this crate support v4 +/// transactions, which commit to the Sapling proofs in the transaction digest. pub struct Unauthorized; impl Authorization for Unauthorized { @@ -303,6 +319,7 @@ impl PartialEq for Transaction { } } +/// The information contained in a Zcash transaction. #[derive(Debug)] pub struct TransactionData { version: TxVersion, @@ -318,6 +335,7 @@ pub struct TransactionData { } impl TransactionData { + /// Constructs a `TransactionData` from its constituent parts. #[allow(clippy::too_many_arguments)] pub fn from_parts( version: TxVersion, @@ -343,6 +361,8 @@ impl TransactionData { } } + /// Constructs a `TransactionData` from its constituent parts, including speculative + /// future parts that are not in the current Zcash consensus rules. #[cfg(feature = "zfuture")] #[allow(clippy::too_many_arguments)] pub fn from_parts_zfuture( @@ -369,10 +389,12 @@ impl TransactionData { } } + /// Returns the transaction version. pub fn version(&self) -> TxVersion { self.version } + /// Returns the Zcash epoch that this transaction can be mined in. pub fn consensus_branch_id(&self) -> BranchId { self.consensus_branch_id }