1
- use merkletree:: hash:: Algorithm ;
2
- use merkletree:: merkle;
3
- use merkletree:: merkle:: VecStore ;
4
- use merkletree:: proof:: Proof ;
1
+ use merkletree:: { hash:: Algorithm , merkle, merkle:: VecStore , proof:: Proof } ;
2
+ use std:: fmt;
5
3
use std:: hash:: Hasher ;
6
4
use std:: iter:: FromIterator ;
5
+ use thiserror:: Error ;
7
6
use tiny_keccak:: Keccak ;
8
7
9
8
#[ derive( Clone ) ]
10
9
struct KeccakAlgorithm ( Keccak ) ;
11
10
11
+ impl fmt:: Debug for KeccakAlgorithm {
12
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
13
+ write ! ( f, "Keccak256 Algorithm" )
14
+ }
15
+ }
16
+
12
17
impl KeccakAlgorithm {
13
18
pub fn new ( ) -> KeccakAlgorithm {
14
19
KeccakAlgorithm ( Keccak :: new_keccak256 ( ) )
@@ -72,39 +77,49 @@ impl Algorithm<MerkleItem> for KeccakAlgorithm {
72
77
type ExternalMerkleTree =
73
78
merkletree:: merkle:: MerkleTree < MerkleItem , KeccakAlgorithm , VecStore < MerkleItem > > ;
74
79
75
- #[ derive( Clone ) ]
80
+ #[ derive( Debug , Clone ) ]
76
81
enum Tree {
77
82
SingleItem ( MerkleItem ) ,
78
83
MerkleTree ( ExternalMerkleTree ) ,
79
84
}
80
85
86
+ #[ derive( Debug , Error , Eq , PartialEq ) ]
87
+ pub enum Error {
88
+ #[ error( "No leaves were provided" ) ]
89
+ ZeroLeaves ,
90
+ }
91
+
92
+ #[ derive( Debug ) ]
81
93
pub struct MerkleTree {
82
94
tree : Tree ,
83
95
root : MerkleItem ,
84
96
}
85
97
86
98
impl MerkleTree {
87
- pub fn new ( data : & [ MerkleItem ] ) -> MerkleTree {
99
+ pub fn new ( data : & [ MerkleItem ] ) -> Result < MerkleTree , Error > {
88
100
let mut leaves: Vec < MerkleItem > = data. to_owned ( ) ;
89
-
90
- let tree: Tree = if leaves. len ( ) == 1 {
91
- Tree :: SingleItem ( leaves[ 0 ] . to_owned ( ) )
92
- } else {
93
- // sort the merkle tree leaves
94
- leaves. sort ( ) ;
95
- // remove duplicates
96
- leaves. dedup_by ( |a, b| a == b) ;
97
-
98
- let merkletree = merkle:: MerkleTree :: from_iter ( leaves) ;
99
- Tree :: MerkleTree ( merkletree)
101
+ // sort the MerkleTree leaves
102
+ leaves. sort ( ) ;
103
+ // remove duplicates **before** we check the leaves length
104
+ leaves. dedup_by ( |a, b| a == b) ;
105
+
106
+ let tree = match leaves. len ( ) {
107
+ 0 => return Err ( Error :: ZeroLeaves ) ,
108
+ // should never `panic!`, we have a single leaf after all
109
+ 1 => Tree :: SingleItem ( leaves. remove ( 0 ) ) ,
110
+ _ => {
111
+ let merkletree = merkle:: MerkleTree :: from_iter ( leaves) ;
112
+
113
+ Tree :: MerkleTree ( merkletree)
114
+ }
100
115
} ;
101
116
102
117
let root: MerkleItem = match & tree {
103
118
Tree :: SingleItem ( root) => root. to_owned ( ) ,
104
119
Tree :: MerkleTree ( merkletree) => merkletree. root ( ) ,
105
120
} ;
106
121
107
- MerkleTree { tree, root }
122
+ Ok ( MerkleTree { tree, root } )
108
123
}
109
124
110
125
pub fn root ( & self ) -> MerkleItem {
@@ -134,6 +149,12 @@ mod test {
134
149
use super :: * ;
135
150
use hex:: FromHex ;
136
151
152
+ #[ test]
153
+ fn it_returns_error_on_zero_leaves ( ) {
154
+ let error = MerkleTree :: new ( & [ ] ) . expect_err ( "ZeroLeaves error expected" ) ;
155
+ assert_eq ! ( Error :: ZeroLeaves , error) ;
156
+ }
157
+
137
158
#[ test]
138
159
fn it_generates_correct_merkle_tree_that_correlates_with_js_impl ( ) {
139
160
let h1 = <[ u8 ; 32 ] >:: from_hex (
@@ -145,7 +166,7 @@ mod test {
145
166
)
146
167
. unwrap ( ) ;
147
168
148
- let top = MerkleTree :: new ( & [ h1, h2] ) ;
169
+ let top = MerkleTree :: new ( & [ h1, h2] ) . expect ( "Should create MerkleTree" ) ;
149
170
150
171
let root = hex:: encode ( & top. root ( ) ) ;
151
172
@@ -172,7 +193,7 @@ mod test {
172
193
. unwrap ( ) ;
173
194
174
195
// duplicate leaves
175
- let top = MerkleTree :: new ( & [ h1, h2, h2] ) ;
196
+ let top = MerkleTree :: new ( & [ h1, h2, h2] ) . expect ( "Should create MerkleTree" ) ;
176
197
177
198
let root = hex:: encode ( & top. root ( ) ) ;
178
199
@@ -204,7 +225,7 @@ mod test {
204
225
. unwrap ( ) ;
205
226
206
227
// odd leaves
207
- let top = MerkleTree :: new ( & [ h1, h2, h3] ) ;
228
+ let top = MerkleTree :: new ( & [ h1, h2, h3] ) . expect ( "Should create MerkleTree" ) ;
208
229
209
230
let root = hex:: encode ( & top. root ( ) ) ;
210
231
0 commit comments