Skip to content

Commit

Permalink
feature: adding serialization to the SMT
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominik1999 committed Apr 17, 2024
1 parent 7edfef5 commit 8bd1407
Showing 1 changed file with 65 additions and 1 deletion.
66 changes: 65 additions & 1 deletion src/merkle/smt/full/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use super::{
EmptySubtreeRoots, Felt, InnerNode, InnerNodeInfo, LeafIndex, MerkleError, MerklePath,
NodeIndex, Rpo256, RpoDigest, SparseMerkleTree, Word, EMPTY_WORD,
};
use alloc::collections::{BTreeMap, BTreeSet};
use alloc::{
collections::{BTreeMap, BTreeSet},
string::ToString,
vec::Vec,
};

mod error;
pub use error::{SmtLeafError, SmtProofError};
Expand All @@ -12,6 +16,7 @@ pub use leaf::SmtLeaf;

mod proof;
pub use proof::SmtProof;
use winter_utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -294,3 +299,62 @@ impl From<&RpoDigest> for LeafIndex<SMT_DEPTH> {
Word::from(value).into()
}
}

// SERIALIZATION
// ================================================================================================

impl Serializable for Smt {
fn write_into<W: ByteWriter>(&self, target: &mut W) {
let filled_leaves = self.entries().collect::<Vec<_>>();

// Write the number of filled leaves for this map
target.write_u8(filled_leaves.len() as u8);

// Write each (key, value) pair
for (key, value) in filled_leaves {
target.write(key);
target.write(value);
}
}
}

impl Deserializable for Smt {
fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
// read the number of filled leaves for this StorageMap
let num_filled_leaves = source.read_u8()?;
let mut entries = Vec::with_capacity(num_filled_leaves as usize);

for _ in 0..num_filled_leaves {
let key = source.read()?;
let value = source.read()?;
entries.push((key, value));
}

Self::with_entries(entries)
.map_err(|err| DeserializationError::InvalidValue(err.to_string()))
}
}

#[test]
fn test_smt_serialization_deserialization() {
// SMT for default types (empty map)
let storage_map_default = Smt::default();
let bytes = storage_map_default.to_bytes();
assert_eq!(storage_map_default, Smt::read_from_bytes(&bytes).unwrap());

// SMT with values
let storage_map_leaves_2: [(RpoDigest, Word); 2] = [
(
RpoDigest::new([Felt::new(101), Felt::new(102), Felt::new(103), Felt::new(104)]),
[Felt::new(1_u64), Felt::new(2_u64), Felt::new(3_u64), Felt::new(4_u64)],
),
(
RpoDigest::new([Felt::new(105), Felt::new(106), Felt::new(107), Felt::new(108)]),
[Felt::new(5_u64), Felt::new(6_u64), Felt::new(7_u64), Felt::new(8_u64)],
),
];
let storage_map = Smt::with_entries(storage_map_leaves_2).unwrap();

let bytes = storage_map.to_bytes();
assert_eq!(storage_map, Smt::read_from_bytes(&bytes).unwrap());
}

0 comments on commit 8bd1407

Please sign in to comment.