@@ -444,6 +444,8 @@ pub fn mock_env() -> Env {
444
444
/// ```
445
445
pub struct Envs {
446
446
contract_address : Addr ,
447
+ /// The number of nanoseconds between two consecutive blocks
448
+ block_time : u64 ,
447
449
last_height : u64 ,
448
450
last_time : Timestamp ,
449
451
envs_produced : u64 ,
@@ -457,21 +459,26 @@ impl Envs {
457
459
Envs {
458
460
// Default values here for compatibility with old `mock_env` function. They could be changed to anything else if there is a good reason.
459
461
contract_address : api. addr_make ( "cosmos2contract" ) ,
462
+ block_time : 5_000_000_000 , // 5s
460
463
last_height : 12_344 ,
461
464
last_time : Timestamp :: from_nanos ( 1_571_797_419_879_305_533 ) . minus_seconds ( 5 ) ,
462
465
envs_produced : 0 ,
463
466
}
464
467
}
465
468
466
469
pub fn make ( & mut self ) -> Env {
467
- let height = self . last_height + 1 ;
468
- let time = self . last_time . plus_seconds ( 5 ) ;
470
+ self . checked_make ( ) . unwrap ( )
471
+ }
472
+
473
+ fn checked_make ( & mut self ) -> Option < Env > {
474
+ let height = self . last_height . checked_add ( 1 ) ?;
475
+ let time = Timestamp :: from_nanos ( self . last_time . nanos ( ) . checked_add ( self . block_time ) ?) ;
469
476
470
477
self . last_height = height;
471
478
self . last_time = time;
472
- self . envs_produced += 1 ;
479
+ self . envs_produced += 1 ; // does not overflow because height increment fails first
473
480
474
- Env {
481
+ Some ( Env {
475
482
block : BlockInfo {
476
483
height,
477
484
time,
@@ -481,21 +488,17 @@ impl Envs {
481
488
contract : ContractInfo {
482
489
address : self . contract_address . clone ( ) ,
483
490
} ,
484
- }
491
+ } )
485
492
}
486
493
}
487
494
488
- // The iterator implementation can produce 1 million envs and then stops for no good reason.
495
+ // The iterator implementation ends in case of overflows to avoid panics.
496
+ // Using this is recommended for very long running test suites.
489
497
impl Iterator for Envs {
490
498
type Item = Env ;
491
499
492
500
fn next ( & mut self ) -> Option < Self :: Item > {
493
- if self . envs_produced < 1_000_000 {
494
- let item = self . make ( ) ;
495
- Some ( item)
496
- } else {
497
- None
498
- }
501
+ self . checked_make ( )
499
502
}
500
503
}
501
504
@@ -1417,7 +1420,7 @@ mod tests {
1417
1420
}
1418
1421
1419
1422
#[ test]
1420
- fn envs_implements_iteratorworks ( ) {
1423
+ fn envs_implements_iterator ( ) {
1421
1424
let envs = Envs :: new ( "food" ) ;
1422
1425
1423
1426
let result: Vec < _ > = envs. into_iter ( ) . take ( 5 ) . collect ( ) ;
@@ -1441,6 +1444,17 @@ mod tests {
1441
1444
result[ 4 ] . block. time,
1442
1445
Timestamp :: from_nanos( 1_571_797_439_879_305_533 )
1443
1446
) ;
1447
+
1448
+ // Get a millions envs through iterator
1449
+ let mut envs = Envs :: new ( "yo" ) ;
1450
+ let first = envs. next ( ) . unwrap ( ) ;
1451
+ let last = envs. take ( 1_000_000 ) . last ( ) . unwrap ( ) ;
1452
+ assert_eq ! ( first. block. height, 12_345 ) ;
1453
+ assert_eq ! ( last. block. height, 1_012_345 ) ;
1454
+ assert_eq ! (
1455
+ last. block. time,
1456
+ first. block. time. plus_seconds( 1_000_000 * 5 )
1457
+ ) ;
1444
1458
}
1445
1459
1446
1460
#[ test]
0 commit comments