miden_crypto/merkle/smt/partial/serialization/
mod.rs1pub mod property_tests;
5mod tests;
6
7use alloc::{collections::BTreeMap, string::ToString};
8
9use miden_field::Word;
10use miden_serde_utils::{
11 ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
12};
13
14use crate::merkle::{
15 EmptySubtreeRoots, NodeIndex,
16 smt::{LeafIndex, SMT_DEPTH, SmtLeaf},
17};
18
19#[derive(Clone, Debug, Eq, PartialEq)]
38pub struct UniqueNodes {
39 pub root: Word,
44
45 pub nodes: BTreeMap<NodeIndex, Word>,
49
50 pub leaves: BTreeMap<u64, SmtLeaf>,
54
55 pub value_only_leaves: BTreeMap<u64, Word>,
59}
60
61impl UniqueNodes {
62 pub fn empty() -> Self {
64 Self {
65 root: *EmptySubtreeRoots::entry(SMT_DEPTH, 0),
66 nodes: BTreeMap::new(),
67 leaves: BTreeMap::new(),
68 value_only_leaves: BTreeMap::new(),
69 }
70 }
71
72 pub fn get_leaf_hash(&self, position: u64) -> Word {
74 self.leaves
75 .get(&position)
76 .map(SmtLeaf::hash)
77 .or_else(|| self.value_only_leaves.get(&position).copied())
78 .unwrap_or_else(|| SmtLeaf::new_empty(LeafIndex::new_max_depth(position)).hash())
79 }
80
81 pub fn get_node_hash(&self, index: NodeIndex) -> Word {
83 self.nodes
84 .get(&index)
85 .copied()
86 .unwrap_or_else(|| *EmptySubtreeRoots::entry(SMT_DEPTH, index.depth()))
87 }
88
89 pub(super) fn validate(&self) -> Result<(), DeserializationError> {
91 for (&position, leaf) in &self.leaves {
92 if position != leaf.index().position() {
93 return Err(DeserializationError::InvalidValue(format!(
94 "Node index {position} did not match the embedded leaf index {}",
95 leaf.index().position()
96 )));
97 }
98 }
99
100 Ok(())
101 }
102}
103
104impl Default for UniqueNodes {
105 fn default() -> Self {
106 Self::empty()
107 }
108}
109
110impl Serializable for UniqueNodes {
111 fn write_into<W: ByteWriter>(&self, target: &mut W) {
112 self.root.write_into(target);
114
115 let mut levels = self.nodes.iter().peekable();
118 let level_count = self
119 .nodes
120 .keys()
121 .map(NodeIndex::depth)
122 .fold((0, None), |(count, previous), depth| {
123 (count + u64::from(previous != Some(depth)), Some(depth))
124 })
125 .0;
126 target.write(level_count);
127
128 while let Some((index, _)) = levels.peek() {
129 let depth = index.depth();
130 target.write(depth);
131 let level_node_count =
132 levels.clone().take_while(|(index, _)| index.depth() == depth).count();
133 target.write(level_node_count as u64);
134 for (index, value) in levels.by_ref().take(level_node_count) {
135 target.write(index.position());
136 target.write(value);
137 }
138 }
139
140 let leaf_count = self.leaves.len() as u64;
142 target.write(leaf_count);
143 target.write_many(self.leaves.iter());
144
145 let value_only_leaf_count = self.value_only_leaves.len() as u64;
147 target.write(value_only_leaf_count);
148 target.write_many(self.value_only_leaves.iter());
149 }
150}
151
152impl Deserializable for UniqueNodes {
153 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
154 let root = Word::read_from(source)?;
157
158 let level_count = source.read_u64()?;
160 let mut nodes = BTreeMap::new();
161
162 for _ in 0..level_count {
164 let depth = source.read_u8()?;
165 let node_count = source.read_u64()?;
166 for _ in 0..node_count {
167 let position = source.read_u64()?;
168 let index = NodeIndex::new(depth, position)
169 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))?;
170 let value = source.read()?;
171 nodes.insert(index, value);
172 }
173 }
174
175 let leaf_count = source.read_u64()?;
177 let mut leaves = BTreeMap::new();
178
179 for _ in 0..leaf_count {
181 let (position, leaf) = source.read()?;
182 leaves.insert(position, leaf);
183 }
184
185 let value_only_leaf_count = source.read_u64()?;
187 let mut value_only_leaves = BTreeMap::new();
188
189 for _ in 0..value_only_leaf_count {
191 let (position, value) = source.read()?;
192 value_only_leaves.insert(position, value);
193 }
194
195 let unique_nodes = Self { root, nodes, leaves, value_only_leaves };
196 unique_nodes.validate()?;
197 Ok(unique_nodes)
198 }
199}