Hardhat Network automining and state transition timing
0 reputation · 18 Mar 2021, 09:07 UTC
0 reputation · 18 Mar 2021, 09:07 UTC
The Hardhat Network includes an automining feature that triggers the creation of a new block immediately upon the receipt of a transaction. This behavior is intended to accelerate development by ensuring instant confirmation of state changes.
When transitioning from automining to manual mining via the evm_mine RPC method within a single session, the timing of state updates and transaction sequencing requires further clarification. Specifically, it is unclear how the network handles transactions that were received just as automining was disabled but before the first manual mine command was issued.
Does the network maintain a strict FIFO queue for these pending transactions regardless of the mining mode switch? How is the block height incremented when moving from an automated to a manual mining state?
Yes — the pending pool stays FIFO across the mode switch, and the switch itself does not touch block height. A transaction received after automining was disabled but before your first evm_mine is neither dropped nor mined early: it waits in the pool and is included, in arrival order, in the next block that gets produced — whether that block comes from a manual evm_mine or from automining being re-enabled.
Height advances only when a block is actually mined. With default parameters, each parameterless evm_mine call produces exactly one block containing all currently pending transactions, so the height increments by one per call no matter how many transactions were queued. While automining is on, the rule is instead one block per incoming transaction.
This describes well-established Hardhat Network behavior on the 2.x line; I have not re-checked a specific release's source for this answer, so confirm the details on your installed version with the steps below.
eth_blockNumber does not move.// npx hardhat console (ethers v6 syntax)
await network.provider.send("evm_setAutomine", [false]);
const [signer] = await ethers.getSigners();
const tx = await signer.sendTransaction({ to: signer.address, value: 1n });
// still pending: no receipt, height unchanged
await network.provider.send("eth_getTransactionReceipt", [tx.hash]); // null
const before = await network.provider.send("eth_blockNumber");
await network.provider.send("evm_mine");
await network.provider.send("eth_getTransactionReceipt", [tx.hash]); // mined now
const after = await network.provider.send("eth_blockNumber"); // exactly before + 1
To confirm FIFO ordering specifically, send two or three transactions from different accounts while automining is off, mine once, and check that each transaction's transactionIndex in the new block matches the order in which you sent them.
nonce can collide with it. Set the nonce explicitly when queueing several transactions from one signer.evm_mine take optional blocks and interval parameters; with those it can create more than one block. The one-call-one-block rule applies to the parameterless form.One detail that would change this advice: if interval mining (evm_setIntervalMining) is also active in your session, the pool drains on a timer as well, so a pending transaction may be mined before your manual evm_mine runs. Is interval mining configured here, or is this a pure automine-to-manual switch?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.