Merge pull request #2025 from ethcore/triedbmut_double_insert

always process trie death row on commit, add more tracing
This commit is contained in:
Robert Habermeier 2016-09-01 11:19:22 +02:00 committed by GitHub
commit c8f3be2d93
2 changed files with 21 additions and 13 deletions

View File

@ -498,7 +498,7 @@ pub fn enact(
{ {
if ::log::max_log_level() >= ::log::LogLevel::Trace { if ::log::max_log_level() >= ::log::LogLevel::Trace {
let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(), factories.clone())); let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce(), factories.clone()));
trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author())); trace!(target: "enact", "num={}, root={}, author={}, author_balance={}\n", header.number(), s.root(), header.author(), s.balance(&header.author()));
} }
} }

View File

@ -56,11 +56,11 @@ impl From<H256> for NodeHandle {
} }
} }
fn empty_children() -> [Option<NodeHandle>; 16] { fn empty_children() -> Box<[Option<NodeHandle>; 16]> {
[ Box::new([
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None,
] ])
} }
/// Node types in the Trie. /// Node types in the Trie.
@ -78,7 +78,7 @@ enum Node {
/// The child node is always a branch. /// The child node is always a branch.
Extension(Bytes, NodeHandle), Extension(Bytes, NodeHandle),
/// A branch has up to 16 children and an optional value. /// A branch has up to 16 children and an optional value.
Branch([Option<NodeHandle>; 16], Option<Bytes>) Branch(Box<[Option<NodeHandle>; 16]>, Option<Bytes>)
} }
impl Node { impl Node {
@ -820,19 +820,19 @@ impl<'a> TrieDBMut<'a> {
/// Commit the in-memory changes to disk, freeing their storage and /// Commit the in-memory changes to disk, freeing their storage and
/// updating the state root. /// updating the state root.
pub fn commit(&mut self) { pub fn commit(&mut self) {
let handle = match self.root_handle() {
NodeHandle::Hash(_) => return, // no changes necessary.
NodeHandle::InMemory(h) => h,
};
trace!(target: "trie", "Committing trie changes to db."); trace!(target: "trie", "Committing trie changes to db.");
// kill all the nodes on death row. // always kill all the nodes on death row.
trace!(target: "trie", "{:?} nodes to remove from db", self.death_row.len()); trace!(target: "trie", "{:?} nodes to remove from db", self.death_row.len());
for hash in self.death_row.drain() { for hash in self.death_row.drain() {
self.db.remove(&hash); self.db.remove(&hash);
} }
let handle = match self.root_handle() {
NodeHandle::Hash(_) => return, // no changes necessary.
NodeHandle::InMemory(h) => h,
};
match self.storage.destroy(handle) { match self.storage.destroy(handle) {
Stored::New(node) => { Stored::New(node) => {
let root_rlp = node.into_rlp(|child, stream| self.commit_node(child, stream)); let root_rlp = node.into_rlp(|child, stream| self.commit_node(child, stream));
@ -906,21 +906,29 @@ impl<'a> TrieMut for TrieDBMut<'a> {
return self.remove(key); return self.remove(key);
} }
trace!(target: "trie", "insert: key={:?}, value={:?}", key.pretty(), value.pretty());
let root_handle = self.root_handle(); let root_handle = self.root_handle();
let (new_handle, _) = try!(self.insert_at(root_handle, NibbleSlice::new(key), value.to_owned())); let (new_handle, changed) = try!(self.insert_at(root_handle, NibbleSlice::new(key), value.to_owned()));
trace!(target: "trie", "insert: altered trie={}", changed);
self.root_handle = NodeHandle::InMemory(new_handle); self.root_handle = NodeHandle::InMemory(new_handle);
Ok(()) Ok(())
} }
fn remove(&mut self, key: &[u8]) -> super::Result<()> { fn remove(&mut self, key: &[u8]) -> super::Result<()> {
trace!(target: "trie", "remove: key={:?}", key.pretty());
let root_handle = self.root_handle(); let root_handle = self.root_handle();
let key = NibbleSlice::new(key); let key = NibbleSlice::new(key);
match try!(self.remove_at(root_handle, key)) { match try!(self.remove_at(root_handle, key)) {
Some((handle, _)) => { Some((handle, changed)) => {
trace!(target: "trie", "remove: altered trie={}", changed);
self.root_handle = NodeHandle::InMemory(handle); self.root_handle = NodeHandle::InMemory(handle);
} }
None => { None => {
trace!(target: "trie", "remove: obliterated trie");
self.root_handle = NodeHandle::Hash(SHA3_NULL_RLP); self.root_handle = NodeHandle::Hash(SHA3_NULL_RLP);
*self.root = SHA3_NULL_RLP; *self.root = SHA3_NULL_RLP;
} }