Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Check for pruned block state
Browse files Browse the repository at this point in the history
  • Loading branch information
arkpar committed Sep 3, 2018
1 parent ee2b68e commit fcffdc7
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 18 deletions.
22 changes: 13 additions & 9 deletions substrate/client/db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,12 @@ impl<Block: BlockT> Backend<Block> {
}

#[cfg(test)]
fn new_test() -> Self {
fn new_test(keep_blocks: u32) -> Self {
use utils::NUM_COLUMNS;

let db = Arc::new(::kvdb_memorydb::create(NUM_COLUMNS));

Backend::from_kvdb(db as Arc<_>, PruningMode::keep_blocks(0), 0).expect("failed to create test-db")
Backend::from_kvdb(db as Arc<_>, PruningMode::keep_blocks(keep_blocks), 0).expect("failed to create test-db")
}

fn from_kvdb(db: Arc<KeyValueDB>, pruning: PruningMode, finalization_window: u64) -> Result<Self, client::error::Error> {
Expand Down Expand Up @@ -454,10 +454,14 @@ impl<Block> client::backend::Backend<Block, KeccakHasher, RlpCodec> for Backend<
_ => {}
}

self.blockchain.header(block).and_then(|maybe_hdr| maybe_hdr.map(|hdr| {
let root: H256 = H256::from_slice(hdr.state_root().as_ref());
DbState::with_storage(self.storage.clone(), root)
}).ok_or_else(|| client::error::ErrorKind::UnknownBlock(format!("{:?}", block)).into()))
match self.blockchain.header(block) {
Ok(Some(ref hdr)) if !self.storage.state_db.is_pruned(hdr.number().as_()) => {
let root: H256 = H256::from_slice(hdr.state_root().as_ref());
Ok(DbState::with_storage(self.storage.clone(), root))
},
Err(e) => Err(e),
_ => Err(client::error::ErrorKind::UnknownBlock(format!("{:?}", block)).into()),
}
}
}

