Skip to content

Commit 2bd55ca

Browse files
committed
Implement TrieDB::is_complete
1 parent 5f29aaf commit 2bd55ca

File tree

1 file changed

+46
-1
lines changed

1 file changed

+46
-1
lines changed

util/merkle/src/triedb.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)