From 99d128ca269b84e8b7a258a7e7d2a26e64d4ec26 Mon Sep 17 00:00:00 2001 From: andri lim Date: Fri, 15 Mar 2019 22:15:40 +0700 Subject: [PATCH] fix CREATE opcode gas cost --- nimbus/vm/computation.nim | 4 ++-- nimbus/vm/interpreter/gas_costs.nim | 19 ++++++++++++++----- nimbus/vm/interpreter/opcodes_impl.nim | 14 +++++++++----- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/nimbus/vm/computation.nim b/nimbus/vm/computation.nim index 2fc69da8a..9b6061bda 100644 --- a/nimbus/vm/computation.nim +++ b/nimbus/vm/computation.nim @@ -175,8 +175,8 @@ proc writeContract*(computation: var BaseComputation, fork: Fork): bool = let storageAddr = computation.msg.storageAddress if computation.isSuicided(storageAddr): return - # tricky gasCost: 1,0,0 -> createCost. 0,0,x -> depositCost - let codeCost = computation.gasCosts[Create].m_handler(0, 0, contractCode.len) + let gasParams = GasParams(kind: Create, cr_memLength: contractCode.len) + let codeCost = computation.gasCosts[Create].c_handler(0.u256, gasParams).gasCost if computation.gasMeter.gasRemaining >= codeCost: computation.gasMeter.consumeGas(codeCost, reason = "Write contract code for CREATE") computation.vmState.mutateStateDb: diff --git a/nimbus/vm/interpreter/gas_costs.nim b/nimbus/vm/interpreter/gas_costs.nim index a621e22ff..b4a78a32d 100644 --- a/nimbus/vm/interpreter/gas_costs.nim +++ b/nimbus/vm/interpreter/gas_costs.nim @@ -72,6 +72,10 @@ type c_memOffset*: Natural c_memLength*: Natural c_opCode*: Op + of Create: + cr_currentMemSize*: Natural + cr_memOffset*: Natural + cr_memLength*: Natural else: discard @@ -169,10 +173,15 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) = if not value.isZero: result += static(FeeSchedule[GasExpByte]) * (1 + log256(value)) - func `prefix gasCreate`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} = - # tricky gasCost: 1,0,0 -> createCost. 0,0,x -> depositCost - result = currentMemSize * static(FeeSchedule[GasCreate]) + - static(FeeSchedule[GasCodeDeposit]) * memLength + func `prefix gasCreate`(value: Uint256, gasParams: GasParams): GasResult {.nimcall.} = + if value.isZero: + result.gasCost = static(FeeSchedule[GasCodeDeposit]) * gasParams.cr_memLength + else: + result.gasCost = static(FeeSchedule[GasCreate]) + + `prefix gasMemoryExpansion`( + gasParams.cr_currentMemSize, + gasParams.cr_memOffset, + gasParams.cr_memLength) func `prefix gasSha3`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} = @@ -509,7 +518,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) = Log4: memExpansion `prefix gasLog4`, # f0s: System operations - Create: memExpansion `prefix gasCreate`, # TODO: Change to dynamic? + Create: complex `prefix gasCreate`, Call: complex `prefix gasCall`, CallCode: complex `prefix gasCall`, Return: memExpansion `prefix gasHalt`, diff --git a/nimbus/vm/interpreter/opcodes_impl.nim b/nimbus/vm/interpreter/opcodes_impl.nim index e00a19ae8..917279dfa 100644 --- a/nimbus/vm/interpreter/opcodes_impl.nim +++ b/nimbus/vm/interpreter/opcodes_impl.nim @@ -506,13 +506,17 @@ genLog() # ########################################## # f0s: System operations. -proc canTransfer(computation: BaseComputation, memPos, len: int, value: Uint256): bool = - # tricky gasCost: 1,0,0 -> createCost. 0,0,x -> depositCost - let gasCost = computation.gasCosts[Create].m_handler(1, 0, 0) - let reason = &"CREATE: GasCreate + {len} * memory expansion" +proc canTransfer(computation: BaseComputation, memPos, memLen: int, value: Uint256): bool = + let gasParams = GasParams(kind: Create, + cr_currentMemSize: computation.memory.len, + cr_memOffset: memPos, + cr_memLength: memLen + ) + let gasCost = computation.gasCosts[Create].c_handler(1.u256, gasParams).gasCost + let reason = &"CREATE: GasCreate + {memLen} * memory expansion" computation.gasMeter.consumeGas(gasCost, reason = reason) - computation.memory.extend(memPos, len) + computation.memory.extend(memPos, memLen) # the sender is childmsg sender, not parent msg sender # perhaps we need to move this code somewhere else