@@ -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,18 @@ 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_tracker = self .epoch_tracker orelse break :feature false ;
90+ const epoch_info = epoch_tracker .getEpochInfo (shred_slot ) catch
91+ break :feature false ;
92+ const feature_slot = epoch_info .feature_set .get (
93+ .chained_merkle_conflict_duplicate_proofs ,
94+ ) orelse break :feature false ;
95+ const feat_epoch = epoch_tracker .epoch_schedule .getEpoch (feature_slot );
96+ const shred_epoch = epoch_tracker .epoch_schedule .getEpoch (shred_slot );
97+ break :feature feat_epoch < shred_epoch ;
98+ };
99+ if (! chained_merkle_conflict_duplicate_proofs ) continue ;
90100
91101 // Although this proof can be immediately stored on detection, we wait until
92102 // here in order to check the feature flag, as storage in ledger can
@@ -373,6 +383,7 @@ test "handleDuplicateSlots: no sender configured" {
373383 var handler : DuplicateShredHandler = .{
374384 .ledger_reader = ledger .reader (),
375385 .result_writer = ledger .resultWriter (),
386+ .epoch_tracker = null ,
376387 .duplicate_slots_sender = null , // No sender configured
377388 .push_msg_queue_mux = null ,
378389 .keypair = & keypair ,
@@ -408,6 +419,7 @@ test "handleDuplicateSlots: no duplicate shreds" {
408419 var handler : DuplicateShredHandler = .{
409420 .ledger_reader = ledger .reader (),
410421 .result_writer = ledger .resultWriter (),
422+ .epoch_tracker = null ,
411423 .duplicate_slots_sender = & duplicate_slots_channel ,
412424 .push_msg_queue_mux = null ,
413425 .keypair = & keypair ,
@@ -440,6 +452,7 @@ test "handleDuplicateSlots: single duplicate shred" {
440452 var handler : DuplicateShredHandler = .{
441453 .ledger_reader = ledger .reader (),
442454 .result_writer = ledger .resultWriter (),
455+ .epoch_tracker = null ,
443456 .duplicate_slots_sender = & duplicate_slots_channel ,
444457 .push_msg_queue_mux = null ,
445458 .keypair = & keypair ,
@@ -502,6 +515,7 @@ test "handleDuplicateSlots: multiple duplicates same slot" {
502515 var handler : DuplicateShredHandler = .{
503516 .ledger_reader = ledger .reader (),
504517 .result_writer = ledger .resultWriter (),
518+ .epoch_tracker = null ,
505519 .duplicate_slots_sender = & duplicate_slots_channel ,
506520 .push_msg_queue_mux = null ,
507521 .keypair = & keypair ,
@@ -576,6 +590,7 @@ test "handleDuplicateSlots: Exists but slot already duplicate" {
576590 var handler : DuplicateShredHandler = .{
577591 .ledger_reader = ledger .reader (),
578592 .result_writer = ledger .resultWriter (),
593+ .epoch_tracker = null ,
579594 .duplicate_slots_sender = & duplicate_slots_channel ,
580595 .push_msg_queue_mux = null ,
581596 .keypair = & keypair ,
@@ -624,6 +639,7 @@ test "handleDuplicateSlots: emits and stores via handleDuplicateSlot" {
624639 var handler : DuplicateShredHandler = .{
625640 .ledger_reader = ledger .reader (),
626641 .result_writer = ledger .resultWriter (),
642+ .epoch_tracker = null ,
627643 .duplicate_slots_sender = & duplicate_slots_channel ,
628644 .push_msg_queue_mux = null ,
629645 .keypair = & keypair ,
@@ -674,6 +690,7 @@ test "pushDuplicateShredToGossip: enqueues chunks and ring indices" {
674690 var handler : DuplicateShredHandler = .{
675691 .ledger_reader = ledger .reader (),
676692 .result_writer = ledger .resultWriter (),
693+ .epoch_tracker = null ,
677694 .duplicate_slots_sender = null ,
678695 .push_msg_queue_mux = & gossip_state .push_msg_queue ,
679696 .keypair = & keypair ,
@@ -763,6 +780,7 @@ test "pushDuplicateShredToGossip: no-op when duplicate for slot exists" {
763780 var handler : DuplicateShredHandler = .{
764781 .ledger_reader = ledger .reader (),
765782 .result_writer = ledger .resultWriter (),
783+ .epoch_tracker = null ,
766784 .duplicate_slots_sender = null ,
767785 .push_msg_queue_mux = & gossip_state .push_msg_queue ,
768786 .keypair = & keypair ,
0 commit comments