move exception handler deeper in the EVM
This commit is contained in:
parent
07ac4620d9
commit
4c0ba876ef
|
@ -167,6 +167,24 @@ proc transferBalance(computation: BaseComputation, opCode: static[Op]) =
|
|||
db.subBalance(computation.msg.sender, computation.msg.value)
|
||||
db.addBalance(computation.msg.storageAddress, computation.msg.value)
|
||||
|
||||
template continuation*(comp: BaseComputation, body: untyped) =
|
||||
var tmpNext = comp.nextProc
|
||||
comp.nextProc = proc() =
|
||||
body
|
||||
tmpNext()
|
||||
|
||||
proc postExecuteVM(computation: BaseComputation) =
|
||||
if computation.isSuccess and computation.msg.isCreate:
|
||||
let fork = computation.getFork
|
||||
let contractFailed = not computation.writeContract(fork)
|
||||
if contractFailed and fork == FkHomestead:
|
||||
computation.setError(&"writeContract failed, depth={computation.msg.depth}", true)
|
||||
|
||||
if computation.isSuccess:
|
||||
computation.commit()
|
||||
else:
|
||||
computation.rollback()
|
||||
|
||||
proc executeOpcodes*(computation: BaseComputation) {.gcsafe.}
|
||||
|
||||
proc applyMessage*(computation: BaseComputation, opCode: static[Op]) =
|
||||
|
@ -182,25 +200,9 @@ proc applyMessage*(computation: BaseComputation, opCode: static[Op]) =
|
|||
if computation.gasMeter.gasRemaining < 0:
|
||||
computation.commit()
|
||||
return
|
||||
|
||||
let fork = computation.getFork
|
||||
|
||||
try:
|
||||
if not computation.execPrecompiles(fork):
|
||||
executeOpcodes(computation)
|
||||
except:
|
||||
let msg = getCurrentExceptionMsg()
|
||||
computation.setError(&"applyMessage Error msg={msg}, depth={computation.msg.depth}", true)
|
||||
|
||||
if computation.isSuccess and computation.msg.isCreate:
|
||||
let contractFailed = not computation.writeContract(fork)
|
||||
if contractFailed and fork == FkHomestead:
|
||||
computation.setError(&"writeContract failed, depth={computation.msg.depth}", true)
|
||||
|
||||
if computation.isSuccess:
|
||||
computation.commit()
|
||||
else:
|
||||
computation.rollback()
|
||||
executeOpcodes(computation)
|
||||
postExecuteVM(computation)
|
||||
|
||||
proc addChildComputation*(computation: BaseComputation, child: BaseComputation) =
|
||||
if child.isError:
|
||||
|
|
|
@ -231,14 +231,23 @@ proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNo
|
|||
|
||||
# Wrap the case statement in while true + computed goto
|
||||
result = quote do:
|
||||
if `computation`.tracingEnabled:
|
||||
`computation`.prepareTracer()
|
||||
`computation`.instr = `computation`.code.next()
|
||||
while true:
|
||||
{.computedGoto.}
|
||||
# TODO lots of macro magic here to unravel, with chronicles...
|
||||
# `computation`.logger.log($`computation`.stack & "\n\n", fgGreen)
|
||||
`result`
|
||||
try:
|
||||
let fork = `computation`.getFork
|
||||
if `computation`.execPrecompiles(fork):
|
||||
return
|
||||
|
||||
if `computation`.tracingEnabled:
|
||||
`computation`.prepareTracer()
|
||||
`computation`.instr = `computation`.code.next()
|
||||
while true:
|
||||
{.computedGoto.}
|
||||
# TODO lots of macro magic here to unravel, with chronicles...
|
||||
# `computation`.logger.log($`computation`.stack & "\n\n", fgGreen)
|
||||
`result`
|
||||
except:
|
||||
let msg = getCurrentExceptionMsg()
|
||||
let errorMsg = "Opcode Dispatch Error msg=" & msg & ", depth=" & $computation.msg.depth
|
||||
`computation`.setError(errorMsg, true)
|
||||
|
||||
macro genFrontierDispatch(computation: BaseComputation): untyped =
|
||||
result = opTableToCaseStmt(FrontierOpDispatch, computation)
|
||||
|
|
|
@ -67,6 +67,7 @@ type
|
|||
dbsnapshot*: Snapshot
|
||||
instr*: Op
|
||||
opIndex*: int
|
||||
nextProc*: proc()
|
||||
|
||||
Error* = ref object
|
||||
info*: string
|
||||
|
|
|
@ -56,11 +56,8 @@ proc testFixture(fixtures: JsonNode, testStatusIMPL: var TestStatus) =
|
|||
createAddress = toAddress))
|
||||
|
||||
var computation = newBaseComputation(vmState, header.blockNumber, message)
|
||||
try:
|
||||
computation.executeOpcodes()
|
||||
except VMError:
|
||||
computation.error = Error(info: getCurrentExceptionMsg())
|
||||
|
||||
computation.executeOpcodes()
|
||||
|
||||
if not fixture{"post"}.isNil:
|
||||
# Success checks
|
||||
check(not computation.isError)
|
||||
|
|
Loading…
Reference in New Issue