diff --git a/src/nibbleslice.rs b/src/nibbleslice.rs index bd9ac494d..5f2615991 100644 --- a/src/nibbleslice.rs +++ b/src/nibbleslice.rs @@ -126,7 +126,10 @@ impl<'a> PartialOrd for NibbleSlice<'a> { impl<'a> fmt::Debug for NibbleSlice<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for i in 0..self.len() { - try!(write!(f, "{:01x}", self.at(i))); + match i { + 0 => try!(write!(f, "{:01x}", self.at(i))), + _ => try!(write!(f, "'{:01x}", self.at(i))), + } } Ok(()) } diff --git a/src/trie.rs b/src/trie.rs index d334b85a3..5bae41f49 100644 --- a/src/trie.rs +++ b/src/trie.rs @@ -280,10 +280,25 @@ impl TrieDB { r } + fn compose_stub_branch(value: &[u8]) -> Bytes { + let mut s = RlpStream::new_list(17); + for _ in 0..16 { s.append_empty_data(); } + s.append(&value); + s.out() + } + fn compose_extension(partial: &NibbleSlice, raw_payload: &[u8]) -> Bytes { Self::compose_raw(partial, raw_payload, false) } + fn create_extension(partial: &NibbleSlice, downstream_node: Bytes, diff: &mut Diff) -> Bytes { + trace!("create_extension partial: {:?}, downstream_node: {:?}", partial, downstream_node.pretty()); + let mut s = RlpStream::new_list(2); + s.append(&partial.encoded(false)); + diff.new_node(downstream_node, &mut s); + s.out() + } + /// Return the bytes encoding the node represented by `rlp`. It will be unlinked from /// the trie. fn take_node<'a, 'rlp_view>(&'a self, rlp: &'rlp_view Rlp<'a>, diff: &mut Diff) -> &'a [u8] where 'a: 'rlp_view { @@ -416,24 +431,14 @@ impl TrieDB { (_, cp) if cp == existing_key.len() => { trace!("complete-prefix (cp={:?}): AUGMENT-AT-END", cp); // fully-shared prefix for this extension: - // skip to the end of this extension and continue to augment there. - let downstream_node: Bytes; - if is_leaf { - // TODO: can maybe do with transmuted_to_branch_and_augmented/transmute to branch? - // create mostly-empty branch node. - let mut s = RlpStream::new_list(17); - for _ in 0..16 { s.append_empty_data(); } - s.append_raw(old_rlp.at(1).raw(), 1); - // create rlp for branch with single leaf item. - downstream_node = self.augmented(&s.out(), &partial.mid(cp), value, diff); + // transform to an extension + augmented version of onward node. + let downstream_node: Bytes = if is_leaf { + // no onward node because we're a leaf - create fake stub and use that. + self.augmented(&Self::compose_stub_branch(old_rlp.at(1).data()), &partial.mid(cp), value, diff) } else { - let n = self.take_node(&old_rlp.at(1), diff); - downstream_node = self.augmented(n, &partial.mid(cp), value, diff); - } - let mut s = RlpStream::new_list(2); - s.append_raw(old_rlp.at(0).raw(), 1); - diff.new_node(downstream_node, &mut s); - s.out() + self.augmented(self.take_node(&old_rlp.at(1), diff), &partial.mid(cp), value, diff) + }; + Self::create_extension(&existing_key, downstream_node, diff) }, (_, cp) => { // partially-shared prefix for this extension: @@ -583,7 +588,7 @@ mod tests { let v: Vec<(Vec, Vec)> = vec![ (From::from("do"), From::from("verb")), (From::from("dog"), From::from("puppy")), -// (From::from("doge"), From::from("coin")), + (From::from("doge"), From::from("coin")), // (From::from("horse"), From::from("stallion")), ]; @@ -593,6 +598,8 @@ mod tests { t.insert(&key, &val); } + trace!("{:?}", t); + assert_eq!(*t.root(), trie_root(v)); /*for i in 0..v.len() {