diff --git a/core/src/shred_fetch_stage.rs b/core/src/shred_fetch_stage.rs index 4aa41f9b6e74c7..59b3c2519d5b17 100644 --- a/core/src/shred_fetch_stage.rs +++ b/core/src/shred_fetch_stage.rs @@ -5,7 +5,7 @@ use { bytes::Bytes, crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}, itertools::Itertools, - solana_feature_set::FeatureSet, + solana_feature_set::{self as feature_set, FeatureSet}, solana_gossip::cluster_info::ClusterInfo, solana_ledger::shred::{self, should_discard_shred, ShredFetchStats}, solana_perf::packet::{ @@ -52,7 +52,6 @@ struct RepairContext { impl ShredFetchStage { // updates packets received on a channel and sends them on another channel - #[allow(unused_variables, unused_assignments)] fn modify_packets( recvr: PacketBatchReceiver, sendr: Sender, @@ -137,10 +136,25 @@ impl ShredFetchStage { // Filter out shreds that are way too far in the future to avoid the // overhead of having to hold onto them. let max_slot = last_slot + MAX_SHRED_DISTANCE_MINIMUM.max(2 * slots_per_epoch); + let drop_unchained_merkle_shreds = |shred_slot| { + check_feature_activation( + &feature_set::drop_unchained_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 - || should_discard_shred(packet, last_root, max_slot, shred_version, &mut stats) + || should_discard_shred( + packet, + last_root, + max_slot, + shred_version, + drop_unchained_merkle_shreds, + &mut stats, + ) { packet.meta_mut().set_discard(true); } else { @@ -413,7 +427,6 @@ pub(crate) fn receive_quic_datagrams( // Returns true if the feature is effective for the shred slot. #[must_use] -#[allow(dead_code)] fn check_feature_activation( feature: &Pubkey, shred_slot: Slot, diff --git a/ledger/src/shred.rs b/ledger/src/shred.rs index 5e972c85ace54a..dc51e1cc3a34f7 100644 --- a/ledger/src/shred.rs +++ b/ledger/src/shred.rs @@ -836,6 +836,7 @@ pub fn should_discard_shred( root: Slot, max_slot: Slot, shred_version: u16, + drop_unchained_merkle_shreds: impl Fn(Slot) -> bool, stats: &mut ShredFetchStats, ) -> bool { debug_assert!(root < max_slot); @@ -914,6 +915,9 @@ pub fn should_discard_shred( return true; } ShredVariant::MerkleCode { chained: false, .. } => { + if drop_unchained_merkle_shreds(slot) { + return true; + } stats.num_shreds_merkle_code = stats.num_shreds_merkle_code.saturating_add(1); } ShredVariant::MerkleCode { chained: true, .. } => { @@ -921,6 +925,9 @@ pub fn should_discard_shred( stats.num_shreds_merkle_code_chained.saturating_add(1); } ShredVariant::MerkleData { chained: false, .. } => { + if drop_unchained_merkle_shreds(slot) { + return true; + } stats.num_shreds_merkle_data = stats.num_shreds_merkle_data.saturating_add(1); } ShredVariant::MerkleData { chained: true, .. } => { @@ -1194,6 +1201,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); } @@ -1206,6 +1214,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 1); @@ -1216,6 +1225,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 2); @@ -1226,6 +1236,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 3); @@ -1236,6 +1247,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.index_overrun, 4); @@ -1246,6 +1258,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.bad_parent_offset, 1); @@ -1257,6 +1270,7 @@ mod tests { root, max_slot, shred_version.wrapping_add(1), + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.shred_version_mismatch, 1); @@ -1268,6 +1282,7 @@ mod tests { parent_slot + 1, // root max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.slot_out_of_range, 1); @@ -1289,6 +1304,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.slot_out_of_range, 1); @@ -1310,6 +1326,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.bad_parent_offset, 1); @@ -1330,6 +1347,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.index_out_of_bounds, 1); @@ -1346,6 +1364,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); } @@ -1356,6 +1375,7 @@ mod tests { root, max_slot, shred_version.wrapping_add(1), + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.shred_version_mismatch, 1); @@ -1367,6 +1387,7 @@ mod tests { slot, // root max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.slot_out_of_range, 1); @@ -1387,6 +1408,7 @@ mod tests { root, max_slot, shred_version, + |_| false, // drop_unchained_merkle_shreds &mut stats )); assert_eq!(stats.index_out_of_bounds, 1); diff --git a/sdk/feature-set/src/lib.rs b/sdk/feature-set/src/lib.rs index cc4239f608a062..3958b17186b646 100644 --- a/sdk/feature-set/src/lib.rs +++ b/sdk/feature-set/src/lib.rs @@ -928,6 +928,10 @@ pub mod raise_block_limits_to_50m { solana_pubkey::declare_id!("5oMCU3JPaFLr8Zr4ct7yFA7jdk6Mw1RmB8K4u9ZbS42z"); } +pub mod drop_unchained_merkle_shreds { + solana_pubkey::declare_id!("3A9WtMU4aHuryD3VN7SFKdfXto8HStLb1Jj6HjkgfnGL"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: AHashMap = [ @@ -1155,6 +1159,7 @@ lazy_static! { (reserve_minimal_cus_for_builtin_instructions::id(), "Reserve minimal CUs for builtin instructions SIMD-170 #2562"), (raise_block_limits_to_50m::id(), "Raise block limit to 50M SIMD-0207"), (fix_alt_bn128_multiplication_input_length::id(), "fix alt_bn128 multiplication input length SIMD-0222 #3686"), + (drop_unchained_merkle_shreds::id(), "drops unchained Merkle shreds #2149"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter()