1use fuel_merkle::binary::root_calculator::MerkleRootCalculator as MerkleTree;
4use fuel_types::Bytes32;
5
6pub fn ephemeral_merkle_root<L, I>(leaves: I) -> Bytes32
8where
9 L: AsRef<[u8]>,
10 I: Iterator<Item = L> + ExactSizeIterator,
11{
12 let mut tree = MerkleTree::new();
13 leaves.for_each(|l| tree.push(l.as_ref()));
14 tree.root().into()
15}
16
17#[test]
18#[cfg(feature = "random")]
19fn ephemeral_merkle_root_returns_the_expected_root() {
20 use fuel_crypto::Hasher;
21 use rand::{
22 rngs::StdRng,
23 Rng,
24 SeedableRng,
25 };
26
27 use alloc::{
28 vec,
29 vec::Vec,
30 };
31
32 use crate::prelude::*;
33
34 let mut rng = StdRng::seed_from_u64(2322u64);
35
36 const LEAF_PREFIX: u8 = 0x00;
37 const NODE_PREFIX: u8 = 0x01;
38
39 let empty: Vec<Address> = vec![];
43
44 let root = ephemeral_merkle_root(empty.iter());
45 let empty = Hasher::default().digest();
46
47 assert_eq!(empty, root);
48
49 let a: Address = rng.gen();
51 let b: Address = rng.gen();
52 let c: Address = rng.gen();
53 let d: Address = rng.gen();
54 let e: Address = rng.gen();
55
56 let initial = [a, b, c, d, e];
57
58 let a = Hasher::default().chain([LEAF_PREFIX]).chain(a).digest();
59 let b = Hasher::default().chain([LEAF_PREFIX]).chain(b).digest();
60 let c = Hasher::default().chain([LEAF_PREFIX]).chain(c).digest();
61 let d = Hasher::default().chain([LEAF_PREFIX]).chain(d).digest();
62 let e = Hasher::default().chain([LEAF_PREFIX]).chain(e).digest();
63
64 let a = Hasher::default()
65 .chain([NODE_PREFIX])
66 .extend_chain([a, b])
67 .digest();
68 let b = Hasher::default()
69 .chain([NODE_PREFIX])
70 .extend_chain([c, d])
71 .digest();
72 let c = e;
73
74 let a = Hasher::default()
75 .chain([NODE_PREFIX])
76 .extend_chain([a, b])
77 .digest();
78 let b = c;
79
80 let root = Hasher::default()
81 .chain([NODE_PREFIX])
82 .extend_chain([a, b])
83 .digest();
84 let root_p = ephemeral_merkle_root(initial.iter());
85
86 assert_eq!(root, root_p);
87}