pub struct LargeSmt<S>where
S: SmtStorage,{ /* private fields */ }Expand description
A large-scale Sparse Merkle tree mapping 256-bit keys to 256-bit values, backed by pluggable storage. Both keys and values are represented by 4 field elements.
Unlike the regular Smt, this implementation is designed for very large trees by using external
storage (such as RocksDB) for the bulk of the tree data, while keeping only the upper levels (up
to depth 24) in memory. This hybrid approach allows the tree to scale beyond memory limitations
while maintaining good performance for common operations.
All leaves sit at depth 64. The most significant element of the key is used to identify the leaf to which the key maps.
A leaf is either empty, or holds one or more key-value pairs. An empty leaf hashes to the empty word. Otherwise, a leaf hashes to the hash of its key-value pairs, ordered by key first, value second.
The tree structure:
- Depths 0-23: Stored in memory as a flat array for fast access
- Depths 24-64: Stored in external storage organized as subtrees for efficient batch operations
Implementations§
Source§impl<S> LargeSmt<S>where
S: SmtStorage,
impl<S> LargeSmt<S>where
S: SmtStorage,
Sourcepub const EMPTY_VALUE: Word
pub const EMPTY_VALUE: Word
The default value used to compute the hash of empty leaves.
Sourcepub const SUBTREE_DEPTHS: [u8; 5]
pub const SUBTREE_DEPTHS: [u8; 5]
Subtree depths for the subtrees stored in storage.
Sourcepub fn new(storage: S) -> Result<LargeSmt<S>, LargeSmtError>
pub fn new(storage: S) -> Result<LargeSmt<S>, LargeSmtError>
Returns a new LargeSmt backed by the provided storage.
The SMT’s root is fetched from the storage backend. If the storage is empty the SMT is initialized with the root of an empty tree. Otherwise, materializes in-memory nodes from the top subtrees.
§Errors
Returns an error if fetching the root or initial in-memory nodes from the storage fails.
Sourcepub fn with_entries(
storage: S,
entries: impl IntoIterator<Item = (Word, Word)>,
) -> Result<LargeSmt<S>, LargeSmtError>
pub fn with_entries( storage: S, entries: impl IntoIterator<Item = (Word, Word)>, ) -> Result<LargeSmt<S>, LargeSmtError>
Returns a new Smt instantiated with leaves set as specified by the provided entries.
If the concurrent feature is enabled, this function uses a parallel implementation to
process the entries efficiently, otherwise it defaults to the sequential implementation.
All leaves omitted from the entries list are set to Self::EMPTY_VALUE.
§Errors
Returns an error if the provided entries contain multiple values for the same key.
Sourcepub fn root(&self) -> Result<Word, LargeSmtError>
pub fn root(&self) -> Result<Word, LargeSmtError>
Returns the root of the tree
Sourcepub fn num_leaves(&self) -> Result<usize, LargeSmtError>
pub fn num_leaves(&self) -> Result<usize, LargeSmtError>
Returns the number of non-empty leaves in this tree.
Note that this may return a different value from Self::num_entries() as a single leaf may contain more than one key-value pair.
§Errors
Returns an error if there is a storage error when retrieving the leaf count.
Sourcepub fn num_entries(&self) -> Result<usize, LargeSmtError>
pub fn num_entries(&self) -> Result<usize, LargeSmtError>
Returns the number of key-value pairs with non-default values in this tree.
Note that this may return a different value from Self::num_leaves() as a single leaf may contain more than one key-value pair.
Also note that this is currently an expensive operation is counting the number of entries requires iterating over all leaves of the tree.
§Errors
Returns an error if there is a storage error when retrieving the entry count.
Sourcepub fn open(&self, key: &Word) -> SmtProof
pub fn open(&self, key: &Word) -> SmtProof
Returns an opening of the leaf associated with key. Conceptually, an opening is a Merkle
path to the leaf, as well as the leaf itself.
Sourcepub fn is_empty(&self) -> Result<bool, LargeSmtError>
pub fn is_empty(&self) -> Result<bool, LargeSmtError>
Returns a boolean value indicating whether the SMT is empty.
§Errors
Returns an error if there is a storage error when retrieving the root or leaf count.
Sourcepub fn leaves(
&self,
) -> Result<impl Iterator<Item = (LeafIndex<miden_crypto::::merkle::smt::large::{impl#0}::leaves::{constant#0}>, SmtLeaf)>, LargeSmtError>
pub fn leaves( &self, ) -> Result<impl Iterator<Item = (LeafIndex<miden_crypto::::merkle::smt::large::{impl#0}::leaves::{constant#0}>, SmtLeaf)>, LargeSmtError>
Sourcepub fn inner_nodes(
&self,
) -> Result<impl Iterator<Item = InnerNodeInfo>, LargeSmtError>
pub fn inner_nodes( &self, ) -> Result<impl Iterator<Item = InnerNodeInfo>, LargeSmtError>
Sourcepub fn insert(&mut self, key: Word, value: Word) -> Result<Word, MerkleError>
pub fn insert(&mut self, key: Word, value: Word) -> Result<Word, MerkleError>
Inserts a value at the specified key, returning the previous value associated with that key.
Recall that by definition, any key that hasn’t been updated is associated with
Self::EMPTY_VALUE.
This also recomputes all hashes between the leaf (associated with the key) and the root, updating the root itself.
§Errors
Returns an error if inserting the key-value pair would exceed
MAX_LEAF_ENTRIES (1024 entries) in the leaf.
Sourcepub fn compute_mutations(
&self,
kv_pairs: impl IntoIterator<Item = (Word, Word)>,
) -> Result<MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::compute_mutations::{constant#0}, Word, Word>, LargeSmtError>
pub fn compute_mutations( &self, kv_pairs: impl IntoIterator<Item = (Word, Word)>, ) -> Result<MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::compute_mutations::{constant#0}, Word, Word>, LargeSmtError>
Computes what changes are necessary to insert the specified key-value pairs into this Merkle tree, allowing for validation before applying those changes.
This method returns a MutationSet, which contains all the information for inserting
kv_pairs into this Merkle tree already calculated, including the new root hash, which can
be queried with MutationSet::root(). Once a mutation set is returned,
Smt::apply_mutations() can be called in order to commit these changes to the Merkle
tree, or drop() to discard them.
§Example
let mut smt = Smt::new();
let pair = (Word::default(), Word::default());
let mutations = smt.compute_mutations(vec![pair]).expect("compute_mutations ok");
assert_eq!(mutations.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));
smt.apply_mutations(mutations);
assert_eq!(smt.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));Sourcepub fn apply_mutations(
&mut self,
mutations: MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::apply_mutations::{constant#0}, Word, Word>,
) -> Result<(), LargeSmtError>
pub fn apply_mutations( &mut self, mutations: MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::apply_mutations::{constant#0}, Word, Word>, ) -> Result<(), LargeSmtError>
Applies the prospective mutations computed with Smt::compute_mutations() to this tree.
§Errors
If mutations was computed on a tree with a different root than this one, returns
MerkleError::ConflictingRoots with a two-item Vec. The first item is the root hash
the mutations were computed against, and the second item is the actual current root of
this tree.
Sourcepub fn apply_mutations_with_reversion(
&mut self,
mutations: MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::apply_mutations_with_reversion::{constant#0}, Word, Word>,
) -> Result<MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::apply_mutations_with_reversion::{constant#1}, Word, Word>, LargeSmtError>
pub fn apply_mutations_with_reversion( &mut self, mutations: MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::apply_mutations_with_reversion::{constant#0}, Word, Word>, ) -> Result<MutationSet<miden_crypto::::merkle::smt::large::{impl#0}::apply_mutations_with_reversion::{constant#1}, Word, Word>, LargeSmtError>
Applies the prospective mutations computed with Smt::compute_mutations() to this tree
and returns the reverse mutation set.
Applying the reverse mutation sets to the updated tree will revert the changes.
§Errors
If mutations was computed on a tree with a different root than this one, returns
MerkleError::ConflictingRoots with a two-item Vec. The first item is the root hash
the mutations were computed against, and the second item is the actual current root of
this tree.
Trait Implementations§
Source§impl<Backend> AccountTreeBackend for LargeSmt<Backend>where
Backend: SmtStorage,
Available on crate feature std only.
impl<Backend> AccountTreeBackend for LargeSmt<Backend>where
Backend: SmtStorage,
std only.type Error = MerkleError
Source§fn num_leaves(&self) -> usize
fn num_leaves(&self) -> usize
Source§fn leaves<'a>(
&'a self,
) -> Box<dyn Iterator<Item = (LeafIndex<SMT_DEPTH>, SmtLeaf)> + 'a>
fn leaves<'a>( &'a self, ) -> Box<dyn Iterator<Item = (LeafIndex<SMT_DEPTH>, SmtLeaf)> + 'a>
Source§fn open(&self, key: &Word) -> SmtProof
fn open(&self, key: &Word) -> SmtProof
Source§fn apply_mutations(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<(), Self::Error>
fn apply_mutations( &mut self, set: MutationSet<SMT_DEPTH, Word, Word>, ) -> Result<(), Self::Error>
Source§fn apply_mutations_with_reversion(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error>
fn apply_mutations_with_reversion( &mut self, set: MutationSet<SMT_DEPTH, Word, Word>, ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error>
Source§fn compute_mutations(
&self,
updates: Vec<(Word, Word)>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error>
fn compute_mutations( &self, updates: Vec<(Word, Word)>, ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error>
Source§impl<S> PartialEq for LargeSmt<S>where
S: SmtStorage,
impl<S> PartialEq for LargeSmt<S>where
S: SmtStorage,
Source§fn eq(&self, other: &LargeSmt<S>) -> bool
fn eq(&self, other: &LargeSmt<S>) -> bool
Compares two LargeSmt instances based on their root hash and metadata.
Note: This comparison only checks the root hash and counts, not the underlying storage contents. Two SMTs with the same root should be cryptographically equivalent, but this doesn’t verify the storage backends are identical.
impl<S> Eq for LargeSmt<S>where
S: SmtStorage,
Auto Trait Implementations§
impl<S> Freeze for LargeSmt<S>where
S: Freeze,
impl<S> RefUnwindSafe for LargeSmt<S>where
S: RefUnwindSafe,
impl<S> Send for LargeSmt<S>
impl<S> Sync for LargeSmt<S>
impl<S> Unpin for LargeSmt<S>where
S: Unpin,
impl<S> UnwindSafe for LargeSmt<S>where
S: 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> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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 moreSource§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more