Skip to content

Commit

Permalink
Merge pull request #427 from ethereum/host_interface
Browse files Browse the repository at this point in the history
Move evmc_host_interface out of evmc_host_context
  • Loading branch information
chfast authored Nov 5, 2019
2 parents bd65396 + 4645d97 commit a15e493
Show file tree
Hide file tree
Showing 17 changed files with 224 additions and 227 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ and this project adheres to [Semantic Versioning].
[[#430](https://github.com/ethereum/evmc/pull/430)]
- The `evmc_context` renamed to `evmc_host_context`.
[[#426](https://github.com/ethereum/evmc/pull/426)]
- The `evmc_host_interface` is now separated from `evmc_host_context`.
This simplifies language bindings which implement the `evmc_host_interface`.
[[#427](https://github.com/ethereum/evmc/pull/427)]
- The `evmc::vm` renamed to `evmc::VM` in C++ API.
[[#252](https://github.com/ethereum/evmc/pull/252)]
- Previously deprecated `helpers.hpp` header file has been removed.
Expand Down
24 changes: 9 additions & 15 deletions bindings/go/evmc/evmc.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,10 @@ static inline enum evmc_set_option_result set_option(struct evmc_vm* vm, char* n
return ret;
}
struct extended_context
{
struct evmc_host_context context;
int64_t index;
};
extern const struct evmc_host_interface evmc_go_host;
static struct evmc_result execute_wrapper(struct evmc_vm* vm,
int64_t context_index, enum evmc_revision rev,
uintptr_t context_index, enum evmc_revision rev,
enum evmc_call_kind kind, uint32_t flags, int32_t depth, int64_t gas,
const evmc_address* destination, const evmc_address* sender,
const uint8_t* input_data, size_t input_size, const evmc_uint256be* value,
Expand All @@ -51,8 +45,8 @@ static struct evmc_result execute_wrapper(struct evmc_vm* vm,
*create2_salt,
};
struct extended_context ctx = {{&evmc_go_host}, context_index};
return evmc_execute(vm, &ctx.context, rev, &msg, code, code_size);
struct evmc_host_context* context = (struct evmc_host_context*)context_index;
return evmc_execute(vm, &evmc_go_host, context, rev, &msg, code, code_size);
}
*/
import "C"
Expand Down Expand Up @@ -242,7 +236,7 @@ func (vm *VM) Execute(ctx HostContext, rev Revision,
evmcSender := evmcAddress(sender)
evmcValue := evmcBytes32(value)
evmcCreate2Salt := evmcBytes32(create2Salt)
result := C.execute_wrapper(vm.handle, C.int64_t(ctxId), uint32(rev),
result := C.execute_wrapper(vm.handle, C.uintptr_t(ctxId), uint32(rev),
C.enum_evmc_call_kind(kind), flags, C.int32_t(depth), C.int64_t(gas),
&evmcDestination, &evmcSender, bytesPtr(input), C.size_t(len(input)), &evmcValue,
bytesPtr(code), C.size_t(len(code)), &evmcCreate2Salt)
Expand All @@ -262,12 +256,12 @@ func (vm *VM) Execute(ctx HostContext, rev Revision,
}

var (
hostContextCounter int
hostContextMap = map[int]HostContext{}
hostContextCounter uintptr
hostContextMap = map[uintptr]HostContext{}
hostContextMapMu sync.Mutex
)

func addHostContext(ctx HostContext) int {
func addHostContext(ctx HostContext) uintptr {
hostContextMapMu.Lock()
id := hostContextCounter
hostContextCounter++
Expand All @@ -276,13 +270,13 @@ func addHostContext(ctx HostContext) int {
return id
}

func removeHostContext(id int) {
func removeHostContext(id uintptr) {
hostContextMapMu.Lock()
delete(hostContextMap, id)
hostContextMapMu.Unlock()
}

func getHostContext(idx int) HostContext {
func getHostContext(idx uintptr) HostContext {
hostContextMapMu.Lock()
ctx := hostContextMap[idx]
hostContextMapMu.Unlock()
Expand Down
42 changes: 12 additions & 30 deletions bindings/go/evmc/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ package evmc
#include <evmc/evmc.h>
#include <evmc/helpers.h>
struct extended_context
{
struct evmc_host_context context;
int64_t index;
};
*/
import "C"
import (
Expand Down Expand Up @@ -99,50 +93,43 @@ type HostContext interface {

//export accountExists
func accountExists(pCtx unsafe.Pointer, pAddr *C.evmc_address) C.bool {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
return C.bool(ctx.AccountExists(goAddress(*pAddr)))
}

//export getStorage
func getStorage(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address, pKey *C.evmc_bytes32) C.evmc_bytes32 {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
return evmcBytes32(ctx.GetStorage(goAddress(*pAddr), goHash(*pKey)))
}

//export setStorage
func setStorage(pCtx unsafe.Pointer, pAddr *C.evmc_address, pKey *C.evmc_bytes32, pVal *C.evmc_bytes32) C.enum_evmc_storage_status {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
return C.enum_evmc_storage_status(ctx.SetStorage(goAddress(*pAddr), goHash(*pKey), goHash(*pVal)))
}

//export getBalance
func getBalance(pCtx unsafe.Pointer, pAddr *C.evmc_address) C.evmc_uint256be {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
return evmcBytes32(ctx.GetBalance(goAddress(*pAddr)))
}

//export getCodeSize
func getCodeSize(pCtx unsafe.Pointer, pAddr *C.evmc_address) C.size_t {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
return C.size_t(ctx.GetCodeSize(goAddress(*pAddr)))
}

//export getCodeHash
func getCodeHash(pCtx unsafe.Pointer, pAddr *C.evmc_address) C.evmc_bytes32 {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
return evmcBytes32(ctx.GetCodeHash(goAddress(*pAddr)))
}

//export copyCode
func copyCode(pCtx unsafe.Pointer, pAddr *C.evmc_address, offset C.size_t, p *C.uint8_t, size C.size_t) C.size_t {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
code := ctx.GetCode(goAddress(*pAddr))
length := C.size_t(len(code))

Expand All @@ -162,15 +149,13 @@ func copyCode(pCtx unsafe.Pointer, pAddr *C.evmc_address, offset C.size_t, p *C.

//export selfdestruct
func selfdestruct(pCtx unsafe.Pointer, pAddr *C.evmc_address, pBeneficiary *C.evmc_address) {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
ctx.Selfdestruct(goAddress(*pAddr), goAddress(*pBeneficiary))
}

//export getTxContext
func getTxContext(pCtx unsafe.Pointer) C.struct_evmc_tx_context {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))

txContext := ctx.GetTxContext()

Expand All @@ -188,15 +173,13 @@ func getTxContext(pCtx unsafe.Pointer) C.struct_evmc_tx_context {

//export getBlockHash
func getBlockHash(pCtx unsafe.Pointer, number int64) C.evmc_bytes32 {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))
return evmcBytes32(ctx.GetBlockHash(number))
}

//export emitLog
func emitLog(pCtx unsafe.Pointer, pAddr *C.evmc_address, pData unsafe.Pointer, dataSize C.size_t, pTopics unsafe.Pointer, topicsCount C.size_t) {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))

// FIXME: Optimize memory copy
data := C.GoBytes(pData, C.int(dataSize))
Expand All @@ -213,8 +196,7 @@ func emitLog(pCtx unsafe.Pointer, pAddr *C.evmc_address, pData unsafe.Pointer, d

//export call
func call(pCtx unsafe.Pointer, msg *C.struct_evmc_message) C.struct_evmc_result {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
ctx := getHostContext(uintptr(pCtx))

kind := CallKind(msg.kind)
output, gasLeft, createAddr, err := ctx.Call(kind, goAddress(msg.destination), goAddress(msg.sender), goHash(msg.value).Big(),
Expand Down
12 changes: 8 additions & 4 deletions bindings/rust/evmc-declare/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ fn build_execute_fn(names: &VMNameSet) -> proc_macro2::TokenStream {
quote! {
extern "C" fn __evmc_execute(
instance: *mut ::evmc_vm::ffi::evmc_vm,
host: *const ::evmc_vm::ffi::evmc_host_interface,
context: *mut ::evmc_vm::ffi::evmc_host_context,
revision: ::evmc_vm::ffi::evmc_revision,
msg: *const ::evmc_vm::ffi::evmc_message,
Expand All @@ -345,14 +346,14 @@ fn build_execute_fn(names: &VMNameSet) -> proc_macro2::TokenStream {
use evmc_vm::EvmcVm;

// TODO: context is optional in case of the "precompiles" capability
if instance.is_null() || context.is_null() || msg.is_null() || (code.is_null() && code_size != 0) {
if instance.is_null() || host.is_null() || msg.is_null() || (code.is_null() && code_size != 0) {
// These are irrecoverable errors that violate the EVMC spec.
std::process::abort();
}

assert!(!instance.is_null());
// TODO: context is optional in case of the "precompiles" capability
assert!(!context.is_null());
// TODO: host is optional in case of the "precompiles" capability
assert!(!host.is_null());
assert!(!msg.is_null());

let execution_message: ::evmc_vm::ExecutionMessage = unsafe {
Expand All @@ -376,7 +377,10 @@ fn build_execute_fn(names: &VMNameSet) -> proc_macro2::TokenStream {

let result = ::std::panic::catch_unwind(|| {
let mut execution_context = unsafe {
::evmc_vm::ExecutionContext::new(context.as_mut().expect("EVMC context is null"))
::evmc_vm::ExecutionContext::new(
host.as_ref().expect("EVMC host is null"),
context,
)
};
container.execute(revision, code_ref, &execution_message, &mut execution_context)
});
Expand Down
1 change: 1 addition & 0 deletions bindings/rust/evmc-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fn gen_bindings() {
.rustified_enum("*")
// force deriving the Hash trait on basic types (address, bytes32)
.derive_hash(true)
.opaque_type("evmc_host_context")
.generate()
.expect("Unable to generate bindings");

Expand Down
11 changes: 6 additions & 5 deletions bindings/rust/evmc-vm/src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ mod tests {
use crate::{ExecutionContext, ExecutionMessage, ExecutionResult};

struct TestVm {}

impl EvmcVm for TestVm {
fn init() -> Self {
TestVm {}
Expand Down Expand Up @@ -131,33 +132,33 @@ mod tests {
get_block_hash: None,
emit_log: None,
};
let mut backing_context = ::evmc_sys::evmc_host_context { host: &host };
let host_context = std::ptr::null_mut();

let mut context = ExecutionContext::new(&mut backing_context);
let mut context = ExecutionContext::new(&host, host_context);
let container = EvmcContainer::<TestVm>::new(instance);
assert_eq!(
container
.execute(
evmc_sys::evmc_revision::EVMC_PETERSBURG,
&code,
&message,
&mut context
&mut context,
)
.status_code(),
::evmc_sys::evmc_status_code::EVMC_FAILURE
);

let ptr = unsafe { EvmcContainer::into_ffi_pointer(container) };

let mut context = ExecutionContext::new(&mut backing_context);
let mut context = ExecutionContext::new(&host, host_context);
let container = unsafe { EvmcContainer::<TestVm>::from_ffi_pointer(ptr) };
assert_eq!(
container
.execute(
evmc_sys::evmc_revision::EVMC_PETERSBURG,
&code,
&message,
&mut context
&mut context,
)
.status_code(),
::evmc_sys::evmc_status_code::EVMC_FAILURE
Expand Down
Loading

0 comments on commit a15e493

Please sign in to comment.