simplify evm call of test_precompiles

first step towards evm call variation reduction
This commit is contained in:
jangko 2021-10-14 13:08:40 +07:00
parent b77034c870
commit eb2251ec37
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
2 changed files with 48 additions and 60 deletions

View File

@ -187,40 +187,21 @@ proc asmCallEvm*(blockNumber: Uint256, chainDB: BaseChainDB, code, data: seq[byt
result.vmState = vmState
result.contractAddress = contractAddress
type
FixtureResult* = object
isError*: bool
error*: Error
gasUsed*: GasInt
output*: seq[byte]
vmState*: BaseVMState
logEntries*: seq[Log]
proc fixtureCallEvm*(vmState: BaseVMState, call: RpcCallData,
origin: EthAddress, forkOverride = none(Fork)): FixtureResult =
let callResult = runComputation(CallParams(
proc testCallEvm*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, fork: Fork): CallResult =
var call = CallParams(
vmState: vmState,
forkOverride: forkOverride,
origin: some(origin), # Differs from `rpcSetupComputation`.
gasPrice: call.gasPrice,
gasLimit: call.gas, # Differs from `rpcSetupComputation`.
sender: call.source,
to: call.to,
isCreate: call.contractCreation,
value: call.value,
input: call.data,
noIntrinsic: true, # Don't charge intrinsic gas.
noAccessList: true, # Don't initialise EIP-2929 access list.
noGasCharge: true, # Don't charge sender account for gas.
noRefund: true, # Don't apply gas refund/burn rule.
noTransfer: true, # Don't update balances, nonces, code.
))
forkOverride: some(fork),
gasPrice: tx.gasPrice,
gasLimit: tx.gasLimit,
sender: sender,
to: tx.destination,
isCreate: tx.contractCreation,
value: tx.value,
input: tx.payload,
# 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 = callResult.isError
result.error = callResult.error
result.gasUsed = callResult.gasUsed
result.output = callResult.output
result.vmState = vmState
shallowCopy(result.logEntries, callResult.logEntries)
noIntrinsic: true, # Don't charge intrinsic gas.
noRefund: true, # Don't apply gas refund/burn rule.
)
if tx.txType > TxLegacy:
shallowCopy(call.accessList, tx.accessList)
runComputation(call)

View File

@ -6,35 +6,43 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
unittest2, ../nimbus/vm_precompiles, json, stew/byteutils, test_helpers, os, tables,
strformat, strutils, eth/trie/db, eth/common, ../nimbus/db/db_chain, ../nimbus/constants,
../nimbus/[vm_computation, vm_state, forks], macros,
test_allowed_to_fail,
../nimbus/transaction/call_evm, options
std/[strformat, strutils, json, os, tables, macros, options],
unittest2, stew/byteutils,
eth/[trie/db, common, keys],
../nimbus/[vm_computation,
vm_state,
forks,
constants,
vm_precompiles,
transaction,
db/db_chain,
transaction/call_evm
],
./test_helpers, ./test_allowed_to_fail
proc initAddress(i: byte): EthAddress = result[19] = i
template doTest(fixture: JsonNode, fork: Fork, address: PrecompileAddresses): untyped =
for test in fixture:
let
blockNum = 1.u256 # TODO: Check other forks
header = BlockHeader(blockNumber: blockNum)
expectedErr = test.hasKey("ExpectedError")
expected = if test.hasKey("Expected"): hexToSeqByte(test["Expected"].getStr) else: @[]
dataStr = test["Input"].getStr
vmState = newBaseVMState(header.stateRoot, header, newBaseChainDB(newMemoryDb()))
dataStr = test["Input"].getStr
gasExpected = if test.hasKey("Gas"): test["Gas"].getInt else: -1
var call: RpcCallData
call.source = ZERO_ADDRESS
call.to = initAddress(address.byte)
call.gas = 1_000_000_000.GasInt
call.gasPrice = 1.GasInt
call.value = 0.u256
call.data = if dataStr.len > 0: dataStr.hexToSeqByte else: @[]
call.contractCreation = false
let fixtureResult = fixtureCallEvm(vmState, call, call.source, some(fork))
let unsignedTx = Transaction(
txType: TxLegacy,
nonce: 0,
gasPrice: 1.GasInt,
gasLimit: 1_000_000_000.GasInt,
to: initAddress(address.byte).some,
value: 0.u256,
payload: if dataStr.len > 0: dataStr.hexToSeqByte else: @[]
)
let tx = signTransaction(unsignedTx, privateKey, ChainId(1), false)
let fixtureResult = testCallEvm(tx, tx.getSender, vmState, fork)
if expectedErr:
check fixtureResult.isError
@ -54,7 +62,10 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
label = fixtures["func"].getStr
fork = parseEnum[Fork](fixtures["fork"].getStr.toLowerAscii)
data = fixtures["data"]
privateKey = PrivateKey.fromHex("7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d")[]
header = BlockHeader(blockNumber: 1.u256)
vmState = newBaseVMState(header.stateRoot, header, newBaseChainDB(newMemoryDb()))
case toLowerAscii(label)
of "ecrecover": data.doTest(fork, paEcRecover)
of "sha256" : data.doTest(fork, paSha256)
@ -82,11 +93,7 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
proc precompilesMain*() =
suite "Precompiles":
# TODO: For now, EVMC is incompatible with these tests.
when defined(evmc_enabled):
discard
else:
jsonTest("PrecompileTests", testFixture, skipPrecompilesTests)
jsonTest("PrecompileTests", testFixture, skipPrecompilesTests)
when isMainModule:
precompilesMain()