From 0f8affb7c9bb3851ca3b3c3134a7ec67649db2b7 Mon Sep 17 00:00:00 2001 From: andri lim Date: Mon, 1 Apr 2019 08:54:02 +0700 Subject: [PATCH] remove explicit return value from VM --- nimbus/vm/computation.nim | 54 ++++++++++++++++---------------- nimbus/vm_state_transactions.nim | 5 +-- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/nimbus/vm/computation.nim b/nimbus/vm/computation.nim index e8ce9fc5c..9905ed7c9 100644 --- a/nimbus/vm/computation.nim +++ b/nimbus/vm/computation.nim @@ -111,6 +111,14 @@ proc commit*(comp: BaseComputation) = proc dispose*(comp: BaseComputation) {.inline.} = comp.dbsnapshot.transaction.dispose() +proc rollback*(comp: BaseComputation) = + comp.dbsnapshot.transaction.rollback() + comp.vmState.accountDb.rootHash = comp.dbsnapshot.intermediateRoot + comp.vmState.blockHeader.stateRoot = comp.dbsnapshot.intermediateRoot + +proc setError*(comp: BaseComputation, msg: string, burnsGas = false) {.inline.} = + comp.error = Error(info: msg, burnsGas: burnsGas) + proc getFork*(computation: BaseComputation): Fork = result = if computation.forkOverride.isSome: @@ -142,34 +150,33 @@ proc writeContract*(computation: var BaseComputation, fork: Fork): bool = if fork < FkHomestead: computation.output = @[] result = false -proc transferBalance(computation: var BaseComputation, opCode: static[Op]): bool = +proc transferBalance(computation: var BaseComputation, opCode: static[Op]) = if computation.msg.depth > MaxCallDepth: - debug "Stack depth limit reached", depth=computation.msg.depth - return false + computation.setError(&"Stack depth limit reached depth={computation.msg.depth}") + return let senderBalance = computation.vmState.readOnlyStateDb(). getBalance(computation.msg.sender) if senderBalance < computation.msg.value: - debug "insufficient funds", available=senderBalance, needed=computation.msg.value - return false + computation.setError(&"insufficient funds available={senderBalance}, needed={computation.msg.value}") + return 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 = +proc applyMessage*(computation: var BaseComputation, opCode: static[Op]) = computation.snapshot() defer: computation.dispose() when opCode in {CallCode, Call, Create}: - if not computation.transferBalance(opCode): - computation.revert() + computation.transferBalance(opCode) + if computation.isError(): + computation.rollback() return if computation.gasMeter.gasRemaining < 0: @@ -178,27 +185,20 @@ proc applyMessage*(computation: var BaseComputation, opCode: static[Op]): bool = 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 + except: + let msg = getCurrentExceptionMsg() + computation.setError(&"applyMessage Error msg={msg}, depth={computation.msg.depth}", true) - if result and computation.msg.isCreate: - var fork = computation.getFork + if computation.isSuccess and computation.msg.isCreate: + let fork = computation.getFork let contractFailed = not computation.writeContract(fork) - result = not(contractFailed and fork == FkHomestead) + if contractFailed and fork == FkHomestead: + computation.setError(&"writeContract failed, depth={computation.msg.depth}", true) - if result: + if computation.isSuccess: computation.commit() else: - computation.revert(true) + computation.rollback() proc addChildComputation(computation: var BaseComputation, child: BaseComputation) = if child.isError: @@ -220,7 +220,7 @@ proc addChildComputation(computation: var BaseComputation, child: BaseComputatio proc applyChildComputation*(parentComp, childComp: var BaseComputation, opCode: static[Op]) = ## Apply the vm message childMsg as a child computation. - discard childComp.applyMessage(opCode) + childComp.applyMessage(opCode) parentComp.addChildComputation(childComp) proc registerAccountForDeletion*(c: var BaseComputation, beneficiary: EthAddress) = diff --git a/nimbus/vm_state_transactions.nim b/nimbus/vm_state_transactions.nim index ba8bfff1f..790449a29 100644 --- a/nimbus/vm_state_transactions.nim +++ b/nimbus/vm_state_transactions.nim @@ -65,9 +65,9 @@ proc setupComputation*(vmState: BaseVMState, tx: Transaction, sender, recipient: proc execComputation*(computation: var BaseComputation): bool = if computation.msg.isCreate: - result = computation.applyMessage(Create) + computation.applyMessage(Create) else: - result = computation.applyMessage(Call) + computation.applyMessage(Call) computation.vmState.mutateStateDB: var suicidedCount = 0 @@ -79,6 +79,7 @@ proc execComputation*(computation: var BaseComputation): bool = const RefundSelfDestruct = 24_000 computation.gasMeter.refundGas(RefundSelfDestruct * suicidedCount) + result = computation.isSuccess if result: computation.vmState.addLogs(computation.logEntries) else: