fixes CALL opcode

This commit is contained in:
andri lim 2019-02-06 14:46:09 +07:00 committed by zah
parent 817bce3555
commit a28f06a825
3 changed files with 49 additions and 30 deletions

View File

@ -131,11 +131,11 @@ proc applyMessage(computation: var BaseComputation, opCode: static[Op]) =
newBalance = senderBalance - computation.msg.value newBalance = senderBalance - computation.msg.value
computation.vmState.mutateStateDb: computation.vmState.mutateStateDb:
db.setBalance(computation.msg.sender, newBalance) db.setBalance(computation.msg.sender, newBalance)
db.addBalance(computation.msg.storage_address, computation.msg.value) db.addBalance(computation.msg.storageAddress, computation.msg.value)
trace "Value transferred", trace "Value transferred",
source = computation.msg.sender, source = computation.msg.sender,
dest = computation.msg.storage_address, dest = computation.msg.storageAddress,
value = computation.msg.value, value = computation.msg.value,
oldSenderBalance = senderBalance, oldSenderBalance = senderBalance,
newSenderBalance = newBalance, newSenderBalance = newBalance,
@ -146,9 +146,15 @@ proc applyMessage(computation: var BaseComputation, opCode: static[Op]) =
value = computation.msg.value, value = computation.msg.value,
senderBalance = newBalance, senderBalance = newBalance,
sender = computation.msg.sender.toHex, sender = computation.msg.sender.toHex,
address = computation.msg.storage_address.toHex, address = computation.msg.storageAddress.toHex,
gasPrice = computation.msg.gasPrice, gasPrice = computation.msg.gasPrice,
gas = computation.msg.gas gas = computation.msg.gas
else:
# even though the value is zero, the account
# should be exist.
when opCode in {Call, CallCode}:
computation.vmState.mutateStateDb:
db.addBalance(computation.msg.storageAddress, computation.msg.value)
# Run code # Run code
# We cannot use the normal dispatching function `executeOpcodes` # We cannot use the normal dispatching function `executeOpcodes`
@ -184,7 +190,7 @@ proc applyCreateMessage(fork: Fork, computation: var BaseComputation, opCode: st
computation.gasCosts[Create].m_handler(0, 0, contractCode.len), computation.gasCosts[Create].m_handler(0, 0, contractCode.len),
reason = "Write contract code for CREATE") reason = "Write contract code for CREATE")
let storageAddr = computation.msg.storage_address let storageAddr = computation.msg.storageAddress
trace "SETTING CODE", trace "SETTING CODE",
address = storageAddr.toHex, address = storageAddr.toHex,
length = len(contract_code), length = len(contract_code),

View File

@ -126,10 +126,10 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
# M(currentMemSize, f, l) = currentMemSize # M(currentMemSize, f, l) = currentMemSize
let let
prev_words: int64 = currentMemSize.wordCount prevWords: int64 = currentMemSize.wordCount
new_words: int64 = (memOffset + memLength).wordCount newWords: int64 = (memOffset + memLength).wordCount
if memLength == 0 or new_words <= prev_words: if memLength == 0 or newWords <= prevWords:
# Special subcase of memory-expansion cost # Special subcase of memory-expansion cost
# currentMemSize - currentMemSize = 0 # currentMemSize - currentMemSize = 0
# "Referencing a zero length range ... does not require memory to be extended # "Referencing a zero length range ... does not require memory to be extended
@ -141,13 +141,13 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
return 0 return 0
let let
prev_cost = prev_words * static(FeeSchedule[GasMemory]) + prevCost = prevWords * static(FeeSchedule[GasMemory]) +
(prev_words ^ 2) shr 9 # div 512 (prevWords ^ 2) shr 9 # div 512
new_cost = new_words * static(FeeSchedule[GasMemory]) + newCost = newWords * static(FeeSchedule[GasMemory]) +
(new_words ^ 2) shr 9 # div 512 (newWords ^ 2) shr 9 # div 512
# TODO: add logging # TODO: add logging
result = max(new_cost - prev_cost, 0) result = max(newCost - prevCost, 0)
func `prefix all_but_one_64th`(gas: GasInt): GasInt {.inline.} = func `prefix all_but_one_64th`(gas: GasInt): GasInt {.inline.} =
## Computes all but 1/64th ## Computes all but 1/64th
@ -169,7 +169,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
result += static(FeeSchedule[GasExpByte]) * (1 + log256(value)) result += static(FeeSchedule[GasExpByte]) * (1 + log256(value))
func `prefix gasCreate`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} = func `prefix gasCreate`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} =
result = result =
static(FeeSchedule[GasCreate]) + static(FeeSchedule[GasCreate]) +
static(FeeSchedule[GasCodeDeposit]) * memLength static(FeeSchedule[GasCodeDeposit]) * memLength
@ -202,10 +202,10 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
gSreset = FeeSchedule[GasSreset] gSreset = FeeSchedule[GasSreset]
# Gas cost - literal translation of Yellow Paper # Gas cost - literal translation of Yellow Paper
result.gasCost = if value.isZero.not and gasParams.s_isStorageEmpty: result.gasCost = if value.isZero.not and gasParams.s_isStorageEmpty:
gSet gSet
else: else:
gSreset gSreset
# Refund # Refund
if value.isZero and not gasParams.s_isStorageEmpty: if value.isZero and not gasParams.s_isStorageEmpty:
@ -319,10 +319,12 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
if gasParams.c_gasBalance >= result.gasCost: if gasParams.c_gasBalance >= result.gasCost:
min( min(
`prefix all_but_one_64th`(gasParams.c_gasBalance - result.gasCost), `prefix all_but_one_64th`(gasParams.c_gasBalance - result.gasCost),
gasParams.c_contract_gas gasParams.c_contractGas
) )
else: else:
gasParams.c_contract_gas gasParams.c_contractGas
else:
result.gasCost += gasParams.c_contractGas
# Ccallgas - Gas sent to the child message # Ccallgas - Gas sent to the child message
result.gasRefund = result.gasCost result.gasRefund = result.gasCost

