@@ -63,7 +63,7 @@ extern crate substrate_keyring;
6363
6464use std:: collections:: { HashMap , HashSet } ;
6565use std:: sync:: Arc ;
66- use std:: time:: { Duration , Instant } ;
66+ use std:: time:: { self , Duration , Instant } ;
6767
6868use codec:: { Decode , Encode } ;
6969use polkadot_api:: PolkadotApi ;
@@ -267,6 +267,9 @@ impl<C, N, P> bft::Environment<Block> for ProposerFactory<C, N, P>
267267 ) -> Result < ( Self :: Proposer , Self :: Input , Self :: Output ) , Error > {
268268 use runtime_primitives:: traits:: { Hash as HashT , BlakeTwo256 } ;
269269
270+ // force delay in evaluation this long.
271+ const FORCE_DELAY : Timestamp = 5 ;
272+
270273 let parent_hash = parent_header. hash ( ) . into ( ) ;
271274
272275 let id = BlockId :: hash ( parent_hash) ;
@@ -330,6 +333,7 @@ impl<C, N, P> bft::Environment<Block> for ProposerFactory<C, N, P>
330333 transaction_pool : self . transaction_pool . clone ( ) ,
331334 offline : self . offline . clone ( ) ,
332335 validators,
336+ minimum_timestamp : current_timestamp ( ) + FORCE_DELAY ,
333337 _drop_signal : drop_signal,
334338 } ;
335339
@@ -386,6 +390,7 @@ pub struct Proposer<C: PolkadotApi> {
386390 transaction_pool : Arc < TransactionPool < C > > ,
387391 offline : SharedOfflineTracker ,
388392 validators : Vec < AccountId > ,
393+ minimum_timestamp : u64 ,
389394 _drop_signal : exit_future:: Signal ,
390395}
391396
@@ -437,6 +442,7 @@ impl<C> bft::Proposer<Block> for Proposer<C>
437442 table : self . table . clone ( ) ,
438443 offline : self . offline . clone ( ) ,
439444 validators : self . validators . clone ( ) ,
445+ minimum_timestamp : self . minimum_timestamp ,
440446 timing,
441447 } )
442448 }
@@ -489,9 +495,11 @@ impl<C> bft::Proposer<Block> for Proposer<C>
489495 ) ;
490496
491497 // the duration until the given timestamp is current
492- let proposed_timestamp = proposal. timestamp ( ) ;
498+ let proposed_timestamp = :: std :: cmp :: max ( self . minimum_timestamp , proposal. timestamp ( ) ) ;
493499 let timestamp_delay = if proposed_timestamp > current_timestamp {
494- Some ( now + Duration :: from_secs ( proposed_timestamp - current_timestamp) )
500+ let delay_s = proposed_timestamp - current_timestamp;
501+ debug ! ( target: "bft" , "Delaying evaluation of proposal for {} seconds" , delay_s) ;
502+ Some ( now + Duration :: from_secs ( delay_s) )
495503 } else {
496504 None
497505 } ;
@@ -642,8 +650,6 @@ impl<C> bft::Proposer<Block> for Proposer<C>
642650}
643651
644652fn current_timestamp ( ) -> Timestamp {
645- use std:: time;
646-
647653 time:: SystemTime :: now ( ) . duration_since ( time:: UNIX_EPOCH )
648654 . expect ( "now always later than unix epoch; qed" )
649655 . as_secs ( )
@@ -697,6 +703,7 @@ pub struct CreateProposal<C: PolkadotApi> {
697703 timing : ProposalTiming ,
698704 validators : Vec < AccountId > ,
699705 offline : SharedOfflineTracker ,
706+ minimum_timestamp : Timestamp ,
700707}
701708
702709impl < C > CreateProposal < C > where C : PolkadotApi {
@@ -708,7 +715,7 @@ impl<C> CreateProposal<C> where C: PolkadotApi {
708715 const MAX_VOTE_OFFLINE_SECONDS : Duration = Duration :: from_secs ( 60 ) ;
709716
710717 // TODO: handle case when current timestamp behind that in state.
711- let timestamp = current_timestamp ( ) ;
718+ let timestamp = :: std :: cmp :: max ( self . minimum_timestamp , current_timestamp ( ) ) ;
712719
713720 let elapsed_since_start = self . timing . dynamic_inclusion . started_at ( ) . elapsed ( ) ;
714721 let offline_indices = if elapsed_since_start > MAX_VOTE_OFFLINE_SECONDS {
0 commit comments