merged contents of computations.nim int interpreter_dispatch.nim

why:
  only two public functions left: executeOpcodes() and execCallOrCreate()
  where the former one was originally in interpreter_dispatch.nim and
  the latter one calls this one.

  improves maintainability
This commit is contained in:
Jordan Hrycaj 2021-04-26 16:16:38 +01:00 committed by zah
parent 49afac46b7
commit a86308c079
2 changed files with 150 additions and 143 deletions

View File

@ -5,144 +5,8 @@
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
when defined(evmc_enabled):
{.fatal: "Flags \"evmc_enabled\" and \"vm2_enabled\" are mutually exclusive"}
import
chronicles, strformat, macros, options,
sets, eth/[common, keys],
../constants,
./compu_helper,
./interpreter/forks_list,
./interpreter_dispatch,
./message, ./types, ./state,
../db/accounts_cache,
./precompiles
./interpreter_dispatch
logScope:
topics = "vm computation"
const
ripemdAddr = block:
proc initAddress(x: int): EthAddress {.compileTime.} =
result[19] = x.byte
initAddress(3)
proc beforeExecCall(c: Computation) =
c.snapshot()
if c.msg.kind == evmcCall:
c.vmState.mutateStateDb:
db.subBalance(c.msg.sender, c.msg.value)
db.addBalance(c.msg.contractAddress, c.msg.value)
proc afterExecCall(c: Computation) =
## Collect all of the accounts that *may* need to be deleted based on EIP161
## https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md
## also see: https://github.com/ethereum/EIPs/issues/716
if c.isError or c.fork >= FKByzantium:
if c.msg.contractAddress == ripemdAddr:
# Special case to account for geth+parity bug
c.vmState.touchedAccounts.incl c.msg.contractAddress
if c.isSuccess:
c.commit()
c.touchedAccounts.incl c.msg.contractAddress
else:
c.rollback()
proc beforeExecCreate(c: Computation): bool =
c.vmState.mutateStateDB:
db.incNonce(c.msg.sender)
# We add this to the access list _before_ taking a snapshot.
# Even if the creation fails, the access-list change should not be rolled back
# EIP2929
if c.fork >= FkBerlin:
db.accessList(c.msg.contractAddress)
c.snapshot()
if c.vmState.readOnlyStateDb().hasCodeOrNonce(c.msg.contractAddress):
c.setError("Address collision when creating contract address={c.msg.contractAddress.toHex}", true)
c.rollback()
return true
c.vmState.mutateStateDb:
db.subBalance(c.msg.sender, c.msg.value)
db.addBalance(c.msg.contractAddress, c.msg.value)
db.clearStorage(c.msg.contractAddress)
if c.fork >= FkSpurious:
# EIP161 nonce incrementation
db.incNonce(c.msg.contractAddress)
return false
proc afterExecCreate(c: Computation) =
if c.isSuccess:
let fork = c.fork
let contractFailed = not c.writeContract(fork)
if contractFailed and fork >= FkHomestead:
c.setError(&"writeContract failed, depth={c.msg.depth}", true)
if c.isSuccess:
c.commit()
else:
c.rollback()
proc beforeExec(c: Computation): bool =
if not c.msg.isCreate:
c.beforeExecCall()
false
else:
c.beforeExecCreate()
proc afterExec(c: Computation) =
if not c.msg.isCreate:
c.afterExecCall()
else:
c.afterExecCreate()
proc executeOpcodes*(c: Computation) =
let fork = c.fork
block:
if not c.continuation.isNil:
c.continuation = nil
elif c.execPrecompiles(fork):
break
try:
c.selectVM(fork)
except CatchableError as e:
c.setError(
&"Opcode Dispatch Error msg={e.msg}, depth={c.msg.depth}", true)
if c.isError() and c.continuation.isNil:
if c.tracingEnabled: c.traceError()
debug "executeOpcodes error", msg=c.error.info
proc execCallOrCreate*(cParam: Computation) =
var (c, before) = (cParam, true)
defer:
while not c.isNil:
c.dispose()
c = c.parent
# No actual recursion, but simulate recursion including before/after/dispose.
while true:
while true:
if before and c.beforeExec():
break
c.executeOpcodes()
if c.continuation.isNil:
c.afterExec()
break
(before, c.child, c, c.parent) = (true, nil.Computation, c.child, c)
if c.parent.isNil:
break
c.dispose()
(before, c.parent, c) = (false, nil.Computation, c.parent)
(c.continuation)()
export
interpreter_dispatch

View File

