@@ -23,6 +23,7 @@ const MAX_DUPLICATE_SHREDS: usize = sig.gossip.data.MAX_DUPLICATE_SHREDS;
2323pub const DuplicateShredHandler = struct {
2424 ledger_reader : sig.ledger.Reader ,
2525 result_writer : sig.ledger.ResultWriter ,
26+ epoch_tracker : * const sig.core.EpochTracker ,
2627 duplicate_slots_sender : ? * Channel (Slot ),
2728 push_msg_queue_mux : ? * sig.gossip.GossipService.PushMessageQueue ,
2829 keypair : * const KeyPair ,
@@ -84,9 +85,17 @@ pub const DuplicateShredHandler = struct {
8485 .ChainedMerkleRootConflict = > | conflict | {
8586 const shred_slot = conflict .original .commonHeader ().slot ;
8687
87- // TODO: Check feature flag for chained_merkle_conflict_duplicate_proofs
88- // For now, we'll store it unconditionally. When feature checking is implemented,
89- // this should check: if (!chained_merkle_conflict_duplicate_proofs) continue;
88+ const chained_merkle_conflict_duplicate_proofs : bool = feature : {
89+ const epoch_info = self .epoch_tracker .getEpochInfo (shred_slot ) catch
90+ break :feature false ;
91+ const feature_slot = epoch_info .feature_set .get (
92+ .chained_merkle_conflict_duplicate_proofs ,
93+ ) orelse break :feature false ;
94+ const feat_epoch = self .epoch_tracker .epoch_schedule .getEpoch (feature_slot );
95+ const shred_epoch = self .epoch_tracker .epoch_schedule .getEpoch (shred_slot );
96+ break :feature feat_epoch < shred_epoch ;
97+ };
98+ if (! chained_merkle_conflict_duplicate_proofs ) continue ;
9099
91100 // Although this proof can be immediately stored on detection, we wait until
92101 // here in order to check the feature flag, as storage in ledger can
0 commit comments