Skip to content

Commit 3c8d9f0

Browse files
remagpieforiequal0
authored andcommitted
Implement TrieDB::is_complete
1 parent 18001f6 commit 3c8d9f0

File tree

1 file changed

+63
-1
lines changed

1 file changed

+63
-1
lines changed

util/merkle/src/triedb.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

17-
use ccrypto::blake256;
17+
use ccrypto::{blake256, BLAKE_NULL_RLP};
1818
use hashdb::HashDB;
1919
use primitives::H256;
2020

@@ -105,6 +105,26 @@ impl<'db> TrieDB<'db> {
105105
None => Ok(None),
106106
}
107107
}
108+
109+
/// Check if every leaf of the trie exists
110+
pub fn is_complete(&self) -> bool {
111+
*self.root == BLAKE_NULL_RLP || self.is_complete_aux(self.root)
112+
}
113+
114+
/// Check if every leaf of the trie starting from `hash` exists
115+
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)) => {
119+
children.iter().flatten().all(|child| self.is_complete_aux(child))
120+
}
121+
Some(RlpNode::Leaf(..)) => true,
122+
None => false,
123+
}
124+
} else {
125+
false
126+
}
127+
}
108128
}
109129

110130
impl<'db> Trie for TrieDB<'db> {
@@ -126,6 +146,19 @@ mod tests {
126146
use crate::*;
127147
use memorydb::*;
128148

149+
fn delete_any_child(db: &mut MemoryDB, root: &H256) {
150+
let node_rlp = db.get(root).unwrap();
151+
match RlpNode::decoded(&node_rlp).unwrap() {
152+
RlpNode::Leaf(..) => {
153+
db.remove(root);
154+
}
155+
RlpNode::Branch(.., children) => {
156+
let first_child = children.iter().find(|c| c.is_some()).unwrap().unwrap();
157+
db.remove(&first_child);
158+
}
159+
}
160+
}
161+
129162
#[test]
130163
fn get() {
131164
let mut memdb = MemoryDB::new();
@@ -141,4 +174,33 @@ mod tests {
141174
assert_eq!(t.get(b"B"), Ok(Some(b"ABCBA".to_vec())));
142175
assert_eq!(t.get(b"C"), Ok(None));
143176
}
177+
178+
#[test]
179+
fn is_complete_success() {
180+
let mut memdb = MemoryDB::new();
181+
let mut root = H256::new();
182+
{
183+
let mut t = TrieDBMut::new(&mut memdb, &mut root);
184+
t.insert(b"A", b"ABC").unwrap();
185+
t.insert(b"B", b"ABCBA").unwrap();
186+
}
187+
188+
let t = TrieDB::try_new(&memdb, &root).unwrap();
189+
assert!(t.is_complete());
190+
}
191+
192+
#[test]
193+
fn is_complete_fail() {
194+
let mut memdb = MemoryDB::new();
195+
let mut root = H256::new();
196+
{
197+
let mut t = TrieDBMut::new(&mut memdb, &mut root);
198+
t.insert(b"A", b"ABC").unwrap();
199+
t.insert(b"B", b"ABCBA").unwrap();
200+
}
201+
delete_any_child(&mut memdb, &root);
202+
203+
let t = TrieDB::try_new(&memdb, &root).unwrap();
204+
assert!(!t.is_complete());
205+
}
144206
}

0 commit comments

Comments
 (0)