* changes Shred::parent return type to Option<Slot> (#21370)
Shred::parent can return garbage if the struct fields are invalid:
https://github.com/solana-labs/solana/blob/8a50b6302/ledger/src/shred.rs#L446-L453
The commit adds more sanity checks and changes the return type to Option<Slot>.
(cherry picked from commit dd338b6c9f
)
# Conflicts:
# ledger/src/shred.rs
* removes mergify merge conflicts
Co-authored-by: behzad nouri <behzadnouri@gmail.com>
This commit is contained in:
@ -598,7 +598,7 @@ mod test {
|
|||||||
.expect("Expected a shred that signals an interrupt");
|
.expect("Expected a shred that signals an interrupt");
|
||||||
|
|
||||||
// Validate the shred
|
// Validate the shred
|
||||||
assert_eq!(shred.parent(), parent);
|
assert_eq!(shred.parent(), Some(parent));
|
||||||
assert_eq!(shred.slot(), slot);
|
assert_eq!(shred.slot(), slot);
|
||||||
assert_eq!(shred.index(), next_shred_index);
|
assert_eq!(shred.index(), next_shred_index);
|
||||||
assert!(shred.is_data());
|
assert!(shred.is_data());
|
||||||
|
@ -163,7 +163,10 @@ impl ReceiveWindowStats {
|
|||||||
fn verify_shred_slot(shred: &Shred, root: u64) -> bool {
|
fn verify_shred_slot(shred: &Shred, root: u64) -> bool {
|
||||||
match shred.shred_type() {
|
match shred.shred_type() {
|
||||||
// Only data shreds have parent information
|
// Only data shreds have parent information
|
||||||
ShredType::Data => blockstore::verify_shred_slots(shred.slot(), shred.parent(), root),
|
ShredType::Data => match shred.parent() {
|
||||||
|
Some(parent) => blockstore::verify_shred_slots(shred.slot(), parent, root),
|
||||||
|
None => false,
|
||||||
|
},
|
||||||
// Filter out outdated coding shreds
|
// Filter out outdated coding shreds
|
||||||
ShredType::Code => shred.slot() >= root,
|
ShredType::Code => shred.slot() >= root,
|
||||||
}
|
}
|
||||||
|
@ -1231,8 +1231,12 @@ impl Blockstore {
|
|||||||
get_index_meta_entry(&self.db, slot, index_working_set, index_meta_time);
|
get_index_meta_entry(&self.db, slot, index_working_set, index_meta_time);
|
||||||
|
|
||||||
let index_meta = &mut index_meta_working_set_entry.index;
|
let index_meta = &mut index_meta_working_set_entry.index;
|
||||||
let slot_meta_entry =
|
let slot_meta_entry = get_slot_meta_entry(
|
||||||
get_slot_meta_entry(&self.db, slot_meta_working_set, slot, shred.parent());
|
&self.db,
|
||||||
|
slot_meta_working_set,
|
||||||
|
slot,
|
||||||
|
shred.parent().ok_or(InsertDataShredError::InvalidShred)?,
|
||||||
|
);
|
||||||
|
|
||||||
let slot_meta = &mut slot_meta_entry.new_slot_meta.borrow_mut();
|
let slot_meta = &mut slot_meta_entry.new_slot_meta.borrow_mut();
|
||||||
|
|
||||||
|
@ -457,12 +457,13 @@ impl Shred {
|
|||||||
self.common_header.slot
|
self.common_header.slot
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This should return Option<Slot>
|
pub fn parent(&self) -> Option<Slot> {
|
||||||
pub fn parent(&self) -> Slot {
|
match self.shred_type() {
|
||||||
if self.is_data() {
|
ShredType::Data => {
|
||||||
self.common_header.slot - u64::from(self.data_header.parent_offset)
|
let parent_offset = Slot::try_from(self.data_header.parent_offset);
|
||||||
} else {
|
self.slot().checked_sub(parent_offset.ok()?)
|
||||||
std::u64::MAX
|
}
|
||||||
|
ShredType::Code => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1125,7 +1126,7 @@ pub fn verify_test_data_shred(
|
|||||||
assert!(shred.is_data());
|
assert!(shred.is_data());
|
||||||
assert_eq!(shred.index(), index);
|
assert_eq!(shred.index(), index);
|
||||||
assert_eq!(shred.slot(), slot);
|
assert_eq!(shred.slot(), slot);
|
||||||
assert_eq!(shred.parent(), parent);
|
assert_eq!(shred.parent(), Some(parent));
|
||||||
assert_eq!(verify, shred.verify(pk));
|
assert_eq!(verify, shred.verify(pk));
|
||||||
if is_last_in_slot {
|
if is_last_in_slot {
|
||||||
assert!(shred.last_in_slot());
|
assert!(shred.last_in_slot());
|
||||||
|
Reference in New Issue
Block a user