From eb2251ec3757ba366fce772350c4048cadee6327 Mon Sep 17 00:00:00 2001 From: jangko Date: Thu, 14 Oct 2021 13:08:40 +0700 Subject: [PATCH] simplify evm call of test_precompiles first step towards evm call variation reduction --- nimbus/transaction/call_evm.nim | 51 +++++++++-------------------- tests/test_precompiles.nim | 57 ++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 60 deletions(-) diff --git a/nimbus/transaction/call_evm.nim b/nimbus/transaction/call_evm.nim index 4a88fa09d..1a16ff94b 100644 --- a/nimbus/transaction/call_evm.nim +++ b/nimbus/transaction/call_evm.nim @@ -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) diff --git a/tests/test_precompiles.nim b/tests/test_precompiles.nim index 0b89df70a..bb84c2b3a 100644 --- a/tests/test_precompiles.nim +++ b/tests/test_precompiles.nim @@ -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()