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
computation.vmState.mutateStateDb:
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",
source = computation.msg.sender,
dest = computation.msg.storage_address,
dest = computation.msg.storageAddress,
value = computation.msg.value,
oldSenderBalance = senderBalance,
newSenderBalance = newBalance,
@ -146,9 +146,15 @@ proc applyMessage(computation: var BaseComputation, opCode: static[Op]) =
value = computation.msg.value,
senderBalance = newBalance,
sender = computation.msg.sender.toHex,
address = computation.msg.storage_address.toHex,
address = computation.msg.storageAddress.toHex,
gasPrice = computation.msg.gasPrice,
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
# 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),
reason = "Write contract code for CREATE")
let storageAddr = computation.msg.storage_address
let storageAddr = computation.msg.storageAddress
trace "SETTING CODE",
address = storageAddr.toHex,
length = len(contract_code),

View File

@ -126,10 +126,10 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
# M(currentMemSize, f, l) = currentMemSize
let
prev_words: int64 = currentMemSize.wordCount
new_words: int64 = (memOffset + memLength).wordCount
prevWords: int64 = currentMemSize.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
# currentMemSize - currentMemSize = 0
# "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
let
prev_cost = prev_words * static(FeeSchedule[GasMemory]) +
(prev_words ^ 2) shr 9 # div 512
new_cost = new_words * static(FeeSchedule[GasMemory]) +
(new_words ^ 2) shr 9 # div 512
prevCost = prevWords * static(FeeSchedule[GasMemory]) +
(prevWords ^ 2) shr 9 # div 512
newCost = newWords * static(FeeSchedule[GasMemory]) +
(newWords ^ 2) shr 9 # div 512
# 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.} =
## Computes all but 1/64th
@ -169,7 +169,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
result += static(FeeSchedule[GasExpByte]) * (1 + log256(value))
func `prefix gasCreate`(currentMemSize, memOffset, memLength: Natural): GasInt {.nimcall.} =
result =
result =
static(FeeSchedule[GasCreate]) +
static(FeeSchedule[GasCodeDeposit]) * memLength
@ -202,10 +202,10 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
gSreset = FeeSchedule[GasSreset]
# Gas cost - literal translation of Yellow Paper
result.gasCost = if value.isZero.not and gasParams.s_isStorageEmpty:
gSet
else:
gSreset
result.gasCost = if value.isZero.not and gasParams.s_isStorageEmpty:
gSet
else:
gSreset
# Refund
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:
min(
`prefix all_but_one_64th`(gasParams.c_gasBalance - result.gasCost),
gasParams.c_contract_gas
gasParams.c_contractGas
)
else:
gasParams.c_contract_gas
gasParams.c_contractGas
else:
result.gasCost += gasParams.c_contractGas
# Ccallgas - Gas sent to the child message
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.
import
strformat, times, ranges, sequtils,
strformat, times, ranges, sequtils, options,
chronicles, stint, nimcrypto, ranges/typedranges, eth/common,
./utils/[macros_procs_opcodes, utils_numeric],
./gas_meter, ./gas_costs, ./opcode_values, ./vm_forks,
@ -599,7 +599,7 @@ proc callParams(computation: var BaseComputation): (UInt256, UInt256, EthAddress
memoryInputStartPosition, memoryInputSize,
memoryOutputStartPosition, memoryOutputSize) = computation.stack.popInt(5)
let to = computation.msg.storageAddress
let to = codeAddress
let sender = computation.msg.storageAddress
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 (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,
GasParams(kind: Call,
c_isNewAccount: true, # TODO stub
c_gasBalance: 0,
c_contractGas: 0,
c_isNewAccount: isNewAccount,
c_gasBalance: computation.gasMeter.gasRemaining,
c_contractGas: gas.truncate(GasInt),
c_currentMemSize: computation.memory.len,
c_memOffset: 0, # TODO make sure if we pass the largest mem requested
c_memLength: 0 # or an addition of mem requested
c_memOffset: memOffset,
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(memOutPos, memOutLen)
@ -715,7 +726,7 @@ template genCall(callName: untyped, opCode: Op): untyped =
var childMsg = prepareChildMessage(
computation,
childMsgGas,
childGasLimit,
to,
value,
callData,