Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions miden-crypto/src/merkle/smt/forest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl SmtForest {
/// Inserts the specified key-value pair into an SMT with the specified root. This will also
/// add a new root to the forest. Returns the new root.
///
/// Returns an error if an SMT with the specified root is not in the forest, these is not
/// Returns an error if an SMT with the specified root is not in the forest, there is not
/// enough data in the forest to perform the insert, or if the insert would create a leaf
/// with too many entries.
pub fn insert(&mut self, root: Word, key: Word, value: Word) -> Result<Word, MerkleError> {
Expand All @@ -136,7 +136,7 @@ impl SmtForest {
/// Inserts the specified key-value pairs into an SMT with the specified root. This will also
/// add a single new root to the forest for the entire batch of inserts. Returns the new root.
///
/// Returns an error if an SMT with the specified root is not in the forest, these is not
/// Returns an error if an SMT with the specified root is not in the forest, there is not
/// enough data in the forest to perform the insert, or if the insert would create a leaf
/// with too many entries.
pub fn batch_insert(
Expand Down
38 changes: 37 additions & 1 deletion miden-crypto/src/merkle/smt/large_forest/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,58 @@ use thiserror::Error;

use crate::merkle::{
MerkleError,
smt::large_forest::{history::error::HistoryError, storage},
smt::large_forest::{error::prefix::PrefixError, history::error::HistoryError, storage},
};

// LARGE SMT FOREST ERROR
// ================================================================================================

/// The type of errors returned by operations on the large SMT forest.
#[derive(Debug, Error)]
pub enum LargeSmtForestError {
/// Errors in the history subsystem of the forest.
#[error(transparent)]
HistoryError(#[from] HistoryError),

/// Errors with the merkle tree operations of the forest.
#[error(transparent)]
MerkleError(#[from] MerkleError),

/// Errors with the storage backend of the forest.
#[error(transparent)]
StorageError(#[from] storage::StorageError),

/// Errors with the in-memory tree prefixes in the forest.
#[error(transparent)]
PrefixError(#[from] PrefixError),
}

/// The result type for use within the large SMT forest portion of the library.
#[allow(dead_code)] // Temporary
pub type Result<T> = core::result::Result<T, LargeSmtForestError>;

pub mod prefix {
use thiserror::Error;

use crate::{Word, merkle::smt::large_forest::utils::LinearIndex};

#[derive(Debug, Eq, Error, PartialEq)]
pub enum PrefixError {
/// Raised if an indexing operation would be out of bounds.
#[error("Index {0} was out of bounds in a prefix with {1} levels")]
IndexOutOfBounds(LinearIndex, u8),

/// Raised if the forest cannot restore correctly from the saved restoration data.
#[error("Restoration data for tree with root {0} produced root {1}")]
InvalidRestoration(Word, Word),

/// Raised if the number of leaves in the restoration data provided to the prefix is
/// incorrect for the depth of the prefix.
#[error("Was given {0} leaves but expected {1}")]
WrongLeafCount(u64, u64),
}

/// The result type for use within the prefix portion of the library.
#[allow(dead_code)] // Temporary
pub type Result<T> = core::result::Result<T, PrefixError>;
}
49 changes: 48 additions & 1 deletion miden-crypto/src/merkle/smt/large_forest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,56 @@

mod error;
pub mod history;
mod prefix;
pub mod storage;
pub mod utils;

pub use error::LargeSmtForestError;
pub use error::{LargeSmtForestError, Result};
pub use storage::{Storage, StorageError, StoredTreeHandle};
pub use utils::SubtreeLevels;

use crate::{Map, Word, merkle::smt::large_forest::prefix::InMemoryPrefix};

// SPARSE MERKLE TREE FOREST
// ================================================================================================

/// A high-performance forest of sparse merkle trees with pluggable storage.
///
/// # Performance
///
/// The performance characteristics of this forest
#[allow(dead_code)] // Temporary, while the tree gets built.
#[derive(Debug)]
pub struct LargeSmtForest<S: Storage> {
/// The underlying data storage for the portion of the tree that is not guaranteed to be in
/// memory. It **must not be exposed** to any client of this struct's API to ensure
/// correctness.
storage: S,

/// The number of levels of each tree that are kept in memory by the forest.
in_memory_depth: SubtreeLevels,

/// The container for the in-memory prefixes of each tree stored in the forest, identified by
/// their current root.
prefixes: Map<Word, InMemoryPrefix>,
}

impl<S: Storage> LargeSmtForest<S> {
// CONSTRUCTORS
// --------------------------------------------------------------------------------------------

/// Constructs a new forest backed by the provided `storage`.
///
/// The constructor will treat whatever state is contained within the provided `storage` as the
/// starting state for the forest. This means that if you pass a newly-initialized storage the
/// forest will start in an empty state, while if you pass a `storage` that already contains
/// some data (e.g. loaded from disk), then the forest will start in _that_ form instead.
///
/// # Errors
///
/// - [`LargeSmtForestError::StorageError`] if the forest cannot be started up correctly from
/// storage.
pub fn new(_storage: S) -> Result<Self> {
todo!()
}
}
Loading