Browse Source

feat: add de/serialization to `InOrderIndex` and `PartialMmr` (#329)

main
Santiago Pittella 7 months ago
committed by GitHub
parent
commit
2b184cd4ca
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
3 changed files with 75 additions and 5 deletions
  1. +4
    -0
      CHANGELOG.md
  2. +26
    -0
      src/merkle/mmr/inorder.rs
  3. +45
    -5
      src/merkle/mmr/partial.rs

+ 4
- 0
CHANGELOG.md

@ -1,3 +1,7 @@
## 0.10.1 (TBD)
* Added `Serializable` and `Deserializable` implementations for `PartialMmr` and `InOrderIndex` (#329).
## 0.10.0 (2024-08-06)
* Added more `RpoDigest` and `RpxDigest` conversions (#311).

+ 26
- 0
src/merkle/mmr/inorder.rs

@ -6,6 +6,8 @@
//! leaves count.
use core::num::NonZeroUsize;
use winter_utils::{Deserializable, Serializable};
// IN-ORDER INDEX
// ================================================================================================
@ -112,6 +114,21 @@ impl InOrderIndex {
}
}
impl Serializable for InOrderIndex {
fn write_into<W: winter_utils::ByteWriter>(&self, target: &mut W) {
target.write_usize(self.idx);
}
}
impl Deserializable for InOrderIndex {
fn read_from<R: winter_utils::ByteReader>(
source: &mut R,
) -> Result<Self, winter_utils::DeserializationError> {
let idx = source.read_usize()?;
Ok(InOrderIndex { idx })
}
}
// CONVERSIONS FROM IN-ORDER INDEX
// ------------------------------------------------------------------------------------------------
@ -127,6 +144,7 @@ impl From for u64 {
#[cfg(test)]
mod test {
use proptest::prelude::*;
use winter_utils::{Deserializable, Serializable};
use super::InOrderIndex;
@ -162,4 +180,12 @@ mod test {
assert_eq!(left.sibling(), right);
assert_eq!(left, right.sibling());
}
#[test]
fn test_inorder_index_serialization() {
let index = InOrderIndex::from_leaf_pos(5);
let bytes = index.to_bytes();
let index2 = InOrderIndex::read_from_bytes(&bytes).unwrap();
assert_eq!(index, index2);
}
}

+ 45
- 5
src/merkle/mmr/partial.rs

@ -1,12 +1,15 @@
use alloc::{
collections::{BTreeMap, BTreeSet},
vec::Vec,
};
use winter_utils::{Deserializable, Serializable};
use super::{MmrDelta, MmrProof, Rpo256, RpoDigest};
use crate::merkle::{
mmr::{leaf_to_corresponding_tree, nodes_in_forest},
InOrderIndex, InnerNodeInfo, MerklePath, MmrError, MmrPeaks,
};
use alloc::{
collections::{BTreeMap, BTreeSet},
vec::Vec,
};
// TYPE ALIASES
// ================================================================================================
@ -572,6 +575,28 @@ impl<'a, I: Iterator> Iterator for InnerNodeIterator<
}
}
impl Serializable for PartialMmr {
fn write_into<W: winter_utils::ByteWriter>(&self, target: &mut W) {
self.forest.write_into(target);
self.peaks.write_into(target);
self.nodes.write_into(target);
target.write_bool(self.track_latest);
}
}
impl Deserializable for PartialMmr {
fn read_from<R: winter_utils::ByteReader>(
source: &mut R,
) -> Result<Self, winter_utils::DeserializationError> {
let forest = usize::read_from(source)?;
let peaks = Vec::<RpoDigest>::read_from(source)?;
let nodes = NodeMap::read_from(source)?;
let track_latest = source.read_bool()?;
Ok(Self { forest, peaks, nodes, track_latest })
}
}
// UTILS
// ================================================================================================
@ -613,12 +638,15 @@ fn forest_to_rightmost_index(forest: usize) -> InOrderIndex {
#[cfg(test)]
mod tests {
use alloc::{collections::BTreeSet, vec::Vec};
use winter_utils::{Deserializable, Serializable};
use super::{
forest_to_rightmost_index, forest_to_root_index, InOrderIndex, MmrPeaks, PartialMmr,
RpoDigest,
};
use crate::merkle::{int_to_node, MerkleStore, Mmr, NodeIndex};
use alloc::{collections::BTreeSet, vec::Vec};
const LEAVES: [RpoDigest; 7] = [
int_to_node(0),
@ -907,4 +935,16 @@ mod tests {
// the openings should be the same
assert_eq!(mmr.open(5, mmr.forest()).unwrap(), partial_mmr.open(5).unwrap().unwrap());
}
#[test]
fn test_partial_mmr_serialization() {
let mmr = Mmr::from((0..7).map(int_to_node));
let forest_size = mmr.forest();
let partial_mmr = PartialMmr::from_peaks(mmr.peaks(forest_size).unwrap());
let bytes = partial_mmr.to_bytes();
let decoded = PartialMmr::read_from_bytes(&bytes).unwrap();
assert_eq!(partial_mmr, decoded);
}
}

Loading…
Cancel
Save