Skip to content

Commit 11230e6

Browse files
remagpieforiequal0
authored andcommitted
Implement TrieDB::is_complete
1 parent 18001f6 commit 11230e6

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

util/merkle/src/triedb.rs

Lines changed: 64 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,27 @@ impl<'db> TrieDB<'db> {
105105
None => Ok(None),
106106
}
107107
}
108+
109+
/// Check if every leaf of the trie exists
110+
#[allow(dead_code)]
111+
pub fn is_complete(&self) -> bool {
112+
*self.root == BLAKE_NULL_RLP || self.is_complete_aux(self.root)
113+
}
114+
115+
/// Check if every leaf of the trie starting from `hash` exists
116+
fn is_complete_aux(&self, hash: &H256) -> bool {
117+
if let Some(node_rlp) = self.db.get(hash) {
118+
match RlpNode::decoded(node_rlp.as_ref()) {
119+
Some(RlpNode::Branch(.., children)) => {
120+
children.iter().flatten().all(|child| self.is_complete_aux(child))
121+
}
122+
Some(RlpNode::Leaf(..)) => true,
123+
None => false,
124+
}
125+
} else {
126+
false
127+
}
128+
}
108129
}
109130

110131
impl<'db> Trie for TrieDB<'db> {
@@ -126,6 +147,19 @@ mod tests {
126147
use crate::*;
127148
use memorydb::*;
128149

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

0 commit comments

Comments
 (0)