This repository has been archived by the owner on May 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathbinary.rs
138 lines (116 loc) · 3.79 KB
/
binary.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
extern crate core;
use rand::{seq::IteratorRandom, thread_rng, Rng};
use sha2::{Digest, Sha256};
use fuel_merkle::{
binary::{MerkleTree, Primitive},
common::{Bytes32, StorageMap},
};
use fuel_merkle_test_helpers::binary::MerkleTree as ReferenceMerkleTree;
use fuel_storage::Mappable;
struct TestTable;
impl Mappable for TestTable {
type Key = u64;
type SetValue = Primitive;
type GetValue = Self::SetValue;
}
// During test setup, we randomly sample the pool of test data to generate the
// leaf set for the test and reference Merkle trees. Each test consists of a
// number of iterations, and at each iteration we specify a larger sample size.
const SAMPLE_SIZES: &[usize] = &[
1, 2, 5, 7, 8, 9, 64, 500, 512, 1000, 1024, 2048, 5000, 10000,
];
fn sum(data: &[u8]) -> Bytes32 {
let mut hash = Sha256::new();
hash.update(data);
hash.finalize().into()
}
#[test]
fn test_roots() {
let test_data_count = 2u64.pow(16);
let test_data = (0..test_data_count)
.map(|i| sum(&i.to_be_bytes()))
.collect::<Vec<Bytes32>>();
let mut rng = thread_rng();
for samples in SAMPLE_SIZES {
let sample_data = test_data
.iter()
.cloned()
.choose_multiple(&mut rng, *samples);
let expected_root = {
let mut reference_tree = ReferenceMerkleTree::new();
for datum in sample_data.iter() {
reference_tree.push(datum);
}
reference_tree.root()
};
let root = {
let storage = StorageMap::<TestTable>::new();
let mut test_tree = MerkleTree::new(storage);
for datum in sample_data.iter() {
test_tree.push(datum).unwrap();
}
test_tree.root()
};
assert_eq!(root, expected_root);
}
}
#[test]
fn test_prove() {
let test_data_count = 2u64.pow(16);
let test_data = (0..test_data_count)
.map(|i| sum(&i.to_be_bytes()))
.collect::<Vec<Bytes32>>();
let mut rng = thread_rng();
for samples in SAMPLE_SIZES {
let sample_data = test_data
.iter()
.cloned()
.choose_multiple(&mut rng, *samples);
let index = rng.gen_range(0..*samples) as u64;
let expected_proof = {
let mut reference_tree = ReferenceMerkleTree::new();
reference_tree.set_proof_index(index);
for datum in sample_data.iter() {
reference_tree.push(datum);
}
reference_tree.prove()
};
let proof = {
let storage = StorageMap::<TestTable>::new();
let mut test_tree = MerkleTree::new(storage);
for datum in sample_data.iter() {
test_tree.push(datum).unwrap();
}
test_tree.prove(index).unwrap()
};
assert_eq!(proof, expected_proof);
}
}
#[test]
fn test_load() {
let test_data_count = 2u64.pow(16);
let test_data = (0..test_data_count)
.map(|i| sum(&i.to_be_bytes()))
.collect::<Vec<Bytes32>>();
let mut rng = thread_rng();
for samples in SAMPLE_SIZES {
let sample_data = test_data
.iter()
.cloned()
.choose_multiple(&mut rng, *samples);
let mut storage = StorageMap::<TestTable>::new();
let expected_root = {
let mut reference_tree = MerkleTree::new(&mut storage);
for datum in sample_data.iter() {
reference_tree.push(datum).unwrap();
}
reference_tree.root()
};
let root = {
let leaves_count = sample_data.len() as u64;
let test_tree = MerkleTree::load(&mut storage, leaves_count).unwrap();
test_tree.root()
};
assert_eq!(root, expected_root);
}
}