miden_crypto/merkle/smt/full/
leaf.rs1use alloc::{string::ToString, vec::Vec};
2
3use super::EMPTY_WORD;
4use crate::{
5 Felt, Word,
6 hash::poseidon2::Poseidon2,
7 merkle::smt::{LEAF_DOMAIN, LeafIndex, MAX_LEAF_ENTRIES, SMT_DEPTH, SmtLeafError},
8 utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
9};
10
11const DOUBLE_WORD_LEN: usize = 8;
13
14#[derive(Clone, Debug, PartialEq, Eq)]
18pub enum SmtLeaf {
19 Empty(LeafIndex<SMT_DEPTH>),
21 Single((Word, Word)),
23 Multiple(Vec<(Word, Word)>),
25}
26
27impl SmtLeaf {
28 pub fn new(
38 entries: Vec<(Word, Word)>,
39 leaf_index: LeafIndex<SMT_DEPTH>,
40 ) -> Result<Self, SmtLeafError> {
41 match entries.len() {
42 0 => Ok(Self::new_empty(leaf_index)),
43 1 => {
44 let (key, value) = entries[0];
45
46 let computed_index = LeafIndex::<SMT_DEPTH>::from(key);
47 if computed_index != leaf_index {
48 return Err(SmtLeafError::InconsistentSingleLeafIndices {
49 key,
50 expected_leaf_index: leaf_index,
51 actual_leaf_index: computed_index,
52 });
53 }
54
55 Ok(Self::new_single(key, value))
56 },
57 _ => {
58 let leaf = Self::new_multiple(entries)?;
59
60 if leaf.index() != leaf_index {
63 Err(SmtLeafError::InconsistentMultipleLeafIndices {
64 leaf_index_from_keys: leaf.index(),
65 leaf_index_supplied: leaf_index,
66 })
67 } else {
68 Ok(leaf)
69 }
70 },
71 }
72 }
73
74 pub fn new_empty(leaf_index: LeafIndex<SMT_DEPTH>) -> Self {
76 Self::Empty(leaf_index)
77 }
78
79 pub fn new_single(key: Word, value: Word) -> Self {
82 Self::Single((key, value))
83 }
84
85 pub fn new_multiple(entries: Vec<(Word, Word)>) -> Result<Self, SmtLeafError> {
92 if entries.len() < 2 {
93 return Err(SmtLeafError::MultipleLeafRequiresTwoEntries(entries.len()));
94 }
95
96 if entries.len() > MAX_LEAF_ENTRIES {
97 return Err(SmtLeafError::TooManyLeafEntries { actual: entries.len() });
98 }
99
100 {
102 let mut keys = entries.iter().map(|(key, _)| key);
103
104 let first_key = *keys.next().expect("ensured at least 2 entries");
105 let first_leaf_index: LeafIndex<SMT_DEPTH> = first_key.into();
106
107 for &next_key in keys {
108 let next_leaf_index: LeafIndex<SMT_DEPTH> = next_key.into();
109
110 if next_leaf_index != first_leaf_index {
111 return Err(SmtLeafError::InconsistentMultipleLeafKeys {
112 key_1: first_key,
113 key_2: next_key,
114 });
115 }
116 }
117 }
118
119 Ok(Self::Multiple(entries))
120 }
121
122 pub fn get_value(&self, key: &Word) -> Option<Word> {
128 if self.index() != (*key).into() {
130 return None;
131 }
132
133 match self {
134 SmtLeaf::Empty(_) => Some(EMPTY_WORD),
135 SmtLeaf::Single((key_in_leaf, value_in_leaf)) => {
136 if key == key_in_leaf {
137 Some(*value_in_leaf)
138 } else {
139 Some(EMPTY_WORD)
140 }
141 },
142 SmtLeaf::Multiple(kv_pairs) => {
143 for (key_in_leaf, value_in_leaf) in kv_pairs {
144 if key == key_in_leaf {
145 return Some(*value_in_leaf);
146 }
147 }
148
149 Some(EMPTY_WORD)
150 },
151 }
152 }
153
154 pub fn is_empty(&self) -> bool {
156 matches!(self, Self::Empty(_))
157 }
158
159 pub fn index(&self) -> LeafIndex<SMT_DEPTH> {
161 match self {
162 SmtLeaf::Empty(leaf_index) => *leaf_index,
163 SmtLeaf::Single((key, _)) => (*key).into(),
164 SmtLeaf::Multiple(entries) => {
165 let (first_key, _) = entries[0];
167 first_key.into()
168 },
169 }
170 }
171
172 pub fn num_entries(&self) -> usize {
174 match self {
175 SmtLeaf::Empty(_) => 0,
176 SmtLeaf::Single(_) => 1,
177 SmtLeaf::Multiple(entries) => entries.len(),
178 }
179 }
180
181 pub fn hash(&self) -> Word {
183 match self {
184 SmtLeaf::Empty(_) => EMPTY_WORD,
185 SmtLeaf::Single((key, value)) => {
186 Poseidon2::merge_in_domain(&[*key, *value], LEAF_DOMAIN)
187 },
188 SmtLeaf::Multiple(kvs) => {
189 let elements: Vec<Felt> = kvs.iter().copied().flat_map(kv_to_elements).collect();
190 Poseidon2::hash_elements_in_domain(&elements, LEAF_DOMAIN)
191 },
192 }
193 }
194
195 pub fn entries(&self) -> &[(Word, Word)] {
200 match self {
201 SmtLeaf::Empty(_) => &[],
202 SmtLeaf::Single(kv_pair) => core::slice::from_ref(kv_pair),
203 SmtLeaf::Multiple(kv_pairs) => kv_pairs,
204 }
205 }
206
207 pub fn to_elements(&self) -> impl Iterator<Item = Felt> + '_ {
212 self.entries().iter().copied().flat_map(kv_to_elements)
213 }
214
215 pub fn to_entries(&self) -> impl Iterator<Item = (&Word, &Word)> + '_ {
217 self.entries().iter().map(|(k, v)| (k, v))
219 }
220
221 pub fn into_elements(self) -> Vec<Felt> {
223 self.into_entries().into_iter().flat_map(kv_to_elements).collect()
224 }
225
226 pub fn into_entries(self) -> Vec<(Word, Word)> {
228 match self {
229 SmtLeaf::Empty(_) => Vec::new(),
230 SmtLeaf::Single(kv_pair) => vec![kv_pair],
231 SmtLeaf::Multiple(kv_pairs) => kv_pairs,
232 }
233 }
234
235 pub fn try_from_elements(
237 elements: &[Felt],
238 leaf_index: LeafIndex<SMT_DEPTH>,
239 ) -> Result<SmtLeaf, SmtLeafError> {
240 if elements.is_empty() {
241 return Ok(SmtLeaf::new_empty(leaf_index));
242 }
243
244 if !elements.len().is_multiple_of(DOUBLE_WORD_LEN) {
246 return Err(SmtLeafError::DecodingError(
247 "elements length is not a multiple of 8".into(),
248 ));
249 }
250
251 let mut entries = Vec::with_capacity(elements.len() / DOUBLE_WORD_LEN);
252 for entry in elements.as_chunks::<DOUBLE_WORD_LEN>().0 {
253 let key = Word::new([entry[0], entry[1], entry[2], entry[3]]);
254 let value = Word::new([entry[4], entry[5], entry[6], entry[7]]);
255 entries.push((key, value));
256 }
257
258 SmtLeaf::new(entries, leaf_index)
259 }
260
261 pub(in crate::merkle::smt) fn insert(
273 &mut self,
274 key: Word,
275 value: Word,
276 ) -> Result<Option<Word>, SmtLeafError> {
277 match self {
278 SmtLeaf::Empty(_) => {
279 *self = SmtLeaf::new_single(key, value);
280 Ok(None)
281 },
282 SmtLeaf::Single(kv_pair) => {
283 if kv_pair.0 == key {
284 let old_value = kv_pair.1;
287 kv_pair.1 = value;
288 Ok(Some(old_value))
289 } else {
290 let mut pairs = vec![*kv_pair, (key, value)];
295 pairs.sort_by_key(|(key, _)| *key);
296 *self = SmtLeaf::Multiple(pairs);
297 Ok(None)
298 }
299 },
300 SmtLeaf::Multiple(kv_pairs) => {
301 match kv_pairs.binary_search_by(|kv_pair| kv_pair.0.cmp(&key)) {
302 Ok(pos) => {
303 let old_value = kv_pairs[pos].1;
304 kv_pairs[pos].1 = value;
305 Ok(Some(old_value))
306 },
307 Err(pos) => {
308 if kv_pairs.len() >= MAX_LEAF_ENTRIES {
309 return Err(SmtLeafError::TooManyLeafEntries {
310 actual: kv_pairs.len() + 1,
311 });
312 }
313 kv_pairs.insert(pos, (key, value));
314 Ok(None)
315 },
316 }
317 },
318 }
319 }
320
321 pub(in crate::merkle::smt) fn remove(&mut self, key: Word) -> (Option<Word>, bool) {
325 match self {
326 SmtLeaf::Empty(_) => (None, false),
327 SmtLeaf::Single((key_at_leaf, value_at_leaf)) => {
328 if *key_at_leaf == key {
329 let old_value = *value_at_leaf;
332
333 *self = SmtLeaf::new_empty(key.into());
336
337 (Some(old_value), true)
338 } else {
339 (None, false)
341 }
342 },
343 SmtLeaf::Multiple(kv_pairs) => {
344 match kv_pairs.binary_search_by(|kv_pair| kv_pair.0.cmp(&key)) {
345 Ok(pos) => {
346 let old_value = kv_pairs[pos].1;
347
348 let _ = kv_pairs.remove(pos);
349 debug_assert!(!kv_pairs.is_empty());
350
351 if kv_pairs.len() == 1 {
352 *self = SmtLeaf::Single(kv_pairs[0]);
354 }
355
356 (Some(old_value), false)
357 },
358 Err(_) => {
359 (None, false)
361 },
362 }
363 },
364 }
365 }
366}
367
368impl Serializable for SmtLeaf {
369 fn write_into<W: ByteWriter>(&self, target: &mut W) {
370 self.num_entries().write_into(target);
372
373 let leaf_index: u64 = self.index().position();
375 leaf_index.write_into(target);
376
377 for (key, value) in self.entries() {
379 key.write_into(target);
380 value.write_into(target);
381 }
382 }
383}
384
385impl Deserializable for SmtLeaf {
386 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
387 let num_entries = source.read_usize()?;
389
390 let leaf_index: LeafIndex<SMT_DEPTH> = {
392 let value = source.read_u64()?;
393 LeafIndex::new_max_depth(value)
394 };
395
396 let entries: Vec<(Word, Word)> =
398 source.read_many_iter(num_entries)?.collect::<Result<_, _>>()?;
399
400 Self::new(entries, leaf_index)
401 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))
402 }
403
404 fn min_serialized_size() -> usize {
406 1 + 8
407 }
408}
409
410pub(crate) fn kv_to_elements((key, value): (Word, Word)) -> impl Iterator<Item = Felt> {
415 let key_elements = key.into_iter();
416 let value_elements = value.into_iter();
417
418 key_elements.chain(value_elements)
419}