v7.3.0
Highlights
New Features
Fixes
Miscellaneous
Changelog
Known Issues
Future Plans
This is our third feature release since Ganache v7.0.0 launched almost 5 months ago! In this release we introduce not one, but two new features, fix four bugs, perform two chores, and introduce one huge performance improvement!
If you have some time, we encourage you to browse our issues to find anything you'd like implemented/fixed sooner and give them a +1; we'll use this community feedback to help prioritize what we work on! Or better yet, open a new issue, open a PR to fix an existing issue, or apply to join our team (we're hiring!) if you really want to get involved.
Speaking of the awesome community of Ganache users, we'd like to extend our gratitude to all issue openers (@gorbak25, @benjamincburns) and contributors (@robmcl4, @AuHau, @jeffsmale90, @tenthirtyone, @MicaiahReid) who were a part of this release!
All in all, we've changed 154 files across 10 merged pull requests, tallying 4788 additions and 4251 deletions, since our last release.
The most noteworthy change in this release is likely the new TypeScript namespace for all RPC method parameters and return types. Check out the details below for more information!
Also worth mentioning is the new --miner.timestampIncrement
option. When used in combination with the existing --chain.time
option it introduces a new way of ensuring deterministic block timestamps that was previously very cumbersome and tedious to accomplish. Details below.
- feat: create arm64 architecture docker build at release (#3037)
- feat: add
miner.timestampIncrement
option (#3131)
feat: create arm64 architecture docker build at release (#3037)
We now publish a Docker build for ARM v8 (ARM64) with every new ganache release, in addition to our AMD64 build. Now when you run docker run --publish 8545:8545 trufflesuite/ganache:latest
on your M1 Mac (and other ARM64-based systems) you'll run a container built specifically for your processor's architecture.
feat: add miner.timestampIncrement
option (#3131)
We've been told that you all want us to have more meme content in our release notes. This is the best I could do this time (sorry, not sorry):
By default ganache uses the system clock time for automatically mined blocks. This behavior is convenient, but results in nondeterminism, invalid block timestamps1, and can cause issues with relative block timestamp dependent contracts and tests. There were workarounds for all of these issues (by manually mining via evm_mine({ timestamp })
) but a built in solution was clearly necessary.
Ganache now enables the use of a new --miner.timestampIncrement
option which can be used to set the amount of seconds between consecutive blocks, regardless of how much system time has passed. The default value, "clock", retains the previous default behavior of using the system time for each block.
The following example will start ganache instructing it to increment each new block's timestamp forward by 60
seconds from the initial starting time of 499162860000
(October 26 1985, as a Unix timestamp with millisecond precision):
$ ganache --time 499162860000 --miner.timestampIncrement=60
- fix:
eth_getTransactionByBlockNumberAndIndex
andeth_getTransactionByBlockHashAndIndex
to respect non-zero transaction index (#3118) - fix: add new
Ethereum
types namespace to fix types (#2527) - fix: save
evm_mine
blocks before returning (#3016) - fix: only mine one block in interval mining (#3032)
fix: eth_getTransactionByBlockNumberAndIndex
and eth_getTransactionByBlockHashAndIndex
to respect non-zero transaction index (#3118)
Both eth_getTransactionByBlockNumberAndIndex
and eth_getTransactionByBlockHashAndIndex
accept an index parameter to indicate the which transaction within the block to return.
Previous to this fix, both functions would return the 0th (first) transaction within the block, regardless of the value passed.
fix: add new Ethereum
types namespace to fix types (#2527)
We fixed our Ethereum RPC types and put them in a new namespace: Ethereum
! Use it as follows:
import Ganache, {ProviderOptions, Ethereum} from "ganache";
async function getLatestBlock(): Promise<Ethereum.Block> {
return await provider.request({method: "eth_getBlockByNumber", params: ["latest"]});
}
async function getAccounts(): Promise<string[]> {
return await provider.request({method: "eth_accounts", params: []});
}
async function sendTransaction(transaction: Ethereum.Transaction): Promise<string> {
return await provider.request({method: "eth_sendTransaction", params: [transaction]});
}
const options: ProviderOptions = {
fork: { network: "mainnet" }
};
const provider = Ganache.provider(options);
const accounts = await getAccounts();
const block = await getLatestBlock();
console.log(block.number); // string
const transaction: Ethereum.Transaction = { from: accounts[0], to: accounts[2], value: "0xffff" };
const hash = await sendTransaction(transaction);
console.log(hash); // string
If you find issues or can think of ways we can further improve our types please open a New Issue (you can view all existing type issues by filtering our issues by the typescript label).
fixes #2134
fix: save evm_mine
blocks before returning (#3016)
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
.
fix: only mine one block in interval mining (#3032)
In a real Ethereum node, blocks are committed approximately every 15 seconds. Ganache allows users to configure how often this mining takes place in this "interval" mining mode with the --miner.blockTime
flag, and it allows users to "instamine" transactions by setting --miner.blockTime=0
(the default).
For each block that is made in a real Ethereum node, the transactions that are included on the block is based off of many factors including the number of transactions in the transaction pool, the gas price and gas limit of those transactions, and the block's gas limit. Regardless of the ordering, the number of transactions included on the block is limited by that block gas limit. Then, once a single block is mined, approximately 15 seconds elapses before another block is generated.
In the interval mining mode before this change, Ganache would begin mining after the blockTime
elapses, but it would mine all transactions in the pool, regardless of how many blocks it would take. This change fixes Ganache's behavior to be more like a real Ethereum node. Now only one block will be mined whenever blockTime
elapses, even if that means leaving some transactions in the transaction pool until the next block is generated. This change fixes #3030.
- docs: update Node.js version recommendation in README (#3038)
- chore: throw if name arg in create script includes scope (#3108)
- chore: add relevant keywords to ganache's package.json (#3151)
- perf: speed up large transaction traces by buffering fragmented send (#2634)
docs: update Node.js version recommendation in README (#3038)
We haven't supported Node.js v10 for a while now; the recommendation in our README.md to use Node.js v10 has been updated to reflect our actual support: at least Node v12 and npm v6.12.0.
chore: throw if name arg in create script includes scope (#3108)
This may be a small change to an internal-facing script, but it is still a big deal: this is the first contribution to the newest member of the Ganache team: @tenthirtyone! Welcome to the team!
chore: add relevant keywords to ganache's package.json (#3151)
Users reported that it was difficult to find the ganache
package in the npm registry because they were used to searching for ganache-cli
and ganache-core
. This change adds those terms to our package.json
's "keywords"
list, which hopefully alleviates the problem.
Fixes #3143
perf: speed up large transaction traces by buffering fragmented send (#2634)
We introduced the ability to return huge transaction traces in v7.0.0, but that ability came with a cost: it was about 30x slower than it needed to be!
Thanks to work started by @robmcl4 large transaction traces (traces with more than 100000 structLogs
) are now consistently more than 30x faster than in previous versions in both WebSocket and HTTP transports. This means that transaction traces that used to take 8 minutes now takes less than 10 seconds!
If you don't mind reading some JavaScript and like reasoning about JavaScript Generator logic you should take a look at the PR that made this performance bump possible!
- #2527 fix: add new
Ethereum
types namespace to fix types (@davidmurdoch) - #3038 docs: update Node.js version recommendation in README (@davidmurdoch)
- #3108 chore: throw if name arg in create script includes scope (@tenthirtyone)
- #3037 feat: create arm64 architecture docker build at release (@AuHau)
- #3151 chore: add relevant keywords to ganache's package.json (@davidmurdoch)
- #3016 fix: save
evm_mine
blocks before returning (@MicaiahReid) - #3032 fix: only mine one block in interval mining (@MicaiahReid)
- #2634 perf: speed up large transaction traces by buffering fragmented send (@robmcl4)
- #3131 feat: add
miner.timestampIncrement
option (@davidmurdoch)
Top Priority:
- Unable to install Ganache (npm) on MacOS 10.15.7 (#2445)
- get forking working in the browser (#1245)
- Implement
eth_getProof
RPC message (#382)
Coming Soon™:
debug_traceTransaction
may crash on Node.js v12 (#2106)evm_mine
andminer_start
don't respect --mode.instamine=eager (#2029)evm_setAccountNonce
is race-conditiony (#1646)- Add
eth_feeHistory
RPC endpoint (#1470) @ganache/filecoin@alpha
doesn't work withganache@alpha
(#1150)- sort executable/pending transactions that have the same price by the time at which the transaction was submitted (#1104)
- Add
eth_createAccessList
RPC method (#1056) - Launching ganache with fork is throwing revert errors when communicating with 3rd party contracts (#956)
- Build a real pending block! (#772)
- Add an upper limit to # of accounts that can be generated by ganache (#736)
- Incorrect gas cost for SSTORE opcode when using fork feature (#625)
Cannot get state root with uncommitted checkpoints
error when starting ganache forking with infura RPC endpoint (#618)- --db Option Requires Same Mnemonic and Network ID (#1030)
- Reduce Bundle Size (#2096)
- Switch to esbuild to make build times faster/reasonable (#1555)
- Opt-in tracking (#945)
- Mine txs in same block with provided sorting (#899)
- Add eip-155 support (#880)
- Add support for debug_accountAt RPC method as implemented by Turbo-Geth (#813)
- Enhance the database to allow for better UX and determinism (#756)
- Create Project and set Milestones for Ganache interactive docs (#680)
- idea: add in warning to help switch over to new "pending tx" mode (#674)
- evm_snapshot ids should be opaque (#655)
- Support for EIP 1898- Add
blockHash
to JSON-RPC methods which accept a default block parameter (#973) - Upgrade custom rpc method
evm_mine
to return the new block (#536) - Add
personal_ecRecover
andpersonal_sign
(#995) - Add flag for starting ganache in detached mode (#1001)
- Implement a streaming trace capability (#381)
- Allow mining to be completely disabled on startup (#248)
- Add support for
eth_getRawTransactionByHash
(#135) - Log contract events (#45)
- Support IPC endpoint (#759)
- Accept a genesis.json file (#1042)
Open new issues (or join our team) to influence what we gets implemented and prioritized.
💖 The Truffle Team
-
The Ethereum Yellowpaper defines:
$H_{\mathrm{s}} > P(H){_\mathrm{H_s}}$ where$H{\mathrm{_s}}$ is the timestamp of block$H$ and$P(H)$ is the parent block. Or in other words: a block's timestamp must be greater than its parent block's timestamp. ↩