diff --git a/core/src/shred_fetch_stage.rs b/core/src/shred_fetch_stage.rs index fd72b8b8eebb3b..481e5333b14198 100644 --- a/core/src/shred_fetch_stage.rs +++ b/core/src/shred_fetch_stage.rs @@ -104,8 +104,22 @@ impl ShredFetchStage { // Limit shreds to 2 epochs away. let max_slot = last_slot + 2 * slots_per_epoch; - let should_drop_legacy_shreds = - |shred_slot| should_drop_legacy_shreds(shred_slot, &feature_set, &epoch_schedule); + let should_drop_legacy_shreds = |shred_slot| { + check_feature_activation( + &feature_set::drop_legacy_shreds::id(), + shred_slot, + &feature_set, + &epoch_schedule, + ) + }; + let enable_chained_merkle_shreds = |shred_slot| { + check_feature_activation( + &feature_set::enable_chained_merkle_shreds::id(), + shred_slot, + &feature_set, + &epoch_schedule, + ) + }; let turbine_disabled = turbine_disabled.load(Ordering::Relaxed); for packet in packet_batch.iter_mut().filter(|p| !p.meta().discard()) { if turbine_disabled @@ -115,6 +129,7 @@ impl ShredFetchStage { max_slot, shred_version, should_drop_legacy_shreds, + enable_chained_merkle_shreds, &mut stats, ) { @@ -394,13 +409,15 @@ pub(crate) fn receive_repair_quic_packets( } } +// Returns true if the feature is effective for the shred slot. #[must_use] -fn should_drop_legacy_shreds( +fn check_feature_activation( + feature: &Pubkey, shred_slot: Slot, feature_set: &FeatureSet, epoch_schedule: &EpochSchedule, ) -> bool { - match feature_set.activated_slot(&feature_set::drop_legacy_shreds::id()) { + match feature_set.activated_slot(feature) { None => false, Some(feature_slot) => { let feature_epoch = epoch_schedule.get_epoch(feature_slot); @@ -451,6 +468,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); let coding = solana_ledger::shred::Shredder::generate_coding_shreds( @@ -465,6 +483,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); } @@ -487,6 +506,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); assert_eq!(stats.index_overrun, 1); @@ -509,6 +529,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); assert_eq!(stats.slot_out_of_range, 1); @@ -519,6 +540,7 @@ mod tests { max_slot, 345, // shred_version |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); assert_eq!(stats.shred_version_mismatch, 1); @@ -530,6 +552,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); @@ -552,6 +575,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); @@ -564,6 +588,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats, )); } diff --git a/ledger/src/shred.rs b/ledger/src/shred.rs index bed8965073429a..54c27e237da980 100644 --- a/ledger/src/shred.rs +++ b/ledger/src/shred.rs @@ -916,6 +916,7 @@ pub fn should_discard_shred( max_slot: Slot, shred_version: u16, should_drop_legacy_shreds: impl Fn(Slot) -> bool, + enable_chained_merkle_shreds: impl Fn(Slot) -> bool, stats: &mut ShredFetchStats, ) -> bool { debug_assert!(root < max_slot); @@ -999,6 +1000,9 @@ pub fn should_discard_shred( stats.num_shreds_merkle_code = stats.num_shreds_merkle_code.saturating_add(1); } ShredVariant::MerkleCode(_, /*chained:*/ true) => { + if !enable_chained_merkle_shreds(slot) { + return true; + } stats.num_shreds_merkle_code_chained = stats.num_shreds_merkle_code_chained.saturating_add(1); } @@ -1006,6 +1010,9 @@ pub fn should_discard_shred( stats.num_shreds_merkle_data = stats.num_shreds_merkle_data.saturating_add(1); } ShredVariant::MerkleData(_, /*chained:*/ true) => { + if !enable_chained_merkle_shreds(slot) { + return true; + } stats.num_shreds_merkle_data_chained = stats.num_shreds_merkle_data_chained.saturating_add(1); } @@ -1209,6 +1216,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(stats, ShredFetchStats::default()); @@ -1220,6 +1228,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 1); @@ -1231,6 +1240,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 2); @@ -1242,6 +1252,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 3); @@ -1253,6 +1264,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 4); @@ -1264,6 +1276,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(stats.bad_parent_offset, 1); @@ -1285,6 +1298,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); @@ -1305,6 +1319,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(1, stats.index_out_of_bounds); @@ -1326,6 +1341,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); packet.buffer_mut()[OFFSET_OF_SHRED_VARIANT] = u8::MAX; @@ -1336,6 +1352,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(1, stats.bad_shred_type); @@ -1348,6 +1365,7 @@ mod tests { max_slot, shred_version, |_| false, // should_drop_legacy_shreds + |_| true, // enable_chained_merkle_shreds &mut stats )); assert_eq!(1, stats.bad_shred_type); diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index 25196462e5bd94..2201ed5c400247 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -776,6 +776,10 @@ pub mod enable_gossip_duplicate_proof_ingestion { solana_sdk::declare_id!("FNKCMBzYUdjhHyPdsKG2LSmdzH8TCHXn3ytj8RNBS4nG"); } +pub mod enable_chained_merkle_shreds { + solana_sdk::declare_id!("7uZBkJXJ1HkuP6R3MJfZs7mLwymBcDbKdqbF51ZWLier"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -965,6 +969,7 @@ lazy_static! { (curve25519_restrict_msm_length::id(), "restrict curve25519 multiscalar multiplication vector lengths #34763"), (cost_model_requested_write_lock_cost::id(), "cost model uses number of requested write locks #34819"), (enable_gossip_duplicate_proof_ingestion::id(), "enable gossip duplicate proof ingestion #32963"), + (enable_chained_merkle_shreds::id(), "Enable chained Merkle shreds #34916"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter()