eve_mine with timestamp parameter is some times off by one second
See original GitHub issueevm_mine with timestamp parameter is some times off by one second. This is not helpful as deterministic behaviour of contracts is often desirable when hunting for bugs.
Expected Behavior
I would expect evm_mine with timestamp to deliver a block with exactly the given timestamp.
Current Behavior
I call evm_mine with a timestamp parameter, which usually is honoured but not always. This is an intermittent problem. Below I provide two sample outputs of a test contract in Truffle, which differ only in the timestamps of block 14.
Here is the first output, with block 14 having a time stamp 1600000071
$ truffle test
Compiling ./contracts/ConvertLib.sol...
Compiling ./contracts/MetaCoin.sol...
Compiling ./contracts/Migrations.sol...
Contract: MetaCoin
block.number 5 block.timestamp 1552999213 timestamp 1600000000
1 'blockNumber' 6
✓ TEST 1: should deploy (42ms)
block.number 6 block.timestamp 1600000000 timestamp 1600000020
2 'blockNumber' 7
✓ TEST 2: should put 10000 MetaCoin in the first account (69ms)
block.number 7 block.timestamp 1600000020 timestamp 1600000030
3 'blockNumber' 8
✓ TEST 3: should fail because function does not exist on contract
block.number 8 block.timestamp 1600000030 timestamp 1600000040
4 'blockNumber' 9
✓ TEST 4: should call a function that depends on a linked library (85ms)
block.number 9 block.timestamp 1600000040 timestamp 1600000050
5 'blockNumber' 10
✓ TEST 5: should send coin (109ms)
block.number 11 block.timestamp 1600000050 timestamp 1600000060
6 'blockNumber' 12
✓ TEST 6: should not send coin (54ms)
block.number 12 block.timestamp 1600000060 timestamp 1600000070
7 'blockNumber' 13
✓ TEST 7: should send coin correctly (227ms)
block.number 14 block.timestamp 1600000071 timestamp 1600000080
8 'blockNumber' 15
0 'blockNumber' 0 'timeStamp' 1552999209
1 'blockNumber' 1 'timeStamp' 1552999212
2 'blockNumber' 2 'timeStamp' 1552999212
3 'blockNumber' 3 'timeStamp' 1552999213
4 'blockNumber' 4 'timeStamp' 1552999213
5 'blockNumber' 5 'timeStamp' 1552999213
6 'blockNumber' 6 'timeStamp' 1600000000
7 'blockNumber' 7 'timeStamp' 1600000020
8 'blockNumber' 8 'timeStamp' 1600000030
9 'blockNumber' 9 'timeStamp' 1600000040
10 'blockNumber' 10 'timeStamp' 1600000050
11 'blockNumber' 11 'timeStamp' 1600000050
12 'blockNumber' 12 'timeStamp' 1600000060
13 'blockNumber' 13 'timeStamp' 1600000070
14 'blockNumber' 14 'timeStamp' 1600000071
15 'blockNumber' 15 'timeStamp' 1600000080
✓ TEST 8: check all addresses (234ms)
8 passing (904ms)
Here is the second output with block 14 having a time stamp 1600000070
$ truffle test
Compiling ./contracts/ConvertLib.sol...
Compiling ./contracts/MetaCoin.sol...
Compiling ./contracts/Migrations.sol...
Contract: MetaCoin
block.number 5 block.timestamp 1552999262 timestamp 1600000000
1 'blockNumber' 6
✓ TEST 1: should deploy (39ms)
block.number 6 block.timestamp 1600000000 timestamp 1600000020
2 'blockNumber' 7
✓ TEST 2: should put 10000 MetaCoin in the first account (67ms)
block.number 7 block.timestamp 1600000020 timestamp 1600000030
3 'blockNumber' 8
✓ TEST 3: should fail because function does not exist on contract
block.number 8 block.timestamp 1600000030 timestamp 1600000040
4 'blockNumber' 9
✓ TEST 4: should call a function that depends on a linked library (91ms)
block.number 9 block.timestamp 1600000040 timestamp 1600000050
5 'blockNumber' 10
✓ TEST 5: should send coin (119ms)
block.number 11 block.timestamp 1600000050 timestamp 1600000060
6 'blockNumber' 12
✓ TEST 6: should not send coin (57ms)
block.number 12 block.timestamp 1600000060 timestamp 1600000070
7 'blockNumber' 13
✓ TEST 7: should send coin correctly (228ms)
block.number 14 block.timestamp 1600000070 timestamp 1600000080
8 'blockNumber' 15
0 'blockNumber' 0 'timeStamp' 1552999258
1 'blockNumber' 1 'timeStamp' 1552999261
2 'blockNumber' 2 'timeStamp' 1552999261
3 'blockNumber' 3 'timeStamp' 1552999262
4 'blockNumber' 4 'timeStamp' 1552999262
5 'blockNumber' 5 'timeStamp' 1552999262
6 'blockNumber' 6 'timeStamp' 1600000000
7 'blockNumber' 7 'timeStamp' 1600000020
8 'blockNumber' 8 'timeStamp' 1600000030
9 'blockNumber' 9 'timeStamp' 1600000040
10 'blockNumber' 10 'timeStamp' 1600000050
11 'blockNumber' 11 'timeStamp' 1600000050
12 'blockNumber' 12 'timeStamp' 1600000060
13 'blockNumber' 13 'timeStamp' 1600000070
14 'blockNumber' 14 'timeStamp' 1600000070
15 'blockNumber' 15 'timeStamp' 1600000080
✓ TEST 8: check all addresses (229ms)
8 passing (914ms)
Possible Solution
I’m sorry, I have no idea.
Steps to Reproduce (for bugs)
Here is the truffle code needed to reproduce the issue: MetaCoin.zip
$ unzip MetaCoin.zip $ cd MetaCoin $ truffle test … keep trying until the behaviour changes $ truffle test
Context
I am trying to debug smart contracts that use now. It would be most helpful if the contracts could be made to behave deterministically.
Your Environment
$ truffle version
Truffle v5.0.2 (core: 5.0.2)
Solidity v0.5.0 (solc-js)
Node v10.15.0
$ uname -a
Darwin 18.2.0 Darwin Kernel Version 18.2.0: Thu Dec 20 20:46:53 PST 2018; root:xnu-4903.241.1~1/RELEASE_X86_64 x86_64
Issue Analytics
- State:
- Created 5 years ago
- Comments:13 (5 by maintainers)

