mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 01:11:10 +00:00
Check for disposed blocks when creating a state. (#1636)
* Check for disposed blocks * fixed changes_tries_with_digest_are_pruned_on_finalization * Indent Co-Authored-By: arkpar <arkady.paronyan@gmail.com>
This commit is contained in:
committed by
Robert Habermeier
parent
da029c87b7
commit
4bcc8eda41
@@ -190,12 +190,6 @@ impl<BlockHash: Hash, Key: Hash> StateDbSync<BlockHash, Key> {
|
||||
}
|
||||
|
||||
pub fn insert_block<E: fmt::Debug>(&mut self, hash: &BlockHash, number: u64, parent_hash: &BlockHash, mut changeset: ChangeSet<Key>) -> Result<CommitSet<Key>, Error<E>> {
|
||||
if number == 0 {
|
||||
return Ok(CommitSet {
|
||||
data: changeset,
|
||||
meta: Default::default(),
|
||||
})
|
||||
}
|
||||
match self.mode {
|
||||
PruningMode::ArchiveAll => {
|
||||
changeset.deleted.clear();
|
||||
@@ -232,12 +226,16 @@ impl<BlockHash: Hash, Key: Hash> StateDbSync<BlockHash, Key> {
|
||||
Ok(commit)
|
||||
}
|
||||
|
||||
pub fn best_canonical(&self) -> u64 {
|
||||
pub fn best_canonical(&self) -> Option<u64> {
|
||||
return self.non_canonical.last_canonicalized_block_number()
|
||||
}
|
||||
|
||||
pub fn is_pruned(&self, number: u64) -> bool {
|
||||
self.pruning.as_ref().map_or(false, |pruning| number < pruning.pending())
|
||||
pub fn is_pruned(&self, hash: &BlockHash, number: u64) -> bool {
|
||||
if self.best_canonical().map(|c| number > c).unwrap_or(true) {
|
||||
!self.non_canonical.have_block(hash)
|
||||
} else {
|
||||
self.pruning.as_ref().map_or(false, |pruning| number < pruning.pending() || !pruning.have_block(hash))
|
||||
}
|
||||
}
|
||||
|
||||
fn prune(&mut self, commit: &mut CommitSet<Key>) {
|
||||
@@ -351,13 +349,13 @@ impl<BlockHash: Hash, Key: Hash> StateDb<BlockHash, Key> {
|
||||
}
|
||||
|
||||
/// Returns last finalized block number.
|
||||
pub fn best_canonical(&self) -> u64 {
|
||||
pub fn best_canonical(&self) -> Option<u64> {
|
||||
return self.db.read().best_canonical()
|
||||
}
|
||||
|
||||
/// Check if block is pruned away.
|
||||
pub fn is_pruned(&self, number: u64) -> bool {
|
||||
return self.db.read().is_pruned(number)
|
||||
pub fn is_pruned(&self, hash: &BlockHash, number: u64) -> bool {
|
||||
return self.db.read().is_pruned(hash, number)
|
||||
}
|
||||
|
||||
/// Apply all pending changes
|
||||
@@ -471,9 +469,10 @@ mod tests {
|
||||
max_blocks: Some(1),
|
||||
max_mem: None,
|
||||
}));
|
||||
assert!(sdb.is_pruned(0));
|
||||
assert!(sdb.is_pruned(1));
|
||||
assert!(!sdb.is_pruned(2));
|
||||
assert!(sdb.is_pruned(&H256::from_low_u64_be(0), 0));
|
||||
assert!(sdb.is_pruned(&H256::from_low_u64_be(1), 1));
|
||||
assert!(sdb.is_pruned(&H256::from_low_u64_be(21), 2));
|
||||
assert!(sdb.is_pruned(&H256::from_low_u64_be(22), 2));
|
||||
assert!(db.data_eq(&make_db(&[21, 3, 922, 93, 94])));
|
||||
}
|
||||
|
||||
@@ -483,8 +482,10 @@ mod tests {
|
||||
max_blocks: Some(2),
|
||||
max_mem: None,
|
||||
}));
|
||||
assert!(sdb.is_pruned(0));
|
||||
assert!(!sdb.is_pruned(1));
|
||||
assert!(sdb.is_pruned(&H256::from_low_u64_be(0), 0));
|
||||
assert!(sdb.is_pruned(&H256::from_low_u64_be(1), 1));
|
||||
assert!(!sdb.is_pruned(&H256::from_low_u64_be(21), 2));
|
||||
assert!(sdb.is_pruned(&H256::from_low_u64_be(22), 2));
|
||||
assert!(db.data_eq(&make_db(&[1, 21, 3, 921, 922, 93, 94])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,10 +119,7 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
|
||||
pub fn insert<E: fmt::Debug>(&mut self, hash: &BlockHash, number: u64, parent_hash: &BlockHash, changeset: ChangeSet<Key>) -> Result<CommitSet<Key>, Error<E>> {
|
||||
let mut commit = CommitSet::default();
|
||||
let front_block_number = self.pending_front_block_number();
|
||||
if self.levels.is_empty() && self.last_canonicalized.is_none() {
|
||||
if number < 1 {
|
||||
return Err(Error::InvalidBlockNumber);
|
||||
}
|
||||
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);
|
||||
commit.meta.inserted.push((to_meta_key(LAST_CANONICAL, &()), last_canonicalized.encode()));
|
||||
@@ -224,8 +221,12 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn last_canonicalized_block_number(&self) -> u64 {
|
||||
self.last_canonicalized.as_ref().map(|&(_, n)| n).unwrap_or(0)
|
||||
pub fn last_canonicalized_block_number(&self) -> Option<u64> {
|
||||
match self.last_canonicalized.as_ref().map(|&(_, n)| n) {
|
||||
Some(n) => Some(n + self.pending_canonicalizations.len() as u64),
|
||||
None if !self.pending_canonicalizations.is_empty() => Some(self.pending_canonicalizations.len() as u64),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Select a top-level root and canonicalized it. Discards all sibling subtrees and the root.
|
||||
@@ -278,7 +279,7 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
|
||||
}
|
||||
}
|
||||
if let Some(hash) = last {
|
||||
let last_canonicalized = (hash, self.last_canonicalized_block_number() + count);
|
||||
let last_canonicalized = (hash, self.last_canonicalized.as_ref().map(|(_, n)| n + count).unwrap_or(count - 1));
|
||||
self.last_canonicalized = Some(last_canonicalized);
|
||||
}
|
||||
}
|
||||
@@ -295,6 +296,12 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Check if the block is in the canonicalization queue.
|
||||
pub fn have_block(&self, hash: &BlockHash) -> bool {
|
||||
(self.parents.contains_key(hash) || self.pending_insertions.contains(hash))
|
||||
&& !self.pending_canonicalizations.contains(hash)
|
||||
}
|
||||
|
||||
/// Revert a single level. Returns commit set that deletes the journal or `None` if not possible.
|
||||
pub fn revert_one(&mut self) -> Option<CommitSet<Key>> {
|
||||
self.levels.pop_back().map(|level| {
|
||||
@@ -589,6 +596,10 @@ mod tests {
|
||||
assert!(contains(&overlay, 121));
|
||||
assert!(contains(&overlay, 122));
|
||||
assert!(contains(&overlay, 123));
|
||||
assert!(overlay.have_block(&h_1_2_1));
|
||||
assert!(!overlay.have_block(&h_1_2));
|
||||
assert!(!overlay.have_block(&h_1_1));
|
||||
assert!(!overlay.have_block(&h_1_1_1));
|
||||
|
||||
// canonicalize 1_2_2
|
||||
db.commit(&overlay.canonicalize::<io::Error>(&h_1_2_2).unwrap());
|
||||
|
||||
@@ -130,6 +130,11 @@ impl<BlockHash: Hash, Key: Hash> RefWindow<BlockHash, Key> {
|
||||
self.pending_number + self.pending_prunings as u64
|
||||
}
|
||||
|
||||
pub fn have_block(&self, hash: &BlockHash) -> bool {
|
||||
self.death_rows.iter().skip(self.pending_prunings).any(|r| r.hash == *hash) ||
|
||||
self.pending_records.iter().any(|(_, record)| record.hash == *hash)
|
||||
}
|
||||
|
||||
/// 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>) {
|
||||
if let Some(pruned) = self.death_rows.get(self.pending_prunings) {
|
||||
@@ -236,7 +241,9 @@ mod tests {
|
||||
let h = H256::random();
|
||||
pruning.note_canonical(&h, &mut commit);
|
||||
db.commit(&commit);
|
||||
assert!(pruning.have_block(&h));
|
||||
pruning.apply_pending();
|
||||
assert!(pruning.have_block(&h));
|
||||
assert!(commit.data.deleted.is_empty());
|
||||
assert_eq!(pruning.death_rows.len(), 1);
|
||||
assert_eq!(pruning.death_index.len(), 2);
|
||||
@@ -245,8 +252,10 @@ mod tests {
|
||||
|
||||
let mut commit = CommitSet::default();
|
||||
pruning.prune_one(&mut commit);
|
||||
assert!(!pruning.have_block(&h));
|
||||
db.commit(&commit);
|
||||
pruning.apply_pending();
|
||||
assert!(!pruning.have_block(&h));
|
||||
assert!(db.data_eq(&make_db(&[2, 4, 5])));
|
||||
assert!(pruning.death_rows.is_empty());
|
||||
assert!(pruning.death_index.is_empty());
|
||||
|
||||
Reference in New Issue
Block a user