@@ -14,30 +14,30 @@ import
1414 chronicles,
1515 stint,
1616 results,
17- eth/ common/ [base, hashes, addresses, accounts, headers, transactions],
17+ eth/ common/ [base, addresses, accounts, headers, transactions],
1818 ../../ execution_chain/ db/ [ledger, access_list],
1919 ../../ execution_chain/ common/ common,
2020 ../../ execution_chain/ transaction/ call_evm,
21- ../../ execution_chain/ evm/ [types, state, evm_errors]
21+ ../../ execution_chain/ evm/ [types, state, evm_errors],
22+ ./ async_evm_backend
2223
23- from web3/ eth_api_types import TransactionArgs
24- from web3/ eth_api_types import Quantity
24+ from web3/ eth_api_types import TransactionArgs , Quantity
2525
2626export
27- results, chronos, hashes, addresses, accounts , headers, TransactionArgs , CallResult ,
27+ async_evm_backend, results, chronos , headers, TransactionArgs , CallResult ,
2828 transactions.AccessList , GasInt
2929
3030logScope:
3131 topics = " async_evm"
3232
33- # The Portal EVM uses the Nimbus in-memory EVM to execute transactions using the
34- # portal state network state data. Currently only call is supported .
33+ # The Async EVM uses the Nimbus in-memory EVM to execute transactions using state
34+ # data fetched asyncronously from a supplied state backend .
3535#
36- # Rather than wire in the portal state lookups into the EVM directly, the approach
36+ # Rather than wire in the async state lookups into the EVM directly, the approach
3737# taken here is to optimistically execute the transaction multiple times with the
3838# goal of building the correct access list so that we can then lookup the accessed
39- # state from the portal network , store the state in the in-memory EVM and then
40- # finally execute the transaction using the correct state. The Portal EVM makes
39+ # state from the async state backend , store the state in the in-memory EVM and then
40+ # finally execute the transaction using the correct state. The Async EVM makes
4141# use of data in memory during the call and therefore each piece of state is never
4242# fetched more than once. We know we have found the correct access list if it
4343# doesn't change after another execution of the transaction.
@@ -48,9 +48,8 @@ logScope:
4848# call given that we gain the ability to fetch the state concurrently.
4949#
5050# There are multiple reasons for choosing this approach:
51- # - Firstly updating the existing Nimbus EVM to support using a different state
52- # backend (portal state in this case) is difficult and would require making
53- # non-trivial changes to the EVM.
51+ # - Firstly updating the existing Nimbus EVM to support using different state
52+ # backends is difficult and would require making non-trivial changes to the EVM.
5453# - This new approach allows us to look up the state concurrently in the event that
5554# multiple new state keys are discovered after executing the transaction. This
5655# should in theory result in improved performance for certain scenarios. The
8281 address: Address
8382 codeFut: Future [Opt [seq [byte ]]]
8483
85- GetAccountProc * = proc (stateRoot: Hash32 , address: Address ): Future [Opt [Account ]] {.
86- async : (raises: [CancelledError ])
87- .}
88-
89- GetStorageProc * = proc (
90- stateRoot: Hash32 , address: Address , slotKey: UInt256
91- ): Future [Opt [UInt256 ]] {.async : (raises: [CancelledError ]).}
92-
93- GetCodeProc * = proc (stateRoot: Hash32 , address: Address ): Future [Opt [seq [byte ]]] {.
94- async : (raises: [CancelledError ])
95- .}
96-
97- AsyncEvmStateBackend * = object
98- getAccount: GetAccountProc
99- getStorage: GetStorageProc
100- getCode: GetCodeProc
101-
10284 AsyncEvm * = ref object
10385 com: CommonRef
10486 backend: AsyncEvmStateBackend
@@ -114,14 +96,6 @@ func init(
11496func init (T: type CodeQuery , adr: Address , fut: Future [Opt [seq [byte ]]]): T =
11597 T (address: adr, codeFut: fut)
11698
117- proc init * (
118- T: type AsyncEvmStateBackend ,
119- accProc: GetAccountProc ,
120- storageProc: GetStorageProc ,
121- codeProc: GetCodeProc ,
122- ): T =
123- AsyncEvmStateBackend (getAccount: accProc, getStorage: storageProc, getCode: codeProc)
124-
12599proc init * (
126100 T: type AsyncEvm , backend: AsyncEvmStateBackend , networkId: NetworkId = MainNet
127101): T =
@@ -165,7 +139,7 @@ proc callFetchingState(
165139 fetchedCode = initHashSet [Address ]()
166140
167141 # Set code of the 'to' address in the EVM so that we can execute the transaction
168- let code = (await evm.backend.getCode (header.stateRoot , to)).valueOr:
142+ let code = (await evm.backend.getCode (header, to)).valueOr:
169143 return err (" Unable to get code" )
170144 vmState.ledger.setCode (to, code)
171145 fetchedCode.incl (to)
@@ -215,8 +189,7 @@ proc callFetchingState(
215189 let slotIdx = (adr, v.storageSlot)
216190 if slotIdx notin fetchedStorage:
217191 debug " Fetching storage slot" , address = adr, slotKey = v.storageSlot
218- let storageFut =
219- evm.backend.getStorage (header.stateRoot, adr, v.storageSlot)
192+ let storageFut = evm.backend.getStorage (header, adr, v.storageSlot)
220193 if not stateFetchDone:
221194 storageQueries.add (StorageQuery .init (adr, v.storageSlot, storageFut))
222195 if not optimisticStateFetch:
@@ -226,15 +199,15 @@ proc callFetchingState(
226199
227200 if adr notin fetchedAccounts:
228201 debug " Fetching account" , address = adr
229- let accFut = evm.backend.getAccount (header.stateRoot , adr)
202+ let accFut = evm.backend.getAccount (header, adr)
230203 if not stateFetchDone:
231204 accountQueries.add (AccountQuery .init (adr, accFut))
232205 if not optimisticStateFetch:
233206 stateFetchDone = true
234207
235208 if v.codeTouched and adr notin fetchedCode:
236209 debug " Fetching code" , address = adr
237- let codeFut = evm.backend.getCode (header.stateRoot , adr)
210+ let codeFut = evm.backend.getCode (header, adr)
238211 if not stateFetchDone:
239212 codeQueries.add (CodeQuery .init (adr, codeFut))
240213 if not optimisticStateFetch:
0 commit comments