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

feat: Add support for linea_estimateGas #2525

Closed
wants to merge 3 commits into from

Conversation

wantedsystem
Copy link
Contributor

@wantedsystem wantedsystem commented Jul 23, 2024

Linea, a layer 2 blockchain, supports the Ethereum EIP-1559 gas price model, known for making transaction fees more predictable. Unlike the base Ethereum layer, Linea aims to offer a more stable and cost-effective approach to handling transaction fees. For detailed information, you can visit Linea's Gas Fees Documentation.

To further enhance the efficiency of transaction fee calculations, Linea has introduced a new RPC method designed to provide the best gas price estimates. This new method is documented in detail here.

The introduction of this new RPC method necessitates changes in how web3 libraries calculate gas prices. Traditionally, these libraries used the eth_gasPrice method. Linea's update shifts this approach to utilize the newly introduced linea_estimateGas method.

Detailed summary

  • Added linea_estimateGas RPC method to calculate accurate gas price on Linea network
  • Updated linea and lineaTestnet definitions to override fee calculation using linea_estimateGas
  • Added lineaEstimateGas and lineaEstimateFeesPerGas actions to calculate gas and fees
  • Updated types and imports related to fee calculation on Linea network

PR-Codex overview

This PR adds Linea and Linea Testnet chains with gas estimation and fee calculation support.

Detailed summary

  • Added Linea and Linea Testnet chains
  • Implemented gas estimation and fee calculation
  • Added lineaEstimateGas and lineaEstimateFeesPerGas functions
  • Updated chain configurations and RPC schemas

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Copy link

changeset-bot bot commented Jul 23, 2024

⚠️ No Changeset found

Latest commit: a5c1675

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

vercel bot commented Jul 23, 2024

@wantedsystem is attempting to deploy a commit to the Wevm Team on Vercel.

A member of the Team first needs to authorize it.

Comment on lines 71 to 86
try {
// Try with the public endpoint
const publicClient = createPublicClient({
chain: client.chain.id === linea.id ? linea : lineaTestnet,
transport: http(),
})
lineaEstimateGasResponse = await getAction(
publicClient,
lineaEstimateGas,
'lineaEstimateGas',
)({
data: request.data,
to: request.to,
...request,
} as unknown as EstimateGasParameters)
} catch (_err) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consumers can set up fallback transport if they want this behavior.

Suggested change
try {
// Try with the public endpoint
const publicClient = createPublicClient({
chain: client.chain.id === linea.id ? linea : lineaTestnet,
transport: http(),
})
lineaEstimateGasResponse = await getAction(
publicClient,
lineaEstimateGas,
'lineaEstimateGas',
)({
data: request.data,
to: request.to,
...request,
} as unknown as EstimateGasParameters)
} catch (_err) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @jxom thanks for reviewing ! Could you please confirm if I need to change transport: http() to transport: fallback([http(), webSocket()]) here ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean we can omit this section of code, and just rely on fallback mechanisms that the consumer defines.

Comment on lines 102 to 104
const adjustedBaseFee =
(BigInt(baseFeePerGas) * BigInt(BASE_FEE_PER_GAS_MARGIN * 100)) /
BigInt(100)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rely on multiply here? This is default to 1.2, but can be adjusted to 1.35 via chain.fees.baseFeeMultiplier

Suggested change
const adjustedBaseFee =
(BigInt(baseFeePerGas) * BigInt(BASE_FEE_PER_GAS_MARGIN * 100)) /
BigInt(100)
const adjustedBaseFee = multiply(BigInt(baseFeePerGas))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey @jxom we will keep the default value 1.2

@jxom
Copy link
Member

jxom commented Jul 26, 2024

Attempting to test this end-to-end, but I am running into issues on Linea Sepolia that the method linea_estimateGas is not available:

$ curl -X POST https://rpc.sepolia.linea.build \
     -H "Content-Type: application/json" \
     -d '{"id": 1, "jsonrpc": "2.0", "method": "linea_estimateGas", "params": [{"to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", "value": "0xde0b6b3a7640000"}]}'
     
