nimbus-eth1/tests/test_op_memory_lazy.nim

75 lines
1.8 KiB
Nim
Raw Normal View History

Added basic async capabilities for vm2. (#1260) * Added basic async capabilities for vm2. This is a whole new Git branch, not the same one as last time (https://github.com/status-im/nimbus-eth1/pull/1250) - there wasn't much worth salvaging. Main differences: I didn't do the "each opcode has to specify an async handler" junk that I put in last time. Instead, in oph_memory.nim you can see sloadOp calling asyncChainTo and passing in an async operation. That async operation is then run by the execCallOrCreate (or asyncExecCallOrCreate) code in interpreter_dispatch.nim. In the test code, the (previously existing) macro called "assembler" now allows you to add a section called "initialStorage", specifying fake data to be used by the EVM computation run by that test. (In the long run we'll obviously want to write tests that for-real use the JSON-RPC API to asynchronously fetch data; for now, this was just an expedient way to write a basic unit test that exercises the async-EVM code pathway.) There's also a new macro called "concurrentAssemblers" that allows you to write a test that runs multiple assemblers concurrently (and then waits for them all to finish). There's one example test using this, in test_op_memory_lazy.nim, though you can't actually see it doing so unless you uncomment some echo statements in async_operations.nim (in which case you can see the two concurrently running EVM computations each printing out what they're doing, and you'll see that they interleave). A question: is it possible to make EVMC work asynchronously? (For now, this code compiles and "make test" passes even if ENABLE_EVMC is turned on, but it doesn't actually work asynchronously, it just falls back on doing the usual synchronous EVMC thing. See FIXME-asyncAndEvmc.) * Moved the AsyncOperationFactory to the BaseVMState object. * Made the AsyncOperationFactory into a table of fn pointers. Also ditched the plain-data Vm2AsyncOperation type; it wasn't really serving much purpose. Instead, the pendingAsyncOperation field directly contains the Future. * Removed the hasStorage idea. It's not the right solution to the "how do we know whether we still need to fetch the storage value or not?" problem. I haven't implemented the right solution yet, but at least we're better off not putting in a wrong one. * Added/modified/removed some comments. (Based on feedback on the PR.) * Removed the waitFor from execCallOrCreate. There was some back-and-forth in the PR regarding whether nested waitFor calls are acceptable: https://github.com/status-im/nimbus-eth1/pull/1260#discussion_r998587449 The eventual decision was to just change the waitFor to a doAssert (since we probably won't want this extra functionality when running synchronously anyway) to make sure that the Future is already finished.
2022-11-01 15:35:46 +00:00
import macro_assembler, unittest2, macros, strutils
proc opMemoryLazyMain*() =
suite "Lazy Loading With Memory Opcodes":
let (vmState, chainDB) = initDatabase()
assembler: # SLOAD OP with (fake) lazy data fetching
title: "LAZY_SLOAD_1"
initialStorage:
"0xAA": "0x42"
code:
PUSH1 "0xAA"
SLOAD
PUSH1 "0x01"
ADD
PUSH1 "0xAA"
SSTORE
PUSH1 "0xAA"
SLOAD
storage:
"0xAA": "0x43"
stack:
"0x0000000000000000000000000000000000000000000000000000000000000043"
let (vmState1, chainDB1) = initDatabase()
let (vmState2, chainDB2) = initDatabase()
concurrentAssemblers:
title: "Concurrent Assemblers"
assemblers:
asm1:
title: "asm1"
vmState: vmState1
chainDB: chainDB1
initialStorage:
"0xBB": "0x42"
"0xCC": "0x20"
code:
PUSH1 "0xBB"
SLOAD
PUSH1 "0xCC"
SLOAD
ADD
PUSH1 "0xBB"
SSTORE
PUSH1 "0xBB"
SLOAD
storage:
"0xBB": "0x62"
"0xCC": "0x20"
stack: "0x0000000000000000000000000000000000000000000000000000000000000062"
asm2:
title: "asm2"
vmState: vmState2
chainDB: chainDB2
initialStorage:
"0xDD": "0x30"
"0xEE": "0x20"
code:
PUSH1 "0xDD"
SLOAD
PUSH1 "0xEE"
SLOAD
ADD
PUSH1 "0xEE"
SSTORE
PUSH1 "0xEE"
SLOAD
storage:
"0xDD": "0x30"
"0xEE": "0x50"
stack: "0x0000000000000000000000000000000000000000000000000000000000000050"
when isMainModule:
opMemoryLazyMain()