Skip to content

Commit

Permalink
v1.18: blockstore: account for blockstore cleanup during shred insert…
Browse files Browse the repository at this point in the history
…ion (backport of #1259) (#1279)

blockstore: account for blockstore cleanup during shred insertion (#1259)

(cherry picked from commit b5c5bd3)

Co-authored-by: Ashwin Sekar <[email protected]>
  • Loading branch information
2 people authored and yihau committed May 14, 2024
1 parent 10e5a10 commit 09d2eaf
Showing 1 changed file with 51 additions and 22 deletions.
73 changes: 51 additions & 22 deletions ledger/src/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1144,7 +1144,7 @@ impl Blockstore {
slot,
erasure_meta
.first_received_coding_shred_index()
.expect("First received coding index must exist for all erasure metas"),
.expect("First received coding index must fit in u32"),
ShredType::Code,
);
let shred = just_inserted_shreds
Expand Down Expand Up @@ -1800,12 +1800,17 @@ impl Blockstore {
merkle_root_meta.first_received_shred_index(),
merkle_root_meta.first_received_shred_type(),
);
let conflicting_shred = self
let Some(conflicting_shred) = self
.get_shred_from_just_inserted_or_db(just_inserted_shreds, shred_id)
.unwrap_or_else(|| {
panic!("First received shred indicated by merkle root meta {:?} is missing from blockstore. This inconsistency may cause duplicate block detection to fail", merkle_root_meta);
})
.into_owned();
.map(Cow::into_owned)
else {
error!(
"Shred {shred_id:?} indiciated by merkle root meta {merkle_root_meta:?} is missing from blockstore.
This should only happen in extreme cases where blockstore cleanup has caught up to the root.
Skipping the merkle root consistency check"
);
return true;
};
duplicate_shreds.push(PossibleDuplicateShred::MerkleRootConflict(
shred.clone(),
conflicting_shred,
Expand Down Expand Up @@ -1859,10 +1864,17 @@ impl Blockstore {
next_merkle_root_meta.first_received_shred_index(),
next_merkle_root_meta.first_received_shred_type(),
);
let next_shred =
let Some(next_shred) =
Self::get_shred_from_just_inserted_or_db(self, just_inserted_shreds, next_shred_id)
.expect("Shred indicated by merkle root meta must exist")
.into_owned();
.map(Cow::into_owned)
else {
error!(
"Shred {next_shred_id:?} indicated by merkle root meta {next_merkle_root_meta:?} is missing from blockstore.
This should only happen in extreme cases where blockstore cleanup has caught up to the root.
Skipping the forward chained merkle root consistency check"
);
return true;
};
let merkle_root = shred.merkle_root().ok();
let chained_merkle_root = shred::layout::get_chained_merkle_root(&next_shred);

Expand Down Expand Up @@ -1952,10 +1964,17 @@ impl Blockstore {
prev_merkle_root_meta.first_received_shred_index(),
prev_merkle_root_meta.first_received_shred_type(),
);
let prev_shred =
let Some(prev_shred) =
Self::get_shred_from_just_inserted_or_db(self, just_inserted_shreds, prev_shred_id)
.expect("Shred indicated by merkle root meta must exist")
.into_owned();
.map(Cow::into_owned)
else {
error!(
"Shred {prev_shred_id:?} indicated by merkle root meta {prev_merkle_root_meta:?} is missing from blockstore.
This should only happen in extreme cases where blockstore cleanup has caught up to the root.
Skipping the backwards chained merkle root consistency check"
);
return true;
};
let merkle_root = shred::layout::get_merkle_root(&prev_shred);
let chained_merkle_root = shred.chained_merkle_root().ok();

Expand Down Expand Up @@ -2022,12 +2041,17 @@ impl Blockstore {
u32::try_from(last_index.unwrap()).unwrap(),
ShredType::Data,
);
let ending_shred: Vec<u8> = self
let Some(ending_shred) = self
.get_shred_from_just_inserted_or_db(just_inserted_shreds, shred_id)
.unwrap_or_else(|| {
panic!("Last index data shred indicated by slot meta {:?} is missing from blockstore. This inconsistency may cause duplicate block detection to fail", slot_meta)
})
.into_owned();
.map(Cow::into_owned)
else {
error!(
"Last index data shred {shred_id:?} indiciated by slot meta {slot_meta:?} is missing from blockstore.
This should only happen in extreme cases where blockstore cleanup has caught up to the root.
Skipping data shred insertion"
);
return false;
};

if self
.store_duplicate_slot(slot, ending_shred.clone(), shred.payload().clone())
Expand Down Expand Up @@ -2065,12 +2089,17 @@ impl Blockstore {
u32::try_from(slot_meta.received - 1).unwrap(),
ShredType::Data,
);
let ending_shred: Vec<u8> = self
let Some(ending_shred) = self
.get_shred_from_just_inserted_or_db(just_inserted_shreds, shred_id)
.unwrap_or_else(|| {
panic!("Last received data shred indicated by slot meta {:?} is missing from blockstore. This inconsistency may cause duplicate block detection to fail", slot_meta)
})
.into_owned();
.map(Cow::into_owned)
else {
error!(
"Last received data shred {shred_id:?} indiciated by slot meta {slot_meta:?} is missing from blockstore.
This should only happen in extreme cases where blockstore cleanup has caught up to the root.
Skipping data shred insertion"
);
return false;
};

if self
.store_duplicate_slot(slot, ending_shred.clone(), shred.payload().clone())
Expand Down

0 comments on commit 09d2eaf

Please sign in to comment.