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

Commit f3c95e6

Browse files
authored
Pin canonincalized block (#12902)
1 parent b3d9f3c commit f3c95e6

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

client/state-db/src/noncanonical.rs

+25-3
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub struct NonCanonicalOverlay<BlockHash: Hash, Key: Hash> {
3838
// would be deleted but kept around because block is pinned, ref counted.
3939
pinned: HashMap<BlockHash, u32>,
4040
pinned_insertions: HashMap<BlockHash, (Vec<Key>, u32)>,
41+
last_canon_pinned: Option<BlockHash>,
4142
}
4243

4344
#[cfg_attr(test, derive(PartialEq, Debug))]
@@ -225,6 +226,7 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
225226
pinned: Default::default(),
226227
pinned_insertions: Default::default(),
227228
values,
229+
last_canon_pinned: None,
228230
})
229231
}
230232

@@ -367,6 +369,16 @@ impl<BlockHash: Hash, Key: Hash> NonCanonicalOverlay<BlockHash, Key> {
367369
.position(|overlay| overlay.hash == *hash)
368370
.ok_or(StateDbError::InvalidBlock)?;
369371

372+
// No failures are possible beyond this point.
373+
374+
// Unpin previously canonicalized block
375+
if let Some(prev_hash) = self.last_canon_pinned.take() {
376+
self.unpin(&prev_hash);
377+
}
378+
// Force pin canonicalized block so that it is no discarded immediately
379+
self.pin(hash);
380+
self.last_canon_pinned = Some(hash.clone());
381+
370382
let mut discarded_journals = Vec::new();
371383
let mut discarded_blocks = Vec::new();
372384
for (i, overlay) in level.blocks.into_iter().enumerate() {
@@ -680,6 +692,7 @@ mod tests {
680692
db.commit(&overlay.insert(&h2, 11, &h1, make_changeset(&[5], &[3])).unwrap());
681693
let mut commit = CommitSet::default();
682694
overlay.canonicalize(&h1, &mut commit).unwrap();
695+
overlay.unpin(&h1);
683696
db.commit(&commit);
684697
assert_eq!(overlay.levels.len(), 1);
685698

@@ -707,15 +720,16 @@ mod tests {
707720
let mut commit = CommitSet::default();
708721
overlay.canonicalize(&h1, &mut commit).unwrap();
709722
db.commit(&commit);
710-
assert!(!contains(&overlay, 5));
723+
assert!(contains(&overlay, 5));
711724
assert!(contains(&overlay, 7));
712725
assert_eq!(overlay.levels.len(), 1);
713-
assert_eq!(overlay.parents.len(), 1);
726+
assert_eq!(overlay.parents.len(), 2);
714727
let mut commit = CommitSet::default();
715728
overlay.canonicalize(&h2, &mut commit).unwrap();
729+
assert!(!contains(&overlay, 5));
716730
db.commit(&commit);
717731
assert_eq!(overlay.levels.len(), 0);
718-
assert_eq!(overlay.parents.len(), 0);
732+
assert_eq!(overlay.parents.len(), 1);
719733
assert!(db.data_eq(&make_db(&[1, 4, 6, 7, 8])));
720734
}
721735

@@ -732,6 +746,8 @@ mod tests {
732746
let mut commit = CommitSet::default();
733747
overlay.canonicalize(&h_1, &mut commit).unwrap();
734748
db.commit(&commit);
749+
// explicitly unpin last block
750+
overlay.unpin(&h_1);
735751
assert!(!contains(&overlay, 1));
736752
}
737753

@@ -818,6 +834,8 @@ mod tests {
818834
// canonicalize 1. 2 and all its children should be discarded
819835
let mut commit = CommitSet::default();
820836
overlay.canonicalize(&h_1, &mut commit).unwrap();
837+
// explicitly unpin last block
838+
overlay.unpin(&h_1);
821839
db.commit(&commit);
822840
assert_eq!(overlay.levels.len(), 2);
823841
assert_eq!(overlay.parents.len(), 6);
@@ -838,6 +856,7 @@ mod tests {
838856
// canonicalize 1_2. 1_1 and all its children should be discarded
839857
let mut commit = CommitSet::default();
840858
overlay.canonicalize(&h_1_2, &mut commit).unwrap();
859+
overlay.unpin(&h_1_2);
841860
db.commit(&commit);
842861
assert_eq!(overlay.levels.len(), 1);
843862
assert_eq!(overlay.parents.len(), 3);
@@ -854,6 +873,7 @@ mod tests {
854873
// canonicalize 1_2_2
855874
let mut commit = CommitSet::default();
856875
overlay.canonicalize(&h_1_2_2, &mut commit).unwrap();
876+
overlay.unpin(&h_1_2_2);
857877
db.commit(&commit);
858878
assert_eq!(overlay.levels.len(), 0);
859879
assert_eq!(overlay.parents.len(), 0);
@@ -964,6 +984,7 @@ mod tests {
964984
assert!(contains(&overlay, 1));
965985
overlay.unpin(&h_21);
966986
assert!(!contains(&overlay, 1));
987+
overlay.unpin(&h_12);
967988
assert!(overlay.pinned.is_empty());
968989
}
969990

@@ -998,6 +1019,7 @@ mod tests {
9981019

9991020
let mut commit = CommitSet::default();
10001021
overlay.canonicalize(&h21, &mut commit).unwrap(); // h11 should stay in the DB
1022+
overlay.unpin(&h21);
10011023
db.commit(&commit);
10021024
assert!(!contains(&overlay, 21));
10031025
}

0 commit comments

Comments
 (0)