pub trait BackendReader: Debug {
// Required methods
fn open(
&self,
lineage: LineageId,
key: Word,
) -> Result<SmtProof, BackendError>;
fn get_leaf(
&self,
lineage: LineageId,
leaf_index: LeafIndex<miden_crypto::::merkle::smt::large_forest::backend::BackendReader::get_leaf::{constant#0}>,
) -> Result<SmtLeaf, BackendError>;
fn get(
&self,
lineage: LineageId,
key: Word,
) -> Result<Option<Word>, BackendError>;
fn version(&self, lineage: LineageId) -> Result<u64, BackendError>;
fn lineages(&self) -> Result<impl Iterator<Item = LineageId>, BackendError>;
fn trees(&self) -> Result<impl Iterator<Item = TreeWithRoot>, BackendError>;
fn entry_count(&self, lineage: LineageId) -> Result<usize, BackendError>;
fn entries(
&self,
lineage: LineageId,
) -> Result<impl Iterator<Item = Result<TreeEntry, BackendError>>, BackendError>;
}Expand description
The read-only interface for the SMT forest storage backend.
This trait provides the query operations necessary to read the full trees that make up the
forest. It is a supertrait of Backend, which extends it with write operations.
§Backend Data Storage
Having a generic BackendReader provides no guarantees to the user about how it stores data
and what patterns are used for data access under the hood. It is, however, guaranteed to store
only the data necessary to describe the latest state of each tree in the forest.
§Error Handling
We separate errors in backend implementations into two semantic categories:
- User-Derived Errors: These are errors that arise downstream of data provided by the user.
These errors must be signaled by returning an
Errvariant with an appropriate error. - Internal Errors: These are errors that are not derived from data provided by the user.
Signaling such an error is up to the implementation, but can be done through both panicking
and returning the
BackendError::Internalvariant as appropriate. These may leave the backend in an inconsistent state as they are designed to effect program termination or perform it directly.
The only reason that BackendError::Internal exists is to allow certain failures to result in
termination at the level of the forest instead of the backend as this can sometimes lead to
cleaner logic. If this is not appropriate, a panic is a better option.
§Expected Behavior
The following behavior is expected of all methods in implementations of this trait:
- For any failure derived from user input (see User-Derived Errors above), the data and the backend must be left in a consistent state when the error is returned to the caller.
- Failures derived from user input (see User-Derived Errors above) must be signaled to the
caller by returning a variant of
BackendErrorthat is notBackendError::Internal. Methods may place additional constraints on which errors are used to signal certain failures. Such failures should not lead to data corruption of any persistent data.
Required Methods§
Sourcefn open(&self, lineage: LineageId, key: Word) -> Result<SmtProof, BackendError>
fn open(&self, lineage: LineageId, key: Word) -> Result<SmtProof, BackendError>
Returns an opening for the specified key in the SMT with the specified lineage.
It is the responsibility of the forest to ensure lineage existence before querying the backend. The backend must return an error if the lineage does not exist.
Sourcefn get_leaf(
&self,
lineage: LineageId,
leaf_index: LeafIndex<miden_crypto::::merkle::smt::large_forest::backend::BackendReader::get_leaf::{constant#0}>,
) -> Result<SmtLeaf, BackendError>
fn get_leaf( &self, lineage: LineageId, leaf_index: LeafIndex<miden_crypto::::merkle::smt::large_forest::backend::BackendReader::get_leaf::{constant#0}>, ) -> Result<SmtLeaf, BackendError>
Returns the leaf stored at the provided leaf_index in the SMT with the specified
lineage. If no leaf is explicitly stored at the given index, the backend must return
an empty leaf for that index.
It is the responsibility of the forest to ensure lineage existence before querying the backend. The backend must return an error if the lineage does not exist.
Sourcefn get(
&self,
lineage: LineageId,
key: Word,
) -> Result<Option<Word>, BackendError>
fn get( &self, lineage: LineageId, key: Word, ) -> Result<Option<Word>, BackendError>
Returns the value associated with the provided key in the SMT with the specified
lineage, or None if no such value exists.
It is the responsibility of the forest to ensure lineage existence before querying the backend. The backend must return an error if the lineage does not exist.
Sourcefn version(&self, lineage: LineageId) -> Result<u64, BackendError>
fn version(&self, lineage: LineageId) -> Result<u64, BackendError>
Returns the version of the tree with the specified lineage.
It is the responsibility of the forest to ensure lineage existence before querying the backend. The backend must return an error if the lineage does not exist.
Sourcefn lineages(&self) -> Result<impl Iterator<Item = LineageId>, BackendError>
fn lineages(&self) -> Result<impl Iterator<Item = LineageId>, BackendError>
Returns an iterator over all the lineages that the backend knows about.
The iteration order is unspecified.
Sourcefn trees(&self) -> Result<impl Iterator<Item = TreeWithRoot>, BackendError>
fn trees(&self) -> Result<impl Iterator<Item = TreeWithRoot>, BackendError>
Returns an iterator over all the trees (and their corresponding roots) that the backend knows about.
The iteration order is unspecified.
Sourcefn entry_count(&self, lineage: LineageId) -> Result<usize, BackendError>
fn entry_count(&self, lineage: LineageId) -> Result<usize, BackendError>
Returns the total number of (key-value) entries in the specified lineage.
It is the responsibility of the forest to ensure lineage existence before querying the backend. The backend must return an error if the lineage does not exist.
§Expected Behavior
Implementations must guarantee the following behavior in addition to the global invariants:
- This method must be cheap to call, not requiring network or disk I/O to service the result. This usually implies in-memory caching of the data.
- This method must not return errors other than if the lineage does not exist.
Sourcefn entries(
&self,
lineage: LineageId,
) -> Result<impl Iterator<Item = Result<TreeEntry, BackendError>>, BackendError>
fn entries( &self, lineage: LineageId, ) -> Result<impl Iterator<Item = Result<TreeEntry, BackendError>>, BackendError>
Returns an iterator that yields the populated (key-value) entries for the specified
lineage.
It is the responsibility of the forest to ensure lineage existence before querying the backend. The backend must return an error if the lineage does not exist.
The iterator may yield entries in any arbitrary order, but must not yield entries for which the value is the empty word.
§Expected Behavior
Implementations must guarantee the following behavior in addition to the global invariants:
- If any kind of error occurs during iteration that should be signaled to the user, the
iterator must return
Some(Err(...)). The caller should stop iteration after receiving an error as the iterator state is no longer valid. Nonewill be returned upon successful completion, or at any time after an error has been returned.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".