@ -9,25 +9,42 @@
# according to those terms.
const
# help with low memory when compiling
# help with low memory when compiling selectVM() function
lowmem {.intdefine.}: int = 0
lowMemoryCompileTime {.used.} = lowmem > 0
import
../constants,
../db/accounts_cache,
./code_stream,
./compu_helper,
./interpreter/op_dispatcher,
./message,
./precompiles,
./state,
./types,
chronicles
chronicles,
eth/[common, keys],
macros,
options,
sets,
stew/byteutils,
strformat
logScope:
topics = "vm opcode"
const
ripemdAddr = block:
proc initAddress(x: int): EthAddress {.compileTime.} =
result[19] = x.byte
initAddress(3)
# ------------------------------------------------------------------------------
# Public functions
# Private functions
# ------------------------------------------------------------------------------
proc selectVM*(c: Computation, fork: Fork) {.gcsafe.} =
proc selectVM(c: Computation, fork: Fork) {.gcsafe.} =
## Op code execution handler main loop.
var desc: Vm2Ctx
desc.cpt = c
@ -87,6 +104,132 @@ proc selectVM*(c: Computation, fork: Fork) {.gcsafe.} =
genLowMemDispatcher(fork, c.instr, desc)
proc beforeExecCall(c: Computation) =
c.snapshot()
if c.msg.kind == evmcCall:
c.vmState.mutateStateDb:
db.subBalance(c.msg.sender, c.msg.value)
db.addBalance(c.msg.contractAddress, c.msg.value)
proc afterExecCall(c: Computation) =
## Collect all of the accounts that *may* need to be deleted based on EIP161
## https://github.com/ethereum/EIPs/blob/master/EIPS/eip-161.md
## also see: https://github.com/ethereum/EIPs/issues/716
if c.isError or c.fork >= FKByzantium:
if c.msg.contractAddress == ripemdAddr:
# Special case to account for geth+parity bug
c.vmState.touchedAccounts.incl c.msg.contractAddress
if c.isSuccess:
c.commit()
c.touchedAccounts.incl c.msg.contractAddress
else:
c.rollback()
proc beforeExecCreate(c: Computation): bool =
c.vmState.mutateStateDB:
db.incNonce(c.msg.sender)
# We add this to the access list _before_ taking a snapshot.
# Even if the creation fails, the access-list change should not be rolled
# back EIP2929
if c.fork >= FkBerlin:
db.accessList(c.msg.contractAddress)
c.snapshot()
if c.vmState.readOnlyStateDb().hasCodeOrNonce(c.msg.contractAddress):
var blurb =c.msg.contractAddress.toHex
c.setError("Address collision when creating contract address={blurb}", true)
c.rollback()
return true
c.vmState.mutateStateDb:
db.subBalance(c.msg.sender, c.msg.value)
db.addBalance(c.msg.contractAddress, c.msg.value)
db.clearStorage(c.msg.contractAddress)
if c.fork >= FkSpurious:
# EIP161 nonce incrementation
db.incNonce(c.msg.contractAddress)
return false
proc afterExecCreate(c: Computation) =
if c.isSuccess:
let fork = c.fork
let contractFailed = not c.writeContract(fork)
if contractFailed and fork >= FkHomestead:
c.setError(&"writeContract failed, depth={c.msg.depth}", true)
if c.isSuccess:
c.commit()
else:
c.rollback()
proc beforeExec(c: Computation): bool =
if not c.msg.isCreate:
c.beforeExecCall()
false
else:
c.beforeExecCreate()
proc afterExec(c: Computation) =
if not c.msg.isCreate:
c.afterExecCall()
else:
c.afterExecCreate()
# ------------------------------------------------------------------------------
# Public functions
# ------------------------------------------------------------------------------
proc executeOpcodes*(c: Computation) =
let fork = c.fork
block:
if not c.continuation.isNil:
c.continuation = nil
elif c.execPrecompiles(fork):
break
try:
c.selectVM(fork)
except CatchableError as e:
c.setError(
&"Opcode Dispatch Error msg={e.msg}, depth={c.msg.depth}", true)
if c.isError() and c.continuation.isNil:
if c.tracingEnabled: c.traceError()
debug "executeOpcodes error", msg=c.error.info
proc execCallOrCreate*(cParam: Computation) =
var (c, before) = (cParam, true)
defer:
while not c.isNil:
c.dispose()
c = c.parent
# No actual recursion, but simulate recursion including before/after/dispose.
while true:
while true:
if before and c.beforeExec():
break
c.executeOpcodes()
if c.continuation.isNil:
c.afterExec()
break
(before, c.child, c, c.parent) = (true, nil.Computation, c.child, c)
if c.parent.isNil:
break
c.dispose()
(before, c.parent, c) = (false, nil.Computation, c.parent)
(c.continuation)()
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------