10

I use truffle + testrpc for testing my contracts and I need to test some time-dependant code (I guess that situation is quite common). I set some objects, check some conditions, then I need to simulate time forwarding to check conditions again.

Testrpc has evm_increaseTime function implemented. Can I use it in truffle tests? If yes, is it limited to javascript-written tests only? So far I wrote only solidity-tests.

I can't figure out what is the best way to use that evm_increaseTime function and how, though I am sure lots of people already solved that problem.

0

2 Answers 2

16

You can use evm_increaseTime from truffle console to adjust timestamp of the next block. Here is an example (from this answer):

> web3.eth.getBlock(web3.eth.blockNumber).timestamp
1500300000
> web3.currentProvider.send({jsonrpc: "2.0", method: "evm_increaseTime", params: [12345], id: 0})
{ id: 0, jsonrpc: '2.0', result: 12345 }
> web3.currentProvider.send({jsonrpc: "2.0", method: "evm_mine", params: [], id: 0})
> web3.eth.getBlock(web3.eth.blockNumber).timestamp
1500312345

It is not possible to call this from Solidity tests. Common practice is to override now or block.timestamp and update it's value manually:

contract X {
  struct FakeBlock {
    uint timestamp;
  }

  FakeBlock block;

  uint now;

  function setBlockTime(uint val) {
    now = val;
    block.timestamp = val;
  }
}

Notice, that now is an alias to the block.timestamp but when overriding only one of them, another one is not updated.

3
  • Thanks, is it possible to run some Solidity tests, then call evm_increaseTime from truffle console and then run another Solidity test with that new time? Jul 18, 2017 at 13:51
  • Don't think there is an easy way to do this. Truffle uses testrpc's snapshots to clean state between test bundles, so any changes issued from console will be reverted. Jul 18, 2017 at 13:56
  • @maxtaldykin your method does not work for me, see ethereum.stackexchange.com/questions/27447/…
    – nubela
    Sep 29, 2017 at 14:43
8

I use zeppelin-solidity function in truffle tests

const increaseTime = function(duration) {
  const id = Date.now()

  return new Promise((resolve, reject) => {
    web3.currentProvider.sendAsync({
      jsonrpc: '2.0',
      method: 'evm_increaseTime',
      params: [duration],
      id: id,
    }, err1 => {
      if (err1) return reject(err1)

      web3.currentProvider.sendAsync({
        jsonrpc: '2.0',
        method: 'evm_mine',
        id: id+1,
      }, (err2, res) => {
        return err2 ? reject(err2) : resolve(res)
      })
    })
  })
}
1
  • <3 thanks my dear
    – btc4cash
    Apr 9, 2019 at 18:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.