mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 22:41:06 +00:00
Check for pruned block state (#648)
This commit is contained in:
committed by
Gav Wood
parent
73ad673404
commit
146ebceab4
@@ -300,12 +300,12 @@ impl<Block: BlockT> Backend<Block> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn new_test() -> Self {
|
fn new_test(keep_blocks: u32) -> Self {
|
||||||
use utils::NUM_COLUMNS;
|
use utils::NUM_COLUMNS;
|
||||||
|
|
||||||
let db = Arc::new(::kvdb_memorydb::create(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> {
|
fn from_kvdb(db: Arc<KeyValueDB>, pruning: PruningMode, finalization_window: u64) -> Result<Self, client::error::Error> {
|
||||||
@@ -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| {
|
match self.blockchain.header(block) {
|
||||||
let root: H256 = H256::from_slice(hdr.state_root().as_ref());
|
Ok(Some(ref hdr)) if !self.storage.state_db.is_pruned(hdr.number().as_()) => {
|
||||||
DbState::with_storage(self.storage.clone(), root)
|
let root = H256::from_slice(hdr.state_root().as_ref());
|
||||||
}).ok_or_else(|| client::error::ErrorKind::UnknownBlock(format!("{:?}", block)).into()))
|
Ok(DbState::with_storage(self.storage.clone(), root))
|
||||||
|
},
|
||||||
|
Err(e) => Err(e),
|
||||||
|
_ => Err(client::error::ErrorKind::UnknownBlock(format!("{:?}", block)).into()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,7 +481,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn block_hash_inserted_correctly() {
|
fn block_hash_inserted_correctly() {
|
||||||
let db = Backend::<Block>::new_test();
|
let db = Backend::<Block>::new_test(1);
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
assert!(db.blockchain().hash(i).unwrap().is_none());
|
assert!(db.blockchain().hash(i).unwrap().is_none());
|
||||||
|
|
||||||
@@ -516,7 +520,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_state_data() {
|
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 op = db.begin_operation(BlockId::Hash(Default::default())).unwrap();
|
||||||
let mut header = Header {
|
let mut header = Header {
|
||||||
@@ -595,7 +599,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn delete_only_when_negative_rc() {
|
fn delete_only_when_negative_rc() {
|
||||||
let key;
|
let key;
|
||||||
let backend = Backend::<Block>::new_test();
|
let backend = Backend::<Block>::new_test(0);
|
||||||
|
|
||||||
let hash = {
|
let hash = {
|
||||||
let mut op = backend.begin_operation(BlockId::Hash(Default::default())).unwrap();
|
let mut op = backend.begin_operation(BlockId::Hash(Default::default())).unwrap();
|
||||||
|
|||||||
@@ -226,6 +226,10 @@ impl<BlockHash: Hash, Key: Hash> StateDbSync<BlockHash, Key> {
|
|||||||
return self.unfinalized.last_finalized_block_number()
|
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>) {
|
fn prune(&mut self, commit: &mut CommitSet<Key>) {
|
||||||
if let (&mut Some(ref mut pruning), &PruningMode::Constrained(ref constraints)) = (&mut self.pruning, &self.mode) {
|
if let (&mut Some(ref mut pruning), &PruningMode::Constrained(ref constraints)) = (&mut self.pruning, &self.mode) {
|
||||||
loop {
|
loop {
|
||||||
@@ -241,7 +245,6 @@ impl<BlockHash: Hash, Key: Hash> StateDbSync<BlockHash, Key> {
|
|||||||
if pruning.next_hash().map_or(false, |h| pinned.contains(&h)) {
|
if pruning.next_hash().map_or(false, |h| pinned.contains(&h)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pruning.prune_one(commit);
|
pruning.prune_one(commit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,6 +331,10 @@ impl<BlockHash: Hash, Key: Hash> StateDb<BlockHash, Key> {
|
|||||||
return self.db.read().best_finalized()
|
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)]
|
#[cfg(test)]
|
||||||
@@ -375,19 +382,24 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prune_window_1() {
|
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_blocks: Some(1),
|
||||||
max_mem: None,
|
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])));
|
assert!(db.data_eq(&make_db(&[21, 3, 922, 93, 94])));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prune_window_2() {
|
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_blocks: Some(2),
|
||||||
max_mem: None,
|
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])));
|
assert!(db.data_eq(&make_db(&[1, 21, 3, 921, 922, 93, 94])));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ impl<BlockHash: Hash, Key: Hash> RefWindow<BlockHash, Key> {
|
|||||||
.map_err(|e| Error::Db(e))?;
|
.map_err(|e| Error::Db(e))?;
|
||||||
let pending_number: u64 = match last_pruned {
|
let pending_number: u64 = match last_pruned {
|
||||||
Some(buffer) => u64::decode(&mut buffer.as_slice()).ok_or(Error::Decoding)? + 1,
|
Some(buffer) => u64::decode(&mut buffer.as_slice()).ok_or(Error::Decoding)? + 1,
|
||||||
None => 1,
|
None => 0,
|
||||||
};
|
};
|
||||||
let mut block = pending_number;
|
let mut block = pending_number;
|
||||||
let mut pruning = RefWindow {
|
let mut pruning = RefWindow {
|
||||||
@@ -69,7 +69,7 @@ impl<BlockHash: Hash, Key: Hash> RefWindow<BlockHash, Key> {
|
|||||||
pending_number: pending_number,
|
pending_number: pending_number,
|
||||||
};
|
};
|
||||||
// read the journal
|
// 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 {
|
loop {
|
||||||
let journal_key = to_journal_key(block);
|
let journal_key = to_journal_key(block);
|
||||||
match db.get_meta(&journal_key).map_err(|e| Error::Db(e))? {
|
match db.get_meta(&journal_key).map_err(|e| Error::Db(e))? {
|
||||||
@@ -119,6 +119,10 @@ impl<BlockHash: Hash, Key: Hash> RefWindow<BlockHash, Key> {
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pending(&self) -> u64 {
|
||||||
|
self.pending_number
|
||||||
|
}
|
||||||
|
|
||||||
/// Prune next block. Expects at least one block in the window. Adds changes to `commit`.
|
/// 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>) {
|
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");
|
let pruned = self.death_rows.pop_front().expect("prune_one is only called with a non-empty window");
|
||||||
@@ -168,7 +172,7 @@ mod tests {
|
|||||||
fn created_from_empty_db() {
|
fn created_from_empty_db() {
|
||||||
let db = make_db(&[]);
|
let db = make_db(&[]);
|
||||||
let pruning: RefWindow<H256, H256> = RefWindow::new(&db).unwrap();
|
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_rows.is_empty());
|
||||||
assert!(pruning.death_index.is_empty());
|
assert!(pruning.death_index.is_empty());
|
||||||
}
|
}
|
||||||
@@ -202,7 +206,7 @@ mod tests {
|
|||||||
assert!(db.data_eq(&make_db(&[2, 4, 5])));
|
assert!(db.data_eq(&make_db(&[2, 4, 5])));
|
||||||
assert!(pruning.death_rows.is_empty());
|
assert!(pruning.death_rows.is_empty());
|
||||||
assert!(pruning.death_index.is_empty());
|
assert!(pruning.death_index.is_empty());
|
||||||
assert_eq!(pruning.pending_number, 2);
|
assert_eq!(pruning.pending_number, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -227,7 +231,7 @@ mod tests {
|
|||||||
pruning.prune_one(&mut commit);
|
pruning.prune_one(&mut commit);
|
||||||
db.commit(&commit);
|
db.commit(&commit);
|
||||||
assert!(db.data_eq(&make_db(&[3, 4, 5])));
|
assert!(db.data_eq(&make_db(&[3, 4, 5])));
|
||||||
assert_eq!(pruning.pending_number, 3);
|
assert_eq!(pruning.pending_number, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -258,6 +262,6 @@ mod tests {
|
|||||||
pruning.prune_one(&mut commit);
|
pruning.prune_one(&mut commit);
|
||||||
db.commit(&commit);
|
db.commit(&commit);
|
||||||
assert!(db.data_eq(&make_db(&[1, 3])));
|
assert!(db.data_eq(&make_db(&[1, 3])));
|
||||||
assert_eq!(pruning.pending_number, 4);
|
assert_eq!(pruning.pending_number, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user