@@ -551,6 +551,20 @@ impl ChainManager {
551551 return ;
552552 }
553553
554+ // Calculate delay for broadcasting blocks
555+ let delay = if let Some ( delay) = calculate_delay_for_broadcasting_block (
556+ chain_info. consensus_constants . checkpoint_zero_timestamp ,
557+ chain_info. consensus_constants . checkpoints_period ,
558+ current_epoch,
559+ ts,
560+ ) {
561+ delay
562+ } else {
563+ log:: debug!( "Block received too late to broadcasting" ) ;
564+
565+ return ;
566+ } ;
567+
554568 let mut vrf_input = chain_info. highest_vrf_output ;
555569 vrf_input. checkpoint = current_epoch;
556570 let active_wips = ActiveWips {
@@ -582,14 +596,7 @@ impl ChainManager {
582596 // In order to do not block possible validate candidates in AlmostSynced
583597 // state, we would broadcast the errors too
584598 if self . sm_state == StateMachine :: AlmostSynced {
585- let delay = calculate_delay_from_mining_timestamp (
586- chain_info. consensus_constants . checkpoint_zero_timestamp ,
587- chain_info. consensus_constants . checkpoints_period ,
588- current_epoch,
589- ts,
590- ) ;
591-
592- ctx. run_later ( delay_function ( delay) , |act, _ctx| {
599+ ctx. run_later ( delay, |act, _ctx| {
593600 act. broadcast_item ( InventoryItem :: Block ( block) )
594601 } ) ;
595602 }
@@ -655,14 +662,7 @@ impl ChainManager {
655662 vrf_proof,
656663 } ) ;
657664
658- let delay = calculate_delay_from_mining_timestamp (
659- chain_info. consensus_constants . checkpoint_zero_timestamp ,
660- chain_info. consensus_constants . checkpoints_period ,
661- current_epoch,
662- ts,
663- ) ;
664-
665- ctx. run_later ( delay_function ( delay) , |act, _ctx| {
665+ ctx. run_later ( delay, |act, _ctx| {
666666 act. broadcast_item ( InventoryItem :: Block ( block) )
667667 } ) ;
668668 }
@@ -676,14 +676,7 @@ impl ChainManager {
676676 // In order to do not block possible validate candidates in AlmostSynced
677677 // state, we would broadcast the errors too
678678 if self . sm_state == StateMachine :: AlmostSynced {
679- let delay = calculate_delay_from_mining_timestamp (
680- chain_info. consensus_constants . checkpoint_zero_timestamp ,
681- chain_info. consensus_constants . checkpoints_period ,
682- current_epoch,
683- ts,
684- ) ;
685-
686- ctx. run_later ( delay_function ( delay) , |act, _ctx| {
679+ ctx. run_later ( delay, |act, _ctx| {
687680 act. broadcast_item ( InventoryItem :: Block ( block) )
688681 } ) ;
689682 }
@@ -2234,28 +2227,49 @@ impl ChainManager {
22342227 }
22352228}
22362229
2237- // Calculate delay between mining block timestamp and another timestamp
2238- fn calculate_delay_from_mining_timestamp (
2230+ // Auxiliary function that converts one delay in another
2231+ fn delay_function ( initial_delay : Duration ) -> Duration {
2232+ // TODO: Apply a right delay function
2233+ // Direct delay
2234+ initial_delay
2235+ }
2236+
2237+ // Calculate the delay to introduce in block broadcasting
2238+ // Returns None in case of overflow the current epoch duration
2239+ #[ allow( clippy:: cast_sign_loss) ]
2240+ fn calculate_delay_for_broadcasting_block (
22392241 checkpoint_zero_timestamp : i64 ,
22402242 checkpoints_period : u16 ,
22412243 current_epoch : Epoch ,
22422244 ts : ( i64 , u32 ) ,
2243- ) -> Duration {
2245+ ) -> Option < Duration > {
22442246 let epoch_constants = EpochConstants {
22452247 checkpoint_zero_timestamp,
22462248 checkpoints_period,
22472249 } ;
2250+
2251+ // Calculate delay between mining block timestamp and another timestamp
22482252 let timestamp_mining = epoch_constants
22492253 . block_mining_timestamp ( current_epoch)
22502254 . unwrap ( ) ;
2255+ let delay_from_mining_ts = duration_between_timestamps ( ( timestamp_mining, 0 ) , ts)
2256+ . unwrap_or_else ( || Duration :: from_secs ( 0 ) ) ;
22512257
2252- duration_between_timestamps ( ( timestamp_mining , 0 ) , ts ) . unwrap_or_else ( || Duration :: from_secs ( 0 ) )
2253- }
2258+ // Apply magic delay function
2259+ let delay_to_broadcasting = delay_function ( delay_from_mining_ts ) ;
22542260
2255- fn delay_function ( initial_delay : Duration ) -> Duration {
2256- // TODO: Apply a right delay function
2257- // Direct delay
2258- initial_delay
2261+ // Return delay only if is before the end of the epoch
2262+ let end_epoch_ts = epoch_constants
2263+ . epoch_timestamp ( current_epoch + 1 )
2264+ . unwrap_or ( i64:: MAX ) as u64 ;
2265+ let ts_with_delay = Duration :: new ( ts. 0 as u64 , ts. 1 ) . checked_add ( delay_to_broadcasting) ;
2266+
2267+ match ts_with_delay {
2268+ Some ( ts_with_delay) if ts_with_delay. as_secs ( ) < end_epoch_ts => {
2269+ Some ( delay_to_broadcasting)
2270+ }
2271+ _ => None ,
2272+ }
22592273}
22602274
22612275/// Helper struct used to persist an old copy of the `ChainState` to the storage
0 commit comments