@@ -79,6 +79,9 @@ use unexpected::{Mismatch, OutOfBounds};
79
79
use types:: BlockNumber ;
80
80
use types:: header:: { ExtendedHeader , Header } ;
81
81
82
+ #[ cfg( not( feature = "time_checked_add" ) ) ]
83
+ use time_utils:: CheckedSystemTime ;
84
+
82
85
use self :: block_state:: CliqueBlockState ;
83
86
use self :: params:: CliqueParams ;
84
87
use self :: step_service:: StepService ;
@@ -241,7 +244,8 @@ impl Clique {
241
244
let mut state = CliqueBlockState :: new (
242
245
extract_signers ( header) ?) ;
243
246
244
- state. calc_next_timestamp ( header, self . period ) ;
247
+ // TODO(niklasad1): refactor to perform this check in the `CliqueBlockState` constructor instead
248
+ state. calc_next_timestamp ( header. timestamp ( ) , self . period ) ?;
245
249
246
250
Ok ( state)
247
251
}
@@ -326,7 +330,7 @@ impl Clique {
326
330
for item in chain {
327
331
new_state. apply ( item, false ) ?;
328
332
}
329
- new_state. calc_next_timestamp ( header, self . period ) ;
333
+ new_state. calc_next_timestamp ( header. timestamp ( ) , self . period ) ? ;
330
334
block_state_by_hash. insert ( header. hash ( ) , new_state. clone ( ) ) ;
331
335
332
336
let elapsed = backfill_start. elapsed ( ) ;
@@ -435,7 +439,7 @@ impl Engine<EthereumMachine> for Clique {
435
439
// locally sealed block don't go through valid_block_family(), so we have to record state here.
436
440
let mut new_state = state. clone ( ) ;
437
441
new_state. apply ( & header, is_checkpoint) ?;
438
- new_state. calc_next_timestamp ( & header, self . period ) ;
442
+ new_state. calc_next_timestamp ( header. timestamp ( ) , self . period ) ? ;
439
443
self . block_state_by_hash . write ( ) . insert ( header. hash ( ) , new_state) ;
440
444
441
445
trace ! ( target: "engine" , "on_seal_block: finished, final header: {:?}" , header) ;
@@ -531,15 +535,23 @@ impl Engine<EthereumMachine> for Clique {
531
535
532
536
// Don't waste time checking blocks from the future
533
537
{
534
- // TODO(niklasad): checked_add
535
- let limit = SystemTime :: now ( ) . duration_since ( UNIX_EPOCH ) . unwrap_or_default ( ) + Duration :: from_secs ( self . period ) ;
538
+ let limit = SystemTime :: now ( ) . checked_add ( Duration :: from_secs ( self . period ) )
539
+ . ok_or ( BlockError :: TimestampOverflow ) ?;
540
+
541
+ // This should succeed under the contraints that the system clock works
542
+ let limit_as_dur = limit. duration_since ( UNIX_EPOCH ) . map_err ( |e| {
543
+ Box :: new ( format ! ( "Converting SystemTime to Duration failed: {}" , e) )
544
+ } ) ?;
545
+
536
546
let hdr = Duration :: from_secs ( header. timestamp ( ) ) ;
537
- if hdr > limit {
538
- return Err ( BlockError :: TemporarilyInvalid ( OutOfBounds {
547
+ if hdr > limit_as_dur {
548
+ let found = UNIX_EPOCH . checked_add ( hdr) . ok_or ( BlockError :: TimestampOverflow ) ?;
549
+
550
+ Err ( BlockError :: TemporarilyInvalid ( OutOfBounds {
539
551
min : None ,
540
- max : Some ( UNIX_EPOCH + limit) ,
541
- found : UNIX_EPOCH + Duration :: from_secs ( header . timestamp ( ) ) ,
542
- } ) ) ?;
552
+ max : Some ( limit) ,
553
+ found,
554
+ } ) ) ?
543
555
}
544
556
}
545
557
@@ -642,11 +654,16 @@ impl Engine<EthereumMachine> for Clique {
642
654
}
643
655
644
656
// Ensure that the block's timestamp isn't too close to it's parent
645
- if parent. timestamp ( ) . saturating_add ( self . period ) > header. timestamp ( ) {
657
+ let limit = parent. timestamp ( ) . saturating_add ( self . period ) ;
658
+ if limit > header. timestamp ( ) {
659
+ let max = UNIX_EPOCH . checked_add ( Duration :: from_secs ( header. timestamp ( ) ) ) ;
660
+ let found = UNIX_EPOCH . checked_add ( Duration :: from_secs ( limit) )
661
+ . ok_or ( BlockError :: TimestampOverflow ) ?;
662
+
646
663
Err ( BlockError :: InvalidTimestamp ( OutOfBounds {
647
- min : Some ( UNIX_EPOCH + Duration :: from_secs ( parent . timestamp ( ) . saturating_add ( self . period ) ) ) ,
648
- max : None ,
649
- found : UNIX_EPOCH + Duration :: from_secs ( header . timestamp ( ) )
664
+ min : None ,
665
+ max,
666
+ found,
650
667
} ) ) ?
651
668
}
652
669
@@ -655,15 +672,15 @@ impl Engine<EthereumMachine> for Clique {
655
672
// Try to apply current state, apply() will further check signer and recent signer.
656
673
let mut new_state = parent_state. clone ( ) ;
657
674
new_state. apply ( header, header. number ( ) % self . epoch_length == 0 ) ?;
658
- new_state. calc_next_timestamp ( header, self . period ) ;
675
+ new_state. calc_next_timestamp ( header. timestamp ( ) , self . period ) ? ;
659
676
self . block_state_by_hash . write ( ) . insert ( header. hash ( ) , new_state) ;
660
677
661
678
Ok ( ( ) )
662
679
}
663
680
664
681
fn genesis_epoch_data ( & self , header : & Header , _call : & Call ) -> Result < Vec < u8 > , String > {
665
682
let mut state = self . new_checkpoint_state ( header) . expect ( "Unable to parse genesis data." ) ;
666
- state. calc_next_timestamp ( header, self . period ) ;
683
+ state. calc_next_timestamp ( header. timestamp ( ) , self . period ) . map_err ( |e| format ! ( "{}" , e ) ) ? ;
667
684
self . block_state_by_hash . write ( ) . insert ( header. hash ( ) , state) ;
668
685
669
686
// no proof.
0 commit comments