From f5e54b8d4f4ba7ebd282005123f17e06c7c85f0d Mon Sep 17 00:00:00 2001 From: andri lim Date: Sat, 23 Feb 2019 20:08:59 +0700 Subject: [PATCH] fix self destruct problem --- nimbus/vm/transaction_tracer.nim | 12 ++++++------ nimbus/vm_state_transactions.nim | 24 ++++++++++++++---------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/nimbus/vm/transaction_tracer.nim b/nimbus/vm/transaction_tracer.nim index f6a053d7c..0534f48f4 100644 --- a/nimbus/vm/transaction_tracer.nim +++ b/nimbus/vm/transaction_tracer.nim @@ -69,18 +69,18 @@ proc traceOpCodeStarted*(tracer: var TransactionTracer, c: BaseComputation, op: if TracerFlags.EnableAccount in tracer.flags: case op of Call, CallCode, DelegateCall, StaticCall: - assert(c.stack.values.len > 2) - tracer.accounts.incl c.stack[^2, EthAddress] + if c.stack.values.len > 2: + tracer.accounts.incl c.stack[^2, EthAddress] of ExtCodeCopy, ExtCodeSize, Balance, SelfDestruct: - assert(c.stack.values.len > 1) - tracer.accounts.incl c.stack[^1, EthAddress] + if c.stack.values.len > 1: + tracer.accounts.incl c.stack[^1, EthAddress] else: discard if TracerFlags.DisableStorage notin tracer.flags: if op == Sstore: - assert(c.stack.values.len > 1) - tracer.rememberStorageKey(c.msg.depth, c.stack[^1, Uint256]) + if c.stack.values.len > 1: + tracer.rememberStorageKey(c.msg.depth, c.stack[^1, Uint256]) result = tracer.trace["structLogs"].len - 1 diff --git a/nimbus/vm_state_transactions.nim b/nimbus/vm_state_transactions.nim index a58989d59..db833c80d 100644 --- a/nimbus/vm_state_transactions.nim +++ b/nimbus/vm_state_transactions.nim @@ -80,7 +80,6 @@ proc applyCreateTransaction*(t: Transaction, vmState: BaseVMState, sender: EthAd if execComputation(c): var db = vmState.accountDb - db.addBalance(contractAddress, t.value) # XXX: copy/pasted from GST fixture # TODO: more merging/refactoring/etc @@ -99,15 +98,20 @@ proc applyCreateTransaction*(t: Transaction, vmState: BaseVMState, sender: EthAd # This apparently is not supposed to actually consume the gas, just be able to, # for purposes of accounting. Py-EVM apparently does consume the gas, but it is # not matching observed blockchain balances if consumeGas is called. - if gasRemaining >= codeCost.u256: - db.setCode(contractAddress, c.output.toRange) - else: - # XXX: Homestead behaves differently; reverts state on gas failure - # https://github.com/ethereum/py-evm/blob/master/eth/vm/forks/homestead/computation.py - codeCost = 0 - db.setCode(contractAddress, ByteRange()) - db.addBalance(sender, (t.gasLimit.u256 - gasUsed2 - codeCost.u256)*t.gasPrice.u256) - return (gasUsed2 + codeCost.u256) * t.gasPrice.u256 + + if db.accountExists(contractAddress): + # make changes only if it not selfdestructed + db.addBalance(contractAddress, t.value) + if gasRemaining >= codeCost.u256: + db.setCode(contractAddress, c.output.toRange) + else: + # XXX: Homestead behaves differently; reverts state on gas failure + # https://github.com/ethereum/py-evm/blob/master/eth/vm/forks/homestead/computation.py + codeCost = 0 + db.setCode(contractAddress, ByteRange()) + + db.addBalance(sender, (t.gasLimit.u256 - gasUsed2 - codeCost.u256 + gasRefund) * t.gasPrice.u256) + return (gasUsed2 + codeCost.u256 - gasRefund) * t.gasPrice.u256 else: # FIXME: don't do this revert, but rather only subBalance correctly # the if transactionfailed at end is what is supposed to pick it up