Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return bool from some Host methods #140

Merged
merged 4 commits into from
Sep 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions bindings/go/evmc/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,16 @@ static inline void go_exported_functions_type_checks()
storage_status = setStorage(context, address, uint256be, uint256be);

evmc_get_balance_fn get_balance_fn = NULL;
get_balance_fn(uint256be, context, address);
getBalance(uint256be, context, address);
bool_flag = get_balance_fn(uint256be, context, address);
bool_flag = getBalance(uint256be, context, address);

evmc_get_code_size_fn get_code_size_fn = NULL;
size = get_code_size_fn(context, address);
size = getCodeSize(context, address);
bool_flag = get_code_size_fn(&size, context, address);
bool_flag = getCodeSize(&size, context, address);

evmc_get_code_hash_fn get_code_hash_fn = NULL;
get_code_hash_fn(uint256be, context, address);
getCodeHash(uint256be, context, address);
bool_flag = get_code_hash_fn(uint256be, context, address);
bool_flag = getCodeHash(uint256be, context, address);

evmc_copy_code_fn copy_code_fn = NULL;
size = copy_code_fn(context, address, size, data, size);
Expand Down
32 changes: 23 additions & 9 deletions bindings/go/evmc/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ type HostContext interface {
AccountExists(addr common.Address) bool
GetStorage(addr common.Address, key common.Hash) common.Hash
SetStorage(addr common.Address, key common.Hash, value common.Hash) StorageStatus
GetBalance(addr common.Address) common.Hash
GetCodeSize(addr common.Address) int
GetCodeHash(addr common.Address) common.Hash
GetBalance(addr common.Address) (common.Hash, error)
GetCodeSize(addr common.Address) (int, error)
GetCodeHash(addr common.Address) (common.Hash, error)
GetCode(addr common.Address) []byte
Selfdestruct(addr common.Address, beneficiary common.Address)
GetTxContext() (gasPrice common.Hash, origin common.Address, coinbase common.Address, number int64, timestamp int64,
Expand Down Expand Up @@ -110,25 +110,39 @@ func setStorage(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address, pKey *C.struc
}

//export getBalance
func getBalance(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) {
func getBalance(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) C.bool {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
balance := ctx.GetBalance(goAddress(*pAddr))
balance, err := ctx.GetBalance(goAddress(*pAddr))
if err != nil {
return false
}
*pResult = evmcUint256be(balance)
return true
}

//export getCodeSize
func getCodeSize(pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) C.size_t {
func getCodeSize(pResult *C.size_t, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) C.bool {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
return C.size_t(ctx.GetCodeSize(goAddress(*pAddr)))
codeSize, err := ctx.GetCodeSize(goAddress(*pAddr))
if err != nil {
return false
}
*pResult = C.size_t(codeSize)
return true
}

//export getCodeHash
func getCodeHash(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) {
func getCodeHash(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, pAddr *C.struct_evmc_address) C.bool {
idx := int((*C.struct_extended_context)(pCtx).index)
ctx := getHostContext(idx)
*pResult = evmcUint256be(ctx.GetCodeHash(goAddress(*pAddr)))
codeHash, err := ctx.GetCodeHash(goAddress(*pAddr))
if err != nil {
return false
}
*pResult = evmcUint256be(codeHash)
return true
}

//export copyCode
Expand Down
75 changes: 54 additions & 21 deletions examples/example_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,42 @@

#include <evmc/helpers.h>

#include <cstring>
#include <map>

/// The comparator for std::map<evmc_address, ...>.
bool operator<(const evmc_address& a, const evmc_address& b)
{
return std::memcmp(a.bytes, b.bytes, sizeof(a)) < 0;
}

/// The comparator for std::map<evmc_uint256be, ...>.
bool operator<(const evmc_uint256be& a, const evmc_uint256be& b)
{
return std::memcmp(a.bytes, b.bytes, sizeof(a)) < 0;
}

struct account
{
evmc_uint256be balance = {};
size_t code_size = 0;
evmc_uint256be code_hash = {};
std::map<evmc_uint256be, evmc_uint256be> storage;
};

struct example_host_context : evmc_context
{
example_host_context();

evmc_tx_context tx_context = {};
};

static evmc_uint256be balance(evmc_context* context, const evmc_address* address)
{
(void)context;
(void)address;
evmc_uint256be ret = {{1, 2, 3, 4}};
return ret;
}
std::map<evmc_address, account> accounts;
};

static bool account_exists(evmc_context* context, const evmc_address* address)
{
(void)context;
(void)address;
return false;
example_host_context* host = static_cast<example_host_context*>(context);
return host->accounts.find(*address) != host->accounts.end();
}

static void get_storage(evmc_uint256be* result,
Expand All @@ -54,25 +70,42 @@ static enum evmc_storage_status set_storage(evmc_context* context,
return EVMC_STORAGE_UNCHANGED;
}

static void get_balance(evmc_uint256be* result, evmc_context* context, const evmc_address* address)
static bool get_balance(evmc_uint256be* result, evmc_context* context, const evmc_address* address)
{
*result = balance(context, address);
example_host_context* host = static_cast<example_host_context*>(context);
auto it = host->accounts.find(*address);
if (it != host->accounts.end())
{
*result = it->second.balance;
return true;
}
return false;
}

static size_t get_code_size(evmc_context* context, const evmc_address* address)
static bool get_code_size(size_t* result, evmc_context* context, const evmc_address* address)
{
(void)context;
(void)address;
return 0;
example_host_context* host = static_cast<example_host_context*>(context);
auto it = host->accounts.find(*address);
if (it != host->accounts.end())
{
*result = it->second.code_size;
return true;
}
return false;
}

static void get_code_hash(evmc_uint256be* result,
static bool get_code_hash(evmc_uint256be* result,
evmc_context* context,
const evmc_address* address)
{
(void)result;
(void)context;
(void)address;
example_host_context* host = static_cast<example_host_context*>(context);
auto it = host->accounts.find(*address);
if (it != host->accounts.end())
{
*result = it->second.code_hash;
return true;
}
return false;
}

static size_t copy_code(evmc_context* context,
Expand Down
58 changes: 41 additions & 17 deletions include/evmc/evmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,36 +475,60 @@ typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_context* con
/**
* Get balance callback function.
*
* This callback function is used by an EVM to query the balance of the given
* address.
* @param[out] result The returned balance value.
* @param context The pointer to the Host execution context.
* @see ::evmc_context.
* @param address The address.
* This callback function is used by a VM to query the balance of the given address.
*
* @param[out] result The pointer to the place where to put the result balance.
* The pointed memory is only modified when the function returns true.
* The pointer MUST NOT be null.
* @param context The pointer to the Host execution context.
* @param address The address of the account.
* @return If the account exists its balance is put at the location
* pointed by @p result and true is returned.
* If the account does not exist false is returned without
* modifying the memory pointed by @p result.
*/
typedef void (*evmc_get_balance_fn)(struct evmc_uint256be* result,
typedef bool (*evmc_get_balance_fn)(struct evmc_uint256be* result,
struct evmc_context* context,
const struct evmc_address* address);

/**
* Get code size callback function.
*
* This callback function is used by an EVM to get the size of the code stored
* in the account at the given address. For accounts not having a code, this
* function returns 0.
* This callback function is used by a VM to get the size of the code stored
* in the account at the given address.
*
* @param[out] result The pointer to the place where to put the result code size.
* The pointed memory is only modified when the function returns true.
* The pointer MUST NOT be null.
* @param context The pointer to the Host execution context.
* @param address The address of the account.
* @return If the account exists the size of its code is put at the location
* pointed by @p result and true is returned.
* If the account does not exist false is returned without
* modifying the memory pointed by @p result.
*/
typedef size_t (*evmc_get_code_size_fn)(struct evmc_context* context,
const struct evmc_address* address);
typedef bool (*evmc_get_code_size_fn)(size_t* result,
struct evmc_context* context,
const struct evmc_address* address);

/**
* Get code size callback function.
*
* This callback function is used by an EVM to get the keccak256 hash of the code stored
* in the account at the given address. For accounts not having a code, this
* function returns keccak256 hash of empty data. For accounts not existing in the state,
* this function returns 0.
* This callback function is used by a VM to get the keccak256 hash of the code stored
* in the account at the given address. For existing accounts not having a code, this
* function returns keccak256 hash of empty data.
*
* @param[out] result The pointer to the place where to put the result code hash.
* The pointed memory is only modified when the function returns true.
* The pointer MUST NOT be null.
* @param context The pointer to the Host execution context.
* @param address The address of the account.
* @return If the account exists the hash of its code is put at the location
* pointed by @p result and true is returned.
* If the account does not exist false is returned without
* modifying the memory pointed by @p result.
*/
typedef void (*evmc_get_code_hash_fn)(struct evmc_uint256be* result,
typedef bool (*evmc_get_code_hash_fn)(struct evmc_uint256be* result,
struct evmc_context* context,
const struct evmc_address* address);

Expand Down