From e54cb62ea408d062ee9ef8fb4ecb5076b7732070 Mon Sep 17 00:00:00 2001 From: Jim Zhang Date: Thu, 4 Apr 2024 16:04:52 -0400 Subject: [PATCH] feat: support zero gas fee chains Private chains like besu can be run in a zero gas fee mode. We support this by altering the gas fee calculation to detect whether we are on such a chain and return zeroed values. --- .../src/internal/execution/jsonrpc-client.ts | 9 ++++++ .../internal/new-execution/jsonrpc-client.ts | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/packages/core/src/internal/execution/jsonrpc-client.ts b/packages/core/src/internal/execution/jsonrpc-client.ts index 59d336d59..10a427818 100644 --- a/packages/core/src/internal/execution/jsonrpc-client.ts +++ b/packages/core/src/internal/execution/jsonrpc-client.ts @@ -640,6 +640,15 @@ export class EIP1193JsonRpcClient implements JsonRpcClient { // We prioritize EIP-1559 fees over legacy gasPrice fees, however, // polygon (chainId 137) requires legacy gasPrice fees so we skip EIP-1559 logic in that case if (latestBlock.baseFeePerGas !== undefined && chainId !== 137) { + if (latestBlock.baseFeePerGas === 0n) { + // Support zero gas fee chains, such as a private instances + // of blockchains using Besu. + return { + maxFeePerGas: 0n, + maxPriorityFeePerGas: 0n, + }; + } + const maxPriorityFeePerGas = await this._resolveMaxFeePerGas(); // Logic copied from ethers v6 diff --git a/packages/core/test-integrations/new-api/internal/new-execution/jsonrpc-client.ts b/packages/core/test-integrations/new-api/internal/new-execution/jsonrpc-client.ts index c27bfdc56..83d4a19ee 100644 --- a/packages/core/test-integrations/new-api/internal/new-execution/jsonrpc-client.ts +++ b/packages/core/test-integrations/new-api/internal/new-execution/jsonrpc-client.ts @@ -154,6 +154,37 @@ describe("JSON-RPC client", function () { assert.equal(fees.gasPrice, 1n); }); + it("Should return zero gas fees when deploying to a network with a zero base fee per gas (e.g. private Besu instances)", async function () { + const besuClient = new EIP1193JsonRpcClient({ + request: async (req) => { + if (req.method === "eth_chainId") { + return "0x42"; + } + + if (req.method === "eth_getBlockByNumber") { + return { + number: "0x0", + hash: "0x0", + baseFeePerGas: "0x0", // Set the base fee to zero + }; + } + + if (req.method === "eth_gasPrice") { + return "0x1"; + } + + throw new Error(`Unimplemented mock for ${req.method}`); + }, + }); + + const fees = await besuClient.getNetworkFees(); + + assert.deepStrictEqual(fees, { + maxFeePerGas: 0n, + maxPriorityFeePerGas: 0n, + }); + }); + it("Should use the `maxPriorityFeePerGas` from the node if `eth_maxPriorityFeePerGas` is present (and there is no config)", async function () { // TODO: Hardhat does not support `eth_maxPriorityFeePerGas` yet, when it does, this // can be removed.