@@ -551,6 +551,20 @@ impl ChainManager {
551
551
return ;
552
552
}
553
553
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
+
554
568
let mut vrf_input = chain_info. highest_vrf_output ;
555
569
vrf_input. checkpoint = current_epoch;
556
570
let active_wips = ActiveWips {
@@ -582,14 +596,7 @@ impl ChainManager {
582
596
// In order to do not block possible validate candidates in AlmostSynced
583
597
// state, we would broadcast the errors too
584
598
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| {
593
600
act. broadcast_item ( InventoryItem :: Block ( block) )
594
601
} ) ;
595
602
}
@@ -655,14 +662,7 @@ impl ChainManager {
655
662
vrf_proof,
656
663
} ) ;
657
664
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| {
666
666
act. broadcast_item ( InventoryItem :: Block ( block) )
667
667
} ) ;
668
668
}
@@ -676,14 +676,7 @@ impl ChainManager {
676
676
// In order to do not block possible validate candidates in AlmostSynced
677
677
// state, we would broadcast the errors too
678
678
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| {
687
680
act. broadcast_item ( InventoryItem :: Block ( block) )
688
681
} ) ;
689
682
}
@@ -2234,28 +2227,49 @@ impl ChainManager {
2234
2227
}
2235
2228
}
2236
2229
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 (
2239
2241
checkpoint_zero_timestamp : i64 ,
2240
2242
checkpoints_period : u16 ,
2241
2243
current_epoch : Epoch ,
2242
2244
ts : ( i64 , u32 ) ,
2243
- ) -> Duration {
2245
+ ) -> Option < Duration > {
2244
2246
let epoch_constants = EpochConstants {
2245
2247
checkpoint_zero_timestamp,
2246
2248
checkpoints_period,
2247
2249
} ;
2250
+
2251
+ // Calculate delay between mining block timestamp and another timestamp
2248
2252
let timestamp_mining = epoch_constants
2249
2253
. block_mining_timestamp ( current_epoch)
2250
2254
. unwrap ( ) ;
2255
+ let delay_from_mining_ts = duration_between_timestamps ( ( timestamp_mining, 0 ) , ts)
2256
+ . unwrap_or_else ( || Duration :: from_secs ( 0 ) ) ;
2251
2257
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 ) ;
2254
2260
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
+ }
2259
2273
}
2260
2274
2261
2275
/// Helper struct used to persist an old copy of the `ChainState` to the storage
0 commit comments