Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix/max-priority-fee-per-gas-from-rpc #744

Merged
merged 1 commit into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions packages/core/src/internal/execution/jsonrpc-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
} from "./types/jsonrpc";
import { toChecksumFormat } from "./utils/address";

const DEFAULT_MAX_FEE_PER_GAS = 1_000_000_000n;

/**
* The params to make an `eth_call`.
*/
Expand Down Expand Up @@ -638,9 +640,9 @@ 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) {
const maxPriorityFeePerGas = await this._resolveMaxFeePerGas();

// Logic copied from ethers v6
const maxPriorityFeePerGas =
this._config?.maxPriorityFeePerGas ?? 1_000_000_000n; // 1gwei
const maxFeePerGas =
latestBlock.baseFeePerGas * 2n + maxPriorityFeePerGas;

Expand All @@ -659,6 +661,44 @@ export class EIP1193JsonRpcClient implements JsonRpcClient {

return { gasPrice: jsonRpcQuantityToBigInt(response) };
}

/**
* The max fee per gas is needed in the max fee calculation.
*
* It is resolved from config if present, falling back to
* the `eth_maxPriorityFeePerGas` RPC call if supported by the chain,
* and finally falling back to the default max fee per gas.
*
* @returns a max fee per gas based on the config, RPC call, or default value.
*/
private async _resolveMaxFeePerGas(): Promise<bigint> {
if (this._config?.maxPriorityFeePerGas !== undefined) {
return this._config?.maxPriorityFeePerGas;
}

try {
return await this._getMaxPrioirtyFeePerGas();
} catch {
// the max priority fee RPC call is not supported by
// this chain
}

return DEFAULT_MAX_FEE_PER_GAS;
}

private async _getMaxPrioirtyFeePerGas(): Promise<bigint> {
const fee = await this._provider.request({
method: "eth_maxPriorityFeePerGas",
});

assertResponseType(
"eth_maxPriorityFeePerGas",
fee,
typeof fee === "string"
);

return jsonRpcQuantityToBigInt(fee);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,56 @@ describe("JSON-RPC client", function () {

assert.equal(fees.gasPrice, 1n);
});

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.
const proxiedProvider = {
...this.hre.network.provider,
request: async (req: { method: string }) => {
if (req.method === "eth_maxPriorityFeePerGas") {
return "2000000000";
}

return this.hre.network.provider.request(req);
},
};

const maxFeeClient = new EIP1193JsonRpcClient(proxiedProvider, {
maxPriorityFeePerGas: undefined, // no config set for maxPriorityFeePerGas
});

const fees = await maxFeeClient.getNetworkFees();

assert("maxPriorityFeePerGas" in fees);

assert.equal(fees.maxPriorityFeePerGas, 2_000_000_000n);
});

it("Should default to 1gwei for maxPriorityFeePerGas if `eth_maxPriorityFeePerGas` is not available and no config set", async function () {
const proxiedProvider = {
...this.hre.network.provider,
request: async (req: { method: string }) => {
if (req.method === "eth_maxPriorityFeePerGas") {
throw new Error(
"Method eth_maxPriorityFeePerGas is not supported"
);
}

return this.hre.network.provider.request(req);
},
};

const maxFeeClient = new EIP1193JsonRpcClient(proxiedProvider, {
maxPriorityFeePerGas: undefined, // no config set for maxPriorityFeePerGas
});

const fees = await maxFeeClient.getNetworkFees();

assert("maxPriorityFeePerGas" in fees);

assert.equal(fees.maxPriorityFeePerGas, 1_000_000_000n);
});
});
});

Expand Down
Loading