Search code examples
javascriptmocha.jsrsk

How to advance block number when I’m developing on RSK Regtest?


I have a smart contract that checks if the actual block number is higher than a fixed one to execute certain functionality and I need to write a unit test to validate that behavior. I’m using RSK in Regtest mode to execute tests and I would need to increment the block number without actually waiting for time to pass.

The smart contract uses a block number, and I need to increment the block number without actually waiting for time to pass.

context('once deployed', function () {
   it('can only be released after cliff', async function () {
     // TODO here I need to increment time or block number
     await this.lockup.release();
   });
)};

How can I do this in a truffle (mocha) test like the one above?


Solution

  • Quick note, to stress this is not possible in "actual" RSK blockchains (Mainnet and Testnet), as it involves "fake" mining.

    However, in Regtest, this is indeed possible:

    (1)

    Use the evm_mine JSON-RPC method to mine blocks.

    function evmMine () {
        return new Promise((resolve, reject) => {
            web3.currentProvider.send({
                jsonrpc: "2.0",
                method: "evm_mine",
                id: new Date().getTime()
                }, (error, result) => {
                    if (error) {
                        return reject(error);
                    }
                    return resolve(result);
                });
        });
    };
    
    await evmMine(); // Force a single block to be mined.
    

    This is consistent with the approach used in Ethereum developer tools, e.g. Ganache.

    (2)

    Use the evm_increaseTime JSON-RPC method to increase time of the block:

    function evmIncreaseTime(seconds) {
        return new Promise((resolve, reject) => {
            web3.currentProvider.send({
                method: "evm_increaseTime",
                params: [seconds],
                jsonrpc: "2.0",
                id: new Date().getTime()
              }, (error, result) => {
                if (error) {
                    return reject(error);
                }
                return asyncMine().then( ()=> resolve(result));
              });
        }); 
    }
    
    await evmIncreaseTime(600); // Force block to be mined such that ~10 minutes has passed