diff --git a/nimbus/transaction/call_evm.nim b/nimbus/transaction/call_evm.nim index e6512aae1..26c99b63f 100644 --- a/nimbus/transaction/call_evm.nim +++ b/nimbus/transaction/call_evm.nim @@ -241,7 +241,7 @@ proc asmSetupComputation(tx: Transaction, sender: EthAddress, vmState: BaseVMSta return newComputation(vmState, msg) -proc asmSetupComputation*(blockNumber: Uint256, chainDB: BaseChainDB, code, data: seq[byte], fork: Fork): Computation = +proc asmSetupComputation(blockNumber: Uint256, chainDB: BaseChainDB, code, data: seq[byte], fork: Fork): Computation = let parentNumber = blockNumber - 1 parent = chainDB.getBlockHeader(parentNumber) @@ -257,3 +257,28 @@ proc asmSetupComputation*(blockNumber: Uint256, chainDB: BaseChainDB, code, data tx.payload = code tx.gasLimit = 500000000 return asmSetupComputation(tx, sender, vmState, data, some(fork)) + +type + AsmResult* = object + isSuccess*: bool + gasUsed*: GasInt + output*: seq[byte] + stack*: Stack + memory*: Memory + vmState*: BaseVMState + contractAddress*: EthAddress + +proc asmCallEvm*(blockNumber: Uint256, chainDB: BaseChainDB, code, data: seq[byte], fork: Fork): AsmResult = + var c = asmSetupComputation(blockNumber, chainDB, code, data, fork) + let gas = c.gasMeter.gasRemaining + c.execComputation() + + # 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.isSuccess = c.isSuccess + result.gasUsed = gas - c.gasMeter.gasRemaining + result.output = c.output + result.stack = c.stack + result.memory = c.memory + result.vmState = c.vmState + result.contractAddress = c.msg.contractAddress diff --git a/tests/macro_assembler.nim b/tests/macro_assembler.nim index cf38267b6..afad48429 100644 --- a/tests/macro_assembler.nim +++ b/tests/macro_assembler.nim @@ -212,13 +212,9 @@ proc initDatabase*(): (Uint256, BaseChainDB) = result = (blockNumber, newBaseChainDB(memoryDB, false)) proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool = - var computation = asmSetupComputation(blockNumber, chainDB, boa.code, boa.data, boa.fork) + var asmResult = asmCallEvm(blockNumber, chainDB, boa.code, boa.data, boa.fork) - let gas = computation.gasMeter.gasRemaining - execComputation(computation) - let gasUsed = gas - computation.gasMeter.gasRemaining - - if computation.isSuccess: + if asmResult.isSuccess: if boa.success == false: error "different success value", expected=boa.success, actual=true return false @@ -228,15 +224,15 @@ proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool = return false if boa.gasUsed != -1: - if boa.gasUsed != gasUsed: - error "different gasUsed", expected=boa.gasUsed, actual=gasUsed + if boa.gasUsed != asmResult.gasUsed: + error "different gasUsed", expected=boa.gasUsed, actual=asmResult.gasUsed return false - if boa.stack.len != computation.stack.values.len: - error "different stack len", expected=boa.stack.len, actual=computation.stack.values.len + if boa.stack.len != asmResult.stack.values.len: + error "different stack len", expected=boa.stack.len, actual=asmResult.stack.values.len return false - for i, v in computation.stack.values: + for i, v in asmResult.stack.values: let actual = v.dumpHex() let val = boa.stack[i].toHex() if actual != val: @@ -244,24 +240,24 @@ proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool = return false const chunkLen = 32 - let numChunks = computation.memory.len div chunkLen + let numChunks = asmResult.memory.len div chunkLen if numChunks != boa.memory.len: error "different memory len", expected=boa.memory.len, actual=numChunks return false for i in 0 ..< numChunks: - let actual = computation.memory.bytes.toOpenArray(i * chunkLen, (i + 1) * chunkLen - 1).toHex() + let actual = asmResult.memory.bytes.toOpenArray(i * chunkLen, (i + 1) * chunkLen - 1).toHex() let mem = boa.memory[i].toHex() if mem != actual: error "different memory value", idx=i, expected=mem, actual=actual return false - var stateDB = computation.vmState.accountDb + var stateDB = asmResult.vmState.accountDb stateDB.persist() var - storageRoot = stateDB.getStorageRoot(computation.msg.contractAddress) + storageRoot = stateDB.getStorageRoot(asmResult.contractAddress) trie = initSecureHexaryTrie(chainDB.db, storageRoot) for kv in boa.storage: @@ -275,7 +271,7 @@ proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool = error "storage has different value", key=key, expected=val, actual=value return false - let logs = computation.vmState.logEntries + let logs = asmResult.vmState.logEntries if logs.len != boa.logs.len: error "different logs len", expected=boa.logs.len, actual=logs.len return false @@ -302,7 +298,7 @@ proc runVM*(blockNumber: Uint256, chainDB: BaseChainDB, boa: Assembler): bool = return false if boa.output.len > 0: - let actual = computation.output.toHex() + let actual = asmResult.output.toHex() let expected = boa.output.toHex() if expected != actual: error "different output detected", expected=expected, actual=actual