Expand All @@ -477,7 +481,7 @@ mod tests {

#[test]
fn block_hash_inserted_correctly() {
let db = Backend::<Block>::new_test();
let db = Backend::<Block>::new_test(1);
for i in 0..10 {
assert!(db.blockchain().hash(i).unwrap().is_none());

Expand Down Expand Up @@ -516,7 +520,7 @@ mod tests {

#[test]
fn set_state_data() {
let db = Backend::<Block>::new_test();
let db = Backend::<Block>::new_test(2);
{
let mut op = db.begin_operation(BlockId::Hash(Default::default())).unwrap();
let mut header = Header {
Expand Down Expand Up @@ -595,7 +599,7 @@ mod tests {
#[test]
fn delete_only_when_negative_rc() {
let key;
let backend = Backend::<Block>::new_test();
let backend = Backend::<Block>::new_test(0);

let hash = {
let mut op = backend.begin_operation(BlockId::Hash(Default::default())).unwrap();
Expand Down
19 changes: 16 additions & 3 deletions substrate/state-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ impl<BlockHash: Hash, Key: Hash> StateDbSync<BlockHash, Key> {
return self.unfinalized.last_finalized_block_number()
}

pub fn is_pruned(&self, number: u64) -> bool {
self.pruning.as_ref().map_or(false, |pruning| number < pruning.pending())
}

fn prune(&mut self, commit: &mut CommitSet<Key>) {
if let (&mut Some(ref mut pruning), &PruningMode::Constrained(ref constraints)) = (&mut self.pruning, &self.mode) {
loop {
Expand All @@ -241,7 +245,6 @@ impl<BlockHash: Hash, Key: Hash> StateDbSync<BlockHash, Key> {
if pruning.next_hash().map_or(false, |h| pinned.contains(&h)) {
break;
}

pruning.prune_one(commit);
}
}
Expand Down Expand Up @@ -328,6 +331,11 @@ impl<BlockHash: Hash, Key: Hash> StateDb<BlockHash, Key> {
return self.db.read().best_finalized()
}

/// Check if block is pruned away.
pub fn is_pruned(&self, number: u64) -> bool {
return self.db.read().is_pruned(number)
}

}

#[cfg(test)]
Expand Down Expand Up @@ -375,19 +383,24 @@ mod tests {

#[test]
fn prune_window_1() {
let (db, _) = make_test_db(PruningMode::Constrained(Constraints {
let (db, sdb) = make_test_db(PruningMode::Constrained(Constraints {
max_blocks: Some(1),
max_mem: None,
}));
assert!(sdb.is_pruned(0));
assert!(sdb.is_pruned(1));
assert!(!sdb.is_pruned(2));
assert!(db.data_eq(&make_db(&[21, 3, 922, 93, 94])));
}

#[test]
fn prune_window_2() {
let (db, _) = make_test_db(PruningMode::Constrained(Constraints {
let (db, sdb) = make_test_db(PruningMode::Constrained(Constraints {
max_blocks: Some(2),
max_mem: None,
}));
assert!(sdb.is_pruned(0));
assert!(!sdb.is_pruned(1));
assert!(db.data_eq(&make_db(&[1, 21, 3, 921, 922, 93, 94])));
}
}
16 changes: 10 additions & 6 deletions substrate/state-db/src/pruning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<BlockHash: Hash, Key: Hash> RefWindow<BlockHash, Key> {
.map_err(|e| Error::Db(e))?;
let pending_number: u64 = match last_pruned {
Some(buffer) => u64::decode(&mut buffer.as_slice()).ok_or(Error::Decoding)? + 1,
None => 1,
None => 0,
};
let mut block = pending_number;
let mut pruning = RefWindow {
Expand All @@ -69,7 +69,7 @@ impl<BlockHash: Hash, Key: Hash> RefWindow<BlockHash, Key> {
pending_number: pending_number,
};
// read the journal
trace!(target: "state-db", "Reading pruning journal. Last pruned #{}", pending_number - 1);
trace!(target: "state-db", "Reading pruning journal. Pending #{}", pending_number);
loop {
let journal_key = to_journal_key(block);
match db.get_meta(&journal_key).map_err(|e| Error::Db(e))? {
Expand Down Expand Up @@ -119,6 +119,10 @@ impl<BlockHash: Hash, Key: Hash> RefWindow<BlockHash, Key> {
0
}

pub fn pending(&self) -> u64 {
self.pending_number
}

/// Prune next block. Expects at least one block in the window. Adds changes to `commit`.
pub fn prune_one(&mut self, commit: &mut CommitSet<Key>) {
let pruned = self.death_rows.pop_front().expect("prune_one is only called with a non-empty window");
Expand Down Expand Up @@ -168,7 +172,7 @@ mod tests {
fn created_from_empty_db() {
let db = make_db(&[]);
let pruning: RefWindow<H256, H256> = RefWindow::new(&db).unwrap();
assert_eq!(pruning.pending_number, 1);
assert_eq!(pruning.pending_number, 0);
assert!(pruning.death_rows.is_empty());
assert!(pruning.death_index.is_empty());
}
Expand Down Expand Up @@ -202,7 +206,7 @@ mod tests {
assert!(db.data_eq(&make_db(&[2, 4, 5])));
assert!(pruning.death_rows.is_empty());
assert!(pruning.death_index.is_empty());
assert_eq!(pruning.pending_number, 2);
assert_eq!(pruning.pending_number, 1);
}

#[test]
Expand All @@ -227,7 +231,7 @@ mod tests {
pruning.prune_one(&mut commit);
db.commit(&commit);
assert!(db.data_eq(&make_db(&[3, 4, 5])));
assert_eq!(pruning.pending_number, 3);
assert_eq!(pruning.pending_number, 2);
}

#[test]
Expand Down Expand Up @@ -258,6 +262,6 @@ mod tests {
pruning.prune_one(&mut commit);
db.commit(&commit);
assert!(db.data_eq(&make_db(&[1, 3])));
assert_eq!(pruning.pending_number, 4);
assert_eq!(pruning.pending_number, 3);
}
}

0 comments on commit fcffdc7

Please sign in to comment.