@@ -108,7 +108,23 @@ impl<'db> TrieDB<'db> {
108108
109109 /// Check if every leaf of the trie exists
110110 pub fn is_complete ( & self ) -> bool {
111- unimplemented ! ( )
111+ self . is_complete_aux ( self . root )
112+ }
113+
114+ /// Check if every leaf of the trie starting from `hash` exists
115+ pub fn is_complete_aux ( & self , hash : & H256 ) -> bool {
116+ if let Some ( node_rlp) = self . db . get ( hash) {
117+ match RlpNode :: decoded ( node_rlp. as_ref ( ) ) {
118+ Some ( RlpNode :: Branch ( .., children) ) => children. iter ( ) . all ( |child| match child {
119+ Some ( h) => self . is_complete_aux ( h) ,
120+ None => true ,
121+ } ) ,
122+ Some ( RlpNode :: Leaf ( ..) ) => true ,
123+ None => false ,
124+ }
125+ } else {
126+ false
127+ }
112128 }
113129}
114130
@@ -146,4 +162,33 @@ mod tests {
146162 assert_eq ! ( t. get( b"B" ) , Ok ( Some ( DBValue :: from_slice( b"ABCBA" ) ) ) ) ;
147163 assert_eq ! ( t. get( b"C" ) , Ok ( None ) ) ;
148164 }
165+
166+ #[ test]
167+ fn is_complete_success ( ) {
168+ let mut memdb = MemoryDB :: new ( ) ;
169+ let mut root = H256 :: new ( ) ;
170+ {
171+ let mut t = TrieDBMut :: new ( & mut memdb, & mut root) ;
172+ t. insert ( b"A" , b"ABC" ) . unwrap ( ) ;
173+ t. insert ( b"B" , b"ABCBA" ) . unwrap ( ) ;
174+ }
175+
176+ let t = TrieDB :: try_new ( & memdb, & root) . unwrap ( ) ;
177+ assert ! ( t. is_complete( ) ) ;
178+ }
179+
180+ #[ test]
181+ fn is_complete_fail ( ) {
182+ let mut memdb = MemoryDB :: new ( ) ;
183+ let mut root = H256 :: new ( ) ;
184+ {
185+ let mut t = TrieDBMut :: new ( & mut memdb, & mut root) ;
186+ t. insert ( b"A" , b"ABC" ) . unwrap ( ) ;
187+ t. insert ( b"B" , b"ABCBA" ) . unwrap ( ) ;
188+ }
189+ memdb. remove ( memdb. keys ( ) . keys ( ) . next ( ) . unwrap ( ) ) ;
190+
191+ let t = TrieDB :: try_new ( & memdb, & root) . unwrap ( ) ;
192+ assert ! ( !t. is_complete( ) ) ;
193+ }
149194}
0 commit comments