fixes gcsafe overrides and reduce unnecessary evmc conversion
This commit is contained in:
parent
349d033d05
commit
95edc54b46
|
@ -25,7 +25,7 @@ const
|
||||||
|
|
||||||
template getCoinbase*(c: Computation): EthAddress =
|
template getCoinbase*(c: Computation): EthAddress =
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
fromEvmc c.host.getTxContext().block_coinbase
|
c.host.getTxContext().block_coinbase
|
||||||
else:
|
else:
|
||||||
c.vmState.coinbase
|
c.vmState.coinbase
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ template getChainId*(c: Computation): uint =
|
||||||
|
|
||||||
template getOrigin*(c: Computation): EthAddress =
|
template getOrigin*(c: Computation): EthAddress =
|
||||||
when evmc_enabled:
|
when evmc_enabled:
|
||||||
fromEvmc c.host.getTxContext().tx_origin
|
c.host.getTxContext().tx_origin
|
||||||
else:
|
else:
|
||||||
c.vmState.txOrigin
|
c.vmState.txOrigin
|
||||||
|
|
||||||
|
|
|
@ -7,25 +7,62 @@
|
||||||
|
|
||||||
import evmc/evmc, evmc_helpers, eth/common, ../constants
|
import evmc/evmc, evmc_helpers, eth/common, ../constants
|
||||||
|
|
||||||
proc nim_host_get_interface*(): ptr evmc_host_interface {.importc, cdecl.}
|
type
|
||||||
|
# we are not using EVMC original signature here
|
||||||
|
# because we want to trick the compiler
|
||||||
|
# and reduce unnecessary conversion/typecast
|
||||||
|
# TODO: move this type definition to nim-evmc
|
||||||
|
# after we have implemented ABI compatibility test
|
||||||
|
# TODO: investigate the possibility to use Big Endian VMWord
|
||||||
|
# directly if it's not involving stint computation
|
||||||
|
# and we can reduce unecessary conversion further
|
||||||
|
nimbus_tx_context* = object
|
||||||
|
tx_gas_price* : evmc_uint256be # The transaction gas price.
|
||||||
|
tx_origin* : EthAddress # The transaction origin account.
|
||||||
|
block_coinbase* : EthAddress # The miner of the block.
|
||||||
|
block_number* : int64 # The block number.
|
||||||
|
block_timestamp* : int64 # The block timestamp.
|
||||||
|
block_gas_limit* : int64 # The block gas limit.
|
||||||
|
block_difficulty*: evmc_uint256be # The block difficulty.
|
||||||
|
chain_id* : evmc_uint256be # The blockchain's ChainID.
|
||||||
|
|
||||||
|
nimbus_host_interface* = object
|
||||||
|
account_exists*: proc(context: evmc_host_context, address: EthAddress): bool {.cdecl, gcsafe.}
|
||||||
|
get_storage*: proc(context: evmc_host_context, address: EthAddress, key: ptr evmc_uint256be): evmc_uint256be {.cdecl, gcsafe.}
|
||||||
|
set_storage*: proc(context: evmc_host_context, address: EthAddress,
|
||||||
|
key, value: ptr evmc_uint256be): evmc_storage_status {.cdecl, gcsafe.}
|
||||||
|
get_balance*: proc(context: evmc_host_context, address: EthAddress): evmc_uint256be {.cdecl, gcsafe.}
|
||||||
|
get_code_size*: proc(context: evmc_host_context, address: EthAddress): uint {.cdecl, gcsafe.}
|
||||||
|
get_code_hash*: proc(context: evmc_host_context, address: EthAddress): Hash256 {.cdecl, gcsafe.}
|
||||||
|
copy_code*: proc(context: evmc_host_context, address: EthAddress,
|
||||||
|
code_offset: int, buffer_data: ptr byte,
|
||||||
|
buffer_size: int): int {.cdecl, gcsafe.}
|
||||||
|
selfdestruct*: proc(context: evmc_host_context, address, beneficiary: EthAddress) {.cdecl, gcsafe.}
|
||||||
|
call*: proc(context: evmc_host_context, msg: ptr evmc_message): evmc_result {.cdecl, gcsafe.}
|
||||||
|
get_tx_context*: proc(context: evmc_host_context): nimbus_tx_context {.cdecl, gcsafe.}
|
||||||
|
get_block_hash*: proc(context: evmc_host_context, number: int64): Hash256 {.cdecl, gcsafe.}
|
||||||
|
emit_log*: proc(context: evmc_host_context, address: EthAddress,
|
||||||
|
data: ptr byte, data_size: uint,
|
||||||
|
topics: ptr evmc_bytes32, topics_count: uint) {.cdecl, gcsafe.}
|
||||||
|
|
||||||
|
proc nim_host_get_interface*(): ptr nimbus_host_interface {.importc, cdecl.}
|
||||||
proc nim_host_create_context*(vmstate: pointer, msg: ptr evmc_message): evmc_host_context {.importc, cdecl.}
|
proc nim_host_create_context*(vmstate: pointer, msg: ptr evmc_message): evmc_host_context {.importc, cdecl.}
|
||||||
proc nim_host_destroy_context*(ctx: evmc_host_context) {.importc, cdecl.}
|
proc nim_host_destroy_context*(ctx: evmc_host_context) {.importc, cdecl.}
|
||||||
proc nim_create_nimbus_vm*(): ptr evmc_vm {.importc, cdecl.}
|
proc nim_create_nimbus_vm*(): ptr evmc_vm {.importc, cdecl.}
|
||||||
|
|
||||||
type
|
type
|
||||||
HostContext* = object
|
HostContext* = object
|
||||||
host*: ptr evmc_host_interface
|
host*: ptr nimbus_host_interface
|
||||||
context*: evmc_host_context
|
context*: evmc_host_context
|
||||||
|
|
||||||
proc init*(x: var HostContext, host: ptr evmc_host_interface, context: evmc_host_context) =
|
proc init*(x: var HostContext, host: ptr nimbus_host_interface, context: evmc_host_context) =
|
||||||
x.host = host
|
x.host = host
|
||||||
x.context = context
|
x.context = context
|
||||||
|
|
||||||
proc init*(x: typedesc[HostContext], host: ptr evmc_host_interface, context: evmc_host_context): HostContext =
|
proc init*(x: typedesc[HostContext], host: ptr nimbus_host_interface, context: evmc_host_context): HostContext =
|
||||||
result.init(host, context)
|
result.init(host, context)
|
||||||
|
|
||||||
proc getTxContext*(ctx: HostContext): evmc_tx_context =
|
proc getTxContext*(ctx: HostContext): nimbus_tx_context {.inline.} =
|
||||||
{.gcsafe.}:
|
|
||||||
ctx.host.get_tx_context(ctx.context)
|
ctx.host.get_tx_context(ctx.context)
|
||||||
|
|
||||||
proc getBlockHash*(ctx: HostContext, number: Uint256): Hash256 =
|
proc getBlockHash*(ctx: HostContext, number: Uint256): Hash256 =
|
||||||
|
@ -36,70 +73,48 @@ proc getBlockHash*(ctx: HostContext, number: Uint256): Hash256 =
|
||||||
return
|
return
|
||||||
if number >= blockNumber:
|
if number >= blockNumber:
|
||||||
return
|
return
|
||||||
{.gcsafe.}:
|
ctx.host.get_block_hash(ctx.context, number.truncate(int64))
|
||||||
Hash256.fromEvmc ctx.host.get_block_hash(ctx.context, number.truncate(int64))
|
|
||||||
|
|
||||||
proc accountExists*(ctx: HostContext, address: EthAddress): bool =
|
proc accountExists*(ctx: HostContext, address: EthAddress): bool {.inline.} =
|
||||||
var address = toEvmc(address)
|
ctx.host.account_exists(ctx.context, address)
|
||||||
{.gcsafe.}:
|
|
||||||
ctx.host.account_exists(ctx.context, address.addr).bool
|
|
||||||
|
|
||||||
proc getStorage*(ctx: HostContext, address: EthAddress, key: Uint256): Uint256 =
|
proc getStorage*(ctx: HostContext, address: EthAddress, key: Uint256): Uint256 =
|
||||||
var
|
var key = toEvmc(key)
|
||||||
address = toEvmc(address)
|
Uint256.fromEvmc ctx.host.get_storage(ctx.context, address, key.addr)
|
||||||
key = toEvmc(key)
|
|
||||||
{.gcsafe.}:
|
|
||||||
Uint256.fromEvmc ctx.host.get_storage(ctx.context, address.addr, key.addr)
|
|
||||||
|
|
||||||
proc setStorage*(ctx: HostContext, address: EthAddress,
|
proc setStorage*(ctx: HostContext, address: EthAddress,
|
||||||
key, value: Uint256): evmc_storage_status =
|
key, value: Uint256): evmc_storage_status {.inline.} =
|
||||||
var
|
var
|
||||||
address = toEvmc(address)
|
|
||||||
key = toEvmc(key)
|
key = toEvmc(key)
|
||||||
value = toEvmc(value)
|
value = toEvmc(value)
|
||||||
{.gcsafe.}:
|
ctx.host.set_storage(ctx.context, address, key.addr, value.addr)
|
||||||
ctx.host.set_storage(ctx.context, address.addr, key.addr, value.addr)
|
|
||||||
|
|
||||||
proc getBalance*(ctx: HostContext, address: EthAddress): Uint256 =
|
proc getBalance*(ctx: HostContext, address: EthAddress): Uint256 {.inline.} =
|
||||||
var address = toEvmc(address)
|
Uint256.fromEvmc ctx.host.get_balance(ctx.context, address)
|
||||||
{.gcsafe.}:
|
|
||||||
Uint256.fromEvmc ctx.host.get_balance(ctx.context, address.addr)
|
|
||||||
|
|
||||||
proc getCodeSize*(ctx: HostContext, address: EthAddress): uint =
|
proc getCodeSize*(ctx: HostContext, address: EthAddress): uint {.inline.} =
|
||||||
var address = toEvmc(address)
|
ctx.host.get_code_size(ctx.context, address)
|
||||||
{.gcsafe.}:
|
|
||||||
ctx.host.get_code_size(ctx.context, address.addr)
|
|
||||||
|
|
||||||
proc getCodeHash*(ctx: HostContext, address: EthAddress): Hash256 =
|
proc getCodeHash*(ctx: HostContext, address: EthAddress): Hash256 {.inline.} =
|
||||||
var address = toEvmc(address)
|
ctx.host.get_code_hash(ctx.context, address)
|
||||||
{.gcsafe.}:
|
|
||||||
Hash256.fromEvmc ctx.host.get_code_hash(ctx.context, address.addr)
|
|
||||||
|
|
||||||
proc copyCode*(ctx: HostContext, address: EthAddress, codeOffset: int = 0): seq[byte] =
|
proc copyCode*(ctx: HostContext, address: EthAddress, codeOffset: int = 0): seq[byte] =
|
||||||
let size = ctx.getCodeSize(address).int
|
let size = ctx.getCodeSize(address).int
|
||||||
var address = toEvmc(address)
|
|
||||||
if size - codeOffset > 0:
|
if size - codeOffset > 0:
|
||||||
result = newSeq[byte](size - codeOffset)
|
result = newSeq[byte](size - codeOffset)
|
||||||
{.gcsafe.}:
|
let read = ctx.host.copy_code(ctx.context, address,
|
||||||
let read = ctx.host.copy_code(ctx.context, address.addr,
|
codeOffset, result[0].addr, result.len)
|
||||||
code_offset.uint, result[0].addr, result.len.uint).int
|
|
||||||
doAssert(read == result.len)
|
doAssert(read == result.len)
|
||||||
|
|
||||||
proc selfdestruct*(ctx: HostContext, address, beneficiary: EthAddress) =
|
proc selfdestruct*(ctx: HostContext, address, beneficiary: EthAddress) {.inline.} =
|
||||||
var
|
ctx.host.selfdestruct(ctx.context, address, beneficiary)
|
||||||
address = toEvmc(address)
|
|
||||||
beneficiary = toEvmc(beneficiary)
|
|
||||||
{.gcsafe.}:
|
|
||||||
ctx.host.selfdestruct(ctx.context, address.addr, beneficiary.addr)
|
|
||||||
|
|
||||||
proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte],
|
proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte],
|
||||||
topics: ptr evmc_bytes32, topicsCount: int) =
|
topics: ptr evmc_bytes32, topicsCount: int) {.inline.} =
|
||||||
var address = toEvmc(address)
|
ctx.host.emit_log(ctx.context, address, if data.len > 0: data[0].unsafeAddr else: nil,
|
||||||
{.gcsafe.}:
|
|
||||||
ctx.host.emit_log(ctx.context, address.addr, if data.len > 0: data[0].unsafeAddr else: nil,
|
|
||||||
data.len.uint, topics, topicsCount.uint)
|
data.len.uint, topics, topicsCount.uint)
|
||||||
|
|
||||||
proc call*(ctx: HostContext, msg: evmc_message): evmc_result =
|
proc call*(ctx: HostContext, msg: evmc_message): evmc_result {.inline.} =
|
||||||
ctx.host.call(ctx.context, msg.unsafeAddr)
|
ctx.host.call(ctx.context, msg.unsafeAddr)
|
||||||
|
|
||||||
#proc vmHost*(vmState: BaseVMState, gasPrice: GasInt, origin: EthAddress): HostContext =
|
#proc vmHost*(vmState: BaseVMState, gasPrice: GasInt, origin: EthAddress): HostContext =
|
||||||
|
|
|
@ -8,43 +8,39 @@
|
||||||
proc hostReleaseResultImpl(result: var evmc_result) {.cdecl.} =
|
proc hostReleaseResultImpl(result: var evmc_result) {.cdecl.} =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc hostGetTxContextImpl(ctx: Computation): evmc_tx_context {.cdecl.} =
|
proc hostGetTxContextImpl(ctx: Computation): nimbus_tx_context {.cdecl.} =
|
||||||
let vmstate = ctx.vmState
|
let vmstate = ctx.vmState
|
||||||
result.tx_gas_price = toEvmc(vmstate.txGasPrice.u256)
|
result.tx_gas_price = toEvmc(vmstate.txGasPrice.u256)
|
||||||
result.tx_origin = toEvmc(vmstate.txOrigin)
|
result.tx_origin = vmstate.txOrigin
|
||||||
result.block_coinbase = toEvmc(vmstate.coinbase)
|
result.block_coinbase = vmstate.coinbase
|
||||||
result.block_number = vmstate.blockNumber.truncate(int64)
|
result.block_number = vmstate.blockNumber.truncate(int64)
|
||||||
result.block_timestamp = vmstate.timestamp.toUnix()
|
result.block_timestamp = vmstate.timestamp.toUnix()
|
||||||
result.block_gas_limit = int64(vmstate.blockHeader.gasLimit)
|
result.block_gas_limit = int64(vmstate.blockHeader.gasLimit)
|
||||||
result.block_difficulty = toEvmc(vmstate.difficulty)
|
result.block_difficulty = toEvmc(vmstate.difficulty)
|
||||||
result.chain_id = toEvmc(vmstate.chaindb.config.chainId.u256)
|
result.chain_id = toEvmc(vmstate.chaindb.config.chainId.u256)
|
||||||
|
|
||||||
proc hostGetBlockHashImpl(ctx: Computation, number: int64): evmc_bytes32 {.cdecl.} =
|
proc hostGetBlockHashImpl(ctx: Computation, number: int64): Hash256 {.cdecl.} =
|
||||||
ctx.vmState.getAncestorHash(number.u256).toEvmc()
|
ctx.vmState.getAncestorHash(number.u256)
|
||||||
|
|
||||||
proc hostAccountExistsImpl(ctx: Computation, address: var evmc_address): c99bool {.cdecl.} =
|
proc hostAccountExistsImpl(ctx: Computation, address: EthAddress): bool {.cdecl.} =
|
||||||
let db = ctx.vmState.readOnlyStateDB
|
let db = ctx.vmState.readOnlyStateDB
|
||||||
if ctx.fork >= FkSpurious:
|
if ctx.fork >= FkSpurious:
|
||||||
not db.isDeadAccount(fromEvmc(address))
|
not db.isDeadAccount(address)
|
||||||
else:
|
else:
|
||||||
db.accountExists(fromEvmc(address))
|
db.accountExists(address)
|
||||||
|
|
||||||
proc hostGetStorageImpl(ctx: Computation, address: var evmc_address, key: var evmc_bytes32): evmc_bytes32 {.cdecl.} =
|
proc hostGetStorageImpl(ctx: Computation, address: EthAddress, key: var evmc_bytes32): evmc_bytes32 {.cdecl.} =
|
||||||
let storageAddr = fromEvmc(address)
|
ctx.vmState.accountDB.getStorage(address, Uint256.fromEvmc(key))[0].toEvmc()
|
||||||
assert storageAddr == ctx.msg.contractAddress
|
|
||||||
let (storage, _) = ctx.vmState.accountDB.getStorage(storageAddr, Uint256.fromEvmc(key))
|
|
||||||
storage.toEvmc()
|
|
||||||
|
|
||||||
proc hostSetStorageImpl(ctx: Computation, address: var evmc_address,
|
proc hostSetStorageImpl(ctx: Computation, address: EthAddress,
|
||||||
key, value: var evmc_bytes32): evmc_storage_status {.cdecl.} =
|
key, value: var evmc_bytes32): evmc_storage_status {.cdecl.} =
|
||||||
let
|
let
|
||||||
storageAddr = fromEvmc(address)
|
|
||||||
slot = Uint256.fromEvmc(key)
|
slot = Uint256.fromEvmc(key)
|
||||||
newValue = Uint256.fromEvmc(value)
|
newValue = Uint256.fromEvmc(value)
|
||||||
statedb = ctx.vmState.readOnlyStateDb
|
statedb = ctx.vmState.readOnlyStateDb
|
||||||
(currValue, _) = statedb.getStorage(storageAddr, slot)
|
currValue = statedb.getStorage(address, slot)[0]
|
||||||
|
|
||||||
assert storageAddr == ctx.msg.contractAddress
|
assert address == ctx.msg.contractAddress
|
||||||
|
|
||||||
var
|
var
|
||||||
status = EVMC_STORAGE_MODIFIED
|
status = EVMC_STORAGE_MODIFIED
|
||||||
|
@ -54,7 +50,7 @@ proc hostSetStorageImpl(ctx: Computation, address: var evmc_address,
|
||||||
if newValue == currValue:
|
if newValue == currValue:
|
||||||
status = EVMC_STORAGE_UNCHANGED
|
status = EVMC_STORAGE_UNCHANGED
|
||||||
else:
|
else:
|
||||||
origValue = statedb.getCommittedStorage(storageAddr, slot)
|
origValue = statedb.getCommittedStorage(address, slot)
|
||||||
if origValue == currValue or ctx.fork < FkIstanbul:
|
if origValue == currValue or ctx.fork < FkIstanbul:
|
||||||
if currValue == 0:
|
if currValue == 0:
|
||||||
status = EVMC_STORAGE_ADDED
|
status = EVMC_STORAGE_ADDED
|
||||||
|
@ -63,7 +59,7 @@ proc hostSetStorageImpl(ctx: Computation, address: var evmc_address,
|
||||||
else:
|
else:
|
||||||
status = EVMC_STORAGE_MODIFIED_AGAIN
|
status = EVMC_STORAGE_MODIFIED_AGAIN
|
||||||
ctx.vmState.mutateStateDB:
|
ctx.vmState.mutateStateDB:
|
||||||
db.setStorage(storageAddr, slot, newValue)
|
db.setStorage(address, slot, newValue)
|
||||||
|
|
||||||
let gasParam = GasParams(kind: Op.Sstore,
|
let gasParam = GasParams(kind: Op.Sstore,
|
||||||
s_status: status,
|
s_status: status,
|
||||||
|
@ -77,46 +73,41 @@ proc hostSetStorageImpl(ctx: Computation, address: var evmc_address,
|
||||||
|
|
||||||
result = status
|
result = status
|
||||||
|
|
||||||
proc hostGetBalanceImpl(ctx: Computation, address: var evmc_address): evmc_uint256be {.cdecl.} =
|
proc hostGetBalanceImpl(ctx: Computation, address: EthAddress): evmc_bytes32 {.cdecl.} =
|
||||||
ctx.vmState.readOnlyStateDB.getBalance(fromEvmc(address)).toEvmc()
|
ctx.vmState.readOnlyStateDB.getBalance(address).toEvmc()
|
||||||
|
|
||||||
proc hostGetCodeSizeImpl(ctx: Computation, address: var evmc_address): uint {.cdecl.} =
|
proc hostGetCodeSizeImpl(ctx: Computation, address: EthAddress): uint {.cdecl.} =
|
||||||
ctx.vmState.readOnlyStateDB.getCode(fromEvmc(address)).len.uint
|
ctx.vmState.readOnlyStateDB.getCode(address).len.uint
|
||||||
|
|
||||||
proc hostGetCodeHashImpl(ctx: Computation, address: var evmc_address): evmc_bytes32 {.cdecl.} =
|
|
||||||
let
|
|
||||||
db = ctx.vmstate.readOnlyStateDB
|
|
||||||
address = fromEvmc(address)
|
|
||||||
|
|
||||||
|
proc hostGetCodeHashImpl(ctx: Computation, address: EthAddress): Hash256 {.cdecl.} =
|
||||||
|
let db = ctx.vmstate.readOnlyStateDB
|
||||||
if not db.accountExists(address):
|
if not db.accountExists(address):
|
||||||
return
|
return
|
||||||
|
|
||||||
if db.isEmptyAccount(address):
|
if db.isEmptyAccount(address):
|
||||||
return
|
return
|
||||||
|
db.getCodeHash(address)
|
||||||
|
|
||||||
db.getCodeHash(address).toEvmc()
|
proc hostCopyCodeImpl(ctx: Computation, address: EthAddress,
|
||||||
|
codeOffset: int, bufferData: ptr byte,
|
||||||
|
bufferSize: int): int {.cdecl.} =
|
||||||
|
|
||||||
proc hostCopyCodeImpl(ctx: Computation, address: var evmc_address,
|
var code = ctx.vmState.readOnlyStateDB.getCode(address)
|
||||||
codeOffset: uint, bufferData: ptr byte,
|
|
||||||
bufferSize: uint): uint {.cdecl.} =
|
|
||||||
|
|
||||||
var code = ctx.vmState.readOnlyStateDB.getCode(fromEvmc(address))
|
|
||||||
|
|
||||||
# Handle "big offset" edge case.
|
# Handle "big offset" edge case.
|
||||||
if codeOffset > code.len.uint:
|
if codeOffset > code.len:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
let maxToCopy = code.len - codeOffset.int
|
let maxToCopy = code.len - codeOffset
|
||||||
let numToCopy = min(maxToCopy, bufferSize.int)
|
let numToCopy = min(maxToCopy, bufferSize)
|
||||||
if numToCopy > 0:
|
if numToCopy > 0:
|
||||||
copyMem(bufferData, code.slice(codeOffset.int).baseAddr, numToCopy)
|
copyMem(bufferData, code.slice(codeOffset).baseAddr, numToCopy)
|
||||||
result = numToCopy.uint
|
result = numToCopy
|
||||||
|
|
||||||
proc hostSelfdestructImpl(ctx: Computation, address, beneficiary: var evmc_address) {.cdecl.} =
|
proc hostSelfdestructImpl(ctx: Computation, address, beneficiary: EthAddress) {.cdecl.} =
|
||||||
assert fromEvmc(address) == ctx.msg.contractAddress
|
assert address == ctx.msg.contractAddress
|
||||||
ctx.execSelfDestruct(fromEvmc(beneficiary))
|
ctx.execSelfDestruct(beneficiary)
|
||||||
|
|
||||||
proc hostEmitLogImpl(ctx: Computation, address: var evmc_address,
|
proc hostEmitLogImpl(ctx: Computation, address: EthAddress,
|
||||||
data: ptr byte, dataSize: int,
|
data: ptr byte, dataSize: int,
|
||||||
topics: UncheckedArray[evmc_bytes32], topicsCount: int) {.cdecl.} =
|
topics: UncheckedArray[evmc_bytes32], topicsCount: int) {.cdecl.} =
|
||||||
var log: Log
|
var log: Log
|
||||||
|
@ -129,7 +120,7 @@ proc hostEmitLogImpl(ctx: Computation, address: var evmc_address,
|
||||||
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 = address
|
||||||
ctx.addLogEntry(log)
|
ctx.addLogEntry(log)
|
||||||
|
|
||||||
proc hostCallImpl(ctx: Computation, msg: var evmc_message): evmc_result {.cdecl.} =
|
proc hostCallImpl(ctx: Computation, msg: var evmc_message): evmc_result {.cdecl.} =
|
||||||
|
@ -177,8 +168,8 @@ proc init(vm: var evmc_vm) =
|
||||||
vm.set_option = vmSetOptionImpl
|
vm.set_option = vmSetOptionImpl
|
||||||
|
|
||||||
let gHost = initHostInterface()
|
let gHost = initHostInterface()
|
||||||
proc nim_host_get_interface(): ptr evmc_host_interface {.exportc, cdecl.} =
|
proc nim_host_get_interface(): ptr nimbus_host_interface {.exportc, cdecl.} =
|
||||||
result = gHost.unsafeAddr
|
result = cast[ptr nimbus_host_interface](gHost.unsafeAddr)
|
||||||
|
|
||||||
proc nim_host_create_context(vmstate: BaseVmState, msg: ptr evmc_message): Computation {.exportc, cdecl.} =
|
proc nim_host_create_context(vmstate: BaseVmState, msg: ptr evmc_message): Computation {.exportc, cdecl.} =
|
||||||
#result = HostContext(
|
#result = HostContext(
|
||||||
|
|
Loading…
Reference in New Issue