Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

fix: save evm_mine blocks before returning #3016

Merged
merged 13 commits into from May 31, 2022

Conversation

MicaiahReid
Copy link
Contributor

@MicaiahReid MicaiahReid commented May 2, 2022

Though it was rare, sometimes calling evm_mine would return before the mined block was actually saved. If you polled for the block that Ganache had claimed to mine directly after calling evm_mine, that block could not yet exist.

This change ensures that the block is saved before emitting the "newHeads" subscription message and before returning during an evm_mine. Fixes #3060.

Potential Side Effect

This change does have one potential side effect, though we really doubt anyone should be impacted, and we consider it a bug fix. Sometimes when a block is mined, Ganache waits until the next iteration of the event loop (using setImmediate) to emit the mined block. This is to ensure that the user has time to listen for the new block's "message" before Ganache emits it.

Previously, Ganache would delay emitting this event if --miner.instamine="eager" AND --miner.blockTime=0. These settings mean that transactions are saved before returning the transaction (as apposed to returning a hash as the transaction enters the transaction pool in "strict" mode), and the miner immediately starts mining transactions as they enter the transaction pool (as opposed to mining a block every blockTime seconds).*

Now, Ganache delays emitting this event when --miner.instamine="eager" regardless of how blockTime is set. The instamine mode affects when the transaction is returned to the user, so it should be the driving factor behind delaying the event. If in --miner.blockTime=0 mode (the default) you somehow relied on the event being emitted at a very specific event tick, this may cause issues for you. For most of us mere mortal developers, this won't make a difference.

*Note: We'll have a blog post or discussion providing a deeper dive into all of our mining modes soon that should help further clarify --miner.instamine, --miner.blockTime, and --chain.vmErrorsOnRPCResponse.

@MicaiahReid MicaiahReid marked this pull request as ready for review May 5, 2022 16:12
@MicaiahReid MicaiahReid changed the title Fix/mining race condition fix: save evm_mine blocks before returning May 5, 2022
@davidmurdoch
Copy link
Member

Thoughts on adding tests for this new timing behavior?

@MicaiahReid
Copy link
Contributor Author

Thoughts on adding tests for this new timing behavior?

I mean our block is null; didn't correctly mine ${numberOfBlocksToMine} blocks test kind of tests this, right? 😄

Yeah, I'll get some tests added.

@MicaiahReid
Copy link
Contributor Author

@davidmurdoch I've added a test!

I'm instantiating a provider where I specify the db using the {database: { db: ... }} flag, and I'm passing in memdown. I'm using patch-package to update memdown's _batch function to delay 20ms before saving. This _batch function is used by our blockchain to save blocks to the db.

I've created a branch that has these tests without the actual race condition fixes as a proof that the tests do what I say they should, and that my changes actually fix the bug.

@MicaiahReid MicaiahReid merged commit 7613c79 into develop May 31, 2022
@MicaiahReid MicaiahReid deleted the fix/mining-race-condition branch May 31, 2022 21:45
davidmurdoch pushed a commit that referenced this pull request Jun 2, 2022
* await _saving_ block before returning evm_mine

* delay emitting block til next event loop in eager blocktime mode

* remove manual awaitBlockSaving

* await `blockBeingSavedPromise` after mining

* add back newline

* add memdown and patch-package as dev dep

* add patch to memdown to delay _batch calls by 20ms

* add test for mining race condition

* remove patch package; monkey patch instead

* remove patch-package dependency

* assert memdown patch works

* add clarifying comment

* remove unneeded return
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
3 participants