Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

feat: add eth_createAccessList RPC method (#3321) #3321

Open
wants to merge 126 commits into
base: develop
Choose a base branch
from

Conversation

MicaiahReid
Copy link
Contributor

@MicaiahReid MicaiahReid commented Jun 30, 2022

This change adds the eth_createAccessList RPC method in accordance with Geth's spec. This RPC method returns an access list and an estimate of the gas consumed by running the transaction with the generated access list included.

For those of us that need a refresher, an access list is a list of addresses and storage keys that will be accessed by the transaction. It essentially tells the EVM "hey, heads up, I'm going to reference this here data", which gives you a discount on the gas usage of accessing that data. However, sending a transaction with an access list incurs and extra base fee, so it isn't always cheaper to include one. How do you know if it's best to include an access list in your transaction? Enter eth_createAccessList.

To call this method, you'll need to send a transaction plus the block number or tag to run the transaction on, since some transactions will touch different addresses and storage keys depending on the block the transaction is running on. Here's how to use it!

const [from] = await provider.request({ method: "eth_accounts", params: [] });
const transaction = { 
    from,
    to: someInterestingContractAddress,
    data: someInterestingContractMethod
 };
const { gasUsed, accessList } = await provider.request({ method: "eth_createAccessList", params: [transaction, "latest"] });
console.log(gasUsed, accessList);

As a cool note about the EVM, a transaction could also touch different addresses and storage when sent on the same block if just the accessList that is passed in as part of the transaction changes. Because the access list can impact the gas usage of certain opcodes, a contract that branches based off of gas usage can have vastly different behavior depending on the access list that is used. Our eth_createAccessList implementation recursively runs the result of generating an access list until the resultant access list stops being different from the previous run. This results in an access list that we call the "best" one, but it does not mean that this access list will yield the least gas usage when sent with your transaction. There are many cases in which it is cheaper to omit the access list, so user beware!

*Note: An address or storage key being "touched" by a transaction happens when certain opcodes are used in running the transaction. This is defined in EIPs 2929 and 2930. For our implementation, we rely on the awesome work of ethereumjs to handle the opcode dissecting.

Fixes #1056.

@MicaiahReid MicaiahReid marked this pull request as ready for review July 1, 2022 01:57
}
}

async #applySimulationOverrides(overrides: CallOverrides): Promise<void> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function is largely unchanged from how it was in the run-call file. To port it over to here, the function no longer receives stateTrie and vm parameters and just pulls it from the class properties instead.

}
}

#validateStorageOverride = (
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function is largely unchanged from how it was in the run-call file.

accessList?: AccessList;
};

type CallOverride =
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No change was made to the CallOverride or CallOverrides type, it was just moved over from run-call

@MicaiahReid
Copy link
Contributor Author

Notes for reviewers:

The /helpers/run-call file was a bunch of helper functions related to setup for eth_call, but some of the methods weren't even used. I decided to turn this into simulation-handler (I put very little thought into a name for this class, opinions are welcome), which will keep the useful bits of those helpers and extend to handle more "simulation" scenarios, including creating an access list. So this PR also is a partial refactor of the eth_call code.

This class could probably also be used to include parts of the setup for the blockchain's #traceTransaction function, a lot of the VM cloning and setup code is the same there. If you think that should be part of this PR or if an issue should be made to work it later, let me know.

In the api file, I also made a helper function to set up a SimulationTransaction from a user-provided rpc transaction. If we wanted to clean up the api file some more, I suppose we could make this a static helper in the SimulationHandler class.

src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/transaction/src/access-lists.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
Copy link
Member

@davidmurdoch davidmurdoch left a comment

Choose a reason for hiding this comment

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

just a partial review

src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/transaction/src/access-lists.ts Outdated Show resolved Hide resolved
src/chains/ethereum/transaction/src/access-lists.ts Outdated Show resolved Hide resolved
@MicaiahReid MicaiahReid force-pushed the feat/eth_createAccessList branch from d615faa to a3c1982 Compare July 13, 2022 18:53
@MicaiahReid
Copy link
Contributor Author

I've incorporated most comments from y'all @tenthirtyone @jeffsmale90 @davidmurdoch. I've also rebased to include the console.log PR, which introduced some changes to the SimulationHandler class. Rather caching the blockchain to emit events directly to the blockchain, the blockchain listens for events from SimulationHandler to re-emit them. This preserves the ability for the user to update the options.logger.log function while ganache is running, which I had previously broken.

@MicaiahReid MicaiahReid force-pushed the feat/eth_createAccessList branch from a139a9f to de82b14 Compare July 27, 2022 17:07
Copy link
Member

@davidmurdoch davidmurdoch left a comment

Choose a reason for hiding this comment

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

I think I answered all questions. Let me know if I missed anything!

@MicaiahReid MicaiahReid force-pushed the feat/eth_createAccessList branch from bc77b3b to 8c65117 Compare August 3, 2022 20:48
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/api.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/helpers/simulations.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/helpers/simulations.ts Outdated Show resolved Hide resolved
@jeffsmale90 jeffsmale90 changed the title feat: add eth_createAccessList RPC method feat: add eth_createAccessList RPC method (#3321) Aug 24, 2022
previousAccessList = accessList;
}
iterations++;
} while (iterations < MAX_ITERATIONS);
Copy link
Contributor

Choose a reason for hiding this comment

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

I figured that might be the case 👍

src/chains/ethereum/ethereum/src/helpers/simulations.ts Outdated Show resolved Hide resolved
src/chains/ethereum/ethereum/src/helpers/simulations.ts Outdated Show resolved Hide resolved
Co-authored-by: jeffsmale90 <6363749+jeffsmale90@users.noreply.github.com>
MicaiahReid and others added 2 commits October 13, 2022 15:24
Co-authored-by: David Murdoch <187813+davidmurdoch@users.noreply.github.com>
@MicaiahReid MicaiahReid changed the base branch from develop to tech-debt-dudes November 16, 2022 19:56
Base automatically changed from tech-debt-dudes to the-merge November 30, 2022 16:29
Base automatically changed from the-merge to develop December 14, 2022 14:04
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Status: Stalled
Development

Successfully merging this pull request may close these issues.

Add eth_createAccessList RPC method
4 participants