@@ -592,26 +592,17 @@ impl Signer {
592
592
) -> Option < BlockResponse > {
593
593
let signer_signature_hash = proposed_block. header . signer_signature_hash ( ) ;
594
594
let proposed_block_consensus_hash = proposed_block. header . consensus_hash ;
595
-
596
- match self . signer_db . get_signer_last_accepted_block ( ) {
597
- Ok ( Some ( last_block_info) ) => {
598
- if proposed_block. header . chain_length <= last_block_info. block . header . chain_length {
599
- // We do not allow reorgs at any time within the same consensus hash OR of globally accepted blocks
600
- let non_reorgable_block = last_block_info. block . header . consensus_hash
601
- == proposed_block_consensus_hash
602
- || last_block_info. state == BlockState :: GloballyAccepted ;
603
- // Is the reorg timeout requirement exceeded?
604
- let reorg_timeout_exceeded = last_block_info
605
- . signed_self
606
- . map ( |signed_over_time| {
607
- signed_over_time. saturating_add (
608
- self . proposal_config
609
- . tenure_last_block_proposal_timeout
610
- . as_secs ( ) ,
611
- ) <= get_epoch_time_secs ( )
612
- } )
613
- . unwrap_or ( false ) ;
614
- if non_reorgable_block || !reorg_timeout_exceeded {
595
+ // If the tenure change block confirms the expected parent block, it should confirm at least one more block than the last accepted block in the parent tenure.
596
+ if let Some ( tenure_change) = proposed_block. get_tenure_change_tx_payload ( ) {
597
+ match SortitionsView :: get_tenure_last_block_info (
598
+ & tenure_change. prev_tenure_consensus_hash ,
599
+ & self . signer_db ,
600
+ self . proposal_config . tenure_last_block_proposal_timeout ,
601
+ ) {
602
+ Ok ( Some ( last_block_info) ) => {
603
+ if proposed_block. header . chain_length
604
+ <= last_block_info. block . header . chain_length
605
+ {
615
606
warn ! (
616
607
"Miner's block proposal does not confirm as many blocks as we expect" ;
617
608
"proposed_block_consensus_hash" => %proposed_block_consensus_hash,
@@ -625,17 +616,54 @@ impl Signer {
625
616
) ) ;
626
617
}
627
618
}
628
- None
619
+ Ok ( _) => {
620
+ // We have no information about the parent consensus hash. Just assume its valid.
621
+ }
622
+ Err ( e) => {
623
+ warn ! ( "{self}: Failed to check block against signer db: {e}" ;
624
+ "signer_sighash" => %signer_signature_hash,
625
+ "block_id" => %proposed_block. block_id( )
626
+ ) ;
627
+ return Some (
628
+ self . create_block_rejection ( RejectCode :: ConnectivityIssues , proposed_block) ,
629
+ ) ;
630
+ }
629
631
}
630
- Ok ( _) => None ,
632
+ }
633
+
634
+ // Ensure that the block proposal confirms the expected number of blocks in the current tenure
635
+ // (This may be redundant for a tenure change block, but we could have had two valid tenure change blocks in a row)
636
+ match self
637
+ . signer_db
638
+ . get_last_accepted_block ( & proposed_block_consensus_hash)
639
+ {
640
+ Ok ( Some ( last_block_info) ) => {
641
+ if proposed_block. header . chain_length <= last_block_info. block . header . chain_length {
642
+ warn ! (
643
+ "Miner's block proposal does not confirm as many blocks as we expect" ;
644
+ "proposed_block_consensus_hash" => %proposed_block_consensus_hash,
645
+ "proposed_block_signer_sighash" => %signer_signature_hash,
646
+ "proposed_chain_length" => proposed_block. header. chain_length,
647
+ "expected_at_least" => last_block_info. block. header. chain_length + 1 ,
648
+ ) ;
649
+ return Some ( self . create_block_rejection (
650
+ RejectCode :: SortitionViewMismatch ,
651
+ proposed_block,
652
+ ) ) ;
653
+ }
654
+ }
655
+ Ok ( _) => { }
631
656
Err ( e) => {
632
657
warn ! ( "{self}: Failed to check block against signer db: {e}" ;
633
658
"signer_sighash" => %signer_signature_hash,
634
659
"block_id" => %proposed_block. block_id( )
635
660
) ;
636
- Some ( self . create_block_rejection ( RejectCode :: ConnectivityIssues , proposed_block) )
661
+ return Some (
662
+ self . create_block_rejection ( RejectCode :: ConnectivityIssues , proposed_block) ,
663
+ ) ;
637
664
}
638
665
}
666
+ None
639
667
}
640
668
641
669
/// Handle the block validate ok response. Returns our block response if we have one
0 commit comments