1

How can we increase block.number on Ganache for testing purpose ? If not possible do you know an alternative like passing X fake transactions to artificially increase block.number.

Or if we have to use a private chain: is it possible to change the time between blocks for faster testing ?

Best regards

2

You can increase block.timestamp (aka now):

web3.currentProvider.send({method: "evm_increaseTime", params: [numOfSeconds]});

Note that this method is a Ganache-extension of the standard.

So do not count on it on other node types (Geth, Parity, etc).

Also note that the code above is valid for web3.js v0.x.

You might need to run it asynchronously in web3.js v1.x.

| improve this answer | |
  • Hi thanks for reply, but I need to use block.number instead of block.timestamp for security reasons. Best regards – Kevin Wad May 12 '19 at 9:55
  • @KevinWad: Well then I guess that you'll have to execute some "dummy" transactions (e.g., add a "dummy" state variable to your contract, and call a function which increments it). – goodvibration May 12 '19 at 10:06
  • 2
    There's evm_mine that can be used to create an empty block and you can use similarly to evm_increaseTime. – Ismael May 13 '19 at 15:26
  • @KevinWad: See Ismael's suggestion above. – goodvibration May 13 '19 at 15:28
  • @Ismael Thanks very much ! Goodvibration thanks for letting me know ! – Kevin Wad May 13 '19 at 15:33
2

In addition to goodvibration's answer, OpenZeppelin recently released their openzeppelin-test-helpers package. This library contains all kinds of helpers for testing smart contracts, including methods to increase the block number or timestamp, such as:

async time.advanceBlock()
async time.increase(duration)
async time.increaseTo(target)

I haven't used the library myself, but it sounds like it might be useful for you.

| improve this answer | |
  • Ok thanks you very much ! – Kevin Wad May 19 '19 at 10:06
  • 1
    This library looks cool, but note that it breaks compatibility with BigNumber.js, due to several imports that use BN.js. For instance, in my case, all tests that had "should.be.bignumber.equal" broke. – Paul Razvan Berg Jul 24 '19 at 21:01
  • @PaulBerg that's a very good point – Rosco Kalis Jul 24 '19 at 21:16
2

I needed a promise-based solution that didn't require installing a third-party library. Copy-pasting from Ethan Wessel's amazing article on truffle time testing:

advanceTime = (time) => {
  return new Promise((resolve, reject) => {
    web3.currentProvider.send({
      jsonrpc: '2.0',
      method: 'evm_increaseTime',
      params: [time],
      id: new Date().getTime()
    }, (err, result) => {
      if (err) { return reject(err) }
      return resolve(result)
    })
  })
}

advanceBlock = () => {
  return new Promise((resolve, reject) => {
    web3.currentProvider.send({
      jsonrpc: '2.0',
      method: 'evm_mine',
      id: new Date().getTime()
    }, (err, result) => {
      if (err) { return reject(err) }
      const newBlockHash = web3.eth.getBlock('latest').hash

      return resolve(newBlockHash)
    })
  })
}

takeSnapshot = () => {
  return new Promise((resolve, reject) => {
    web3.currentProvider.send({
      jsonrpc: '2.0',
      method: 'evm_snapshot',
      id: new Date().getTime()
    }, (err, snapshotId) => {
      if (err) { return reject(err) }
      return resolve(snapshotId)
    })
  })
}

revertToSnapShot = (id) => {
  return new Promise((resolve, reject) => {
    web3.currentProvider.send({
      jsonrpc: '2.0',
      method: 'evm_revert',
      params: [id],
      id: new Date().getTime()
    }, (err, result) => {
      if (err) { return reject(err) }
      return resolve(result)
    })
  })
}

advanceTimeAndBlock = async (time) => {
  await advanceTime(time)
  await advanceBlock()
  return Promise.resolve(web3.eth.getBlock('latest'))
}

module.exports = {
  advanceTime,
  advanceBlock,
  advanceTimeAndBlock,
  takeSnapshot,
  revertToSnapShot
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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