From 4549331f4b199696b3739ff8b6561229614cf132 Mon Sep 17 00:00:00 2001 From: andri lim Date: Mon, 11 Mar 2019 22:32:25 +0700 Subject: [PATCH] fix block 1155095 problem --- nimbus/p2p/executor.nim | 17 ++++++++++++++++- nimbus/vm_state_transactions.nim | 5 ++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/nimbus/p2p/executor.nim b/nimbus/p2p/executor.nim index 0cfce2df0..1e86e646f 100644 --- a/nimbus/p2p/executor.nim +++ b/nimbus/p2p/executor.nim @@ -12,6 +12,12 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta trace "Sender", sender trace "txHash", rlpHash = tx.rlpHash + let fork = + if forkOverride.isSome: + forkOverride.get + else: + vmState.blockNumber.toFork + let upfrontGasCost = tx.gasLimit.u256 * tx.gasPrice.u256 var balance = vmState.readOnlyStateDb().getBalance(sender) if balance < upfrontGasCost: @@ -21,14 +27,23 @@ proc processTransaction*(tx: Transaction, sender: EthAddress, vmState: BaseVMSta db.incNonce(sender) db.subBalance(sender, upfrontGasCost) + var snapshot = vmState.snapshot() var computation = setupComputation(vmState, tx, sender, forkOverride) + var contractOK = true result = tx.gasLimit if execComputation(computation): if tx.isContractCreation: - computation.writeContract() + contractOK = computation.writeContract() result = computation.refundGas(tx, sender) + if not contractOK and fork == FkHomestead: + snapshot.revert() + # consume all gas + result = tx.gasLimit + else: + snapshot.commit() + type # TODO: these types need to be removed # once eth/bloom and eth/common sync'ed diff --git a/nimbus/vm_state_transactions.nim b/nimbus/vm_state_transactions.nim index 3606a6872..91a96991e 100644 --- a/nimbus/vm_state_transactions.nim +++ b/nimbus/vm_state_transactions.nim @@ -99,20 +99,23 @@ proc refundGas*(computation: BaseComputation, tx: Transaction, sender: EthAddres result = gasUsed - gasRefund -proc writeContract*(computation: var BaseComputation) = +proc writeContract*(computation: var BaseComputation): bool = let codeCost = computation.gasCosts[Create].m_handler(0, 0, computation.output.len) let contractAddress = computation.msg.storageAddress + result = true if not computation.isSuicided(contractAddress): # make changes only if it not selfdestructed if computation.gasMeter.gasRemaining >= codeCost: computation.gasMeter.consumeGas(codeCost, reason = "Write contract code for CREATE") computation.vmState.mutateStateDB: db.setCode(contractAddress, computation.output.toRange) + result = true else: # XXX: Homestead behaves differently; reverts state on gas failure # https://github.com/ethereum/py-evm/blob/master/eth/vm/forks/homestead/computation.py computation.vmState.mutateStateDB: db.setCode(contractAddress, ByteRange()) + result = false #[ method executeTransaction(vmState: BaseVMState, transaction: Transaction): (BaseComputation, BlockHeader) {.base.}=