pub mod memory;
#[cfg(feature = "persistent-forest")]
pub mod persistent;
use alloc::{boxed::Box, string::String, vec::Vec};
use core::fmt::Debug;
use thiserror::Error;
use crate::{
Word,
merkle::{
MerkleError,
smt::{
LeafIndex, SMT_DEPTH, SmtLeaf, SmtProof,
large_forest::{
operation::{SmtForestUpdateBatch, SmtUpdateBatch},
root::{LineageId, TreeEntry, TreeWithRoot, VersionId},
utils::MutationSet,
},
},
},
};
pub trait Backend
where
Self: Debug,
{
fn open(&self, lineage: LineageId, key: Word) -> Result<SmtProof>;
fn get_leaf(&self, lineage: LineageId, leaf_index: LeafIndex<SMT_DEPTH>) -> Result<SmtLeaf>;
fn get(&self, lineage: LineageId, key: Word) -> Result<Option<Word>>;
fn version(&self, lineage: LineageId) -> Result<VersionId>;
fn lineages(&self) -> Result<impl Iterator<Item = LineageId>>;
fn trees(&self) -> Result<impl Iterator<Item = TreeWithRoot>>;
fn entry_count(&self, lineage: LineageId) -> Result<usize>;
fn entries(&self, lineage: LineageId) -> Result<impl Iterator<Item = Result<TreeEntry>>>;
fn add_lineage(
&mut self,
lineage: LineageId,
version: VersionId,
updates: SmtUpdateBatch,
) -> Result<TreeWithRoot>;
fn update_tree(
&mut self,
lineage: LineageId,
new_version: VersionId,
updates: SmtUpdateBatch,
) -> Result<MutationSet>;
fn add_lineages(
&mut self,
version: VersionId,
lineages: SmtForestUpdateBatch,
) -> Result<Vec<(LineageId, TreeWithRoot)>>;
fn update_forest(
&mut self,
new_version: VersionId,
updates: SmtForestUpdateBatch,
) -> Result<Vec<(LineageId, MutationSet)>>;
}
#[derive(Debug, Error)]
pub enum BackendError {
#[error("Backend data corruption encountered: {0}")]
CorruptedData(String),
#[error("Duplicate lineage ID {0} provided")]
DuplicateLineage(LineageId),
#[error(transparent)]
Internal(Box<dyn core::error::Error + Sync + Send>),
#[error(transparent)]
Merkle(#[from] MerkleError),
#[error(transparent)]
Other(Box<dyn core::error::Error + Sync + Send>),
#[error("Lineage {0} is not known by the backend")]
UnknownLineage(LineageId),
#[error("Unspecified error: {0}")]
Unspecified(String),
}
impl BackendError {
fn internal_from<E: core::error::Error + Sync + Send + 'static>(e: E) -> Self {
Self::Internal(Box::new(e))
}
#[cfg(feature = "persistent-forest")]
fn internal_from_message(message: impl Into<String>) -> Self {
Self::internal_from(Self::Unspecified(message.into()))
}
}
pub type Result<T> = core::result::Result<T, BackendError>;