@@ -18,6 +18,7 @@ use std::iter::Iterator;
1818use std:: mem;
1919use std:: sync:: { Arc , Weak } ;
2020use std:: thread:: { Builder , JoinHandle } ;
21+ use std:: time:: { Duration , SystemTime , UNIX_EPOCH } ;
2122
2223use ccrypto:: blake256;
2324use ckey:: { public_to_address, verify_schnorr, Address , SchnorrSignature } ;
@@ -651,11 +652,16 @@ impl Worker {
651652 // In the case, self.votes_received is not empty.
652653 self . request_messages_to_all ( vote_step, & BitSet :: all_set ( ) - & self . votes_received ) ;
653654 if !self . already_generated_message ( ) {
654- let block_hash = match & self . last_two_thirds_majority {
655+ let block_hash_candidate = match & self . last_two_thirds_majority {
655656 TwoThirdsMajority :: Empty => self . proposal . imported_block_hash ( ) ,
656657 TwoThirdsMajority :: Unlock ( _) => self . proposal . imported_block_hash ( ) ,
657658 TwoThirdsMajority :: Lock ( _, block_hash) => Some ( * block_hash) ,
658659 } ;
660+ let block_hash = block_hash_candidate. filter ( |hash| {
661+ let block =
662+ self . client ( ) . block ( & BlockId :: Hash ( * hash) ) . expect ( "Already got imported block hash" ) ;
663+ self . is_generation_time_relevant ( & block. decode_header ( ) )
664+ } ) ;
659665 self . generate_and_broadcast_message ( block_hash, is_restoring) ;
660666 }
661667 }
@@ -686,6 +692,21 @@ impl Worker {
686692 }
687693 }
688694
695+ fn is_generation_time_relevant ( & self , block_header : & Header ) -> bool {
696+ const ACCEPTABLE_FUTURE_GAP : Duration = Duration :: from_secs ( 5 ) ;
697+ const ACCEPTABLE_PAST_GAP : Duration = Duration :: from_secs ( 30 ) ;
698+ let now = SystemTime :: now ( ) ;
699+ let allowed_min = now - ACCEPTABLE_PAST_GAP ;
700+ let allowed_max = now + ACCEPTABLE_FUTURE_GAP ;
701+ let block_generation_time = UNIX_EPOCH . checked_add ( Duration :: from_secs ( block_header. timestamp ( ) ) ) ;
702+
703+ match block_generation_time {
704+ Some ( generation_time) => generation_time <= allowed_max && allowed_min <= generation_time,
705+ // Overflow occurred
706+ None => false ,
707+ }
708+ }
709+
689710 fn locked_proposal_block ( & self , locked_view : View ) -> Result < encoded:: Block , String > {
690711 let vote_step = VoteStep :: new ( self . height , locked_view, Step :: Propose ) ;
691712 let locked_proposal_hash = self . votes . get_block_hashes ( & vote_step) . first ( ) . cloned ( ) ;
0 commit comments