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
Open
Changes from 3 commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
1c3bb99
add helper to validate an access list
MicaiahReid Jun 29, 2022
6473d2c
add a helper to create a simulated transaction
MicaiahReid Jun 29, 2022
ac2a502
add accessList field to simulation transaction
MicaiahReid Jun 29, 2022
f804773
fix off by one bug in precompiles
MicaiahReid Jun 30, 2022
8852c9f
add .equals prop to light ejs address
MicaiahReid Jun 30, 2022
a199fc8
remove unneeded async
MicaiahReid Jun 30, 2022
51597c1
return precompiles from warmPrecompiles
MicaiahReid Jun 30, 2022
9071a03
git mv run-call to sim-handler
MicaiahReid Jul 27, 2022
3318134
sim handler changes
MicaiahReid Jul 27, 2022
ec25b6a
remove run-call.ts. switch to simulation-handler
MicaiahReid Jun 30, 2022
6ef8466
switch eth_call to use simulatedTransaction helper
MicaiahReid Jun 30, 2022
eff40bd
remove param from createVmFromStateTrie function
MicaiahReid Jun 30, 2022
fcf041d
use simulation-handler for eth_call
MicaiahReid Jun 30, 2022
c108786
add getAccessList method to api
MicaiahReid Jun 30, 2022
1c26480
move SimulationTransaction type import
MicaiahReid Jun 30, 2022
5dbaa77
make eth_call test more robust to contract changes
MicaiahReid Jun 30, 2022
a06982c
add solidity function to set storage at a slot
MicaiahReid Jun 30, 2022
4ff6d53
add solidity function to get balance of addr stored in storage
MicaiahReid Jun 30, 2022
08f1720
add solidity function that causes different accessLists to generate
MicaiahReid Jun 30, 2022
0e7dc0c
add tests
MicaiahReid Jun 30, 2022
206cba2
add jsdoc comment for api function
MicaiahReid Jun 30, 2022
92ca1b4
set caller address for state trie context
MicaiahReid Jun 30, 2022
b12138c
add jsdoc comments
MicaiahReid Jun 30, 2022
0a04c17
fix error handling a bit
MicaiahReid Jun 30, 2022
24807d1
rename functions
MicaiahReid Jun 30, 2022
ec6f9b5
if to else if, ooooooops
MicaiahReid Jun 30, 2022
634c284
undo setting and address in forking context
MicaiahReid Jun 30, 2022
3026f98
add to address to addressesOnlyStorage list
MicaiahReid Jul 1, 2022
4b8c269
add test contract function to send moneys
MicaiahReid Jul 1, 2022
bddf9e8
fix/add tests
MicaiahReid Jul 1, 2022
7b3f0fc
correct jsdoc comments
MicaiahReid Jul 1, 2022
cc0629f
include accessList on SimulationTransaction
MicaiahReid Jul 6, 2022
9f47424
fix forgotten hardcoding
MicaiahReid Jul 7, 2022
4e446b6
use correct type on transaction
MicaiahReid Jul 12, 2022
ff3e6d4
handle 0 baseFeePerGas
MicaiahReid Jul 12, 2022
5501fdf
clean up conditional
MicaiahReid Jul 12, 2022
3eb5219
rename previously gloriously named `a` variable
MicaiahReid Jul 12, 2022
83bc085
require eip2930 to warm access lists
MicaiahReid Jul 12, 2022
0f04843
use Data.Empty
MicaiahReid Jul 12, 2022
aeeda71
Apply suggestions from code review
MicaiahReid Jul 12, 2022
5d96b65
update accessList creation to not be recursive
MicaiahReid Jul 13, 2022
0abd9a6
add method to compare access lists
MicaiahReid Jul 13, 2022
bf4099e
fix encodeValue implementation
MicaiahReid Jul 13, 2022
adc2705
touch more accounts in test
MicaiahReid Jul 13, 2022
d22292c
clean up tests
MicaiahReid Jul 13, 2022
1d98ce3
fix preberlin case
MicaiahReid Jul 13, 2022
eea9153
add pre-berlin test
MicaiahReid Jul 13, 2022
2284ac6
make simhandler an emitter to preserve modifiability of options
MicaiahReid Jul 14, 2022
b2ea4d4
add todo
MicaiahReid Jul 18, 2022
667f3d4
remove commented line
MicaiahReid Jul 18, 2022
8e6c290
remove unnecessary private vars in simhandler
MicaiahReid Jul 18, 2022
4c0fa2a
Update src/chains/ethereum/ethereum/src/helpers/simulation-handler.ts
MicaiahReid Jul 19, 2022
cf598ea
update areAccessListsSame func
MicaiahReid Jul 19, 2022
ef995fb
fix issues from rebase
MicaiahReid Jul 27, 2022
6c06986
change comment to jsdoc format
MicaiahReid Jul 27, 2022
853b245
don't allow simhandler reinits
MicaiahReid Jul 27, 2022
146e944
create new event context on each runcall
MicaiahReid Jul 27, 2022
23d7449
make initial access list optional
MicaiahReid Jul 27, 2022
10a7e26
Read private properties outside of loop
MicaiahReid Jul 27, 2022
6452fd6
remove unneded null check
MicaiahReid Jul 27, 2022
0d04975
remove check on extra keys to access list. require address/storageKeys
MicaiahReid Jul 27, 2022
c713c34
use NatSpec on sol comment
MicaiahReid Jul 27, 2022
53964bb
add public/private types for CreateAccessListResult
MicaiahReid Jul 30, 2022
997f384
use Quantity.toBuffer rather than Quantity.from
MicaiahReid Jul 30, 2022
4c3fd71
move private var declaration outside loop
MicaiahReid Jul 30, 2022
a516792
add default value to initialAccessList
MicaiahReid Jul 30, 2022
abec37a
finish changing over types oopps
MicaiahReid Jul 30, 2022
84e1d4a
finish fixing types smore
MicaiahReid Jul 30, 2022
634fad1
rename simulation-handler file to simulations
MicaiahReid Jul 30, 2022
dd08726
fix import
MicaiahReid Aug 1, 2022
9a6c5d4
add test for vm errors
MicaiahReid Aug 1, 2022
6f9c1de
refactor simulations to not use a class
MicaiahReid Aug 1, 2022
7e90660
fix api argLength
MicaiahReid Aug 23, 2022
4c5e35c
Apply suggestions from code review
MicaiahReid Aug 23, 2022
a72ef15
use conditionals for cleaner codez
MicaiahReid Aug 23, 2022
15da13d
strict equal comparison
MicaiahReid Aug 23, 2022
e12982d
clean precompiles assignment
MicaiahReid Aug 23, 2022
b8591ed
simplify logic/add jsdoc comment
MicaiahReid Aug 23, 2022
65cb001
add jsdoc comment
MicaiahReid Aug 23, 2022
c5b3fbf
any to EVMResult
MicaiahReid Aug 23, 2022
97b1202
import error
MicaiahReid Aug 23, 2022
1990224
any to EVMResult
MicaiahReid Aug 23, 2022
af688ef
remove unneeded any
MicaiahReid Aug 23, 2022
2dfcce1
export/import access list from ethereum-transaction
MicaiahReid Oct 3, 2022
b469e69
fix typo from review suggestion
MicaiahReid Oct 3, 2022
b308616
ues generator to access precompiles
MicaiahReid Oct 3, 2022
e5effc4
move revert for optimization, fix comment
MicaiahReid Oct 3, 2022
19463a4
fix test types, remove unused value
MicaiahReid Oct 3, 2022
25a921d
add eth_unsubscribe to test
MicaiahReid Oct 3, 2022
9535a50
fix bug with access list creation
MicaiahReid Oct 4, 2022
14b8886
implement tryGetValidatedAccessList
MicaiahReid Oct 4, 2022
d3bcbae
change test to increase code coverage
MicaiahReid Oct 4, 2022
1c559b4
add tests for access list helpers
MicaiahReid Oct 4, 2022
67ff6f3
fix simulation types
MicaiahReid Oct 5, 2022
019d07b
remove BN.toBuffer usage for browser
MicaiahReid Oct 5, 2022
fe4bd90
remove unused eth_call
MicaiahReid Oct 5, 2022
344c74a
unsubscribe from eth_subscribe in test
MicaiahReid Oct 5, 2022
31afac2
fix typo
MicaiahReid Oct 5, 2022
8752bb3
remove .only
MicaiahReid Oct 5, 2022
85adefd
fix comment
MicaiahReid Oct 5, 2022
3dea760
fix jsdoc variable names
MicaiahReid Oct 5, 2022
feec9a1
remove map.has
MicaiahReid Oct 11, 2022
1d4fa55
use Address class rather than Data
MicaiahReid Oct 11, 2022
c9ab4bf
remove invalid comment
MicaiahReid Oct 12, 2022
42a491c
manually warm/clear access list
MicaiahReid Oct 12, 2022
51e68b3
return access list if max_iterations is hit
MicaiahReid Oct 12, 2022
a3f8e3e
Apply suggestions from code review
MicaiahReid Oct 13, 2022
b51a946
add jsdoc comment for createAccessList
MicaiahReid Oct 13, 2022
b217854
add eth_createAccessList to RPC methods list.
MicaiahReid Oct 13, 2022
f250218
fix transaction type in rpc-methods.md
MicaiahReid Oct 13, 2022
ea5444c
fix docs
MicaiahReid Oct 13, 2022
e7aef50
of => off in docs
MicaiahReid Oct 13, 2022
b52cbf9
chore: remove support for Node.js v12 (#3705)
davidmurdoch Sep 23, 2022
3868ea1
chore: upgrade @ethereumjs/vm to v6.0.0 (#3656)
MicaiahReid Sep 23, 2022
a0c4e74
feat: add support for the `merge` hardfork (#3658)
davidmurdoch Sep 23, 2022
21c250b
remove .only
MicaiahReid Oct 7, 2022
beaa1fe
test: correctly read stream in `eth_call` test (#3826)
MicaiahReid Oct 22, 2022
fdfcd02
put tags in alphabetical order
MicaiahReid Oct 31, 2022
8b644c9
perf: use keccak from `@ganache/utils` where possible (#3820)
MicaiahReid Oct 31, 2022
c6dc462
chore: remove resolved todo (#3815)
MicaiahReid Nov 7, 2022
05ce874
fix: simplify database implementation to allow removal of type assert…
MicaiahReid Nov 8, 2022
2b0487c
refactor: rework `@ganache/ethereum-address` to extend `ethereumjs/ut…
MicaiahReid Nov 9, 2022
6b7b45d
refactor: remove ts-ignores and fix types (#3778)
MicaiahReid Nov 10, 2022
999adf7
chore: upgrade ethereumjs packages (#3821)
MicaiahReid Nov 10, 2022
8016f7c
fix: implement review suggestions (#3912)
MicaiahReid Nov 16, 2022
fb5b796
Merge branch 'tech-debt-dudes' into feat/eth_createAccessList
MicaiahReid Nov 16, 2022
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
46 changes: 34 additions & 12 deletions src/chains/ethereum/ethereum/src/helpers/simulations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,7 @@ export const runCall = async ({
overrides
});

// we want to warm the access list provided by the user for a run call but
// _not_ for creating an access list. warming the addresses ahead of time will
// make it so that the contents of the user-provided access list are _always_
// in the generated access list, but we want the generated access list to be
// the "best". so we do this here rather than in the common setup functions
// we want to warm the access list provided by the user
if (common.isActivatedEIP(2930) && transaction.accessList) {
warmAccessList(stateManager, transaction.accessList);
}
Expand Down Expand Up @@ -546,12 +542,14 @@ export const createAccessList = async ({
// no real reason why this is our max, feel free to change
const MAX_ITERATIONS = 1000;
let previousAccessList = transaction.accessList || [];
let callResult: EVMResult;
let iterations = 0;
do {
// checkpoint so we can get back to this vm state after every time we
// run this loop
await stateManager.checkpoint();
const callResult = await _runCall({
warmAccessList(stateManager, previousAccessList);
callResult = await _runCall({
blockchain,
runCallOpts,
vm,
Expand All @@ -566,18 +564,42 @@ export const createAccessList = async ({
// generated by the VM, or the VM generated the same access list twice
// in a row, so this is our "best" access list.
if (AccessLists.areAccessListsSame(previousAccessList, accessList)) {
const { dataFeeEIP2930 } = AccessLists.getAccessListData(accessList);
const baseFeeBigInt = intrinsicGas + dataFeeEIP2930;
const gasUsedBigInt =
Quantity.toBigInt(callResult.gasUsed.toArrayLike(Buffer)) +
baseFeeBigInt;
const gasUsed = Quantity.from(gasUsedBigInt);
const gasUsed = _getAccessListGasUsed(
accessList,
intrinsicGas,
callResult
);
return { accessList, gasUsed };
} else {
// we are going to run this loop again so revert our changes
await stateManager.revert();
stateManager.clearWarmedAccounts();
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.

Would it be worthwhile having a test case for this?

Also, in this case, shouldn't we also return the best-so-far access-list?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good find, we definitely should return if we hit max iterations. I've written a test for this, but it takes significant time to hit that many iterations, so it's not feasible for a test :/

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 👍

// we've tried too many times, but so return our latest attempt
MicaiahReid marked this conversation as resolved.
Show resolved Hide resolved
const gasUsed = _getAccessListGasUsed(
previousAccessList,
intrinsicGas,
callResult
);
return { accessList: previousAccessList, gasUsed };
};

/**
* @returns {Quantity} The gas used by the transaction with the EIPP2930 data
MicaiahReid marked this conversation as resolved.
Show resolved Hide resolved
* fee.
*/
const _getAccessListGasUsed = (
accessList: AccessList,
intrinsicGas: bigint,
callResult: EVMResult
) => {
const { dataFeeEIP2930 } = AccessLists.getAccessListData(accessList);
const baseFeeBigInt = intrinsicGas + dataFeeEIP2930;
const gasUsedBigInt =
Quantity.toBigInt(callResult.gasUsed.toArrayLike(Buffer)) + baseFeeBigInt;
const gasUsed = Quantity.from(gasUsedBigInt);
return gasUsed;
};