use alloc::boxed::Box;
use alloc::vec::Vec;
use crate::Word;
use crate::crypto::merkle::MerkleError;
#[cfg(feature = "std")]
use crate::crypto::merkle::smt::{LargeSmt, LargeSmtError, SmtStorage, SmtStorageReader};
use crate::crypto::merkle::smt::{LeafIndex, MutationSet, SMT_DEPTH, Smt, SmtLeaf, SmtProof};
pub trait SmtBackendReader: Sized {
type Error: core::error::Error + Send + 'static;
fn num_leaves(&self) -> usize;
fn num_entries(&self) -> usize;
fn leaves(&self) -> Box<dyn Iterator<Item = (LeafIndex<SMT_DEPTH>, SmtLeaf)> + '_>;
fn entries(&self) -> Box<dyn Iterator<Item = (Word, Word)> + '_>;
fn open(&self, key: &Word) -> SmtProof;
fn get_value(&self, key: &Word) -> Word;
fn get_leaf(&self, key: &Word) -> SmtLeaf;
fn root(&self) -> Word;
}
pub trait SmtBackend: SmtBackendReader {
fn compute_mutations(
&self,
updates: Vec<(Word, Word)>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error>;
fn apply_mutations(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<(), Self::Error>;
fn apply_mutations_with_reversion(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error>;
fn insert(&mut self, key: Word, value: Word) -> Result<Word, Self::Error>;
}
impl SmtBackendReader for Smt {
type Error = MerkleError;
fn num_leaves(&self) -> usize {
Smt::num_leaves(self)
}
fn num_entries(&self) -> usize {
Smt::num_entries(self)
}
fn leaves(&self) -> Box<dyn Iterator<Item = (LeafIndex<SMT_DEPTH>, SmtLeaf)> + '_> {
Box::new(Smt::leaves(self).map(|(idx, leaf)| (idx, leaf.clone())))
}
fn entries(&self) -> Box<dyn Iterator<Item = (Word, Word)> + '_> {
Box::new(Smt::entries(self).map(|(k, v)| (*k, *v)))
}
fn open(&self, key: &Word) -> SmtProof {
Smt::open(self, key)
}
fn get_value(&self, key: &Word) -> Word {
Smt::get_value(self, key)
}
fn get_leaf(&self, key: &Word) -> SmtLeaf {
Smt::get_leaf(self, key)
}
fn root(&self) -> Word {
Smt::root(self)
}
}
impl SmtBackend for Smt {
fn compute_mutations(
&self,
updates: Vec<(Word, Word)>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error> {
Smt::compute_mutations(self, updates)
}
fn apply_mutations(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<(), Self::Error> {
Smt::apply_mutations(self, set)
}
fn apply_mutations_with_reversion(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error> {
Smt::apply_mutations_with_reversion(self, set)
}
fn insert(&mut self, key: Word, value: Word) -> Result<Word, Self::Error> {
Smt::insert(self, key, value)
}
}
#[cfg(feature = "std")]
impl<Backend> SmtBackendReader for LargeSmt<Backend>
where
Backend: SmtStorageReader,
{
type Error = MerkleError;
fn num_leaves(&self) -> usize {
LargeSmt::num_leaves(self)
}
fn num_entries(&self) -> usize {
LargeSmt::num_entries(self)
}
fn leaves(&self) -> Box<dyn Iterator<Item = (LeafIndex<SMT_DEPTH>, SmtLeaf)> + '_> {
Box::new(
LargeSmt::leaves(self)
.expect("Only IO can error out here")
.map(|leaf| leaf.expect("Only IO can error out here")),
)
}
fn entries(&self) -> Box<dyn Iterator<Item = (Word, Word)> + '_> {
Box::new(
LargeSmt::entries(self)
.expect("Storage I/O error accessing entries")
.map(|entry| entry.expect("Storage I/O error accessing entries")),
)
}
fn open(&self, key: &Word) -> SmtProof {
LargeSmt::open(self, key)
}
fn get_value(&self, key: &Word) -> Word {
LargeSmt::get_value(self, key)
}
fn get_leaf(&self, key: &Word) -> SmtLeaf {
LargeSmt::get_leaf(self, key)
}
fn root(&self) -> Word {
LargeSmt::root(self)
}
}
#[cfg(feature = "std")]
impl<Backend> SmtBackend for LargeSmt<Backend>
where
Backend: SmtStorage,
{
fn compute_mutations(
&self,
updates: Vec<(Word, Word)>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error> {
LargeSmt::compute_mutations(self, updates).map_err(large_smt_error_to_merkle_error)
}
fn apply_mutations(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<(), Self::Error> {
LargeSmt::apply_mutations(self, set).map_err(large_smt_error_to_merkle_error)
}
fn apply_mutations_with_reversion(
&mut self,
set: MutationSet<SMT_DEPTH, Word, Word>,
) -> Result<MutationSet<SMT_DEPTH, Word, Word>, Self::Error> {
LargeSmt::apply_mutations_with_reversion(self, set).map_err(large_smt_error_to_merkle_error)
}
fn insert(&mut self, key: Word, value: Word) -> Result<Word, Self::Error> {
LargeSmt::insert(self, key, value)
}
}
#[cfg(feature = "std")]
pub(crate) fn large_smt_error_to_merkle_error(err: LargeSmtError) -> MerkleError {
match err {
LargeSmtError::Storage(storage_err) => {
panic!("Storage error encountered: {:?}", storage_err)
},
LargeSmtError::StorageNotEmpty => {
panic!("StorageNotEmpty error encountered: {:?}", err)
},
LargeSmtError::Merkle(merkle_err) => merkle_err,
LargeSmtError::RootMismatch { expected, actual } => MerkleError::ConflictingRoots {
expected_root: expected,
actual_root: actual,
},
}
}