Skip to content
Snippets Groups Projects
Commit 831fd994 authored by Arkadiy Paronyan's avatar Arkadiy Paronyan Committed by Gav Wood
Browse files

Make sure displaced leaves are removed from the db (#1338)

parent 236208b6
No related merge requests found
...@@ -64,6 +64,8 @@ pub struct DisplacedLeaf<H, N> { ...@@ -64,6 +64,8 @@ pub struct DisplacedLeaf<H, N> {
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct LeafSet<H, N> { pub struct LeafSet<H, N> {
storage: BTreeSet<LeafSetItem<H, N>>, storage: BTreeSet<LeafSetItem<H, N>>,
pending_added: Vec<LeafSetItem<H, N>>,
pending_removed: Vec<H>,
} }
impl<H, N> LeafSet<H, N> where impl<H, N> LeafSet<H, N> where
...@@ -73,7 +75,9 @@ impl<H, N> LeafSet<H, N> where ...@@ -73,7 +75,9 @@ impl<H, N> LeafSet<H, N> where
/// Construct a new, blank leaf set. /// Construct a new, blank leaf set.
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
storage: BTreeSet::new() storage: BTreeSet::new(),
pending_added: Vec::new(),
pending_removed: Vec::new(),
} }
} }
...@@ -94,7 +98,11 @@ impl<H, N> LeafSet<H, N> where ...@@ -94,7 +98,11 @@ impl<H, N> LeafSet<H, N> where
}; };
storage.insert(LeafSetItem { hash, number }); storage.insert(LeafSetItem { hash, number });
} }
Ok(Self { storage }) Ok(Self {
storage,
pending_added: Vec::new(),
pending_removed: Vec::new(),
})
} }
/// update the leaf list on import. returns a displaced leaf if there was one. /// update the leaf list on import. returns a displaced leaf if there was one.
...@@ -102,12 +110,13 @@ impl<H, N> LeafSet<H, N> where ...@@ -102,12 +110,13 @@ impl<H, N> LeafSet<H, N> where
// avoid underflow for genesis. // avoid underflow for genesis.
let displaced = if number != N::zero() { let displaced = if number != N::zero() {
let displaced = LeafSetItem { let displaced = LeafSetItem {
hash: parent_hash, hash: parent_hash.clone(),
number: number.clone() - N::one(), number: number.clone() - N::one(),
}; };
let was_displaced = self.storage.remove(&displaced); let was_displaced = self.storage.remove(&displaced);
if was_displaced { if was_displaced {
self.pending_removed.push(parent_hash);
Some(DisplacedLeaf { Some(DisplacedLeaf {
new_hash: hash.clone(), new_hash: hash.clone(),
displaced, displaced,
...@@ -119,7 +128,9 @@ impl<H, N> LeafSet<H, N> where ...@@ -119,7 +128,9 @@ impl<H, N> LeafSet<H, N> where
None None
}; };
self.storage.insert(LeafSetItem { hash, number }); let item = LeafSetItem { hash, number };
self.storage.insert(item.clone());
self.pending_added.push(item);
displaced displaced
} }
...@@ -128,6 +139,8 @@ impl<H, N> LeafSet<H, N> where ...@@ -128,6 +139,8 @@ impl<H, N> LeafSet<H, N> where
let new_number = displaced.displaced.number.clone() + N::one(); let new_number = displaced.displaced.number.clone() + N::one();
self.storage.remove(&LeafSetItem { hash: displaced.new_hash, number: new_number }); self.storage.remove(&LeafSetItem { hash: displaced.new_hash, number: new_number });
self.storage.insert(displaced.displaced); self.storage.insert(displaced.displaced);
self.pending_added.clear();
self.pending_removed.clear();
} }
/// currently since revert only affects the canonical chain /// currently since revert only affects the canonical chain
...@@ -148,13 +161,18 @@ impl<H, N> LeafSet<H, N> where ...@@ -148,13 +161,18 @@ impl<H, N> LeafSet<H, N> where
} }
/// Write the leaf list to the database transaction. /// Write the leaf list to the database transaction.
pub fn prepare_transaction(&self, tx: &mut DBTransaction, column: Option<u32>, prefix: &[u8]) { pub fn prepare_transaction(&mut self, tx: &mut DBTransaction, column: Option<u32>, prefix: &[u8]) {
let mut buf = prefix.to_vec(); let mut buf = prefix.to_vec();
for &LeafSetItem { ref hash, ref number } in &self.storage { for LeafSetItem { hash, number } in self.pending_added.drain(..) {
hash.using_encoded(|s| buf.extend(s)); hash.using_encoded(|s| buf.extend(s));
tx.put_vec(column, &buf[..], number.encode()); tx.put_vec(column, &buf[..], number.encode());
buf.truncate(prefix.len()); // reuse allocation. buf.truncate(prefix.len()); // reuse allocation.
} }
for hash in self.pending_removed.drain(..) {
hash.using_encoded(|s| buf.extend(s));
tx.delete(column, &buf[..]);
buf.truncate(prefix.len()); // reuse allocation.
}
} }
} }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment