1use alloc::{string::String, vec::Vec};
2use core::{fmt, slice};
3
4use super::{InnerNodeInfo, MerkleError, MerklePath, NodeIndex, Poseidon2, Word};
5use crate::utils::{assume_init_vec, uninit_vector, word_to_hex};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct MerkleTree {
13 nodes: Vec<Word>,
14}
15
16impl MerkleTree {
17 pub fn new<T>(leaves: T) -> Result<Self, MerkleError>
24 where
25 T: AsRef<[Word]>,
26 {
27 let leaves = leaves.as_ref();
28 let n = leaves.len();
29 if n <= 1 {
30 return Err(MerkleError::DepthTooSmall(n as u8));
31 } else if !n.is_power_of_two() {
32 return Err(MerkleError::NumLeavesNotPowerOfTwo(n));
33 }
34
35 let mut nodes = uninit_vector::<Word>(2 * n);
40 nodes[0].write(Word::default());
41
42 nodes[n..].iter_mut().zip(leaves).for_each(|(node, leaf)| {
44 node.write(*leaf);
45 });
46
47 for i in (1..n).rev() {
49 let left = unsafe { nodes[2 * i].assume_init_read() };
52 let right = unsafe { nodes[2 * i + 1].assume_init_read() };
53 nodes[i].write(Poseidon2::merge(&[left, right]));
54 }
55
56 let nodes = unsafe { assume_init_vec(nodes) };
58
59 Ok(Self { nodes })
60 }
61
62 pub fn root(&self) -> Word {
67 self.nodes[1]
68 }
69
70 pub fn depth(&self) -> u8 {
74 (self.nodes.len() / 2).ilog2() as u8
75 }
76
77 pub fn get_node(&self, index: NodeIndex) -> Result<Word, MerkleError> {
84 if index.is_root() {
85 return Err(MerkleError::DepthTooSmall(index.depth()));
86 } else if index.depth() > self.depth() {
87 return Err(MerkleError::DepthTooBig(index.depth() as u64));
88 }
89
90 let pos = index.to_scalar_index()? as usize;
91 Ok(self.nodes[pos])
92 }
93
94 pub fn get_path(&self, index: NodeIndex) -> Result<MerklePath, MerkleError> {
102 if index.is_root() {
103 return Err(MerkleError::DepthTooSmall(index.depth()));
104 } else if index.depth() > self.depth() {
105 return Err(MerkleError::DepthTooBig(index.depth() as u64));
106 }
107
108 Ok(MerklePath::from(Vec::from_iter(
109 index.proof_indices().map(|index| self.get_node(index).unwrap()),
110 )))
111 }
112
113 pub fn leaves(&self) -> impl Iterator<Item = (u64, &Word)> {
118 let leaves_start = self.nodes.len() / 2;
119 self.nodes.iter().skip(leaves_start).enumerate().map(|(i, v)| (i as u64, v))
120 }
121
122 pub fn inner_nodes(&self) -> InnerNodeIterator<'_> {
126 InnerNodeIterator {
127 nodes: &self.nodes,
128 index: 1, }
130 }
131
132 pub fn update_leaf<'a>(&'a mut self, index_value: u64, value: Word) -> Result<(), MerkleError> {
140 let mut index = NodeIndex::new(self.depth(), index_value)?;
141
142 debug_assert_eq!(self.nodes.len() & 1, 0);
151 let n = self.nodes.len() / 2;
152
153 let ptr = self.nodes.as_ptr() as *const [Word; 2];
159 let pairs: &'a [[Word; 2]] = unsafe { slice::from_raw_parts(ptr, n) };
160
161 let pos = index.to_scalar_index()? as usize;
163 self.nodes[pos] = value;
164
165 for _ in 0..index.depth() {
167 index.move_up();
168 let pos = index.to_scalar_index()? as usize;
169 let value = Poseidon2::merge(&pairs[pos]);
170 self.nodes[pos] = value;
171 }
172
173 Ok(())
174 }
175}
176
177impl TryFrom<&[Word]> for MerkleTree {
181 type Error = MerkleError;
182
183 fn try_from(value: &[Word]) -> Result<Self, Self::Error> {
184 MerkleTree::new(value)
185 }
186}
187
188pub struct InnerNodeIterator<'a> {
195 nodes: &'a Vec<Word>,
196 index: usize,
197}
198
199impl Iterator for InnerNodeIterator<'_> {
200 type Item = InnerNodeInfo;
201
202 fn next(&mut self) -> Option<Self::Item> {
203 if self.index < self.nodes.len() / 2 {
204 let value = self.index;
205 let left = self.index * 2;
206 let right = left + 1;
207
208 self.index += 1;
209
210 Some(InnerNodeInfo {
211 value: self.nodes[value],
212 left: self.nodes[left],
213 right: self.nodes[right],
214 })
215 } else {
216 None
217 }
218 }
219}
220
221pub fn tree_to_text(tree: &MerkleTree) -> Result<String, fmt::Error> {
226 let indent = " ";
227 let mut s = String::new();
228 s.push_str(&word_to_hex(&tree.root())?);
229 s.push('\n');
230 for d in 1..=tree.depth() {
231 let entries = 2u64.pow(d.into());
232 for i in 0..entries {
233 let index = NodeIndex::new(d, i).expect("The index must always be valid");
234 let node = tree.get_node(index).expect("The node must always be found");
235
236 for _ in 0..d {
237 s.push_str(indent);
238 }
239 s.push_str(&word_to_hex(&node)?);
240 s.push('\n');
241 }
242 }
243
244 Ok(s)
245}
246
247pub fn path_to_text(path: &MerklePath) -> Result<String, fmt::Error> {
249 let mut s = String::new();
250 s.push('[');
251
252 for el in path.iter() {
253 s.push_str(&word_to_hex(el)?);
254 s.push_str(", ");
255 }
256
257 if !path.is_empty() {
259 s.pop();
260 s.pop();
261 }
262 s.push(']');
263
264 Ok(s)
265}
266
267#[cfg(test)]
271mod tests {
272 use core::mem::size_of;
273
274 use proptest::prelude::*;
275
276 use super::*;
277 use crate::{
278 Felt,
279 merkle::{int_to_leaf, int_to_node},
280 };
281
282 const LEAVES4: [Word; Word::NUM_ELEMENTS] =
283 [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
284
285 const LEAVES8: [Word; 8] = [
286 int_to_node(1),
287 int_to_node(2),
288 int_to_node(3),
289 int_to_node(4),
290 int_to_node(5),
291 int_to_node(6),
292 int_to_node(7),
293 int_to_node(8),
294 ];
295
296 #[test]
297 fn build_merkle_tree() {
298 let tree = MerkleTree::new(LEAVES4).unwrap();
299 assert_eq!(8, tree.nodes.len());
300
301 for (a, b) in tree.nodes.iter().skip(4).zip(LEAVES4.iter()) {
303 assert_eq!(a, b);
304 }
305
306 let (root, node2, node3) = compute_internal_nodes();
307
308 assert_eq!(root, tree.nodes[1]);
309 assert_eq!(node2, tree.nodes[2]);
310 assert_eq!(node3, tree.nodes[3]);
311
312 assert_eq!(root, tree.root());
313 }
314
315 #[test]
316 fn get_leaf() {
317 let tree = MerkleTree::new(LEAVES4).unwrap();
318
319 assert_eq!(LEAVES4[0], tree.get_node(NodeIndex::make(2, 0)).unwrap());
321 assert_eq!(LEAVES4[1], tree.get_node(NodeIndex::make(2, 1)).unwrap());
322 assert_eq!(LEAVES4[2], tree.get_node(NodeIndex::make(2, 2)).unwrap());
323 assert_eq!(LEAVES4[3], tree.get_node(NodeIndex::make(2, 3)).unwrap());
324
325 let (_, node2, node3) = compute_internal_nodes();
327
328 assert_eq!(node2, tree.get_node(NodeIndex::make(1, 0)).unwrap());
329 assert_eq!(node3, tree.get_node(NodeIndex::make(1, 1)).unwrap());
330 }
331
332 #[test]
333 fn get_path() {
334 let tree = MerkleTree::new(LEAVES4).unwrap();
335
336 let (_, node2, node3) = compute_internal_nodes();
337
338 assert_eq!(vec![LEAVES4[1], node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap());
340 assert_eq!(vec![LEAVES4[0], node3], *tree.get_path(NodeIndex::make(2, 1)).unwrap());
341 assert_eq!(vec![LEAVES4[3], node2], *tree.get_path(NodeIndex::make(2, 2)).unwrap());
342 assert_eq!(vec![LEAVES4[2], node2], *tree.get_path(NodeIndex::make(2, 3)).unwrap());
343
344 assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap());
346 assert_eq!(vec![node2], *tree.get_path(NodeIndex::make(1, 1)).unwrap());
347 }
348
349 #[test]
350 fn update_leaf() {
351 let mut tree = MerkleTree::new(LEAVES8).unwrap();
352
353 let value = 3;
355 let new_node = int_to_leaf(9);
356 let mut expected_leaves = LEAVES8.to_vec();
357 expected_leaves[value as usize] = new_node;
358 let expected_tree = MerkleTree::new(expected_leaves.clone()).unwrap();
359
360 tree.update_leaf(value, new_node).unwrap();
361 assert_eq!(expected_tree.nodes, tree.nodes);
362
363 let value = 6;
365 let new_node = int_to_leaf(10);
366 expected_leaves[value as usize] = new_node;
367 let expected_tree = MerkleTree::new(expected_leaves.clone()).unwrap();
368
369 tree.update_leaf(value, new_node).unwrap();
370 assert_eq!(expected_tree.nodes, tree.nodes);
371 }
372
373 #[test]
374 fn nodes() -> Result<(), MerkleError> {
375 let tree = MerkleTree::new(LEAVES4).unwrap();
376 let root = tree.root();
377 let l1n0 = tree.get_node(NodeIndex::make(1, 0))?;
378 let l1n1 = tree.get_node(NodeIndex::make(1, 1))?;
379 let l2n0 = tree.get_node(NodeIndex::make(2, 0))?;
380 let l2n1 = tree.get_node(NodeIndex::make(2, 1))?;
381 let l2n2 = tree.get_node(NodeIndex::make(2, 2))?;
382 let l2n3 = tree.get_node(NodeIndex::make(2, 3))?;
383
384 let nodes: Vec<InnerNodeInfo> = tree.inner_nodes().collect();
385 let expected = vec![
386 InnerNodeInfo { value: root, left: l1n0, right: l1n1 },
387 InnerNodeInfo { value: l1n0, left: l2n0, right: l2n1 },
388 InnerNodeInfo { value: l1n1, left: l2n2, right: l2n3 },
389 ];
390 assert_eq!(nodes, expected);
391
392 Ok(())
393 }
394
395 proptest! {
396 #[test]
397 fn arbitrary_word_can_be_represented_as_digest(
398 a in prop::num::u64::ANY,
399 b in prop::num::u64::ANY,
400 c in prop::num::u64::ANY,
401 d in prop::num::u64::ANY,
402 ) {
403 let word = [Felt::new_unchecked(a), Felt::new_unchecked(b), Felt::new_unchecked(c), Felt::new_unchecked(d)];
409 let digest = Word::from(word);
410
411 let word_ptr = word.as_ptr() as *const u8;
413 let digest_ptr = digest.as_ptr() as *const u8;
414 assert_ne!(word_ptr, digest_ptr);
415
416 let word_bytes = unsafe { slice::from_raw_parts(word_ptr, size_of::<Word>()) };
418 let digest_bytes = unsafe { slice::from_raw_parts(digest_ptr, size_of::<Word>()) };
419 assert_eq!(word_bytes, digest_bytes);
420 }
421 }
422
423 fn compute_internal_nodes() -> (Word, Word, Word) {
427 let node2 = Poseidon2::hash_elements(&[*LEAVES4[0], *LEAVES4[1]].concat());
428 let node3 = Poseidon2::hash_elements(&[*LEAVES4[2], *LEAVES4[3]].concat());
429 let root = Poseidon2::merge(&[node2, node3]);
430
431 (root, node2, node3)
432 }
433}