pub struct IncrementalWitness<const DEPTH: usize, Node> { /* private fields */ }
Expand description
A Merkle path to a specific note commitment in a Merkle tree, along with metadata about the state of the tree at the time the Merkle path was computed.
IncrementalWitness
creates and maintains the cryptographic evidence needed to prove
that a specific note commitment exists in the blockchain’s commitment tree.
§Zcash Concept Relation
In Zcash’s shielded protocols, witnesses serve several critical functions:
- Spending Notes: When spending a shielded note, the witness proves the note exists in the blockchain’s commitment tree without revealing which specific note is being spent
Each shielded protocol has a different Merkle tree depth:
- Sprout: 29 levels deep, using SHA-256 compression
- Sapling: 32 levels deep, using Pedersen hashes
- Orchard: 32 levels deep, using Poseidon hashes
§Data Preservation
During wallet migration, maintaining complete witness data is absolutely critical:
- Unspent Notes: Without valid witnesses, unspent notes cannot be spent after migration
- Path Components: The authentication path for each note must be preserved exactly
- Tree State: The current state of the tree at the time of the witness creation
§Type Parameters
DEPTH
- The depth of the Merkle tree (29 for Sprout, 32 for Sapling/Orchard)Node
- The hash type used for tree nodes (varies by protocol)
§Examples
// Create a witness for a note at a specific position
let witness = IncrementalWitness::<32, [u8; 32]>::from_parts(
[0u8; 32], // fake note commitment hash
12345,
vec![[1u8; 32]; 32], // fake hashes
[2u8; 32], // fake anchor
67891, // tree size at anchor
vec![] // optional, can be empty
);
Implementations§
Source§impl<const DEPTH: usize, Node> IncrementalWitness<DEPTH, Node>
impl<const DEPTH: usize, Node> IncrementalWitness<DEPTH, Node>
Sourcepub fn from_parts(
note_commitment: Node,
note_position: u32,
merkle_path: Vec<Node>,
anchor: Node,
anchor_tree_size: u32,
anchor_frontier: Vec<Node>,
) -> Self
pub fn from_parts( note_commitment: Node, note_position: u32, merkle_path: Vec<Node>, anchor: Node, anchor_tree_size: u32, anchor_frontier: Vec<Node>, ) -> Self
Constructs an incremental witness from its constituent parts.
Sourcepub fn note_commitment(&self) -> &Node
pub fn note_commitment(&self) -> &Node
The note commitment that this witness provides an inclusion proof for.
Sourcepub fn note_position(&self) -> u32
pub fn note_position(&self) -> u32
The position (index) of the note commitment in the note commitment tree.
Sourcepub fn merkle_path(&self) -> &[Node]
pub fn merkle_path(&self) -> &[Node]
The Merkle path to the note commitment that produces given anchor.
Ordered from leaf to root. As Zcash witnesses are computed by hashing with empty nodes on on the right-hand margin of the tree, this witness will contain data that is the result of such hashing. Such nodes must be discarded in order to update the witness.
Sourcepub fn anchor(&self) -> &Node
pub fn anchor(&self) -> &Node
The anchor for which this witness’s merkle path is valid.
Note that in the case of a reorg, this may not correspond to any anchor in the main chain.
Sourcepub fn anchor_tree_size(&self) -> u32
pub fn anchor_tree_size(&self) -> u32
The size of the note commitment tree as of the given anchor. This can be used to determine which of the witness nodes include dummy hashes so that these nodes may be discarded when restoring the witness in a new wallet.
Sourcepub fn anchor_frontier(&self) -> &[Node]
pub fn anchor_frontier(&self) -> &[Node]
The frontier
of the note commitment tree as of the anchor tree size.
Ordered from leaf to root. If the anchor corresponds to a stable anchor in the main chain, then these frontier nodes also correspond to stable nodes in the note commitment tree and can be used as a starting point for updating the witness, obviating the need to .
Trait Implementations§
Source§impl<const DEPTH: usize, Node: Clone> Clone for IncrementalWitness<DEPTH, Node>
impl<const DEPTH: usize, Node: Clone> Clone for IncrementalWitness<DEPTH, Node>
Source§fn clone(&self) -> IncrementalWitness<DEPTH, Node>
fn clone(&self) -> IncrementalWitness<DEPTH, Node>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<const DEPTH: usize, Node: PartialEq> PartialEq for IncrementalWitness<DEPTH, Node>
impl<const DEPTH: usize, Node: PartialEq> PartialEq for IncrementalWitness<DEPTH, Node>
Source§fn eq(&self, other: &IncrementalWitness<DEPTH, Node>) -> bool
fn eq(&self, other: &IncrementalWitness<DEPTH, Node>) -> bool
self
and other
values to be equal, and is used by ==
.impl<const DEPTH: usize, Node: Eq> Eq for IncrementalWitness<DEPTH, Node>
impl<const DEPTH: usize, Node> StructuralPartialEq for IncrementalWitness<DEPTH, Node>
Auto Trait Implementations§
impl<const DEPTH: usize, Node> Freeze for IncrementalWitness<DEPTH, Node>where
Node: Freeze,
impl<const DEPTH: usize, Node> RefUnwindSafe for IncrementalWitness<DEPTH, Node>where
Node: RefUnwindSafe,
impl<const DEPTH: usize, Node> Send for IncrementalWitness<DEPTH, Node>where
Node: Send,
impl<const DEPTH: usize, Node> Sync for IncrementalWitness<DEPTH, Node>where
Node: Sync,
impl<const DEPTH: usize, Node> Unpin for IncrementalWitness<DEPTH, Node>where
Node: Unpin,
impl<const DEPTH: usize, Node> UnwindSafe for IncrementalWitness<DEPTH, Node>where
Node: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more