fuel_vm/
crypto.rs

1//! Crypto implementations for the instructions
2
3use fuel_merkle::binary::root_calculator::MerkleRootCalculator as MerkleTree;
4use fuel_types::Bytes32;
5
6/// Calculate a binary merkle root with in-memory storage
7pub 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    // Test for 0 leaves
40    //
41    // Expected root is `h()`
42    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    // Test for 5 leaves
50    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}