Merge branch 'cleanups' of https://github.com/jangko/nimbus into jangko-cleanups
This commit is contained in:
commit
3c6ea4ac9c
|
@ -1,5 +1,5 @@
|
||||||
import ../db/[db_chain, state_db], eth/common, chronicles, ../vm_state, ../vm_types, ../transaction, ranges,
|
import ../db/[db_chain, state_db], eth/common, chronicles, ../vm_state, ../vm_types, ../transaction, ranges,
|
||||||
../vm/[computation, interpreter_dispatch, message], ../constants, stint, nimcrypto,
|
../vm/[computation, message], ../constants, stint, nimcrypto,
|
||||||
../vm_state_transactions, sugar, ../utils, eth/trie/db, ../tracer, ./executor
|
../vm_state_transactions, sugar, ../utils, eth/trie/db, ../tracer, ./executor
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
@ -3,7 +3,7 @@ import options,
|
||||||
../db/[db_chain, state_db],
|
../db/[db_chain, state_db],
|
||||||
../utils, ../constants, ../transaction,
|
../utils, ../constants, ../transaction,
|
||||||
../vm_state, ../vm_types, ../vm_state_transactions,
|
../vm_state, ../vm_types, ../vm_state_transactions,
|
||||||
../vm/[computation, interpreter_dispatch, message],
|
../vm/[computation, message],
|
||||||
../vm/interpreter/vm_forks
|
../vm/interpreter/vm_forks
|
||||||
|
|
||||||
proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, forkOverride=none(Fork)): GasInt =
|
proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMState, forkOverride=none(Fork)): GasInt =
|
||||||
|
@ -12,18 +12,6 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
|
||||||
trace "Sender", sender
|
trace "Sender", sender
|
||||||
trace "txHash", rlpHash = tx.rlpHash
|
trace "txHash", rlpHash = tx.rlpHash
|
||||||
|
|
||||||
# TODO: we have identical `fork` code in setupComputation.
|
|
||||||
# at later stage, we need to get rid of it
|
|
||||||
# and apply changes in eth_*, debug_* RPC,
|
|
||||||
# macro assembler and premix tool set.
|
|
||||||
# at every place where setupComputation and
|
|
||||||
# processTransaction are used.
|
|
||||||
let fork =
|
|
||||||
if forkOverride.isSome:
|
|
||||||
forkOverride.get
|
|
||||||
else:
|
|
||||||
vmState.blockNumber.toFork
|
|
||||||
|
|
||||||
let upfrontGasCost = tx.gasLimit.u256 * tx.gasPrice.u256
|
let upfrontGasCost = tx.gasLimit.u256 * tx.gasPrice.u256
|
||||||
var balance = vmState.readOnlyStateDb().getBalance(sender)
|
var balance = vmState.readOnlyStateDb().getBalance(sender)
|
||||||
if balance < upfrontGasCost:
|
if balance < upfrontGasCost:
|
||||||
|
@ -43,24 +31,10 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta
|
||||||
if tx.isContractCreation and isCollision:
|
if tx.isContractCreation and isCollision:
|
||||||
return tx.gasLimit
|
return tx.gasLimit
|
||||||
|
|
||||||
var snapshot = vmState.snapshot()
|
|
||||||
defer: snapshot.dispose()
|
|
||||||
|
|
||||||
var contractOK = true
|
|
||||||
result = tx.gasLimit
|
result = tx.gasLimit
|
||||||
|
|
||||||
if execComputation(computation):
|
if execComputation(computation):
|
||||||
if tx.isContractCreation:
|
|
||||||
contractOK = computation.writeContract(fork)
|
|
||||||
result = computation.refundGas(tx, sender)
|
result = computation.refundGas(tx, sender)
|
||||||
|
|
||||||
if not contractOK and fork == FkHomestead:
|
|
||||||
snapshot.revert()
|
|
||||||
# consume all gas
|
|
||||||
result = tx.gasLimit
|
|
||||||
else:
|
|
||||||
snapshot.commit()
|
|
||||||
|
|
||||||
if computation.isSuicided(vmState.blockHeader.coinbase):
|
if computation.isSuicided(vmState.blockHeader.coinbase):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import
|
||||||
../transaction, ../config, ../vm_state, ../constants, ../vm_types,
|
../transaction, ../config, ../vm_state, ../constants, ../vm_types,
|
||||||
../vm_state_transactions, ../utils,
|
../vm_state_transactions, ../utils,
|
||||||
../db/[db_chain, state_db, storage_types],
|
../db/[db_chain, state_db, storage_types],
|
||||||
rpc_types, rpc_utils, ../vm/[message, computation, interpreter_dispatch]
|
rpc_types, rpc_utils, ../vm/[message, computation]
|
||||||
|
|
||||||
#[
|
#[
|
||||||
Note:
|
Note:
|
||||||
|
|
|
@ -112,61 +112,12 @@ proc commit*(snapshot: var ComputationSnapshot) {.inline.} =
|
||||||
proc dispose*(snapshot: var ComputationSnapshot) {.inline.} =
|
proc dispose*(snapshot: var ComputationSnapshot) {.inline.} =
|
||||||
snapshot.snapshot.dispose()
|
snapshot.snapshot.dispose()
|
||||||
|
|
||||||
proc transferBalance(computation: var BaseComputation, opCode: static[Op]) =
|
proc getFork*(computation: BaseComputation): Fork =
|
||||||
if computation.msg.depth >= MaxCallDepth:
|
result =
|
||||||
raise newException(StackDepthError, "Stack depth limit reached")
|
if computation.forkOverride.isSome:
|
||||||
|
computation.forkOverride.get
|
||||||
let senderBalance = computation.vmState.readOnlyStateDb().
|
else:
|
||||||
getBalance(computation.msg.sender)
|
computation.vmState.blockNumber.toFork
|
||||||
|
|
||||||
if senderBalance < computation.msg.value:
|
|
||||||
raise newException(InsufficientFunds,
|
|
||||||
&"Insufficient funds: {senderBalance} < {computation.msg.value}")
|
|
||||||
|
|
||||||
when opCode in {Call, Create}:
|
|
||||||
computation.vmState.mutateStateDb:
|
|
||||||
db.subBalance(computation.msg.sender, computation.msg.value)
|
|
||||||
db.addBalance(computation.msg.storageAddress, computation.msg.value)
|
|
||||||
|
|
||||||
proc applyMessage(computation: var BaseComputation, opCode: static[Op]): bool =
|
|
||||||
var snapshot = computation.snapshot()
|
|
||||||
defer: snapshot.dispose()
|
|
||||||
|
|
||||||
when opCode in {CallCode, Call, Create}:
|
|
||||||
try:
|
|
||||||
computation.transferBalance(opCode)
|
|
||||||
except VMError:
|
|
||||||
snapshot.revert()
|
|
||||||
debug "transferBalance failed", msg = computation.error.info
|
|
||||||
return
|
|
||||||
|
|
||||||
if computation.gasMeter.gasRemaining < 0:
|
|
||||||
snapshot.commit()
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Run code
|
|
||||||
# We cannot use the normal dispatching function `executeOpcodes`
|
|
||||||
# within `interpreter_dispatch.nim` due to a cyclic dependency.
|
|
||||||
computation.opcodeExec(computation)
|
|
||||||
snapshot.commit()
|
|
||||||
except VMError:
|
|
||||||
snapshot.revert(true)
|
|
||||||
debug "VMError applyMessage failed",
|
|
||||||
msg = computation.error.info,
|
|
||||||
depth = computation.msg.depth
|
|
||||||
except EVMError:
|
|
||||||
snapshot.revert() # TODO: true or false?
|
|
||||||
debug "EVMError applyMessage failed",
|
|
||||||
msg = computation.error.info,
|
|
||||||
depth = computation.msg.depth
|
|
||||||
except ValueError:
|
|
||||||
snapshot.revert(true)
|
|
||||||
debug "ValueError applyMessage failed",
|
|
||||||
msg = computation.error.info,
|
|
||||||
depth = computation.msg.depth
|
|
||||||
|
|
||||||
result = not computation.isError
|
|
||||||
|
|
||||||
proc writeContract*(computation: var BaseComputation, fork: Fork): bool =
|
proc writeContract*(computation: var BaseComputation, fork: Fork): bool =
|
||||||
result = true
|
result = true
|
||||||
|
@ -192,19 +143,65 @@ proc writeContract*(computation: var BaseComputation, fork: Fork): bool =
|
||||||
if fork < FkHomestead: computation.output = @[]
|
if fork < FkHomestead: computation.output = @[]
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc generateChildComputation*(fork: Fork, computation: var BaseComputation, childMsg: Message): BaseComputation =
|
proc transferBalance(computation: var BaseComputation, opCode: static[Op]): bool =
|
||||||
var childComp = newBaseComputation(
|
if computation.msg.depth >= MaxCallDepth:
|
||||||
computation.vmState,
|
debug "Stack depth limit reached", depth=computation.msg.depth
|
||||||
computation.vmState.blockNumber,
|
return false
|
||||||
childMsg,
|
|
||||||
some(fork))
|
|
||||||
|
|
||||||
# Copy the fork op code executor proc (assumes child computation is in the same fork)
|
let senderBalance = computation.vmState.readOnlyStateDb().
|
||||||
childComp.opCodeExec = computation.opCodeExec
|
getBalance(computation.msg.sender)
|
||||||
|
|
||||||
return childComp
|
if senderBalance < computation.msg.value:
|
||||||
|
debug "insufficient funds", available=senderBalance, needed=computation.msg.value
|
||||||
|
return false
|
||||||
|
|
||||||
proc addChildComputation(fork: Fork, computation: var BaseComputation, child: BaseComputation) =
|
when opCode in {Call, Create}:
|
||||||
|
computation.vmState.mutateStateDb:
|
||||||
|
db.subBalance(computation.msg.sender, computation.msg.value)
|
||||||
|
db.addBalance(computation.msg.storageAddress, computation.msg.value)
|
||||||
|
|
||||||
|
result = true
|
||||||
|
|
||||||
|
proc executeOpcodes*(computation: var BaseComputation) {.gcsafe.}
|
||||||
|
|
||||||
|
proc applyMessage*(computation: var BaseComputation, opCode: static[Op]): bool =
|
||||||
|
var snapshot = computation.snapshot()
|
||||||
|
defer: snapshot.dispose()
|
||||||
|
|
||||||
|
when opCode in {CallCode, Call, Create}:
|
||||||
|
if not computation.transferBalance(opCode):
|
||||||
|
snapshot.revert()
|
||||||
|
return
|
||||||
|
|
||||||
|
if computation.gasMeter.gasRemaining < 0:
|
||||||
|
snapshot.commit()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
executeOpcodes(computation)
|
||||||
|
result = not computation.isError
|
||||||
|
except VMError:
|
||||||
|
result = false
|
||||||
|
debug "applyMessage VM Error",
|
||||||
|
msg = getCurrentExceptionMsg(),
|
||||||
|
depth = computation.msg.depth
|
||||||
|
except ValueError:
|
||||||
|
result = false
|
||||||
|
debug "applyMessage Value Error",
|
||||||
|
msg = getCurrentExceptionMsg(),
|
||||||
|
depth = computation.msg.depth
|
||||||
|
|
||||||
|
if result and computation.msg.isCreate:
|
||||||
|
var fork = computation.getFork
|
||||||
|
let contractFailed = not computation.writeContract(fork)
|
||||||
|
result = not(contractFailed and fork == FkHomestead)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
snapshot.commit()
|
||||||
|
else:
|
||||||
|
snapshot.revert(true)
|
||||||
|
|
||||||
|
proc addChildComputation(computation: var BaseComputation, child: BaseComputation) =
|
||||||
if child.isError:
|
if child.isError:
|
||||||
if child.msg.isCreate:
|
if child.msg.isCreate:
|
||||||
computation.returnData = child.output
|
computation.returnData = child.output
|
||||||
|
@ -222,32 +219,10 @@ proc addChildComputation(fork: Fork, computation: var BaseComputation, child: Ba
|
||||||
computation.logEntries.add child.logEntries
|
computation.logEntries.add child.logEntries
|
||||||
computation.children.add(child)
|
computation.children.add(child)
|
||||||
|
|
||||||
proc getFork*(computation: BaseComputation): Fork =
|
|
||||||
result =
|
|
||||||
if computation.forkOverride.isSome:
|
|
||||||
computation.forkOverride.get
|
|
||||||
else:
|
|
||||||
computation.vmState.blockNumber.toFork
|
|
||||||
|
|
||||||
proc applyChildComputation*(parentComp, childComp: var BaseComputation, opCode: static[Op]) =
|
proc applyChildComputation*(parentComp, childComp: var BaseComputation, opCode: static[Op]) =
|
||||||
## Apply the vm message childMsg as a child computation.
|
## Apply the vm message childMsg as a child computation.
|
||||||
let fork = parentComp.getFork
|
discard childComp.applyMessage(opCode)
|
||||||
|
parentComp.addChildComputation(childComp)
|
||||||
var snapshot = parentComp.snapshot()
|
|
||||||
defer: snapshot.dispose()
|
|
||||||
var contractOK = true
|
|
||||||
|
|
||||||
if applyMessage(childComp, opCode):
|
|
||||||
if childComp.msg.isCreate:
|
|
||||||
contractOK = childComp.writeContract(fork)
|
|
||||||
|
|
||||||
if not contractOK and fork == FkHomestead:
|
|
||||||
# consume all gas
|
|
||||||
snapshot.revert(true)
|
|
||||||
else:
|
|
||||||
snapshot.commit()
|
|
||||||
|
|
||||||
fork.addChildComputation(parentComp, childComp)
|
|
||||||
|
|
||||||
proc registerAccountForDeletion*(c: var BaseComputation, beneficiary: EthAddress) =
|
proc registerAccountForDeletion*(c: var BaseComputation, beneficiary: EthAddress) =
|
||||||
if c.msg.storageAddress in c.accountsToDelete:
|
if c.msg.storageAddress in c.accountsToDelete:
|
||||||
|
@ -261,14 +236,10 @@ proc addLogEntry*(c: var BaseComputation, log: Log) {.inline.} =
|
||||||
|
|
||||||
# many methods are basically TODO, but they still return valid values
|
# many methods are basically TODO, but they still return valid values
|
||||||
# in order to test some existing code
|
# in order to test some existing code
|
||||||
func getAccountsForDeletion*(c: BaseComputation): seq[EthAddress] =
|
iterator accountsForDeletion*(c: BaseComputation): EthAddress =
|
||||||
# TODO
|
if not c.isError:
|
||||||
if c.isError:
|
|
||||||
result = @[]
|
|
||||||
else:
|
|
||||||
result = @[]
|
|
||||||
for account in c.accountsToDelete.keys:
|
for account in c.accountsToDelete.keys:
|
||||||
result.add(account)
|
yield account
|
||||||
|
|
||||||
proc getGasRefund*(c: BaseComputation): GasInt =
|
proc getGasRefund*(c: BaseComputation): GasInt =
|
||||||
if c.isError:
|
if c.isError:
|
||||||
|
@ -302,3 +273,5 @@ proc traceError*(c: BaseComputation) =
|
||||||
|
|
||||||
proc prepareTracer*(c: BaseComputation) =
|
proc prepareTracer*(c: BaseComputation) =
|
||||||
c.vmState.tracer.prepare(c.msg.depth)
|
c.vmState.tracer.prepare(c.msg.depth)
|
||||||
|
|
||||||
|
include interpreter_dispatch
|
||||||
|
|
|
@ -10,11 +10,11 @@ import
|
||||||
./interpreter/vm_forks
|
./interpreter/vm_forks
|
||||||
|
|
||||||
import # Used in vm_types. Beware of recursive dependencies
|
import # Used in vm_types. Beware of recursive dependencies
|
||||||
./code_stream, ./computation, ./stack, ./message, interpreter_dispatch
|
./code_stream, ./computation, ./stack, ./message
|
||||||
|
|
||||||
export
|
export
|
||||||
opcode_values, gas_meter,
|
opcode_values, gas_meter,
|
||||||
vm_forks
|
vm_forks
|
||||||
|
|
||||||
export
|
export
|
||||||
code_stream, computation, stack, message, interpreter_dispatch
|
code_stream, computation, stack, message
|
||||||
|
|
|
@ -572,7 +572,11 @@ proc setupCreate(computation: var BaseComputation, memPos, len: int, value: Uint
|
||||||
)
|
)
|
||||||
|
|
||||||
childMsg.sender = computation.msg.storageAddress
|
childMsg.sender = computation.msg.storageAddress
|
||||||
result = generateChildComputation(computation.getFork, computation, childMsg)
|
result = newBaseComputation(
|
||||||
|
computation.vmState,
|
||||||
|
computation.vmState.blockNumber,
|
||||||
|
childMsg,
|
||||||
|
some(computation.getFork))
|
||||||
|
|
||||||
op create, inline = false, value, startPosition, size:
|
op create, inline = false, value, startPosition, size:
|
||||||
## 0xf0, Create a new account with associated code.
|
## 0xf0, Create a new account with associated code.
|
||||||
|
@ -739,7 +743,12 @@ template genCall(callName: untyped, opCode: Op): untyped =
|
||||||
when opCode == CallCode:
|
when opCode == CallCode:
|
||||||
childMsg.storageAddress = computation.msg.storageAddress
|
childMsg.storageAddress = computation.msg.storageAddress
|
||||||
|
|
||||||
var childComp = generateChildComputation(computation.getFork, computation, childMsg)
|
var childComp = newBaseComputation(
|
||||||
|
computation.vmState,
|
||||||
|
computation.vmState.blockNumber,
|
||||||
|
childMsg,
|
||||||
|
some(computation.getFork))
|
||||||
|
|
||||||
result = (childComp, memOutPos, memOutLen)
|
result = (childComp, memOutPos, memOutLen)
|
||||||
|
|
||||||
op callName, inline = false:
|
op callName, inline = false:
|
||||||
|
|
|
@ -11,13 +11,13 @@ import
|
||||||
./interpreter/[opcode_values, opcodes_impl, vm_forks, gas_costs, gas_meter, utils/macros_gen_opcodes],
|
./interpreter/[opcode_values, opcodes_impl, vm_forks, gas_costs, gas_meter, utils/macros_gen_opcodes],
|
||||||
./code_stream,
|
./code_stream,
|
||||||
../vm_types, ../errors, precompiles,
|
../vm_types, ../errors, precompiles,
|
||||||
./stack, ./computation, terminal # Those are only needed for logging
|
./stack, terminal # Those are only needed for logging
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
topics = "vm opcode"
|
topics = "vm opcode"
|
||||||
|
|
||||||
func invalidInstruction*(computation: var BaseComputation) {.inline.} =
|
func invalidInstruction*(computation: var BaseComputation) {.inline.} =
|
||||||
raise newException(ValueError, "Invalid instruction, received an opcode not implemented in the current fork.")
|
raise newException(InvalidInstruction, "Invalid instruction, received an opcode not implemented in the current fork.")
|
||||||
|
|
||||||
let FrontierOpDispatch {.compileTime.}: array[Op, NimNode] = block:
|
let FrontierOpDispatch {.compileTime.}: array[Op, NimNode] = block:
|
||||||
fill_enum_table_holes(Op, newIdentNode("invalidInstruction")):
|
fill_enum_table_holes(Op, newIdentNode("invalidInstruction")):
|
||||||
|
@ -256,24 +256,14 @@ proc homesteadVM(computation: var BaseComputation) =
|
||||||
if not computation.execPrecompiles:
|
if not computation.execPrecompiles:
|
||||||
genHomesteadDispatch(computation)
|
genHomesteadDispatch(computation)
|
||||||
|
|
||||||
proc updateOpcodeExec*(computation: var BaseComputation, fork: Fork) =
|
proc executeOpcodes(computation: var BaseComputation) =
|
||||||
|
# TODO: Optimise getting fork and updating opCodeExec only when necessary
|
||||||
|
let fork = computation.getFork
|
||||||
|
|
||||||
case fork
|
case fork
|
||||||
of FkFrontier..FkThawing:
|
of FkFrontier..FkThawing:
|
||||||
computation.opCodeExec = frontierVM
|
|
||||||
computation.frontierVM()
|
computation.frontierVM()
|
||||||
of FkHomestead..FkSpurious:
|
of FkHomestead..FkSpurious:
|
||||||
computation.opCodeExec = homesteadVM
|
|
||||||
computation.homesteadVM()
|
computation.homesteadVM()
|
||||||
else:
|
else:
|
||||||
raise newException(VMError, "Unknown or not implemented fork: " & $fork)
|
raise newException(VMError, "Unknown or not implemented fork: " & $fork)
|
||||||
|
|
||||||
proc executeOpcodes*(computation: var BaseComputation) =
|
|
||||||
# TODO: Optimise getting fork and updating opCodeExec only when necessary
|
|
||||||
let fork = computation.getFork
|
|
||||||
try:
|
|
||||||
computation.updateOpcodeExec(fork)
|
|
||||||
except VMError:
|
|
||||||
computation.error = Error(info: getCurrentExceptionMsg())
|
|
||||||
debug "VM Error executeOpcodes() failed", error = getCurrentExceptionMsg()
|
|
||||||
except EVMError:
|
|
||||||
debug "EVM Error executeOpcodes() failed", error = getCurrentExceptionMsg()
|
|
||||||
|
|
|
@ -64,28 +64,18 @@ proc setupComputation*(vmState: BaseVMState, tx: Transaction, sender, recipient:
|
||||||
doAssert result.isOriginComputation
|
doAssert result.isOriginComputation
|
||||||
|
|
||||||
proc execComputation*(computation: var BaseComputation): bool =
|
proc execComputation*(computation: var BaseComputation): bool =
|
||||||
var snapshot = computation.snapshot()
|
if computation.msg.isCreate:
|
||||||
defer: snapshot.dispose()
|
result = computation.applyMessage(Create)
|
||||||
|
else:
|
||||||
|
result = computation.applyMessage(Call)
|
||||||
|
|
||||||
computation.vmState.mutateStateDB:
|
computation.vmState.mutateStateDB:
|
||||||
db.subBalance(computation.msg.origin, computation.msg.value)
|
for deletedAccount in computation.accountsForDeletion:
|
||||||
db.addBalance(computation.msg.storageAddress, computation.msg.value)
|
db.deleteAccount deletedAccount
|
||||||
|
|
||||||
try:
|
|
||||||
computation.executeOpcodes()
|
|
||||||
computation.vmState.mutateStateDB:
|
|
||||||
for deletedAccount in computation.getAccountsForDeletion:
|
|
||||||
db.deleteAccount deletedAccount
|
|
||||||
result = not computation.isError
|
|
||||||
except ValueError:
|
|
||||||
result = false
|
|
||||||
debug "execComputation() error", msg = getCurrentExceptionMsg()
|
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
snapshot.commit()
|
|
||||||
computation.vmState.addLogs(computation.logEntries)
|
computation.vmState.addLogs(computation.logEntries)
|
||||||
else:
|
else:
|
||||||
snapshot.revert()
|
|
||||||
if computation.tracingEnabled: computation.traceError()
|
if computation.tracingEnabled: computation.traceError()
|
||||||
|
|
||||||
proc refundGas*(computation: BaseComputation, tx: Transaction, sender: EthAddress): GasInt =
|
proc refundGas*(computation: BaseComputation, tx: Transaction, sender: EthAddress): GasInt =
|
||||||
|
|
|
@ -44,8 +44,6 @@ type
|
||||||
accounts*: HashSet[EthAddress]
|
accounts*: HashSet[EthAddress]
|
||||||
storageKeys*: seq[HashSet[Uint256]]
|
storageKeys*: seq[HashSet[Uint256]]
|
||||||
|
|
||||||
OpcodeExecutor* = proc(computation: var BaseComputation)
|
|
||||||
|
|
||||||
BaseComputation* = ref object of RootObj
|
BaseComputation* = ref object of RootObj
|
||||||
# The execution computation
|
# The execution computation
|
||||||
vmState*: BaseVMState
|
vmState*: BaseVMState
|
||||||
|
@ -62,7 +60,6 @@ type
|
||||||
accountsToDelete*: Table[EthAddress, EthAddress]
|
accountsToDelete*: Table[EthAddress, EthAddress]
|
||||||
opcodes*: Table[Op, proc(computation: var BaseComputation){.nimcall.}]
|
opcodes*: Table[Op, proc(computation: var BaseComputation){.nimcall.}]
|
||||||
gasCosts*: GasCosts # TODO - will be hidden at a lower layer
|
gasCosts*: GasCosts # TODO - will be hidden at a lower layer
|
||||||
opCodeExec*: OpcodeExecutor
|
|
||||||
forkOverride*: Option[Fork]
|
forkOverride*: Option[Fork]
|
||||||
logEntries*: seq[Log]
|
logEntries*: seq[Log]
|
||||||
|
|
||||||
|
@ -71,13 +68,6 @@ type
|
||||||
burnsGas*: bool
|
burnsGas*: bool
|
||||||
erasesReturnData*: bool
|
erasesReturnData*: bool
|
||||||
|
|
||||||
Opcode* = ref object of RootObj
|
|
||||||
# TODO can't use a stack-allocated object because
|
|
||||||
# "BaseComputation is not a concrete type"
|
|
||||||
# TODO: We can probably remove this.
|
|
||||||
kind*: Op
|
|
||||||
runLogic*: proc(computation: var BaseComputation)
|
|
||||||
|
|
||||||
GasMeter* = object
|
GasMeter* = object
|
||||||
gasRefunded*: GasInt
|
gasRefunded*: GasInt
|
||||||
startGas*: GasInt
|
startGas*: GasInt
|
||||||
|
|
|
@ -7,13 +7,9 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
unittest, strformat, strutils, sequtils, tables, json, ospaths, times,
|
unittest, strformat, strutils, sequtils, tables, json, ospaths, times,
|
||||||
byteutils, ranges/typedranges,
|
byteutils, ranges/typedranges, eth/[rlp, common], eth/trie/db,
|
||||||
eth/[rlp, common], eth/trie/db,
|
./test_helpers, ../nimbus/vm/interpreter,
|
||||||
./test_helpers,
|
../nimbus/[constants, errors, vm_state, vm_types, utils],
|
||||||
../nimbus/[constants, errors],
|
|
||||||
../nimbus/[vm_state, vm_types],
|
|
||||||
../nimbus/utils,
|
|
||||||
../nimbus/vm/interpreter,
|
|
||||||
../nimbus/db/[db_chain, state_db]
|
../nimbus/db/[db_chain, state_db]
|
||||||
|
|
||||||
proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus)
|
proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus)
|
||||||
|
@ -60,7 +56,10 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
||||||
createAddress = toAddress))
|
createAddress = toAddress))
|
||||||
|
|
||||||
var computation = newBaseComputation(vmState, header.blockNumber, message)
|
var computation = newBaseComputation(vmState, header.blockNumber, message)
|
||||||
computation.executeOpcodes()
|
try:
|
||||||
|
computation.executeOpcodes()
|
||||||
|
except VMError:
|
||||||
|
computation.error = Error(info: getCurrentExceptionMsg())
|
||||||
|
|
||||||
if not fixture{"post"}.isNil:
|
if not fixture{"post"}.isNil:
|
||||||
# Success checks
|
# Success checks
|
||||||
|
@ -92,7 +91,7 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
||||||
if not fixture{"post"}.isNil:
|
if not fixture{"post"}.isNil:
|
||||||
verifyStateDb(fixture{"post"}, computation.vmState.readOnlyStateDB)
|
verifyStateDb(fixture{"post"}, computation.vmState.readOnlyStateDB)
|
||||||
else:
|
else:
|
||||||
# Error checks
|
# Error checks
|
||||||
check(computation.isError)
|
check(computation.isError)
|
||||||
# TODO postState = fixture{"pre"}
|
if not fixture{"pre"}.isNil:
|
||||||
|
verifyStateDb(fixture{"pre"}, computation.vmState.readOnlyStateDB)
|
||||||
|
|
Loading…
Reference in New Issue