Top Related StackOverflow Question
Thanks @pieterhartel for the detailed reproduction steps!
This apparent non-determinism is caused by ganache “instamining”; that is to say: it mines a new block immediately after a transaction is received.
evm_mine(timestamp)causes a block to be mined exactly at the timestamp given, and also updates the internaltimeAdjustment(this basically lets us fast-forward or rewind time) so blocks mined in the future always happen after the last block mined. Block timestamps are still based on the real clock though, just with thistimeAdjustmentadded in.The amount of time between
evm_mineand your next transaction is not going to be0, and sometimes the time difference will span two different real seconds – and this can happen even if the difference is a single millisecond. This is what causes the block timestamps vary in your tests.To make your tests deterministic you should:
timeoption (in addition to a deterministic seed/mnemonic option). This will create a genesis block at the given timestamp (there is actually a bug here so this part might not always happen perfectly).miner_stopRPC call to prevent any more blocks from being insta-mined.evm_mineRPC call with a timestamp to cause the transaction(s) you sent in step 3 to be mined at the specific timestamp.Let me know if you have an questions. Thanks again!
@davidmurdoch some of my transactions now timeout after 750 seconds.
Transaction was not mined within750 seconds, please make sure your transaction was properly sent. Be aware that it might still be mined!I’m trying to reproduce it in a small test but that’s not easy. Would it be possible to improve the code that you suggested to make such timeouts impossible, or at least a lot less likely?