mirror of https://github.com/status-im/evmc.git
Merge pull request #131 from ethereum/evmc-no-factory
EVM-C: Remove factory class
This commit is contained in:
commit
bbd5f0d34e
|
@ -5,19 +5,19 @@
|
||||||
|
|
||||||
|
|
||||||
struct evm_uint256be balance(struct evm_context* context,
|
struct evm_uint256be balance(struct evm_context* context,
|
||||||
const struct evm_uint160be* address)
|
const struct evm_address* address)
|
||||||
{
|
{
|
||||||
struct evm_uint256be ret = {.bytes = {1, 2, 3, 4}};
|
struct evm_uint256be ret = {.bytes = {1, 2, 3, 4}};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct evm_uint160be address(struct evm_context* context)
|
struct evm_address address(struct evm_context* context)
|
||||||
{
|
{
|
||||||
struct evm_uint160be ret = {.bytes = {1, 2, 3, 4}};
|
struct evm_address ret = {.bytes = {1, 2, 3, 4}};
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_address(const struct evm_uint160be* address)
|
static void print_address(const struct evm_address* address)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < sizeof(address->bytes); ++i)
|
for (i = 0; i < sizeof(address->bytes); ++i)
|
||||||
|
@ -25,7 +25,7 @@ static void print_address(const struct evm_uint160be* address)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int account_exists(struct evm_context* context,
|
static int account_exists(struct evm_context* context,
|
||||||
const struct evm_uint160be* address) {
|
const struct evm_address* address) {
|
||||||
printf("EVM-C: EXISTS @");
|
printf("EVM-C: EXISTS @");
|
||||||
print_address(address);
|
print_address(address);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -34,7 +34,7 @@ static int account_exists(struct evm_context* context,
|
||||||
|
|
||||||
static void get_storage(struct evm_uint256be* result,
|
static void get_storage(struct evm_uint256be* result,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
const struct evm_uint160be* address,
|
const struct evm_address* address,
|
||||||
const struct evm_uint256be* key)
|
const struct evm_uint256be* key)
|
||||||
{
|
{
|
||||||
printf("EVM-C: SLOAD @");
|
printf("EVM-C: SLOAD @");
|
||||||
|
@ -43,7 +43,7 @@ static void get_storage(struct evm_uint256be* result,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_storage(struct evm_context* context,
|
static void set_storage(struct evm_context* context,
|
||||||
const struct evm_uint160be* address,
|
const struct evm_address* address,
|
||||||
const struct evm_uint256be* key,
|
const struct evm_uint256be* key,
|
||||||
const struct evm_uint256be* value)
|
const struct evm_uint256be* value)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ static void set_storage(struct evm_context* context,
|
||||||
|
|
||||||
static void get_balance(struct evm_uint256be* result,
|
static void get_balance(struct evm_uint256be* result,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
const struct evm_uint160be* address)
|
const struct evm_address* address)
|
||||||
{
|
{
|
||||||
printf("EVM-C: BALANCE @");
|
printf("EVM-C: BALANCE @");
|
||||||
print_address(address);
|
print_address(address);
|
||||||
|
@ -64,7 +64,7 @@ static void get_balance(struct evm_uint256be* result,
|
||||||
|
|
||||||
static size_t get_code(const uint8_t** code,
|
static size_t get_code(const uint8_t** code,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
const struct evm_uint160be* address)
|
const struct evm_address* address)
|
||||||
{
|
{
|
||||||
printf("EVM-C: CODE @");
|
printf("EVM-C: CODE @");
|
||||||
print_address(address);
|
print_address(address);
|
||||||
|
@ -73,8 +73,8 @@ static size_t get_code(const uint8_t** code,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void selfdestruct(struct evm_context* context,
|
static void selfdestruct(struct evm_context* context,
|
||||||
const struct evm_uint160be* address,
|
const struct evm_address* address,
|
||||||
const struct evm_uint160be* beneficiary)
|
const struct evm_address* beneficiary)
|
||||||
{
|
{
|
||||||
printf("EVM-C: SELFDESTRUCT ");
|
printf("EVM-C: SELFDESTRUCT ");
|
||||||
print_address(address);
|
print_address(address);
|
||||||
|
@ -88,7 +88,7 @@ static void call(struct evm_result* result,
|
||||||
const struct evm_message* msg)
|
const struct evm_message* msg)
|
||||||
{
|
{
|
||||||
printf("EVM-C: CALL (depth: %d)\n", msg->depth);
|
printf("EVM-C: CALL (depth: %d)\n", msg->depth);
|
||||||
result->code = EVM_FAILURE;
|
result->status_code = EVM_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_tx_context(struct evm_tx_context* result, struct evm_context* context)
|
static void get_tx_context(struct evm_tx_context* result, struct evm_context* context)
|
||||||
|
@ -105,14 +105,14 @@ static void get_block_hash(struct evm_uint256be* result, struct evm_context* con
|
||||||
/// EVM log callback.
|
/// EVM log callback.
|
||||||
///
|
///
|
||||||
/// @note The `evm_log` name is used to avoid conflict with `log()` C function.
|
/// @note The `evm_log` name is used to avoid conflict with `log()` C function.
|
||||||
static void evm_log(struct evm_context* context, const struct evm_uint160be* address,
|
static void evm_log(struct evm_context* context, const struct evm_address* address,
|
||||||
const uint8_t* data, size_t data_size,
|
const uint8_t* data, size_t data_size,
|
||||||
const struct evm_uint256be topics[], size_t topics_count)
|
const struct evm_uint256be topics[], size_t topics_count)
|
||||||
{
|
{
|
||||||
printf("EVM-C: LOG%d\n", (int)topics_count);
|
printf("EVM-C: LOG%d\n", (int)topics_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct evm_host example_host = {
|
static const struct evm_context_fn_table ctx_fn_table = {
|
||||||
account_exists,
|
account_exists,
|
||||||
get_storage,
|
get_storage,
|
||||||
set_storage,
|
set_storage,
|
||||||
|
@ -127,29 +127,29 @@ static const struct evm_host example_host = {
|
||||||
|
|
||||||
/// Example how the API is supposed to be used.
|
/// Example how the API is supposed to be used.
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
struct evm_factory factory = examplevm_get_factory();
|
struct evm_instance* jit = examplevm_create();
|
||||||
if (factory.abi_version != EVM_ABI_VERSION)
|
if (jit->abi_version != EVM_ABI_VERSION)
|
||||||
return 1; // Incompatible ABI version.
|
return 1; // Incompatible ABI version.
|
||||||
|
|
||||||
struct evm_instance* jit = factory.create(&example_host);
|
|
||||||
|
|
||||||
uint8_t const code[] = "Place some EVM bytecode here";
|
uint8_t const code[] = "Place some EVM bytecode here";
|
||||||
const size_t code_size = sizeof(code);
|
const size_t code_size = sizeof(code);
|
||||||
struct evm_uint256be code_hash = {.bytes = {1, 2, 3,}};
|
struct evm_uint256be code_hash = {.bytes = {1, 2, 3,}};
|
||||||
uint8_t const input[] = "Hello World!";
|
uint8_t const input[] = "Hello World!";
|
||||||
struct evm_uint256be value = {{1, 0,}};
|
struct evm_uint256be value = {{1, 0,}};
|
||||||
struct evm_uint160be addr = {{0, 1, 2,}};
|
struct evm_address addr = {{0, 1, 2,}};
|
||||||
int64_t gas = 200000;
|
int64_t gas = 200000;
|
||||||
|
|
||||||
|
struct evm_context ctx = {&ctx_fn_table};
|
||||||
|
|
||||||
struct evm_message msg = {addr, addr, value, input, sizeof(input),
|
struct evm_message msg = {addr, addr, value, input, sizeof(input),
|
||||||
code_hash, gas, 0};
|
code_hash, gas, 0};
|
||||||
|
|
||||||
struct evm_result result =
|
struct evm_result result =
|
||||||
jit->execute(jit, NULL, EVM_HOMESTEAD, &msg, code, code_size);
|
jit->execute(jit, &ctx, EVM_HOMESTEAD, &msg, code, code_size);
|
||||||
|
|
||||||
printf("Execution result:\n");
|
printf("Execution result:\n");
|
||||||
if (result.code != EVM_SUCCESS) {
|
if (result.status_code != EVM_SUCCESS) {
|
||||||
printf(" EVM execution failure: %d\n", result.code);
|
printf(" EVM execution failure: %d\n", result.status_code);
|
||||||
} else {
|
} else {
|
||||||
printf(" Gas used: %ld\n", gas - result.gas_left);
|
printf(" Gas used: %ld\n", gas - result.gas_left);
|
||||||
printf(" Gas left: %ld\n", result.gas_left);
|
printf(" Gas left: %ld\n", result.gas_left);
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
|
#include <evm.h>
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <evm.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct examplevm
|
struct examplevm
|
||||||
{
|
{
|
||||||
struct evm_instance instance;
|
struct evm_instance instance;
|
||||||
const struct evm_host* host;
|
int verbose;
|
||||||
|
|
||||||
int example_option;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void evm_destroy(struct evm_instance* evm)
|
static void evm_destroy(struct evm_instance* evm)
|
||||||
|
@ -25,11 +25,11 @@ int evm_set_option(struct evm_instance* instance,
|
||||||
char const* value)
|
char const* value)
|
||||||
{
|
{
|
||||||
struct examplevm* vm = (struct examplevm*)instance;
|
struct examplevm* vm = (struct examplevm*)instance;
|
||||||
if (strcmp(name, "example-option") == 0) {
|
if (strcmp(name, "verbose") == 0) {
|
||||||
long int v = strtol(value, NULL, 0);
|
long int v = strtol(value, NULL, 0);
|
||||||
if (v > INT_MAX || v < INT_MIN)
|
if (v > INT_MAX || v < INT_MIN)
|
||||||
return 0;
|
return 0;
|
||||||
vm->example_option = (int)v;
|
vm->verbose = (int)v;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ static struct evm_result execute(struct evm_instance* instance,
|
||||||
"Welcome to Byzantium!" : "Hello Ethereum!";
|
"Welcome to Byzantium!" : "Hello Ethereum!";
|
||||||
ret.output_data = (const uint8_t*)error;
|
ret.output_data = (const uint8_t*)error;
|
||||||
ret.output_size = strlen(error);
|
ret.output_size = strlen(error);
|
||||||
ret.code = EVM_FAILURE;
|
ret.status_code = EVM_FAILURE;
|
||||||
ret.release = NULL; // We don't need to release the constant messages.
|
ret.release = NULL; // We don't need to release the constant messages.
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -77,52 +77,52 @@ static struct evm_result execute(struct evm_instance* instance,
|
||||||
const char counter[] = "600160005401600055";
|
const char counter[] = "600160005401600055";
|
||||||
|
|
||||||
if (code_size == strlen(return_address) &&
|
if (code_size == strlen(return_address) &&
|
||||||
strncmp((const char*)code, return_address, code_size)) {
|
strncmp((const char*)code, return_address, code_size) == 0) {
|
||||||
static const size_t address_size = sizeof(msg->address);
|
static const size_t address_size = sizeof(msg->address);
|
||||||
uint8_t* output_data = (uint8_t*)malloc(address_size);
|
uint8_t* output_data = (uint8_t*)malloc(address_size);
|
||||||
if (!output_data) {
|
if (!output_data) {
|
||||||
// malloc failed, report internal error.
|
// malloc failed, report internal error.
|
||||||
ret.code = EVM_INTERNAL_ERROR;
|
ret.status_code = EVM_INTERNAL_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
memcpy(output_data, &msg->address, address_size);
|
memcpy(output_data, &msg->address, address_size);
|
||||||
ret.code = EVM_SUCCESS;
|
ret.status_code = EVM_SUCCESS;
|
||||||
ret.output_data = output_data;
|
ret.output_data = output_data;
|
||||||
ret.output_size = address_size;
|
ret.output_size = address_size;
|
||||||
ret.release = &free_result_output_data;
|
ret.release = &free_result_output_data;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else if (code_size == strlen(counter) &&
|
else if (code_size == strlen(counter) &&
|
||||||
strncmp((const char*)code, counter, code_size)) {
|
strncmp((const char*)code, counter, code_size) == 0) {
|
||||||
struct evm_uint256be value;
|
struct evm_uint256be value;
|
||||||
const struct evm_uint256be index = {{0,}};
|
const struct evm_uint256be index = {{0,}};
|
||||||
vm->host->get_storage(&value, context, &msg->address, &index);
|
context->fn_table->get_storage(&value, context, &msg->address, &index);
|
||||||
value.bytes[31] += 1;
|
value.bytes[31] += 1;
|
||||||
vm->host->set_storage(context, &msg->address, &index, &value);
|
context->fn_table->set_storage(context, &msg->address, &index, &value);
|
||||||
ret.code = EVM_SUCCESS;
|
ret.status_code = EVM_SUCCESS;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.release = evm_release_result;
|
ret.release = evm_release_result;
|
||||||
ret.code = EVM_FAILURE;
|
ret.status_code = EVM_FAILURE;
|
||||||
ret.gas_left = 0;
|
ret.gas_left = 0;
|
||||||
|
|
||||||
|
if (vm->verbose)
|
||||||
|
printf("Execution done.\n");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct evm_instance* evm_create(const struct evm_host* host)
|
struct evm_instance* examplevm_create()
|
||||||
{
|
{
|
||||||
|
struct evm_instance init = {
|
||||||
|
.abi_version = EVM_ABI_VERSION,
|
||||||
|
.destroy = evm_destroy,
|
||||||
|
.execute = execute,
|
||||||
|
.set_option = evm_set_option
|
||||||
|
};
|
||||||
struct examplevm* vm = calloc(1, sizeof(struct examplevm));
|
struct examplevm* vm = calloc(1, sizeof(struct examplevm));
|
||||||
struct evm_instance* interface = &vm->instance;
|
struct evm_instance* interface = &vm->instance;
|
||||||
interface->destroy = evm_destroy;
|
memcpy(interface, &init, sizeof(init));
|
||||||
interface->execute = execute;
|
|
||||||
interface->set_option = evm_set_option;
|
|
||||||
vm->host = host;
|
|
||||||
return interface;
|
return interface;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct evm_factory examplevm_get_factory()
|
|
||||||
{
|
|
||||||
struct evm_factory factory = {EVM_ABI_VERSION, evm_create};
|
|
||||||
return factory;
|
|
||||||
}
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct evm_uint256be {
|
||||||
|
|
||||||
/// Big-endian 160-bit hash suitable for keeping an Ethereum address.
|
/// Big-endian 160-bit hash suitable for keeping an Ethereum address.
|
||||||
/// TODO: Rename to "address".
|
/// TODO: Rename to "address".
|
||||||
struct evm_uint160be {
|
struct evm_address {
|
||||||
/// The 20 bytes of the hash.
|
/// The 20 bytes of the hash.
|
||||||
uint8_t bytes[20];
|
uint8_t bytes[20];
|
||||||
};
|
};
|
||||||
|
@ -67,8 +67,8 @@ enum evm_flags {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct evm_message {
|
struct evm_message {
|
||||||
struct evm_uint160be address;
|
struct evm_address address;
|
||||||
struct evm_uint160be sender;
|
struct evm_address sender;
|
||||||
struct evm_uint256be value;
|
struct evm_uint256be value;
|
||||||
const uint8_t* input;
|
const uint8_t* input;
|
||||||
size_t input_size;
|
size_t input_size;
|
||||||
|
@ -81,8 +81,8 @@ struct evm_message {
|
||||||
|
|
||||||
struct evm_tx_context {
|
struct evm_tx_context {
|
||||||
struct evm_uint256be tx_gas_price;
|
struct evm_uint256be tx_gas_price;
|
||||||
struct evm_uint160be tx_origin;
|
struct evm_address tx_origin;
|
||||||
struct evm_uint160be block_coinbase;
|
struct evm_address block_coinbase;
|
||||||
int64_t block_number;
|
int64_t block_number;
|
||||||
int64_t block_timestamp;
|
int64_t block_timestamp;
|
||||||
int64_t block_gas_limit;
|
int64_t block_gas_limit;
|
||||||
|
@ -98,8 +98,8 @@ typedef void (*evm_get_block_hash_fn)(struct evm_uint256be* result,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
int64_t number);
|
int64_t number);
|
||||||
|
|
||||||
/// The execution result code.
|
/// The execution status code.
|
||||||
enum evm_result_code {
|
enum evm_status_code {
|
||||||
EVM_SUCCESS = 0, ///< Execution finished with success.
|
EVM_SUCCESS = 0, ///< Execution finished with success.
|
||||||
EVM_FAILURE = 1, ///< Generic execution failure.
|
EVM_FAILURE = 1, ///< Generic execution failure.
|
||||||
EVM_OUT_OF_GAS = 2,
|
EVM_OUT_OF_GAS = 2,
|
||||||
|
@ -111,7 +111,7 @@ enum evm_result_code {
|
||||||
|
|
||||||
/// EVM implementation internal error.
|
/// EVM implementation internal error.
|
||||||
///
|
///
|
||||||
/// FIXME: We should rethink reporting internal errors. One of the options
|
/// @todo We should rethink reporting internal errors. One of the options
|
||||||
/// it to allow using any negative value to represent internal errors.
|
/// it to allow using any negative value to represent internal errors.
|
||||||
EVM_INTERNAL_ERROR = -1,
|
EVM_INTERNAL_ERROR = -1,
|
||||||
};
|
};
|
||||||
|
@ -130,9 +130,8 @@ typedef void (*evm_release_result_fn)(struct evm_result const* result);
|
||||||
|
|
||||||
/// The EVM code execution result.
|
/// The EVM code execution result.
|
||||||
struct evm_result {
|
struct evm_result {
|
||||||
/// The execution result code.
|
/// The execution status code.
|
||||||
/// FIXME: Rename to 'status' or 'status_code'.
|
enum evm_status_code status_code;
|
||||||
enum evm_result_code code;
|
|
||||||
|
|
||||||
/// The amount of gas left after the execution.
|
/// The amount of gas left after the execution.
|
||||||
///
|
///
|
||||||
|
@ -197,7 +196,7 @@ struct evm_result {
|
||||||
/// @param address The address of the account the query is about.
|
/// @param address The address of the account the query is about.
|
||||||
/// @return 1 if exists, 0 otherwise.
|
/// @return 1 if exists, 0 otherwise.
|
||||||
typedef int (*evm_account_exists_fn)(struct evm_context* context,
|
typedef int (*evm_account_exists_fn)(struct evm_context* context,
|
||||||
const struct evm_uint160be* address);
|
const struct evm_address* address);
|
||||||
|
|
||||||
/// Get storage callback function.
|
/// Get storage callback function.
|
||||||
///
|
///
|
||||||
|
@ -210,7 +209,7 @@ typedef int (*evm_account_exists_fn)(struct evm_context* context,
|
||||||
/// @param key The index of the storage entry.
|
/// @param key The index of the storage entry.
|
||||||
typedef void (*evm_get_storage_fn)(struct evm_uint256be* result,
|
typedef void (*evm_get_storage_fn)(struct evm_uint256be* result,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
const struct evm_uint160be* address,
|
const struct evm_address* address,
|
||||||
const struct evm_uint256be* key);
|
const struct evm_uint256be* key);
|
||||||
|
|
||||||
/// Set storage callback function.
|
/// Set storage callback function.
|
||||||
|
@ -223,7 +222,7 @@ typedef void (*evm_get_storage_fn)(struct evm_uint256be* result,
|
||||||
/// @param key The index of the storage entry.
|
/// @param key The index of the storage entry.
|
||||||
/// @param value The value to be stored.
|
/// @param value The value to be stored.
|
||||||
typedef void (*evm_set_storage_fn)(struct evm_context* context,
|
typedef void (*evm_set_storage_fn)(struct evm_context* context,
|
||||||
const struct evm_uint160be* address,
|
const struct evm_address* address,
|
||||||
const struct evm_uint256be* key,
|
const struct evm_uint256be* key,
|
||||||
const struct evm_uint256be* value);
|
const struct evm_uint256be* value);
|
||||||
|
|
||||||
|
@ -237,7 +236,7 @@ typedef void (*evm_set_storage_fn)(struct evm_context* context,
|
||||||
/// @param address The address.
|
/// @param address The address.
|
||||||
typedef void (*evm_get_balance_fn)(struct evm_uint256be* result,
|
typedef void (*evm_get_balance_fn)(struct evm_uint256be* result,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
const struct evm_uint160be* address);
|
const struct evm_address* address);
|
||||||
|
|
||||||
/// Get code callback function.
|
/// Get code callback function.
|
||||||
///
|
///
|
||||||
|
@ -252,7 +251,7 @@ typedef void (*evm_get_balance_fn)(struct evm_uint256be* result,
|
||||||
/// @return The size of the code.
|
/// @return The size of the code.
|
||||||
typedef size_t (*evm_get_code_fn)(const uint8_t** result_code,
|
typedef size_t (*evm_get_code_fn)(const uint8_t** result_code,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
const struct evm_uint160be* address);
|
const struct evm_address* address);
|
||||||
|
|
||||||
/// Selfdestruct callback function.
|
/// Selfdestruct callback function.
|
||||||
///
|
///
|
||||||
|
@ -263,8 +262,8 @@ typedef size_t (*evm_get_code_fn)(const uint8_t** result_code,
|
||||||
/// @param beneficiary The address where the remaining ETH is going to be
|
/// @param beneficiary The address where the remaining ETH is going to be
|
||||||
/// transferred.
|
/// transferred.
|
||||||
typedef void (*evm_selfdestruct_fn)(struct evm_context* context,
|
typedef void (*evm_selfdestruct_fn)(struct evm_context* context,
|
||||||
const struct evm_uint160be* address,
|
const struct evm_address* address,
|
||||||
const struct evm_uint160be* beneficiary);
|
const struct evm_address* beneficiary);
|
||||||
|
|
||||||
/// Log callback function.
|
/// Log callback function.
|
||||||
///
|
///
|
||||||
|
@ -279,7 +278,7 @@ typedef void (*evm_selfdestruct_fn)(struct evm_context* context,
|
||||||
/// @param topics_count The number of the topics. Valid values are between
|
/// @param topics_count The number of the topics. Valid values are between
|
||||||
/// 0 and 4 inclusively.
|
/// 0 and 4 inclusively.
|
||||||
typedef void (*evm_log_fn)(struct evm_context* context,
|
typedef void (*evm_log_fn)(struct evm_context* context,
|
||||||
const struct evm_uint160be* address,
|
const struct evm_address* address,
|
||||||
const uint8_t* data,
|
const uint8_t* data,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
const struct evm_uint256be topics[],
|
const struct evm_uint256be topics[],
|
||||||
|
@ -295,13 +294,13 @@ typedef void (*evm_call_fn)(struct evm_result* result,
|
||||||
struct evm_context* context,
|
struct evm_context* context,
|
||||||
const struct evm_message* msg);
|
const struct evm_message* msg);
|
||||||
|
|
||||||
/// The Host interface.
|
/// The context interface.
|
||||||
///
|
///
|
||||||
/// The set of all callback functions expected by EVM instances. This is C
|
/// The set of all callback functions expected by EVM instances. This is C
|
||||||
/// realisation of OOP interface (only virtual methods, no data).
|
/// realisation of vtable for OOP interface (only virtual methods, no data).
|
||||||
/// Host implementations SHOULD create constant singletons of this (similarly
|
/// Host implementations SHOULD create constant singletons of this (similarly
|
||||||
/// to vtables) to lower the maintenance and memory management cost.
|
/// to vtables) to lower the maintenance and memory management cost.
|
||||||
struct evm_host {
|
struct evm_context_fn_table {
|
||||||
evm_account_exists_fn account_exists;
|
evm_account_exists_fn account_exists;
|
||||||
evm_get_storage_fn get_storage;
|
evm_get_storage_fn get_storage;
|
||||||
evm_set_storage_fn set_storage;
|
evm_set_storage_fn set_storage;
|
||||||
|
@ -325,21 +324,13 @@ struct evm_host {
|
||||||
/// Optionally, The Host MAY include in the context additional data.
|
/// Optionally, The Host MAY include in the context additional data.
|
||||||
struct evm_context {
|
struct evm_context {
|
||||||
|
|
||||||
/// Function table defining the context interface.
|
/// Function table defining the context interface (vtable).
|
||||||
const struct evm_host* fn_table;
|
const struct evm_context_fn_table* fn_table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct evm_instance; ///< Forward declaration.
|
struct evm_instance; ///< Forward declaration.
|
||||||
|
|
||||||
/// Creates the EVM instance.
|
|
||||||
///
|
|
||||||
/// Creates and initializes an EVM instance by providing the information
|
|
||||||
/// about runtime callback functions.
|
|
||||||
///
|
|
||||||
/// @return Pointer to the created EVM instance.
|
|
||||||
typedef struct evm_instance* (*evm_create_fn)();
|
|
||||||
|
|
||||||
/// Destroys the EVM instance.
|
/// Destroys the EVM instance.
|
||||||
///
|
///
|
||||||
/// @param evm The EVM instance to be destroyed.
|
/// @param evm The EVM instance to be destroyed.
|
||||||
|
@ -437,6 +428,15 @@ typedef void (*evm_prepare_code_fn)(struct evm_instance* instance,
|
||||||
///
|
///
|
||||||
/// Defines the base struct of the EVM implementation.
|
/// Defines the base struct of the EVM implementation.
|
||||||
struct evm_instance {
|
struct evm_instance {
|
||||||
|
|
||||||
|
/// EVM-C ABI version implemented by the EVM instance.
|
||||||
|
///
|
||||||
|
/// For future use to detect ABI incompatibilities. The EVM-C ABI version
|
||||||
|
/// represented by this file is in ::EVM_ABI_VERSION.
|
||||||
|
///
|
||||||
|
/// @todo Consider removing this field.
|
||||||
|
const int abi_version;
|
||||||
|
|
||||||
/// Pointer to function destroying the EVM instance.
|
/// Pointer to function destroying the EVM instance.
|
||||||
evm_destroy_fn destroy;
|
evm_destroy_fn destroy;
|
||||||
|
|
||||||
|
@ -459,30 +459,15 @@ struct evm_instance {
|
||||||
evm_set_option_fn set_option;
|
evm_set_option_fn set_option;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The EVM instance factory.
|
|
||||||
///
|
|
||||||
/// Provides ABI protection and method to create an EVM instance.
|
|
||||||
struct evm_factory {
|
|
||||||
/// EVM-C ABI version implemented by the EVM factory and instance.
|
|
||||||
///
|
|
||||||
/// For future use to detect ABI incompatibilities. The EVM-C ABI version
|
|
||||||
/// represented by this file is in ::EVM_ABI_VERSION.
|
|
||||||
int abi_version;
|
|
||||||
|
|
||||||
/// Pointer to function creating and initializing the EVM instance.
|
|
||||||
evm_create_fn create;
|
|
||||||
};
|
|
||||||
|
|
||||||
// END Python CFFI declarations
|
// END Python CFFI declarations
|
||||||
|
|
||||||
/// Example of a function creating uninitialized instance of an example VM.
|
/// Example of a function creating an instance of an example EVM implementation.
|
||||||
///
|
///
|
||||||
/// Each EVM implementation is obligated to provided a function returning
|
/// Each EVM implementation MUST provide a function returning an EVM instance.
|
||||||
/// an EVM instance.
|
/// The function SHOULD be named `<vm-name>_create(void)`.
|
||||||
/// The function has to be named as `<vm-name>_get_factory(void)`.
|
|
||||||
///
|
///
|
||||||
/// @return EVM instance.
|
/// @return EVM instance or NULL indicating instance creation failure.
|
||||||
struct evm_factory examplevm_get_factory(void);
|
struct evm_instance* examplevm_create(void);
|
||||||
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue