nimbus-eth1/nimbus/vm/evmc_api.nim

112 lines
4.2 KiB
Nim
Raw Normal View History

2020-01-16 04:20:13 +00:00
# Nimbus
# Copyright (c) 2019 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except according to those terms.
2020-01-16 14:34:16 +00:00
import evmc/evmc, evmc_helpers, eth/common, ../constants
2020-01-16 04:20:13 +00:00
2020-01-16 10:23:51 +00:00
proc nim_host_get_interface*(): ptr evmc_host_interface {.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_create_nimbus_vm*(): ptr evmc_vm {.importc, cdecl.}
2020-01-16 04:20:13 +00:00
type
HostContext* = object
2020-01-16 10:23:51 +00:00
host*: ptr evmc_host_interface
2020-01-16 04:20:13 +00:00
context*: evmc_host_context
proc init*(x: var HostContext, host: ptr evmc_host_interface, context: evmc_host_context) =
x.host = host
x.context = context
proc init*(x: typedesc[HostContext], host: ptr evmc_host_interface, context: evmc_host_context): HostContext =
result.init(host, context)
proc getTxContext*(ctx: HostContext): evmc_tx_context =
2020-01-16 10:23:51 +00:00
{.gcsafe.}:
ctx.host.get_tx_context(ctx.context)
2020-01-16 04:20:13 +00:00
2020-01-16 14:34:16 +00:00
proc getBlockHash*(ctx: HostContext, number: Uint256): Hash256 =
2020-01-16 14:43:29 +00:00
let
blockNumber = ctx.getTxContext().block_number.u256
ancestorDepth = blockNumber - number - 1
if ancestorDepth >= constants.MAX_PREV_HEADER_DEPTH:
return
if number >= blockNumber:
return
2020-01-16 10:23:51 +00:00
{.gcsafe.}:
2020-01-16 14:34:16 +00:00
Hash256.fromEvmc ctx.host.get_block_hash(ctx.context, number.truncate(int64))
2020-01-16 04:20:13 +00:00
proc accountExists*(ctx: HostContext, address: EthAddress): bool =
var address = toEvmc(address)
2020-01-16 14:43:29 +00:00
{.gcsafe.}:
ctx.host.account_exists(ctx.context, address.addr).bool
2020-01-16 04:20:13 +00:00
proc getStorage*(ctx: HostContext, address: EthAddress, key: Uint256): Uint256 =
var
address = toEvmc(address)
key = toEvmc(key)
2020-01-16 14:56:59 +00:00
{.gcsafe.}:
Uint256.fromEvmc ctx.host.get_storage(ctx.context, address.addr, key.addr)
2020-01-16 04:20:13 +00:00
proc setStorage*(ctx: HostContext, address: EthAddress,
key, value: Uint256): evmc_storage_status =
var
address = toEvmc(address)
key = toEvmc(key)
value = toEvmc(value)
2020-01-17 14:49:22 +00:00
{.gcsafe.}:
ctx.host.set_storage(ctx.context, address.addr, key.addr, value.addr)
2020-01-16 04:20:13 +00:00
proc getBalance*(ctx: HostContext, address: EthAddress): Uint256 =
var address = toEvmc(address)
2020-01-16 15:07:04 +00:00
{.gcsafe.}:
Uint256.fromEvmc ctx.host.get_balance(ctx.context, address.addr)
2020-01-16 04:20:13 +00:00
2020-01-16 15:15:20 +00:00
proc getCodeSize*(ctx: HostContext, address: EthAddress): uint =
2020-01-16 04:20:13 +00:00
var address = toEvmc(address)
2020-01-16 15:15:20 +00:00
{.gcsafe.}:
ctx.host.get_code_size(ctx.context, address.addr)
2020-01-16 04:20:13 +00:00
proc getCodeHash*(ctx: HostContext, address: EthAddress): Hash256 =
var address = toEvmc(address)
2020-01-16 15:48:22 +00:00
{.gcsafe.}:
Hash256.fromEvmc ctx.host.get_code_hash(ctx.context, address.addr)
2020-01-16 04:20:13 +00:00
proc copyCode*(ctx: HostContext, address: EthAddress, codeOffset: int = 0): seq[byte] =
2020-01-16 15:15:20 +00:00
let size = ctx.getCodeSize(address).int
2020-01-16 04:20:13 +00:00
var address = toEvmc(address)
if size - codeOffset > 0:
result = newSeq[byte](size - codeOffset)
{.gcsafe.}:
let read = ctx.host.copy_code(ctx.context, address.addr,
code_offset.uint, result[0].addr, result.len.uint).int
2020-01-16 04:20:13 +00:00
doAssert(read == result.len)
proc selfdestruct*(ctx: HostContext, address, beneficiary: EthAddress) =
var
address = toEvmc(address)
beneficiary = toEvmc(beneficiary)
{.gcsafe.}:
ctx.host.selfdestruct(ctx.context, address.addr, beneficiary.addr)
2020-01-16 04:20:13 +00:00
2020-01-17 13:11:02 +00:00
proc emitLog*(ctx: HostContext, address: EthAddress, data: openArray[byte],
topics: ptr evmc_bytes32, topicsCount: int) =
2020-01-16 04:20:13 +00:00
var address = toEvmc(address)
2020-01-17 13:11:02 +00:00
{.gcsafe.}:
ctx.host.emit_log(ctx.context, address.addr, if data.len > 0: data[0].unsafeAddr else: nil,
data.len.uint, topics, topicsCount.uint)
2020-01-16 04:20:13 +00:00
proc call*(ctx: HostContext, msg: evmc_message): evmc_result =
ctx.host.call(ctx.context, msg.unsafeAddr)
#proc vmHost*(vmState: BaseVMState, gasPrice: GasInt, origin: EthAddress): HostContext =
# let host = nim_host_get_interface()
# let context = nim_host_create_context(cast[pointer](vmState), gasPrice, toEvmc(origin))
# result.init(host, context)
#
#proc destroy*(hc: HostContext) =
# nim_host_destroy_context(hc.context)