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

Feature: use eth_createAccessList to estimate gas costs against eth_estimateGas #3284

Open
sambacha opened this issue Aug 16, 2022 · 3 comments
Labels
enhancement New feature or improvement.

Comments

@sambacha
Copy link

Describe the Feature

use eth_createAccessList to estimate gas costs

eth_createAccessList

Geth (starting from version 1.10.2) includes a new eth_createAccessList RPC method that you can use to generate access lists. It is used like eth_estimateGas, but instead of a gas estimation, it returns something like this:

{
  "accessList": [
    {
      "address": "0xb0ee076d7779a6ce152283f009f4c32b5f88756c",
      "storageKeys": [
        "0x0000000000000000000000000000000000000000000000000000000000000000",
        "0x0000000000000000000000000000000000000000000000000000000000000001"
      ]
    }
  ],
  "gasUsed": "0x8496"
}

That is, it gives you the list of addresses and storage keys that will be used by that transaction, plus the gas consumed if the access list is included. (And, like eth_estimateGas, this is an estimation; the list could change when the transaction is actually mined.) But, again, this doesn’t mean that this gas will be lower than the gas used if you just send the same transaction without an access list!

This isn't per se the same as this issue: #3086 - I am not wanting to actually create an accessList, rather I want to use this to estimate fees and compare to the existing method of estimating gas.

Can help implement this if you would like, just give me the clearance boss man.

Cheers

Code Example

No response

@sambacha sambacha added the enhancement New feature or improvement. label Aug 16, 2022
@sambacha sambacha changed the title Feature Request Title Feature: use eth_createAccessList to estimate gas costs against eth_estimateGas Aug 16, 2022
@sambacha sambacha changed the title Feature: use eth_createAccessList to estimate gas costs against eth_estimateGas Feature: use eth_createAccessList to estimate gas costs against eth_estimateGas Aug 16, 2022
@qd-qd
Copy link

qd-qd commented Sep 5, 2022

If I understand well, you would like to offer a way to compare the gas consumption with and without the access list? That way you would know if including them would be a smart move, right? Is it not correlated to the fact that the contract is deterministic or not?

@sambacha
Copy link
Author

sambacha commented Sep 5, 2022

If I understand well, you would like to offer a way to compare the gas consumption with and without the access list? That way you would know if including them would be a smart move, right? Is it not correlated to the fact that the contract is deterministic or not?

this would be for transactions, not just contracts.

The reasoning is because of specific repricins for certain opcodes. For example, the CALL opcode had a fixed cost of 700. But after EIP-2929 its cost is 2600 if the address is not in the access list and 100 if it is. And, like the accessed storage keys, it doesn’t matter what OPCODE accessed that address before (for example, if an EXTCODESIZE was called first, then that opcode will cost 2600, and any subsequent EXTCODESIZE, CALL, STATICCALL that uses the same address will cost 100).

How is this affected by transactions with access lists? For example, if we send a transaction to contract A, and that contract calls another contract B, then we can include an access list like this:

accessList: [{ address: "<address of B>", storageKeys: [] }]

We’ll have to pay a cost of 2400 to include this access list in the transaction, but then the first opcode that uses the address of B will cost 100 instead of 2600. So we saved 100 of gas by doing this.

And if B uses its storage somehow and we know which keys it will use, then we can also include them in the access list and save 100/200 of gas for each one (depending on whether the first opcode is an SLOAD or an SSTORE).

But why are we talking about another contract? What happens with the contract that we are calling? Why don’t we do this?

accessList: [
  {address: "<address of A>", storageKeys: []},
  {address: "<address of B>", storageKeys: []},
]

We could do it, but it wouldn’t be worth it because EIP-2929 specifies that the address of the contract that is being called (that is, tx.to) is always included in the accessed_addresses list. So we are paying 2400 more for nothing.

Let’s analyze our example of the previous section again:

accessList: [{
  address: "<address of A>",
  storageKeys: [
    "0x0000000000000000000000000000000000000000000000000000000000000000"
  ]
}]

This will actually be wasteful unless we include several storage keys more. If we assume that a storage key is always used first by an SLOAD, then we need at least 24 storage keys just to break even.

As you can imagine, analyzing this and creating an access list by hand is not fun. Luckily, there is a better way.

eth_createAccessList

Geth (starting from version 1.10.2) includes a new eth_createAccessList RPC method that you can use to generate access lists. It is used like eth_estimateGas, but instead of a gas estimation, it returns something like this:

{
  "accessList": [
    {
      "address": "0xb0ee076d7779a6ce152283f009f4c32b5f88756c",
      "storageKeys": [
        "0x0000000000000000000000000000000000000000000000000000000000000000",
        "0x0000000000000000000000000000000000000000000000000000000000000001"
      ]
    }
  ],
  "gasUsed": "0x8496"
}

That is, it gives you the list of addresses and storage keys that will be used by that transaction, plus the gas consumed if the access list is included. (And, like eth_estimateGas, this is an estimation; the list could change when the transaction is actually mined.) But, again, this doesn’t mean that this gas will be lower than the gas used if you just send the same transaction without an access list!

source, https://hackmd.io/@fvictorio/gas-costs-after-berlin#EIP-2930-Optional-Access-List-transactions

You could create a heuristic value where this method of comparison would be triggered, for example lets say your doing a swap on sushiswap, you would want to trigger this logic only if your doing a multi-hop swap (as an example your transaction is touching at least 5 addresses).

@qd-qd
Copy link

qd-qd commented Sep 20, 2022

It's crystal clear now, thanks for your complete explanation. I would be happy to help if needed, that will allow me to dig into this topic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or improvement.
Projects
None yet
Development

No branches or pull requests

2 participants