How to make local hardhat network run faster

Viewed 263

I have a local hardhat node spawned simply as:

npx hardhat node

I have a smart contract code that I want to test that mints 100 NFTs with a simple loop. The code basically adds the address to a map and calls OpenZeppelin's _safeMint function in a pretty standard manner.

However, in my tests it takes a few seconds to run this function, which is a bit too much for 100-iteration for loop. I've tried enabling/disabling autominting from Hardhat config but doesn't seem to change anything.

I will need to run this function for many iterations (10000) in my tests, so the duration of the call is unacceptable. I'm also on M1 Max so I doubt it's my CPU that's the bottleneck for a 100-iteration for loop which should probably take a few nanoseconds.

How can I make hardhat execute contract code faster?

(Solidity ^0.8.0, hardhat 2.8.2)

1 Answers

The solution below is a hack, but I've used it extensively in my tests with for loops up to 5000 iterations and it can run just fine (takes only a couple minutes instead of hours when using automining). The gist of it is to disable automining and interval mining and instead manually mine the blocks on demand.

// enable manual mining
await network.provider.send("evm_setAutomine", [false]);
await network.provider.send("evm_setIntervalMining", [0]);

// create the transactions, which will be pending
await Promise.all(promises); // promises consists of all the txs

// mine the needed blocks, below we mine 256 blocks at once (how many blocks to
// mine depends on how many pending transactions you have), instead of having 
// to call `evm_mine` for every single block which is time consuming
await network.provider.send("hardhat_mine", ["0x100"]);

// re-enable automining when you are done, so you dont need to manually mine future blocks
await network.provider.send("evm_setAutomine", [true]);
Related