View File

@ -6,7 +6,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import import
strformat, times, ranges, sequtils, strformat, times, ranges, sequtils, options,
chronicles, stint, nimcrypto, ranges/typedranges, eth/common, chronicles, stint, nimcrypto, ranges/typedranges, eth/common,
./utils/[macros_procs_opcodes, utils_numeric], ./utils/[macros_procs_opcodes, utils_numeric],
./gas_meter, ./gas_costs, ./opcode_values, ./vm_forks, ./gas_meter, ./gas_costs, ./opcode_values, ./vm_forks,
@ -599,7 +599,7 @@ proc callParams(computation: var BaseComputation): (UInt256, UInt256, EthAddress
memoryInputStartPosition, memoryInputSize, memoryInputStartPosition, memoryInputSize,
memoryOutputStartPosition, memoryOutputSize) = computation.stack.popInt(5) memoryOutputStartPosition, memoryOutputSize) = computation.stack.popInt(5)
let to = computation.msg.storageAddress let to = codeAddress
let sender = computation.msg.storageAddress let sender = computation.msg.storageAddress
result = (gas, result = (gas,
@ -689,18 +689,29 @@ template genCall(callName: untyped, opCode: Op): untyped =
let (memInPos, memInLen, memOutPos, memOutLen) = (memoryInputStartPosition.cleanMemRef, memoryInputSize.cleanMemRef, memoryOutputStartPosition.cleanMemRef, memoryOutputSize.cleanMemRef) let (memInPos, memInLen, memOutPos, memOutLen) = (memoryInputStartPosition.cleanMemRef, memoryInputSize.cleanMemRef, memoryOutputStartPosition.cleanMemRef, memoryOutputSize.cleanMemRef)
let (gasCost, childMsgGas) = computation.gasCosts[opCode].c_handler( let isNewAccount = if getFork(computation) >= FkSpurious:
computation.vmState.readOnlyStateDb.isDeadAccount(to)
else:
not computation.vmState.readOnlyStateDb.accountExists(to)
let (memOffset, memLength) = if memInPos + memInLen > memOutPos + memOutLen:
(memInPos, memInLen)
else:
(memOutPos, memOutLen)
let (childGasFee, childGasLimit) = computation.gasCosts[opCode].c_handler(
value, value,
GasParams(kind: Call, GasParams(kind: Call,
c_isNewAccount: true, # TODO stub c_isNewAccount: isNewAccount,
c_gasBalance: 0, c_gasBalance: computation.gasMeter.gasRemaining,
c_contractGas: 0, c_contractGas: gas.truncate(GasInt),
c_currentMemSize: computation.memory.len, c_currentMemSize: computation.memory.len,
c_memOffset: 0, # TODO make sure if we pass the largest mem requested c_memOffset: memOffset,
c_memLength: 0 # or an addition of mem requested c_memLength: memLength
)) ))
trace "Call (" & callName.astToStr & ")", gasCost = gasCost, childCost = childMsgGas
computation.gasMeter.consumeGas(gasCost, reason = $opCode) trace "Call (" & callName.astToStr & ")", childGasLimit, childGasFee
computation.gasMeter.consumeGas(childGasFee, reason = $opCode)
computation.memory.extend(memInPos, memInLen) computation.memory.extend(memInPos, memInLen)
computation.memory.extend(memOutPos, memOutLen) computation.memory.extend(memOutPos, memOutLen)
@ -715,7 +726,7 @@ template genCall(callName: untyped, opCode: Op): untyped =
var childMsg = prepareChildMessage( var childMsg = prepareChildMessage(
computation, computation,
childMsgGas, childGasLimit,
to, to,
value, value,
callData, callData,