fixes balance transfer for CALL and CALLCODE

This commit is contained in:
andri lim 2020-01-15 14:56:39 +07:00 committed by zah
parent 73c60fe694
commit d300bc352d
2 changed files with 14 additions and 19 deletions

View File

@ -100,19 +100,6 @@ proc writeContract*(c: Computation, fork: Fork): bool {.gcsafe.} =
if fork < FkHomestead or fork >= FkByzantium: c.output = @[] if fork < FkHomestead or fork >= FkByzantium: c.output = @[]
result = false result = false
proc transferBalance(c: Computation, opCode: static[Op]) =
let senderBalance = c.vmState.readOnlyStateDb().
getBalance(c.msg.sender)
if senderBalance < c.msg.value:
c.setError(&"insufficient funds available={senderBalance}, needed={c.msg.value}")
return
when opCode in {Call, Create}:
c.vmState.mutateStateDb:
db.subBalance(c.msg.sender, c.msg.value)
db.addBalance(c.msg.contractAddress, c.msg.value)
template continuation*(c: Computation, body: untyped) = template continuation*(c: Computation, body: untyped) =
# this is a helper template to implement continuation # this is a helper template to implement continuation
# passing and convert all recursion into tail call # passing and convert all recursion into tail call
@ -157,12 +144,10 @@ proc applyMessage*(c: Computation, opCode: static[Op]) =
# EIP161 nonce incrementation # EIP161 nonce incrementation
db.incNonce(c.msg.contractAddress) db.incNonce(c.msg.contractAddress)
when opCode in {CallCode, Call, Create}: when opCode in {Call, Create}:
c.transferBalance(opCode) c.vmState.mutateStateDb:
if c.isError(): db.subBalance(c.msg.sender, c.msg.value)
c.rollback() db.addBalance(c.msg.contractAddress, c.msg.value)
c.nextProc()
return
if c.gasMeter.gasRemaining < 0: if c.gasMeter.gasRemaining < 0:
c.commit() c.commit()

View File

@ -719,6 +719,8 @@ template genCall(callName: untyped, opCode: Op): untyped =
if childGasFee >= 0: if childGasFee >= 0:
c.gasMeter.consumeGas(childGasFee, reason = $opCode) c.gasMeter.consumeGas(childGasFee, reason = $opCode)
c.returnData.setLen(0)
if c.msg.depth >= MaxCallDepth: if c.msg.depth >= MaxCallDepth:
debug "Computation Failure", reason = "Stack too deep", maximumDepth = MaxCallDepth, depth = c.msg.depth debug "Computation Failure", reason = "Stack too deep", maximumDepth = MaxCallDepth, depth = c.msg.depth
# return unused gas # return unused gas
@ -731,6 +733,14 @@ template genCall(callName: untyped, opCode: Op): untyped =
c.memory.extend(memInPos, memInLen) c.memory.extend(memInPos, memInLen)
c.memory.extend(memOutPos, memOutLen) c.memory.extend(memOutPos, memOutLen)
when opCode in {CallCode, Call}:
let senderBalance = c.vmState.readOnlyStateDb().getBalance(sender)
if senderBalance < value:
debug "Insufficient funds", available = senderBalance, needed = c.msg.value
# return unused gas
c.gasMeter.returnGas(childGasLimit)
return
let let
callData = c.memory.read(memInPos, memInLen) callData = c.memory.read(memInPos, memInLen)
code = c.vmState.readOnlyStateDb.getCode(codeAddress) code = c.vmState.readOnlyStateDb.getCode(codeAddress)