mirror of
https://github.com/status-im/evmc.git
synced 2025-02-23 08:28:15 +00:00
EVM-C: Improve execution context opaque struct
This commit is contained in:
parent
4c2202ebcf
commit
581ba3ef2e
@ -4,14 +4,14 @@
|
||||
#include "evm.h"
|
||||
|
||||
|
||||
struct evm_uint256be balance(struct evm_env* env,
|
||||
struct evm_uint256be balance(struct evm_context* context,
|
||||
const struct evm_uint160be* address)
|
||||
{
|
||||
struct evm_uint256be ret = {.bytes = {1, 2, 3, 4}};
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct evm_uint160be address(struct evm_env* env)
|
||||
struct evm_uint160be address(struct evm_context* context)
|
||||
{
|
||||
struct evm_uint160be ret = {.bytes = {1, 2, 3, 4}};
|
||||
return ret;
|
||||
@ -24,7 +24,7 @@ static void print_address(const struct evm_uint160be* address)
|
||||
printf("%x", address->bytes[i] & 0xff);
|
||||
}
|
||||
|
||||
static int account_exists(struct evm_env* env,
|
||||
static int account_exists(struct evm_context* context,
|
||||
const struct evm_uint160be* address) {
|
||||
printf("EVM-C: EXISTS @");
|
||||
print_address(address);
|
||||
@ -33,7 +33,7 @@ static int account_exists(struct evm_env* env,
|
||||
}
|
||||
|
||||
static void get_storage(struct evm_uint256be* result,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
const struct evm_uint160be* address,
|
||||
const struct evm_uint256be* key)
|
||||
{
|
||||
@ -42,7 +42,7 @@ static void get_storage(struct evm_uint256be* result,
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void set_storage(struct evm_env* env,
|
||||
static void set_storage(struct evm_context* context,
|
||||
const struct evm_uint160be* address,
|
||||
const struct evm_uint256be* key,
|
||||
const struct evm_uint256be* value)
|
||||
@ -53,17 +53,17 @@ static void set_storage(struct evm_env* env,
|
||||
}
|
||||
|
||||
static void get_balance(struct evm_uint256be* result,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
const struct evm_uint160be* address)
|
||||
{
|
||||
printf("EVM-C: BALANCE @");
|
||||
print_address(address);
|
||||
printf("\n");
|
||||
*result = balance(env, address);
|
||||
*result = balance(context, address);
|
||||
}
|
||||
|
||||
static size_t get_code(const uint8_t** code,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
const struct evm_uint160be* address)
|
||||
{
|
||||
printf("EVM-C: CODE @");
|
||||
@ -72,7 +72,7 @@ static size_t get_code(const uint8_t** code,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void selfdestruct(struct evm_env* env,
|
||||
static void selfdestruct(struct evm_context* context,
|
||||
const struct evm_uint160be* address,
|
||||
const struct evm_uint160be* beneficiary)
|
||||
{
|
||||
@ -84,19 +84,19 @@ static void selfdestruct(struct evm_env* env,
|
||||
}
|
||||
|
||||
static void call(struct evm_result* result,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
const struct evm_message* msg)
|
||||
{
|
||||
printf("EVM-C: CALL (depth: %d)\n", msg->depth);
|
||||
result->code = EVM_FAILURE;
|
||||
}
|
||||
|
||||
static void get_tx_context(struct evm_tx_context* result, struct evm_env* env)
|
||||
static void get_tx_context(struct evm_tx_context* result, struct evm_context* context)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void get_block_hash(struct evm_uint256be* result, struct evm_env* env,
|
||||
static void get_block_hash(struct evm_uint256be* result, struct evm_context* context,
|
||||
int64_t number)
|
||||
{
|
||||
|
||||
@ -105,7 +105,7 @@ static void get_block_hash(struct evm_uint256be* result, struct evm_env* env,
|
||||
/// EVM log callback.
|
||||
///
|
||||
/// @note The `evm_log` name is used to avoid conflict with `log()` C function.
|
||||
static void evm_log(struct evm_env* env, const struct evm_uint160be* address,
|
||||
static void evm_log(struct evm_context* context, const struct evm_uint160be* address,
|
||||
const uint8_t* data, size_t data_size,
|
||||
const struct evm_uint256be topics[], size_t topics_count)
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ static void free_result_output_data(struct evm_result const* result)
|
||||
}
|
||||
|
||||
static struct evm_result execute(struct evm_instance* instance,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
enum evm_mode mode,
|
||||
const struct evm_message* msg,
|
||||
const uint8_t* code,
|
||||
@ -96,9 +96,9 @@ static struct evm_result execute(struct evm_instance* instance,
|
||||
strncmp((const char*)code, counter, code_size)) {
|
||||
struct evm_uint256be value;
|
||||
const struct evm_uint256be index = {{0,}};
|
||||
vm->host->get_storage(&value, env, &msg->address, &index);
|
||||
vm->host->get_storage(&value, context, &msg->address, &index);
|
||||
value.bytes[31] += 1;
|
||||
vm->host->set_storage(env, &msg->address, &index, &value);
|
||||
vm->host->set_storage(context, &msg->address, &index, &value);
|
||||
ret.code = EVM_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/// EVM-C -- C interface to Ethereum Virtual Machine
|
||||
///
|
||||
/// ## High level design rules
|
||||
///
|
||||
/// 1. Pass function arguments and results by value.
|
||||
/// This rule comes from modern C++ and tries to avoid costly alias analysis
|
||||
/// needed for optimization. As the result we have a lots of complex structs
|
||||
@ -10,6 +11,12 @@
|
||||
/// The interface also tries to match host application "natural" endianess.
|
||||
/// I would like to know what endianess you use and where.
|
||||
///
|
||||
/// ## Terms
|
||||
///
|
||||
/// 1. EVM -- an Ethereum Virtual Machine instance/implementation.
|
||||
/// 2. Host -- an entity controlling the EVM. The Host requests code execution
|
||||
/// and responses to EVM queries by callback functions.
|
||||
///
|
||||
/// @defgroup EVMC EVM-C
|
||||
/// @{
|
||||
#ifndef EVM_H
|
||||
@ -29,9 +36,12 @@ enum {
|
||||
EVM_ABI_VERSION = 0
|
||||
};
|
||||
|
||||
/// Opaque struct representing execution environment managed by the host
|
||||
/// application.
|
||||
struct evm_env;
|
||||
/// Opaque structure representing execution context managed by the Host.
|
||||
///
|
||||
/// The Host MAY pass the pointer to the Host execution context to
|
||||
/// ::evm_execute_fn. The EVM MUST pass the same pointer back to the Host in
|
||||
/// every callback function.
|
||||
struct evm_context {};
|
||||
|
||||
/// Big-endian 256-bit integer.
|
||||
///
|
||||
@ -87,10 +97,10 @@ struct evm_tx_context {
|
||||
};
|
||||
|
||||
typedef void (*evm_get_tx_context_fn)(struct evm_tx_context* result,
|
||||
struct evm_env* env);
|
||||
struct evm_context* context);
|
||||
|
||||
typedef void (*evm_get_block_hash_fn)(struct evm_uint256be* result,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
int64_t number);
|
||||
|
||||
/// The execution result code.
|
||||
@ -187,11 +197,11 @@ struct evm_result {
|
||||
///
|
||||
/// This callback function is used by the EVM to check if
|
||||
/// there exists an account at given address.
|
||||
/// @param env Pointer to execution environment managed by the host
|
||||
/// application.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param address The address of the account the query is about.
|
||||
/// @return 1 if exists, 0 otherwise.
|
||||
typedef int (*evm_account_exists_fn)(struct evm_env* env,
|
||||
typedef int (*evm_account_exists_fn)(struct evm_context* context,
|
||||
const struct evm_uint160be* address);
|
||||
|
||||
/// Get storage callback function.
|
||||
@ -199,12 +209,12 @@ typedef int (*evm_account_exists_fn)(struct evm_env* env,
|
||||
/// This callback function is used by an EVM to query the given contract
|
||||
/// storage entry.
|
||||
/// @param[out] result The returned storage value.
|
||||
/// @param env Pointer to execution environment managed by the host
|
||||
/// application.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param address The address of the contract.
|
||||
/// @param key The index of the storage entry.
|
||||
typedef void (*evm_get_storage_fn)(struct evm_uint256be* result,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
const struct evm_uint160be* address,
|
||||
const struct evm_uint256be* key);
|
||||
|
||||
@ -212,12 +222,12 @@ typedef void (*evm_get_storage_fn)(struct evm_uint256be* result,
|
||||
///
|
||||
/// This callback function is used by an EVM to update the given contract
|
||||
/// storage entry.
|
||||
/// @param env Pointer to execution environment managed by the host
|
||||
/// application.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param address The address of the contract.
|
||||
/// @param key The index of the storage entry.
|
||||
/// @param value The value to be stored.
|
||||
typedef void (*evm_set_storage_fn)(struct evm_env* env,
|
||||
typedef void (*evm_set_storage_fn)(struct evm_context* context,
|
||||
const struct evm_uint160be* address,
|
||||
const struct evm_uint256be* key,
|
||||
const struct evm_uint256be* value);
|
||||
@ -227,11 +237,11 @@ typedef void (*evm_set_storage_fn)(struct evm_env* env,
|
||||
/// This callback function is used by an EVM to query the balance of the given
|
||||
/// address.
|
||||
/// @param[out] result The returned balance value.
|
||||
/// @param env Pointer to execution environment managed by the host
|
||||
/// application.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param address The address.
|
||||
typedef void (*evm_get_balance_fn)(struct evm_uint256be* result,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
const struct evm_uint160be* address);
|
||||
|
||||
/// Get code callback function.
|
||||
@ -241,22 +251,23 @@ typedef void (*evm_get_balance_fn)(struct evm_uint256be* result,
|
||||
/// @param[out] result_code The pointer to the contract code. This argument is
|
||||
/// optional. If NULL is provided, the host MUST only
|
||||
/// return the code size.
|
||||
/// @param env Pointer to execution context managed by the Host.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param address The address of the contract.
|
||||
/// @return The size of the code.
|
||||
typedef size_t (*evm_get_code_fn)(const uint8_t** result_code,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
const struct evm_uint160be* address);
|
||||
|
||||
/// Selfdestruct callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to SELFDESTRUCT given contract.
|
||||
/// @param env The pointer to the execution environment managed by
|
||||
/// the host application.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param address The address of the contract to be selfdestructed.
|
||||
/// @param beneficiary The address where the remaining ETH is going to be
|
||||
/// transferred.
|
||||
typedef void (*evm_selfdestruct_fn)(struct evm_env* env,
|
||||
typedef void (*evm_selfdestruct_fn)(struct evm_context* context,
|
||||
const struct evm_uint160be* address,
|
||||
const struct evm_uint160be* beneficiary);
|
||||
|
||||
@ -264,15 +275,15 @@ typedef void (*evm_selfdestruct_fn)(struct evm_env* env,
|
||||
///
|
||||
/// This callback function is used by an EVM to inform about a LOG that happened
|
||||
/// during an EVM bytecode execution.
|
||||
/// @param env The pointer to execution environment managed by
|
||||
/// the host application.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param address The address of the contract that generated the log.
|
||||
/// @param data The pointer to unindexed data attached to the log.
|
||||
/// @param data_size The length of the data.
|
||||
/// @param topics The pointer to the array of topics attached to the log.
|
||||
/// @param topics_count The number of the topics. Valid values are between
|
||||
/// 0 and 4 inclusively.
|
||||
typedef void (*evm_log_fn)(struct evm_env* env,
|
||||
typedef void (*evm_log_fn)(struct evm_context* context,
|
||||
const struct evm_uint160be* address,
|
||||
const uint8_t* data,
|
||||
size_t data_size,
|
||||
@ -282,22 +293,19 @@ typedef void (*evm_log_fn)(struct evm_env* env,
|
||||
/// Pointer to the callback function supporting EVM calls.
|
||||
///
|
||||
/// @param[out] result Call result.
|
||||
/// @param env Pointer to execution environment managed by the host
|
||||
/// application.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evm_context.
|
||||
/// @param msg Call parameters.
|
||||
typedef void (*evm_call_fn)(
|
||||
struct evm_result* result,
|
||||
struct evm_env* env,
|
||||
typedef void (*evm_call_fn)(struct evm_result* result,
|
||||
struct evm_context* context,
|
||||
const struct evm_message* msg);
|
||||
|
||||
/// EVM Host interface.
|
||||
/// The Host interface.
|
||||
///
|
||||
/// The set of all callback functions expected by EVM instances. This is C
|
||||
/// realisation of OOP interface (only virtual methods, no data).
|
||||
/// Host implementations SHOULD create constant singletons of this (similar
|
||||
/// Host implementations SHOULD create constant singletons of this (similarly
|
||||
/// to vtables) to lower the maintenance and memory management cost.
|
||||
///
|
||||
/// @todo Merge evm_host with evm_env?
|
||||
struct evm_host {
|
||||
evm_account_exists_fn account_exists;
|
||||
evm_get_storage_fn get_storage;
|
||||
@ -363,8 +371,8 @@ enum evm_mode {
|
||||
/// All the fun is here. This function actually does something useful.
|
||||
///
|
||||
/// @param instance A EVM instance.
|
||||
/// @param env A pointer to the execution environment provided by the
|
||||
/// user and passed to callback functions.
|
||||
/// @param context The pointer to the Host execution context to be passed
|
||||
/// to callback functions. @see ::evm_context.
|
||||
/// @param mode EVM compatibility mode.
|
||||
/// @param code_hash A hash of the bytecode, usually Keccak. The EVM uses it
|
||||
/// as the code identifier. A EVM implementation is able to
|
||||
@ -378,7 +386,7 @@ enum evm_mode {
|
||||
/// @param value Call value.
|
||||
/// @return All execution results.
|
||||
typedef struct evm_result (*evm_execute_fn)(struct evm_instance* instance,
|
||||
struct evm_env* env,
|
||||
struct evm_context* context,
|
||||
enum evm_mode mode,
|
||||
const struct evm_message* msg,
|
||||
uint8_t const* code,
|
||||
|
Loading…
x
Reference in New Issue
Block a user