> {"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"the method linea_estimateGas does not exist/is not available"}}

What RPC URL can I use to test this end-to-end?

@wantedsystem
Copy link
Contributor Author

Attempting to test this end-to-end, but I am running into issues on Linea Sepolia that the method linea_estimateGas is not available:

$ curl -X POST https://rpc.sepolia.linea.build \
     -H "Content-Type: application/json" \
     -d '{"id": 1, "jsonrpc": "2.0", "method": "linea_estimateGas", "params": [{"to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", "value": "0xde0b6b3a7640000"}]}'
     
> {"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"the method linea_estimateGas does not exist/is not available"}}

What RPC URL can I use to test this end-to-end?

Hey @jxom It will be available soon -i'll keep you posted

Comment on lines 28 to 45
fees: {
// Override the fees calculation to accurately price the fees
// on Linea using the rpc call linea_estimateGas
estimateFeesPerGas: lineaEstimateFeesPerGas,
async defaultPriorityFee(args): Promise<bigint> {
const { maxPriorityFeePerGas } = await lineaEstimateFeesPerGas({
client: args.client,
request: args.request,
type: 'eip1559',
} as any)

if (maxPriorityFeePerGas === undefined) {
throw new Error('maxPriorityFeePerGas is undefined')
}

return maxPriorityFeePerGas
},
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you set up a shared chainConfig object and spread it into the Linea chain definitions? (Similar to how things are set up for OP Stack and Zksync support.)

// src/linea/chainConfig.ts
import type { Chain } from '../types/chain.js'

export const chainConfig = {
  fees: {
    // Override the fees calculation to accurately price the fees
    // on Linea using the rpc call linea_estimateGas
    async estimateFeesPerGas(args) { ... },
    async defaultPriorityFee(args) { ... },
  },
} as const satisfies Pick<Chain, 'fees'>
// src/chains/definitions/linea.ts
import { chainConfig } from '../../linea/chainConfig.js'
import { defineChain } from '../../utils/chain/defineChain.js'

export const linea = /*#__PURE__*/ defineChain({
  ...chainConfig,
  id: 59_144,
  name: 'Linea Mainnet',
  // other properties ...
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment on linea.ts about chainConfig

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move to src/linea/utils/estimateFeesPerGas.ts or inline into chainConfig.

* value: 0n,
* })
*/
export async function lineaEstimateGas<
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's drop the linea prefix since it will be namespaced by the import 'viem/linea'.

TAccount extends Account | undefined = undefined,
>(
client: Client<Transport, TChain, TAccount>,
args: EstimateGasParameters<TChain>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add a type for EstimateGasParameters

import type { EstimateGasParameters as base_EstimateGasParameters } from '../../actions/public/estimateGas.js'

export type EstimateGasParameters = base_EstimateGasParameters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide more informations on what to do here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type AssertRequestParameters,
assertRequest,
} from '../../utils/transaction/assertRequest.js'
import type { LineaEstimateGasReturnType } from '../types/fee.js'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add this return type directly to this file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are also using it in src/linea/utils/estimateFeesPerGas.ts so we had to duplicate the type here as well

{
Method: 'linea_estimateGas'
Parameters?: any
ReturnType: LineaEstimateGasReturnType
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's inline ReturnType. Duplication is fine in this case.

Suggested change
ReturnType: LineaEstimateGasReturnType
ReturnType: {
gasLimit: Hex
baseFeePerGas: Hex
priorityFeePerGas: Hex
}

*/
{
Method: 'linea_estimateGas'
Parameters?: any
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's type this. See EIP-1993 types for inspiration.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's colocate these with their actions/utils and export from those places as needed.

@tmm
Copy link
Member

tmm commented Aug 6, 2024

Since there are a few outstanding comments, going to convert this to a draft.

@tmm tmm marked this pull request as draft August 6, 2024 12:55
@wantedsystem
Copy link
Contributor Author

Attempting to test this end-to-end, but I am running into issues on Linea Sepolia that the method linea_estimateGas is not available:

$ curl -X POST https://rpc.sepolia.linea.build \
     -H "Content-Type: application/json" \
     -d '{"id": 1, "jsonrpc": "2.0", "method": "linea_estimateGas", "params": [{"to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", "value": "0xde0b6b3a7640000"}]}'
     
> {"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"the method linea_estimateGas does not exist/is not available"}}

What RPC URL can I use to test this end-to-end?

You can test now for Linea Mainnet

curl https://rpc.linea.build \
       -X POST \
       -H "Content-Type: application/json" \
       -d '{"jsonrpc": "2.0","method": "linea_estimateGas","params": [{"from": "0x91ba6c8DE41deC8E4d4E1C858f00FaE1819990Ca","gas":"0x21000"}],"id": 53}'

And for Linea Sepolia :

curl https://rpc.sepolia.linea.build \
       -X POST \
       -H "Content-Type: application/json" \
       -d '{"jsonrpc": "2.0","method": "linea_estimateGas","params": [{"from": "0x91ba6c8DE41deC8E4d4E1C858f00FaE1819990Ca","gas":"0x21000"}],"id": 53}'

@wantedsystem
Copy link
Contributor Author

Attempting to test this end-to-end, but I am running into issues on Linea Sepolia that the method linea_estimateGas is not available:

$ curl -X POST https://rpc.sepolia.linea.build \
     -H "Content-Type: application/json" \
     -d '{"id": 1, "jsonrpc": "2.0", "method": "linea_estimateGas", "params": [{"to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", "value": "0xde0b6b3a7640000"}]}'
     
> {"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"the method linea_estimateGas does not exist/is not available"}}

What RPC URL can I use to test this end-to-end?

You can test now for Linea Mainnet

curl https://rpc.linea.build \
       -X POST \
       -H "Content-Type: application/json" \
       -d '{"jsonrpc": "2.0","method": "linea_estimateGas","params": [{"from": "0x91ba6c8DE41deC8E4d4E1C858f00FaE1819990Ca","gas":"0x21000"}],"id": 53}'

And for Linea Sepolia :

curl https://rpc.sepolia.linea.build \
       -X POST \
       -H "Content-Type: application/json" \
       -d '{"jsonrpc": "2.0","method": "linea_estimateGas","params": [{"from": "0x91ba6c8DE41deC8E4d4E1C858f00FaE1819990Ca","gas":"0x21000"}],"id": 53}'

Hey @jxom you had the opportunity to test ?

@jxom jxom marked this pull request as ready for review August 28, 2024 11:42
@jxom jxom self-assigned this Aug 28, 2024
@jxom
Copy link
Member

jxom commented Aug 29, 2024

Superseded by #2665

@jxom jxom closed this Aug 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants