get the current latest block's timestamp via
web3.eth.getBlock('latest').timestamp // 1516043000
then:
web3.currentProvider.sendAsync({
jsonrpc: '2.0',
method: 'evm_increaseTime',
params: [5],
id: new Date().getMillseconds()
}, (err, resp) => {
if (!err) {
web3.currentProvider.send({
jsonrpc: '2.0',
method: 'evm_mine',
params: [],
id: new Date().getMillseconds()
}
}
})
after mining new block get new
timestamp- should see1516043000 + 5=1516043005
get the current latest block's timestamp via
web3.eth.getBlock('latest').timestamp // e.g 1516043000
then:
web3.currentProvider.sendAsync({
jsonrpc: '2.0',
method: 'evm_increaseTime',
params: [5],
id: new Date().getMillseconds()
}, (err, resp) => {
if (!err) {
web3.currentProvider.send({
jsonrpc: '2.0',
method: 'evm_mine',
params: [],
id: new Date().getMillseconds()
}
}
})
after mining new block get new
timestamp- you get some arbitrary time added to the newtimestamp+ your added time.
When increasing by 5 from 1516043000 I get --> e.g 1516043037 NOT 1516043005
Mining on test network should be instantaneous no?
Don't know
ganache-clitruffle consoleget the current latest block's timestamp via
web3.eth.getBlock('latest').timestamp // e.g 1516043000
then:
web3.currentProvider.sendAsync({
jsonrpc: '2.0',
method: 'evm_increaseTime',
params: [500],
id: new Date().getMillseconds()
}, (err, resp) => {
if (!err) {
web3.currentProvider.send({
jsonrpc: '2.0',
method: 'evm_mine',
params: [],
id: new Date().getMillseconds()
}
}
})
web3.eth.getBlock('latest').timestamp // I get non deterministic timestamp 1516048032Truffle v4.0.4 (core: 4.0.4)
Solidity v0.4.18 (solc-js)
Ganache CLI v.6.0.3
ganache-core: 2.0.2
4.0.4The intention behind evm_increaseTime is to set a fixed offset from the current (at time of mining) wall clock time. That is, it sets the clock skew.
This is affecting our testing because we have time sensitive variables that can not be asserted/tested exactly due to the non-deterministic nature of the time needed to evm_mine
There is an open PR (trufflesuite/ganache-core#13) for this change in behavior, with similar motivations to what you describe here, however I'm still on the fence about whether or not it's a good idea to accept this change.
My reasoning for not wanting to accept the change is that it shouldn't be important for you to be able to write tests which check a block timestamp down to the millisecond. If this is important for you, then you're likely introducing a major security flaw into your contract, as miners can manipulate block timestamps.
But perhaps I'm assuming too much about my users... If you're willing, could tell me a bit more about your use case? Does it fit this pattern, or are you doing something different which I haven't even thought of?
Also if you're using interval mining for your test suite (the -b flag), unless there's a big reason that you need it, I think your life will be much happier and more productive if you switch to instamining (drop the -b flag). You can still call evm_mine when you need arbitrary blocks created. Your test suite will certainly execute much faster as a result of this change.
@benjamincburns Thanks for the response and mind food.
I really just boils down to the fact that we'd like to have a deterministic testing environment. Maybe introducing a new flag for removing this time skew could keep default truffle like you originally intended and allow users like us to set the determinism.
Just as an example we are using pricing function sensitive to time that we would like to assert absolutely.
Cheers.
On this topic is there a way to increase the current block number more rapidly?
We're doing this right now in testing and to mine a lot of blocks take a lot of time!
const mineOneBlock = async () => {
await web3.currentProvider.send({
jsonrpc: '2.0',
method: 'evm_mine',
params: [],
id: 0,
})
}
const mineNBlocks = async n => {
for (let i = 0; i < n; i++) {
await mineOneBlock()
}
}
@elie222 Did you solve this?
So I think in the end we used time rather than block number, but I'm trying to think if that actually helps in terms of making the simulation easier.
I don't think I had a good solution with block number, but with timestamp we had a more workable solution although I don't remember the details.
This issue costs me quite some time, because I was assuming it's a rounding error first. Then I saw the comments at https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/test/helpers/increaseTime.js#L28-L30 and changed my tests accordingly.
I think you are correct that a contract should not rely on anything down to a second. However, it makes testing a lot easier if ganache-cli is predictable.
https://github.com/trufflesuite/ganache-core/pull/13 has been merged, and the documentation on the ganache-cli repo was updated in https://github.com/trufflesuite/ganache-cli/commit/6c0d5820bc3634fa00cbeb2bd97ad721066761a5
You'll have the ability to specify a timestamp in the evm_mine call to mine exactly at. This should solve this issue. This will go into the next release (sometime this week is the goal). Thanks!
Most helpful comment
On this topic is there a way to increase the current block number more rapidly?
We're doing this right now in testing and to mine a lot of blocks take a lot of time!