Fixtures: Make fixture "vm json tests" use new function fixtureCallEvm

Move the EVM setup and call in fixtures "vm json tests" to new function
`fixtureCallEvm` in `call_evm`.  Extra return values needed for testing are
returned specially.

This entry point is different from all other `..CallEvm` type functions,
because it uses `executeOpcodes` instead of `execComputation`, so it doesn't
update the account balance or nonce on entry and exit from the EVM.

The new code is a bit redundant and simplistic intentionally, as the purpose is
to move functionality to `call_evm` with high confidence nothing really
changed.  The calls will be jointly refactored afterwards to merge differences.

Signed-off-by: Jamie Lokier <jamie@shareable.org>
This commit is contained in:
Jamie Lokier 2021-05-04 15:02:16 +01:00
parent 9e99bb6cd9
commit 236a65d598
No known key found for this signature in database
GPG Key ID: CBC25C68435C30A2
2 changed files with 36 additions and 13 deletions

View File

@ -283,7 +283,7 @@ proc asmCallEvm*(blockNumber: Uint256, chainDB: BaseChainDB, code, data: seq[byt
result.vmState = c.vmState
result.contractAddress = c.msg.contractAddress
proc fixtureSetupComputation*(vmState: BaseVMState, call: RpcCallData, origin: EthAddress): Computation =
proc fixtureSetupComputation(vmState: BaseVMState, call: RpcCallData, origin: EthAddress): Computation =
vmState.setupTxContext(
origin = origin, # Differs from `rpcSetupComputation`
gasPrice = call.gasPrice,
@ -302,3 +302,28 @@ proc fixtureSetupComputation*(vmState: BaseVMState, call: RpcCallData, origin: E
)
return newComputation(vmState, msg)
type
FixtureResult* = object
isError*: bool
error*: Error
gasRemaining*: GasInt
output*: seq[byte]
vmState*: BaseVMState
logEntries*: seq[Log]
proc fixtureCallEvm*(vmState: BaseVMState, call: RpcCallData, origin: EthAddress): FixtureResult =
var c = fixtureSetupComputation(vmState, call, origin)
# Next line differs from all the other EVM calls. With `execComputation`,
# most "vm json tests" fail with either `balanceDiff` or `nonceDiff` errors.
c.executeOpcodes()
# Some of these are extra returned state, for testing, that a normal EVMC API
# computation doesn't return. We'll have to obtain them outside EVMC.
result.isError = c.isError
result.error = c.error
result.gasRemaining = c.gasMeter.gasRemaining
result.output = c.output
result.vmState = c.vmState
shallowCopy(result.logEntries, c.logEntries)

View File

@ -59,16 +59,15 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
# assume ZERO_ADDRESS is a contract creation
call.contractCreation = (toAddress == ZERO_ADDRESS)
var computation = fixtureSetupComputation(vmState, call, origin)
computation.executeOpcodes()
var fixtureResult = fixtureCallEvm(vmState, call, origin)
if not fixture{"post"}.isNil:
# Success checks
check(not computation.isError)
if computation.isError:
echo "Computation error: ", computation.error.info
check(not fixtureResult.isError)
if fixtureResult.isError:
echo "Computation error: ", fixtureResult.error.info
let logEntries = computation.logEntries
let logEntries = fixtureResult.logEntries
if not fixture{"logs"}.isNil:
let actualLogsHash = hashLogEntries(logEntries)
let expectedLogsHash = toLowerAscii(fixture{"logs"}.getStr)
@ -78,21 +77,20 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
fail()
let expectedOutput = fixture{"out"}.getStr
check(computation.output.bytesToHex == expectedOutput)
let gasMeter = computation.gasMeter
check(fixtureResult.output.bytesToHex == expectedOutput)
let expectedGasRemaining = fixture{"gas"}.getHexadecimalInt
let actualGasRemaining = gasMeter.gasRemaining
let actualGasRemaining = fixtureResult.gasRemaining
checkpoint(&"Remaining: {actualGasRemaining} - Expected: {expectedGasRemaining}")
check(actualGasRemaining == expectedGasRemaining)
if not fixture{"post"}.isNil:
verifyStateDb(fixture{"post"}, computation.vmState.readOnlyStateDB)
verifyStateDb(fixture{"post"}, fixtureResult.vmState.readOnlyStateDB)
else:
# Error checks
check(computation.isError)
check(fixtureResult.isError)
if not fixture{"pre"}.isNil:
verifyStateDb(fixture{"pre"}, computation.vmState.readOnlyStateDB)
verifyStateDb(fixture{"pre"}, fixtureResult.vmState.readOnlyStateDB)
when isMainModule:
vmJsonMain()