From 1ea56905cf49e8a5e983651b95fb8d6711e56dfd Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Fri, 1 Feb 2019 17:17:31 +0100 Subject: [PATCH] Fixed state-db block insertion and added forks trace (#1657) --- substrate/core/state-db/src/lib.rs | 7 ++++ substrate/core/state-db/src/noncanonical.rs | 38 ++++++++++++++++----- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/substrate/core/state-db/src/lib.rs b/substrate/core/state-db/src/lib.rs index 0aedd16a3b..a821a5a127 100644 --- a/substrate/core/state-db/src/lib.rs +++ b/substrate/core/state-db/src/lib.rs @@ -292,6 +292,13 @@ impl StateDbSync { if let Some(pruning) = &mut self.pruning { pruning.apply_pending(); } + trace!(target: "forks", "First available: {:?} ({}), Last canon: {:?} ({}), Best forks: {:?}", + self.pruning.as_ref().and_then(|p| p.next_hash()), + self.pruning.as_ref().map(|p| p.pending()).unwrap_or(0), + self.non_canonical.last_canonicalized_hash(), + self.non_canonical.last_canonicalized_block_number().unwrap_or(0), + self.non_canonical.top_level(), + ); } pub fn revert_pending(&mut self) { diff --git a/substrate/core/state-db/src/noncanonical.rs b/substrate/core/state-db/src/noncanonical.rs index 847b73f13a..54ad58f891 100644 --- a/substrate/core/state-db/src/noncanonical.rs +++ b/substrate/core/state-db/src/noncanonical.rs @@ -118,7 +118,7 @@ impl NonCanonicalOverlay { /// Insert a new block into the overlay. If inserted on the second level or lover expects parent to be present in the window. pub fn insert(&mut self, hash: &BlockHash, number: u64, parent_hash: &BlockHash, changeset: ChangeSet) -> Result, Error> { let mut commit = CommitSet::default(); - let front_block_number = self.pending_front_block_number(); + let front_block_number = self.front_block_number(); if self.levels.is_empty() && self.last_canonicalized.is_none() && number > 0 { // assume that parent was canonicalized let last_canonicalized = (parent_hash.clone(), number - 1); @@ -214,13 +214,6 @@ impl NonCanonicalOverlay { self.last_canonicalized.as_ref().map(|&(_, n)| n + 1).unwrap_or(0) } - fn pending_front_block_number(&self) -> u64 { - self.last_canonicalized - .as_ref() - .map(|&(_, n)| n + 1 + self.pending_canonicalizations.len() as u64) - .unwrap_or(0) - } - pub fn last_canonicalized_block_number(&self) -> Option { match self.last_canonicalized.as_ref().map(|&(_, n)| n) { Some(n) => Some(n + self.pending_canonicalizations.len() as u64), @@ -229,6 +222,18 @@ impl NonCanonicalOverlay { } } + pub fn last_canonicalized_hash(&self) -> Option { + self.last_canonicalized.as_ref().map(|&(ref h, _)| h.clone()) + } + + pub fn top_level(&self) -> Vec<(BlockHash, u64)> { + let start = self.last_canonicalized_block_number().unwrap_or(0); + self.levels + .get(self.pending_canonicalizations.len()) + .map(|level| level.iter().map(|r| (r.hash.clone(), start)).collect()) + .unwrap_or_default() + } + /// Select a top-level root and canonicalized it. Discards all sibling subtrees and the root. /// Returns a set of changes that need to be added to the DB. pub fn canonicalize(&mut self, hash: &BlockHash) -> Result, Error> { @@ -504,6 +509,23 @@ mod tests { assert!(db.data_eq(&make_db(&[1, 4, 6, 7, 8]))); } + #[test] + fn insert_with_pending_canonicalization() { + let h1 = H256::random(); + let h2 = H256::random(); + let h3 = H256::random(); + let mut db = make_db(&[]); + let mut overlay = NonCanonicalOverlay::::new(&db).unwrap(); + let changeset = make_changeset(&[], &[]); + db.commit(&overlay.insert::(&h1, 1, &H256::default(), changeset.clone()).unwrap()); + db.commit(&overlay.insert::(&h2, 2, &h1, changeset.clone()).unwrap()); + overlay.apply_pending(); + db.commit(&overlay.canonicalize::(&h1).unwrap()); + db.commit(&overlay.canonicalize::(&h2).unwrap()); + db.commit(&overlay.insert::(&h3, 3, &h2, changeset.clone()).unwrap()); + overlay.apply_pending(); + assert_eq!(overlay.levels.len(), 1); + } #[test] fn complex_tree() {