@@ -5,8 +5,6 @@ use bincode::enc::write::Writer;
55
66use super :: tag:: LeafTag ;
77use super :: tag:: Tag ;
8- use super :: transform:: ModifyResult ;
9- use super :: transform:: impl_modify_map_collect;
108use crate :: hash:: Hash ;
119use crate :: tree:: Tree ;
1210
@@ -77,6 +75,58 @@ pub enum MerkleProofLeaf {
7775 Read ( Vec < u8 > ) ,
7876}
7977
78+ enum NodeLeaf {
79+ Node ,
80+ Leaf ,
81+ }
82+
83+ struct HashState {
84+ node_leaf : NodeLeaf ,
85+ parent_index : usize ,
86+ digests : Vec < [ u8 ; 32 ] > ,
87+ }
88+
89+ impl HashState {
90+ pub fn new ( node_leaf : NodeLeaf , parent_index : usize ) -> Self {
91+ Self {
92+ node_leaf,
93+ parent_index,
94+ digests : vec ! [ ] ,
95+ }
96+ }
97+
98+ pub fn new_with_digest ( node_leaf : NodeLeaf , parent_index : usize , digest : [ u8 ; 32 ] ) -> Self {
99+ Self {
100+ node_leaf,
101+ parent_index,
102+ digests : vec ! [ digest] ,
103+ }
104+ }
105+
106+ pub fn push ( & mut self , digest : [ u8 ; 32 ] ) {
107+ self . digests . push ( digest) ;
108+ }
109+
110+ pub fn get_digest ( & self ) -> [ u8 ; 32 ] {
111+ match self . node_leaf {
112+ NodeLeaf :: Node => {
113+ let mut hasher = blake3:: Hasher :: new ( ) ;
114+
115+ for digest in self . digests . iter ( ) {
116+ hasher. update ( digest) ;
117+ }
118+
119+ hasher. finalize ( ) . into ( )
120+ }
121+ NodeLeaf :: Leaf => self . digests [ 0 ] ,
122+ }
123+ }
124+
125+ pub fn get_parent_index ( & self ) -> usize {
126+ self . parent_index
127+ }
128+ }
129+
80130impl MerkleProof {
81131 /// Create a new Merkle proof as a read leaf.
82132 pub fn leaf_read ( data : Vec < u8 > ) -> Self {
@@ -90,18 +140,43 @@ impl MerkleProof {
90140
91141 /// Compute the root hash of the Merkle proof.
92142 pub fn root_hash ( & self ) -> Hash {
93- impl_modify_map_collect (
94- self ,
95- |subtree| match subtree {
96- Tree :: Node ( vec) => ModifyResult :: NodeContinue ( ( ) , vec. iter ( ) . collect ( ) ) ,
97- Tree :: Leaf ( data) => ModifyResult :: LeafStop ( data) ,
98- } ,
99- |leaf| match leaf {
100- MerkleProofLeaf :: Blind ( hash) => * hash,
101- MerkleProofLeaf :: Read ( data) => Hash :: blake3_hash_bytes ( data. as_slice ( ) ) ,
102- } ,
103- |( ) , leaves| Hash :: combine ( leaves) ,
104- )
143+ let mut nodes: Vec < ( & MerkleProof , usize ) > = vec ! [ ( self , 0 ) ] ;
144+ let mut hashes: Vec < HashState > = vec ! [ ] ;
145+
146+ while let Some ( ( node, parent_index) ) = nodes. pop ( ) {
147+ match node {
148+ Tree :: Leaf ( MerkleProofLeaf :: Blind ( hash) ) => {
149+ hashes. push ( HashState :: new_with_digest (
150+ NodeLeaf :: Leaf ,
151+ parent_index,
152+ hash. to_digest ( ) ,
153+ ) ) ;
154+ }
155+ Tree :: Leaf ( MerkleProofLeaf :: Read ( data) ) => {
156+ hashes. push ( HashState :: new_with_digest (
157+ NodeLeaf :: Leaf ,
158+ parent_index,
159+ Hash :: blake3_hash_bytes ( data. as_slice ( ) ) . to_digest ( ) ,
160+ ) ) ;
161+ }
162+ Tree :: Node ( children) => {
163+ hashes. push ( HashState :: new ( NodeLeaf :: Node , parent_index) ) ;
164+ let new_parent_index = hashes. len ( ) - 1 ;
165+ for child in children. iter ( ) {
166+ nodes. push ( ( child, new_parent_index) ) ;
167+ }
168+ }
169+ }
170+ }
171+
172+ while hashes. len ( ) > 1 {
173+ let hash_state = hashes
174+ . pop ( )
175+ . expect ( "This can't panic since we verified it's not empty" ) ;
176+ hashes[ hash_state. get_parent_index ( ) ] . push ( hash_state. get_digest ( ) ) ;
177+ }
178+
179+ Hash :: new ( hashes[ 0 ] . get_digest ( ) )
105180 }
106181}
107182
0 commit comments