同时我们可以发现,Trie是一个functional data
structure,我们的每一次修改都创建了一个新的Trie(因为根hash发生了变化),因此只需要将根hash和对应的树插入到一个键值数据库中,并且在之后的每次修改后都插入新的hash和新的树,那么只要知道过去某个状态下Trie的根hash,我们就能回退到当时的状态。
let (dbkey, rlp) = node_collapsed.encode(); // after collapsing, a node either keeps unchanged, or part of it is committed to database, // in the later case, the node must contains a database key, whose length is 32 // so the rlp length of collapsed node must exceed the 32 byte limit assert!(rlp.len() >= 32); db.insert(&dbkey, rlp); Subtree::NodeKey(dbkey)
// proof of existence let (proof, exists) = trie.prove::<MapDb>(&"aaaa"); assert_eq!(exists, true); // verify with old hash, this should fail assert!(!verify_prove(&old_root_hash, &proof, &"aaaa")); // verify with the newest hash, should success assert!(verify_prove(&new_root_hash, &proof, &"aaaa"));
// proof of non-existence let (proof, exists) = trie.prove::<MapDb>(&"a"); assert_eq!(exists, false); // both should fail assert!(!verify_prove(&old_root_hash, &proof, &"a")); assert!(!verify_prove(&new_root_hash, &proof, &"a")); }