uses enum for shred type

Current code is using u8 which does not have any type-safety and can
contain invalid values:
https://github.com/solana-labs/solana/blob/66fa062f1/ledger/src/shred.rs#L167

Checks for invalid shred-types are scattered through the code:
https://github.com/solana-labs/solana/blob/66fa062f1/ledger/src/blockstore.rs#L849-L851
https://github.com/solana-labs/solana/blob/66fa062f1/ledger/src/shred.rs#L346-L348

The commit uses enum for shred type with #[repr(u8)]. Backward
compatibility is maintained by implementing Serialize and Deserialize
compatible with u8, and adding a test to assert that.
This commit is contained in:
behzad nouri
2021-11-16 12:50:56 -05:00
parent bae5dae61d
commit 57057f8d39
8 changed files with 183 additions and 127 deletions

View File

@ -22,7 +22,7 @@ use {
contact_info::ContactInfo,
},
solana_ledger::{
shred::Shred,
shred::{Shred, ShredType},
{blockstore::Blockstore, leader_schedule_cache::LeaderScheduleCache},
},
solana_measure::measure::Measure,
@ -143,14 +143,14 @@ impl RetransmitStats {
}
}
// Map of shred (slot, index, is_data) => list of hash values seen for that key.
type ShredFilter = LruCache<(Slot, u32, bool), Vec<u64>>;
// Map of shred (slot, index, type) => list of hash values seen for that key.
type ShredFilter = LruCache<(Slot, u32, ShredType), Vec<u64>>;
type ShredFilterAndHasher = (ShredFilter, PacketHasher);
// Returns true if shred is already received and should skip retransmit.
fn should_skip_retransmit(shred: &Shred, shreds_received: &Mutex<ShredFilterAndHasher>) -> bool {
let key = (shred.slot(), shred.index(), shred.is_data());
let key = (shred.slot(), shred.index(), shred.shred_type());
let mut shreds_received = shreds_received.lock().unwrap();
let (cache, hasher) = shreds_received.deref_mut();
match cache.get_mut(&key) {

View File

@ -18,7 +18,7 @@ use {
solana_ledger::{
blockstore::{self, Blockstore, BlockstoreInsertionMetrics, MAX_DATA_SHREDS_PER_SLOT},
leader_schedule_cache::LeaderScheduleCache,
shred::{Nonce, Shred},
shred::{Nonce, Shred, ShredType},
},
solana_measure::measure::Measure,
solana_metrics::{inc_new_counter_debug, inc_new_counter_error},
@ -162,12 +162,11 @@ impl ReceiveWindowStats {
}
fn verify_shred_slot(shred: &Shred, root: u64) -> bool {
if shred.is_data() {
match shred.shred_type() {
// Only data shreds have parent information
blockstore::verify_shred_slots(shred.slot(), shred.parent(), root)
} else {
ShredType::Data => blockstore::verify_shred_slots(shred.slot(), shred.parent(), root),
// Filter out outdated coding shreds
shred.slot() >= root
ShredType::Code => shred.slot() >= root,
}
}