This repository has been archived by the owner on Feb 26, 2024. It is now read-only.
Ganache v7's Instamine Modes Explained #2111
davidmurdoch
started this conversation in
General
Replies: 1 comment
-
Thanks for this excellent explanation @davidmurdoch! |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
This is an explanation of Ganache v7's new "instamine" modes . Let us know in the comments below if you need any further clarification.
New option
--miner.instamine
Ganache has historically "instamined" transactions in a way that can cause code that works with Ganache to not work when run against a real network. By default Ganache returns the transaction's hash to the caller after the transaction has been included in a block, whereas transactions sent to a real node always return the hash before the transaction has been included in a block.
The following assertion will pass in Ganache, but fail when run on a real node:
--miner.instamine=eager
(default)The new
--miner.instamine
defaults toeager
, which is the same default behavior Ganache has always had. While convenient for writing tests and quick prototypes, this default behavior has led many new Ethereum developers to believe thateth_sendTransaction
doesn't return until the transaction is included in a block.That said, this behavior is so convenient that while wrong, we are not getting rid of it and will be keeping it as the default instamine mode in Ganache v7. We'll work on educating users where we can, and will provide a new method for users that want the speed of instamine, but behavior closer to that of a real node.
One related change in Ganache v7 that does depart from the old defaults is that the
--vmErrorsOnRPCResponse
flag now defaults tofalse
; meaning you won't get transactionrevert
errors as a response to aneth_sendTransaction
. If you need this behavior set the--chain.vmErrorsOnRPCResponse
flag.--miner.instamine=strict
To bring Ganache more in alignment with the behavior of a real node we've introduced a new
strict
instamine mode.In
strict
mode we now add the transaction to an internal transaction pool, return the transaction's hash to the caller, and then process the transaction for inclusion in a block.This change causes the previous code to fail, as the
receipt
will benull
. We currently detect when a transaction receipt for a transaction that is currently in the pool is requested and log the following message with a link to this very discussion:If you connect to Ganache with a Web3 library like web3.js or ethers.js your code probably still works, but it may be much slower! 😲 This can happen if the library doesn't listen to the
newHeads
event early enough, causing the provider to poll for changes.We'll be working with library authors to make sure the libraries listen to events correctly, so if the library you are using appears to fall back to polling make sure you've updated to the latest version, and if so please let us, or them, know by opening an Issue!
Now, to enable this new mode:
Awaiting Transactions in Strict Mode
A robust approach to wait for a transaction to be confirmed without a helper library like web3.js or ethers.js would be:
If your use case can safely assume that transactions will always be successful and no other
"message"
events will be emitted by the provider (e.g. in your tests), this more terse (albeit naive) way of waiting for a transaction with a Ganache provider could be helpful:Another important side effect of this change is that EVM exceptions that occur during the execution of your transaction are now discarded, and the
vmErrorsOnRPCResponse
option has no effect! 😬In the future we plan on implementing EIP-758 Subscriptions and filter for completed transactions in Ganache and other nodes, but in the meantime you'll have to work around this problem by replaying your transaction with
eth_call
(see this).Let us know below if you have any questions.
Beta Was this translation helpful? Give feedback.
All reactions