Merge branch 'master' of https://github.com/gavofyork/ethcore-util into at
This commit is contained in:
commit
3e497f46c0
86
src/trie.rs
86
src/trie.rs
@ -115,6 +115,7 @@ impl Diff {
|
|||||||
self.0.push(Operation::New(rlp_sha3, rlp));
|
self.0.push(Operation::New(rlp_sha3, rlp));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
trace!("new_node: inline node {:?}", &rlp);
|
||||||
out.append_raw(&rlp, 1);
|
out.append_raw(&rlp, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,13 +143,11 @@ pub struct TrieDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TrieDB {
|
impl TrieDB {
|
||||||
pub fn new<T>(db: T) -> Self where T: HashDB + 'static { TrieDB{ db: Box::new(db), root: H256::new() } }
|
pub fn new_boxed(db_box: Box<HashDB>) -> Self { let mut r = TrieDB{ db: db_box, root: H256::new() }; r.set_root_rlp(&NULL_RLP); r }
|
||||||
|
|
||||||
pub fn new_boxed(db_box: Box<HashDB>) -> Self { TrieDB{ db: db_box, root: H256::new() } }
|
pub fn new<T>(db: T) -> Self where T: HashDB + 'static { Self::new_boxed(Box::new(db)) }
|
||||||
|
|
||||||
pub fn new_memory() -> Self { TrieDB{ db: Box::new(MemoryDB::new()), root: H256::new() } }
|
pub fn new_memory() -> Self { Self::new(MemoryDB::new()) }
|
||||||
|
|
||||||
pub fn init(&mut self) { self.set_root_rlp(&NULL_RLP); }
|
|
||||||
|
|
||||||
pub fn db(&self) -> &HashDB { self.db.as_ref() }
|
pub fn db(&self) -> &HashDB { self.db.as_ref() }
|
||||||
|
|
||||||
@ -159,6 +158,7 @@ impl TrieDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn apply(&mut self, diff: Diff) {
|
fn apply(&mut self, diff: Diff) {
|
||||||
|
trace!("applying {:?} changes", diff.0.len());
|
||||||
for d in diff.0.into_iter() {
|
for d in diff.0.into_iter() {
|
||||||
match d {
|
match d {
|
||||||
Operation::Delete(h) => {
|
Operation::Delete(h) => {
|
||||||
@ -198,11 +198,13 @@ impl TrieDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add(&mut self, key: &NibbleSlice, value: &[u8]) {
|
fn add(&mut self, key: &NibbleSlice, value: &[u8]) {
|
||||||
|
trace!("ADD: {:?} {:?}", key, value);
|
||||||
// determine what the new root is, insert new nodes and remove old as necessary.
|
// determine what the new root is, insert new nodes and remove old as necessary.
|
||||||
let mut todo: Diff = Diff::new();
|
let mut todo: Diff = Diff::new();
|
||||||
let root_rlp = self.augmented(self.db.lookup(&self.root).expect("Trie root not found!"), key, value, &mut todo);
|
let root_rlp = self.augmented(self.db.lookup(&self.root).expect("Trie root not found!"), key, value, &mut todo);
|
||||||
self.apply(todo);
|
self.apply(todo);
|
||||||
self.set_root_rlp(&root_rlp);
|
self.set_root_rlp(&root_rlp);
|
||||||
|
trace!("---");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compose_leaf(partial: &NibbleSlice, value: &[u8]) -> Bytes {
|
fn compose_leaf(partial: &NibbleSlice, value: &[u8]) -> Bytes {
|
||||||
@ -211,7 +213,7 @@ impl TrieDB {
|
|||||||
s.append(&partial.encoded(true));
|
s.append(&partial.encoded(true));
|
||||||
s.append(&value);
|
s.append(&value);
|
||||||
let r = s.out();
|
let r = s.out();
|
||||||
trace!("output: -> {:?}", &r);
|
trace!("compose_leaf: -> {:?}", &r);
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +223,7 @@ impl TrieDB {
|
|||||||
s.append(&partial.encoded(is_leaf));
|
s.append(&partial.encoded(is_leaf));
|
||||||
s.append_raw(raw_payload, 1);
|
s.append_raw(raw_payload, 1);
|
||||||
let r = s.out();
|
let r = s.out();
|
||||||
println!("output: -> {:?}", &r);
|
println!("compose_raw: -> {:?}", &r);
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,22 +312,16 @@ impl TrieDB {
|
|||||||
let mut s = RlpStream::new_list(17);
|
let mut s = RlpStream::new_list(17);
|
||||||
let index = if partial.is_empty() {16} else {partial.at(0) as usize};
|
let index = if partial.is_empty() {16} else {partial.at(0) as usize};
|
||||||
for i in 0usize..17 {
|
for i in 0usize..17 {
|
||||||
if index == i {
|
match (index == i, i) {
|
||||||
// this is node to augment into...
|
(true, 16) => // leaf entry - just replace.
|
||||||
if orig.at(i).is_empty() {
|
{ s.append(&value); },
|
||||||
// easy - original had empty slot.
|
(true, i) if orig.at(i).is_empty() => // easy - original had empty slot.
|
||||||
diff.new_node(Self::compose_leaf(&partial.mid(if i == 16 {0} else {1}), value), &mut s);
|
diff.new_node(Self::compose_leaf(&partial.mid(1), value), &mut s),
|
||||||
} else if i == 16 {
|
(true, i) => { // harder - original has something there already
|
||||||
// leaf entry - just replace.
|
|
||||||
let new = Self::compose_leaf(&partial.mid(if i == 16 {0} else {1}), value);
|
|
||||||
diff.replace_node(&orig.at(i), new, &mut s);
|
|
||||||
} else {
|
|
||||||
// harder - original has something there already
|
|
||||||
let new = self.augmented(orig.at(i).raw(), &partial.mid(1), value, diff);
|
let new = self.augmented(orig.at(i).raw(), &partial.mid(1), value, diff);
|
||||||
diff.replace_node(&orig.at(i), new, &mut s);
|
diff.replace_node(&orig.at(i), new, &mut s);
|
||||||
}
|
}
|
||||||
} else {
|
(false, i) => { s.append_raw(orig.at(i).raw(), 1); },
|
||||||
s.append_raw(orig.at(i).raw(), 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.out()
|
s.out()
|
||||||
@ -345,6 +341,7 @@ impl TrieDB {
|
|||||||
let old_rlp = Rlp::new(old);
|
let old_rlp = Rlp::new(old);
|
||||||
match old_rlp.prototype() {
|
match old_rlp.prototype() {
|
||||||
Prototype::List(17) => {
|
Prototype::List(17) => {
|
||||||
|
trace!("branch: ROUTE,AUGMENT");
|
||||||
// already have a branch. route and augment.
|
// already have a branch. route and augment.
|
||||||
self.augmented_into_branch(&old_rlp, partial, value, diff)
|
self.augmented_into_branch(&old_rlp, partial, value, diff)
|
||||||
},
|
},
|
||||||
@ -396,6 +393,7 @@ impl TrieDB {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Prototype::Data(0) => {
|
Prototype::Data(0) => {
|
||||||
|
trace!("empty: COMPOSE");
|
||||||
Self::compose_leaf(partial, value)
|
Self::compose_leaf(partial, value)
|
||||||
},
|
},
|
||||||
_ => panic!("Invalid RLP for node."),
|
_ => panic!("Invalid RLP for node."),
|
||||||
@ -425,7 +423,6 @@ impl Trie for TrieDB {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use memorydb::*;
|
|
||||||
use triehash::*;
|
use triehash::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
use nibbleslice::*;
|
use nibbleslice::*;
|
||||||
@ -479,15 +476,13 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_at_empty() {
|
fn test_at_empty() {
|
||||||
let mut t = TrieDB::new(MemoryDB::new());
|
let mut t = TrieDB::new_memory();
|
||||||
t.init();
|
|
||||||
assert_eq!(t.at(&[0x5]), None);
|
assert_eq!(t.at(&[0x5]), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_at_one() {
|
fn test_at_one() {
|
||||||
let mut t = TrieDB::new(MemoryDB::new());
|
let mut t = TrieDB::new_memory();
|
||||||
t.init();
|
|
||||||
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
||||||
assert_eq!(t.at(&[0x1, 0x23]).unwrap(), &[0x1u8, 0x23]);
|
assert_eq!(t.at(&[0x1, 0x23]).unwrap(), &[0x1u8, 0x23]);
|
||||||
}
|
}
|
||||||
@ -496,33 +491,58 @@ mod tests {
|
|||||||
fn playpen() {
|
fn playpen() {
|
||||||
env_logger::init().unwrap();
|
env_logger::init().unwrap();
|
||||||
|
|
||||||
let mut t = TrieDB::new(MemoryDB::new());
|
let mut t = TrieDB::new_memory();
|
||||||
t.init();
|
|
||||||
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
||||||
|
t.insert(&[], &[0x0]);
|
||||||
|
assert_eq!(*t.root(), trie_root(vec![
|
||||||
|
(vec![], vec![0x0]),
|
||||||
|
(vec![0x01u8, 0x23], vec![0x01u8, 0x23]),
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn init() {
|
fn init() {
|
||||||
let mut t = TrieDB::new(MemoryDB::new());
|
let t = TrieDB::new_memory();
|
||||||
t.init();
|
|
||||||
assert_eq!(*t.root(), SHA3_NULL_RLP);
|
assert_eq!(*t.root(), SHA3_NULL_RLP);
|
||||||
assert!(t.is_empty());
|
assert!(t.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_on_empty() {
|
fn insert_on_empty() {
|
||||||
let mut t = TrieDB::new(MemoryDB::new());
|
let mut t = TrieDB::new_memory();
|
||||||
t.init();
|
|
||||||
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
||||||
assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x01u8, 0x23]) ]));
|
assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x01u8, 0x23]) ]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insert_replace_root() {
|
fn insert_replace_root() {
|
||||||
let mut t = TrieDB::new(MemoryDB::new());
|
let mut t = TrieDB::new_memory();
|
||||||
t.init();
|
|
||||||
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
||||||
t.insert(&[0x01u8, 0x23], &[0x23u8, 0x45]);
|
t.insert(&[0x01u8, 0x23], &[0x23u8, 0x45]);
|
||||||
assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x23u8, 0x45]) ]));
|
assert_eq!(*t.root(), trie_root(vec![ (vec![0x01u8, 0x23], vec![0x23u8, 0x45]) ]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert_make_branch_root() {
|
||||||
|
let mut t = TrieDB::new_memory();
|
||||||
|
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
||||||
|
t.insert(&[0x11u8, 0x23], &[0x11u8, 0x23]);
|
||||||
|
assert_eq!(*t.root(), trie_root(vec![
|
||||||
|
(vec![0x01u8, 0x23], vec![0x01u8, 0x23]),
|
||||||
|
(vec![0x11u8, 0x23], vec![0x11u8, 0x23])
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn insert_into_branch_root() {
|
||||||
|
let mut t = TrieDB::new_memory();
|
||||||
|
t.insert(&[0x01u8, 0x23], &[0x01u8, 0x23]);
|
||||||
|
t.insert(&[0xf1u8, 0x23], &[0xf1u8, 0x23]);
|
||||||
|
t.insert(&[0x81u8, 0x23], &[0x81u8, 0x23]);
|
||||||
|
assert_eq!(*t.root(), trie_root(vec![
|
||||||
|
(vec![0x01u8, 0x23], vec![0x01u8, 0x23]),
|
||||||
|
(vec![0x81u8, 0x23], vec![0x81u8, 0x23]),
|
||||||
|
(vec![0xf1u8, 0x23], vec![0xf1u8, 0x23]),
|
||||||
|
]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,6 +319,20 @@ mod tests {
|
|||||||
assert_eq!(trie_root(v), H256::from_str("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84").unwrap());
|
assert_eq!(trie_root(v), H256::from_str("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84").unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn out_of_order() {
|
||||||
|
assert!(trie_root(vec![
|
||||||
|
(vec![0x01u8, 0x23], vec![0x01u8, 0x23]),
|
||||||
|
(vec![0x81u8, 0x23], vec![0x81u8, 0x23]),
|
||||||
|
(vec![0xf1u8, 0x23], vec![0xf1u8, 0x23]),
|
||||||
|
]) ==
|
||||||
|
trie_root(vec![
|
||||||
|
(vec![0x01u8, 0x23], vec![0x01u8, 0x23]),
|
||||||
|
(vec![0xf1u8, 0x23], vec![0xf1u8, 0x23]),
|
||||||
|
(vec![0x81u8, 0x23], vec![0x81u8, 0x23]),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_trie_root() {
|
fn test_trie_root() {
|
||||||
let v = vec![
|
let v = vec![
|
||||||
|
Loading…
Reference in New Issue
Block a user