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