integrate evmc 'emitLog'

This commit is contained in:
andri lim 2020-01-17 20:11:02 +07:00 committed by zah
parent bf7b4c7273
commit 62f96e9bd4
3 changed files with 35 additions and 18 deletions

View File

@ -91,9 +91,12 @@ proc selfdestruct*(ctx: HostContext, address, beneficiary: EthAddress) =
{.gcsafe.}: {.gcsafe.}:
ctx.host.selfdestruct(ctx.context, address.addr, beneficiary.addr) ctx.host.selfdestruct(ctx.context, address.addr, beneficiary.addr)
proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte], topics: openArray[evmc_bytes32]) = proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte],
topics: ptr evmc_bytes32, topicsCount: int) =
var address = toEvmc(address) var address = toEvmc(address)
ctx.host.emit_log(ctx.context, address.addr, data[0].unsafeAddr, data.len.uint, topics[0].unsafeAddr, topics.len.uint) {.gcsafe.}:
ctx.host.emit_log(ctx.context, address.addr, if data.len > 0: data[0].unsafeAddr else: nil,
data.len.uint, topics, topicsCount.uint)
proc call*(ctx: HostContext, msg: evmc_message): evmc_result = proc call*(ctx: HostContext, msg: evmc_message): evmc_result =
ctx.host.call(ctx.context, msg.unsafeAddr) ctx.host.call(ctx.context, msg.unsafeAddr)

View File

@ -117,15 +117,18 @@ proc hostSelfdestructImpl(ctx: Computation, address, beneficiary: var evmc_addre
ctx.registerAccountForDeletion(fromEvmc(beneficiary)) ctx.registerAccountForDeletion(fromEvmc(beneficiary))
proc hostEmitLogImpl(ctx: Computation, address: var evmc_address, proc hostEmitLogImpl(ctx: Computation, address: var evmc_address,
data: ptr byte, dataSize: uint, data: ptr byte, dataSize: int,
topics: UncheckedArray[evmc_bytes32], topicsCount: uint) {.cdecl.} = topics: UncheckedArray[evmc_bytes32], topicsCount: int) {.cdecl.} =
var log: Log var log: Log
if topicsCount > 0:
log.topics = newSeq[Topic](topicsCount) log.topics = newSeq[Topic](topicsCount)
for i in 0 ..< topicsCount: for i in 0 ..< topicsCount:
log.topics[i] = topics[i].bytes log.topics[i] = topics[i].bytes
if dataSize > 0:
log.data = newSeq[byte](dataSize) log.data = newSeq[byte](dataSize)
copyMem(log.data[0].addr, data, dataSize) copyMem(log.data[0].addr, data, dataSize)
log.address = fromEvmc(address) log.address = fromEvmc(address)
ctx.addLogEntry(log) ctx.addLogEntry(log)

View File

@ -13,7 +13,8 @@ import
../../computation, ../../stack, ../../code_stream, ../../computation, ../../stack, ../../code_stream,
../../../vm_types, ../../memory, ../../../vm_types, ../../memory,
../../../errors, ../../message, ../../interpreter/[gas_meter, opcode_values], ../../../errors, ../../message, ../../interpreter/[gas_meter, opcode_values],
../../interpreter/utils/utils_numeric ../../interpreter/utils/utils_numeric,
../../evmc_api, evmc/evmc
proc pop(tree: var NimNode): NimNode = proc pop(tree: var NimNode): NimNode =
## Returns the last value of a NimNode and remove it ## Returns the last value of a NimNode and remove it
@ -115,15 +116,25 @@ proc logImpl(c: Computation, opcode: Op, topicCount: int) =
if memPos < 0 or len < 0: if memPos < 0 or len < 0:
raise newException(OutOfBoundsRead, "Out of bounds memory access") raise newException(OutOfBoundsRead, "Out of bounds memory access")
c.gasMeter.consumeGas(
c.gasCosts[opcode].m_handler(c.memory.len, memPos, len),
reason="Memory expansion, Log topic and data gas cost")
c.memory.extend(memPos, len)
when evmc_enabled:
var topics: array[4, evmc_bytes32]
for i in 0 ..< topicCount:
topics[i].bytes = c.stack.popTopic()
c.host.emitLog(c.msg.contractAddress,
c.memory.read(memPos, len),
topics[0].addr, topicCount)
else:
var log: Log var log: Log
log.topics = newSeqOfCap[Topic](topicCount) log.topics = newSeqOfCap[Topic](topicCount)
for i in 0 ..< topicCount: for i in 0 ..< topicCount:
log.topics.add(c.stack.popTopic()) log.topics.add(c.stack.popTopic())
c.gasMeter.consumeGas(
c.gasCosts[opcode].m_handler(c.memory.len, memPos, len),
reason="Memory expansion, Log topic and data gas cost")
c.memory.extend(memPos, len)
log.data = c.memory.read(memPos, len) log.data = c.memory.read(memPos, len)
log.address = c.msg.contractAddress log.address = c.msg.contractAddress
c.addLogEntry(log) c.addLogEntry(log)