Skip to content

Commit 91850aa

Browse files
authored
Fluffy: eth_createAccessList fixes and improvements (#3247)
1 parent 04d44e2 commit 91850aa

File tree

3 files changed

+41
-19
lines changed

3 files changed

+41
-19
lines changed

fluffy/evm/async_evm.nim

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
{.push raises: [].}
99

1010
import
11-
std/sets,
11+
std/[sets, algorithm],
1212
stew/byteutils,
1313
chronos,
1414
chronicles,
@@ -141,10 +141,7 @@ template toCallResult(evmResult: EvmResult[CallResult]): Result[CallResult, stri
141141
"EVM execution failed: " & $e.code
142142
)
143143

144-
if callResult.error.len() > 0:
145-
err("EVM execution failed: " & callResult.error)
146-
else:
147-
ok(callResult)
144+
ok(callResult)
148145

149146
proc callFetchingState(
150147
evm: AsyncEvm,
@@ -277,8 +274,7 @@ proc callFetchingState(
277274
vmState.ledger.setCode(q.address, code)
278275
fetchedCode.incl(q.address)
279276
except CatchableError as e:
280-
# TODO: why do the above futures throw a CatchableError and not CancelledError?
281-
raiseAssert(e.msg)
277+
raise newException(CancelledError, e.msg)
282278

283279
evmResult.toCallResult()
284280

@@ -335,12 +331,19 @@ proc call*(
335331
defer:
336332
txFrame.dispose() # always dispose state changes
337333

338-
let vmState = evm.setupVmState(txFrame, header)
339-
await evm.callFetchingState(vmState, header, tx, optimisticStateFetch)
334+
let
335+
vmState = evm.setupVmState(txFrame, header)
336+
callResult =
337+
?(await evm.callFetchingState(vmState, header, tx, optimisticStateFetch))
338+
339+
if callResult.error.len() > 0:
340+
err("EVM execution failed: " & callResult.error)
341+
else:
342+
ok(callResult)
340343

341344
proc createAccessList*(
342345
evm: AsyncEvm, header: Header, tx: TransactionArgs, optimisticStateFetch = true
343-
): Future[Result[(transactions.AccessList, GasInt), string]] {.
346+
): Future[Result[(transactions.AccessList, Opt[string], GasInt), string]] {.
344347
async: (raises: [CancelledError])
345348
.} =
346349
let
@@ -375,11 +378,27 @@ proc createAccessList*(
375378
txWithAl.accessList = Opt.some(al.getAccessList())
376379
# converts to transactions.AccessList
377380

378-
let finalCallResult = ?evm.call(vmState, header, txWithAl)
381+
let
382+
finalCallResult = ?evm.call(vmState, header, txWithAl)
383+
error =
384+
if finalCallResult.error.len() > 0:
385+
Opt.some(finalCallResult.error)
386+
else:
387+
Opt.none(string)
388+
389+
# Sort the access list
390+
var accessList = txWithAl.accessList.get(@[])
391+
for a in accessList.mitems():
392+
a.storageKeys.sort(
393+
proc(x, y: Bytes32): int =
394+
cmp(x.data, y.data)
395+
)
396+
accessList.sort(
397+
proc(x, y: AccessPair): int =
398+
cmp(x.address.data, y.address.data)
399+
)
379400

380-
# TODO: Do we need to use the estimate gas calculation here to get a more acturate
381-
# estimation of the gas requirement?
382-
ok((txWithAl.accessList.get(@[]), finalCallResult.gasUsed))
401+
ok((accessList, error, finalCallResult.gasUsed))
383402

384403
proc estimateGas*(
385404
evm: AsyncEvm, header: Header, tx: TransactionArgs, optimisticStateFetch = true

fluffy/rpc/rpc_eth_api.nim

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ proc installEthApiHandlers*(
486486
## quantityTag: integer block number, or the string "latest", "earliest" or "pending",
487487
## see the default block parameter.
488488
## Returns: the access list object which contains the addresses and storage keys which
489-
## are read by the transaction.
489+
## are read and written by the transaction.
490490

491491
if tx.to.isNone():
492492
raise newException(ValueError, "to address is required")
@@ -502,12 +502,13 @@ proc installEthApiHandlers*(
502502
optimisticStateFetch = optimisticStateFetch.valueOr:
503503
true
504504

505-
let (accessList, gasUsed) = (
505+
let (accessList, error, gasUsed) = (
506506
await evm.createAccessList(header, tx, optimisticStateFetch)
507507
).valueOr:
508508
raise newException(ValueError, error)
509509

510-
return AccessListResult(accessList: accessList, gasUsed: gasUsed.Quantity)
510+
return
511+
AccessListResult(accessList: accessList, error: error, gasUsed: gasUsed.Quantity)
511512

512513
rpcServer.rpc("eth_estimateGas") do(
513514
tx: TransactionArgs, quantityTag: RtBlockIdentifier, optimisticStateFetch: Opt[bool]

fluffy/tests/evm/test_async_evm.nim

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,14 @@ suite "Async EVM":
186186
input: Opt.some(testCase.txArgs.input.hexToSeqByte()),
187187
)
188188

189-
let (accessList, gasUsed) = (
189+
let (accessList, error, gasUsed) = (
190190
waitFor evm.createAccessList(header, tx, optimisticStateFetch = true)
191191
).expect("success")
192192

193193
check:
194194
accessList.len() == testCase.expected.accessList.len()
195195
gasUsed > 0
196+
error.isNone()
196197

197198
for accessPair in accessList:
198199
let
@@ -220,13 +221,14 @@ suite "Async EVM":
220221
input: Opt.some(testCase.txArgs.input.hexToSeqByte()),
221222
)
222223

223-
let (accessList, gasUsed) = (
224+
let (accessList, error, gasUsed) = (
224225
waitFor evm.createAccessList(header, tx, optimisticStateFetch = false)
225226
).expect("success")
226227

227228
check:
228229
accessList.len() == testCase.expected.accessList.len()
229230
gasUsed > 0
231+
error.isNone()
230232

231233
for accessPair in accessList:
232234
let

0 commit comments

Comments
 (0)