mirror of
https://github.com/status-im/evmc.git
synced 2025-02-23 08:28:15 +00:00
Merge pull request #30 from ethereum/pedantic-c
Make header compilable in C99 and C11 pedantic mode
This commit is contained in:
commit
d7c0312f31
@ -1,141 +1,177 @@
|
||||
/// EVMC -- Ethereum Client-VM Connector API
|
||||
///
|
||||
/// ## 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
|
||||
/// and unions. And variable sized arrays of bytes cannot be passed by copy.
|
||||
/// 2. The EVM operates on integers so it prefers values to be host-endian.
|
||||
/// On the other hand, LLVM can generate good code for byte swaping.
|
||||
/// 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 EVMC
|
||||
/// @{
|
||||
/**
|
||||
* EVMC: Ethereum Client-VM Connector API
|
||||
*
|
||||
* @copyright
|
||||
* Copyright 2018 Pawel Bylica.
|
||||
* Licensed under the MIT License. See the LICENSE file.
|
||||
*
|
||||
* ## 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
|
||||
* and unions. And variable sized arrays of bytes cannot be passed by copy.
|
||||
* 2. The EVM operates on integers so it prefers values to be host-endian.
|
||||
* On the other hand, LLVM can generate good code for byte swaping.
|
||||
* 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 EVMC
|
||||
* @{
|
||||
*/
|
||||
#ifndef EVMC_H
|
||||
#define EVMC_H
|
||||
|
||||
#include <stdint.h> // Definition of int64_t, uint64_t.
|
||||
#include <stddef.h> // Definition of size_t.
|
||||
#include <stddef.h> /* Definition of size_t. */
|
||||
#include <stdint.h> /* Definition of int64_t, uint64_t. */
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// BEGIN Python CFFI declarations
|
||||
/* BEGIN Python CFFI declarations */
|
||||
|
||||
enum
|
||||
{
|
||||
/// The EVMC ABI version number of the interface declared in this file.
|
||||
/** The EVMC ABI version number of the interface declared in this file. */
|
||||
EVMC_ABI_VERSION = 1
|
||||
};
|
||||
|
||||
/// Big-endian 256-bit integer.
|
||||
///
|
||||
/// 32 bytes of data representing big-endian 256-bit integer. I.e. bytes[0] is
|
||||
/// the most significant byte, bytes[31] is the least significant byte.
|
||||
/// This type is used to transfer to/from the VM values interpreted by the user
|
||||
/// as both 256-bit integers and 256-bit hashes.
|
||||
struct evmc_uint256be {
|
||||
/// The 32 bytes of the big-endian integer or hash.
|
||||
/**
|
||||
* Big-endian 256-bit integer.
|
||||
*
|
||||
* 32 bytes of data representing big-endian 256-bit integer. I.e. bytes[0] is
|
||||
* the most significant byte, bytes[31] is the least significant byte.
|
||||
* This type is used to transfer to/from the VM values interpreted by the user
|
||||
* as both 256-bit integers and 256-bit hashes.
|
||||
*/
|
||||
struct evmc_uint256be
|
||||
{
|
||||
/** The 32 bytes of the big-endian integer or hash. */
|
||||
uint8_t bytes[32];
|
||||
};
|
||||
|
||||
/// Big-endian 160-bit hash suitable for keeping an Ethereum address.
|
||||
struct evmc_address {
|
||||
/// The 20 bytes of the hash.
|
||||
/** Big-endian 160-bit hash suitable for keeping an Ethereum address. */
|
||||
struct evmc_address
|
||||
{
|
||||
/** The 20 bytes of the hash. */
|
||||
uint8_t bytes[20];
|
||||
};
|
||||
|
||||
/// The kind of call-like instruction.
|
||||
enum evmc_call_kind {
|
||||
EVMC_CALL = 0, ///< Request CALL.
|
||||
EVMC_DELEGATECALL = 1, ///< Request DELEGATECALL. The value param ignored.
|
||||
EVMC_CALLCODE = 2, ///< Request CALLCODE.
|
||||
EVMC_CREATE = 3, ///< Request CREATE. Semantic of some params changes.
|
||||
/** The kind of call-like instruction. */
|
||||
enum evmc_call_kind
|
||||
{
|
||||
EVMC_CALL = 0, /**< Request CALL. */
|
||||
EVMC_DELEGATECALL = 1, /**< Request DELEGATECALL. The value param ignored. */
|
||||
EVMC_CALLCODE = 2, /**< Request CALLCODE. */
|
||||
EVMC_CREATE = 3 /**< Request CREATE. Semantic of some params changes. */
|
||||
};
|
||||
|
||||
/// The flags for ::evmc_message.
|
||||
enum evmc_flags {
|
||||
EVMC_STATIC = 1 ///< Static call mode.
|
||||
/** The flags for ::evmc_message. */
|
||||
enum evmc_flags
|
||||
{
|
||||
EVMC_STATIC = 1 /**< Static call mode. */
|
||||
};
|
||||
|
||||
/// The message describing an EVM call,
|
||||
/// including a zero-depth calls from a transaction origin.
|
||||
struct evmc_message {
|
||||
struct evmc_address destination; ///< The destination of the message.
|
||||
struct evmc_address sender; ///< The sender of the message.
|
||||
/**
|
||||
* The message describing an EVM call,
|
||||
* including a zero-depth calls from a transaction origin.
|
||||
*/
|
||||
struct evmc_message
|
||||
{
|
||||
/** The destination of the message. */
|
||||
struct evmc_address destination;
|
||||
|
||||
/// The amount of Ether transferred with the message.
|
||||
/** The sender of the message. */
|
||||
struct evmc_address sender;
|
||||
|
||||
/**
|
||||
* The amount of Ether transferred with the message.
|
||||
*/
|
||||
struct evmc_uint256be value;
|
||||
|
||||
/// The message input data.
|
||||
///
|
||||
/// This MAY be NULL.
|
||||
/**
|
||||
* The message input data.
|
||||
*
|
||||
* This MAY be NULL.
|
||||
*/
|
||||
const uint8_t* input_data;
|
||||
|
||||
/// The size of the message input data.
|
||||
///
|
||||
/// If input_data is NULL this MUST be 0.
|
||||
/**
|
||||
* The size of the message input data.
|
||||
*
|
||||
* If input_data is NULL this MUST be 0.
|
||||
*/
|
||||
size_t input_size;
|
||||
|
||||
/// The optional hash of the code of the destination account.
|
||||
/// The null hash MUST be used when not specified.
|
||||
/**
|
||||
* The optional hash of the code of the destination account.
|
||||
* The null hash MUST be used when not specified.
|
||||
*/
|
||||
struct evmc_uint256be code_hash;
|
||||
|
||||
int64_t gas; ///< The amount of gas for message execution.
|
||||
int32_t depth; ///< The call depth.
|
||||
/** The amount of gas for message execution. */
|
||||
int64_t gas;
|
||||
|
||||
/// The kind of the call. For zero-depth calls ::EVMC_CALL SHOULD be used.
|
||||
/** The call depth. */
|
||||
int32_t depth;
|
||||
|
||||
/** The kind of the call. For zero-depth calls ::EVMC_CALL SHOULD be used. */
|
||||
enum evmc_call_kind kind;
|
||||
|
||||
/// Additional flags modifying the call execution behavior.
|
||||
/// In the current version the only valid values are ::EVMC_STATIC or 0.
|
||||
/**
|
||||
* Additional flags modifying the call execution behavior.
|
||||
* In the current version the only valid values are ::EVMC_STATIC or 0.
|
||||
*/
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
|
||||
/// The transaction and block data for execution.
|
||||
struct evmc_tx_context {
|
||||
struct evmc_uint256be tx_gas_price; ///< The transaction gas price.
|
||||
struct evmc_address tx_origin; ///< The transaction origin account.
|
||||
struct evmc_address block_coinbase; ///< The miner of the block.
|
||||
int64_t block_number; ///< The block number.
|
||||
int64_t block_timestamp; ///< The block timestamp.
|
||||
int64_t block_gas_limit; ///< The block gas limit.
|
||||
struct evmc_uint256be block_difficulty; ///< The block difficulty.
|
||||
/** The transaction and block data for execution. */
|
||||
struct evmc_tx_context
|
||||
{
|
||||
struct evmc_uint256be tx_gas_price; /**< The transaction gas price. */
|
||||
struct evmc_address tx_origin; /**< The transaction origin account. */
|
||||
struct evmc_address block_coinbase; /**< The miner of the block. */
|
||||
int64_t block_number; /**< The block number. */
|
||||
int64_t block_timestamp; /**< The block timestamp. */
|
||||
int64_t block_gas_limit; /**< The block gas limit. */
|
||||
struct evmc_uint256be block_difficulty; /**< The block difficulty. */
|
||||
};
|
||||
|
||||
struct evmc_context;
|
||||
|
||||
/// Get transaction context callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to retrieve the transaction and
|
||||
/// block context.
|
||||
///
|
||||
/// @param[out] result The returned transaction context.
|
||||
/// @see ::evmc_tx_context.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evmc_context.
|
||||
/**
|
||||
* Get transaction context callback function.
|
||||
*
|
||||
* This callback function is used by an EVM to retrieve the transaction and
|
||||
* block context.
|
||||
*
|
||||
* @param[out] result The returned transaction context.
|
||||
* @see ::evmc_tx_context.
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @see ::evmc_context.
|
||||
*/
|
||||
typedef void (*evmc_get_tx_context_fn)(struct evmc_tx_context* result,
|
||||
struct evmc_context* context);
|
||||
|
||||
/// Get block hash callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to query the block hash of
|
||||
/// a given block.
|
||||
///
|
||||
/// @param[out] result The returned block hash value.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @param number The block number. Must be a value between
|
||||
// (and including) 0 and 255.
|
||||
/**
|
||||
* Get block hash callback function.
|
||||
*
|
||||
* This callback function is used by an EVM to query the block hash of
|
||||
* a given block.
|
||||
*
|
||||
* @param[out] result The returned block hash value.
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @param number The block number. Must be a value between
|
||||
* (and including) 0 and 255.
|
||||
*/
|
||||
typedef void (*evmc_get_block_hash_fn)(struct evmc_uint256be* result,
|
||||
struct evmc_context* context,
|
||||
int64_t number);
|
||||
@ -245,228 +281,261 @@ enum evmc_status_code
|
||||
* For example, the Client tries running a code in the EVM 1.5. If the
|
||||
* code is not supported there, the execution falls back to the EVM 1.0.
|
||||
*/
|
||||
EVMC_REJECTED = -2,
|
||||
EVMC_REJECTED = -2
|
||||
};
|
||||
|
||||
struct evmc_result; ///< Forward declaration.
|
||||
/* Forward declaration. */
|
||||
struct evmc_result;
|
||||
|
||||
/// Releases resources assigned to an execution result.
|
||||
///
|
||||
/// This function releases memory (and other resources, if any) assigned to the
|
||||
/// specified execution result making the result object invalid.
|
||||
///
|
||||
/// @param result The execution result which resource are to be released. The
|
||||
/// result itself it not modified by this function, but becomes
|
||||
/// invalid and user should discard it as well.
|
||||
/**
|
||||
* Releases resources assigned to an execution result.
|
||||
*
|
||||
* This function releases memory (and other resources, if any) assigned to the
|
||||
* specified execution result making the result object invalid.
|
||||
*
|
||||
* @param result The execution result which resource are to be released. The
|
||||
* result itself it not modified by this function, but becomes
|
||||
* invalid and user should discard it as well.
|
||||
*/
|
||||
typedef void (*evmc_release_result_fn)(const struct evmc_result* result);
|
||||
|
||||
/// The EVM code execution result.
|
||||
struct evmc_result {
|
||||
/// The execution status code.
|
||||
/** The EVM code execution result. */
|
||||
struct evmc_result
|
||||
{
|
||||
/** The execution status code. */
|
||||
enum evmc_status_code status_code;
|
||||
|
||||
/// The amount of gas left after the execution.
|
||||
///
|
||||
/// If evmc_result::code is not ::EVMC_SUCCESS nor ::EVMC_REVERT
|
||||
/// the value MUST be 0.
|
||||
/**
|
||||
* The amount of gas left after the execution.
|
||||
*
|
||||
* If evmc_result::code is not ::EVMC_SUCCESS nor ::EVMC_REVERT
|
||||
* the value MUST be 0.
|
||||
*/
|
||||
int64_t gas_left;
|
||||
|
||||
/// The reference to output data.
|
||||
///
|
||||
/// The output contains data coming from RETURN opcode (iff evmc_result::code
|
||||
/// field is ::EVMC_SUCCESS) or from REVERT opcode.
|
||||
///
|
||||
/// The memory containing the output data is owned by EVM and has to be
|
||||
/// freed with evmc_result::release().
|
||||
///
|
||||
/// This MAY be NULL.
|
||||
/**
|
||||
* The reference to output data.
|
||||
*
|
||||
* The output contains data coming from RETURN opcode (iff evmc_result::code
|
||||
* field is ::EVMC_SUCCESS) or from REVERT opcode.
|
||||
*
|
||||
* The memory containing the output data is owned by EVM and has to be
|
||||
* freed with evmc_result::release().
|
||||
*
|
||||
* This MAY be NULL.
|
||||
*/
|
||||
const uint8_t* output_data;
|
||||
|
||||
/// The size of the output data.
|
||||
///
|
||||
/// If output_data is NULL this MUST be 0.
|
||||
/**
|
||||
* The size of the output data.
|
||||
*
|
||||
* If output_data is NULL this MUST be 0.
|
||||
*/
|
||||
size_t output_size;
|
||||
|
||||
/// The pointer to a function releasing all resources associated with
|
||||
/// the result object.
|
||||
///
|
||||
/// This function pointer is optional (MAY be NULL) and MAY be set by
|
||||
/// the EVM implementation. If set it MUST be used by the user to
|
||||
/// release memory and other resources associated with the result object.
|
||||
/// After the result resources are released the result object
|
||||
/// MUST NOT be used any more.
|
||||
///
|
||||
/// The suggested code pattern for releasing EVM results:
|
||||
/// @code
|
||||
/// struct evmc_result result = ...;
|
||||
/// if (result.release)
|
||||
/// result.release(&result);
|
||||
/// @endcode
|
||||
///
|
||||
/// @note
|
||||
/// It works similarly to C++ virtual destructor. Attaching the release
|
||||
/// function to the result itself allows EVM composition.
|
||||
/**
|
||||
* The pointer to a function releasing all resources associated with
|
||||
* the result object.
|
||||
*
|
||||
* This function pointer is optional (MAY be NULL) and MAY be set by
|
||||
* the EVM implementation. If set it MUST be used by the user to
|
||||
* release memory and other resources associated with the result object.
|
||||
* After the result resources are released the result object
|
||||
* MUST NOT be used any more.
|
||||
*
|
||||
* The suggested code pattern for releasing EVM results:
|
||||
* @code
|
||||
* struct evmc_result result = ...;
|
||||
* if (result.release)
|
||||
* result.release(&result);
|
||||
* @endcode
|
||||
*
|
||||
* @note
|
||||
* It works similarly to C++ virtual destructor. Attaching the release
|
||||
* function to the result itself allows EVM composition.
|
||||
*/
|
||||
evmc_release_result_fn release;
|
||||
|
||||
/// The address of the contract created by CREATE opcode.
|
||||
///
|
||||
/// This field has valid value only if the result describes successful
|
||||
/// CREATE (evmc_result::status_code is ::EVMC_SUCCESS).
|
||||
/**
|
||||
* The address of the contract created by CREATE opcode.
|
||||
*
|
||||
* This field has valid value only if the result describes successful
|
||||
* CREATE (evmc_result::status_code is ::EVMC_SUCCESS).
|
||||
*/
|
||||
struct evmc_address create_address;
|
||||
|
||||
/// Reserved data that MAY be used by a evmc_result object creator.
|
||||
///
|
||||
/// This reserved 4 bytes together with 20 bytes from create_address form
|
||||
/// 24 bytes of memory called "optional data" within evmc_result struct
|
||||
/// to be optionally used by the evmc_result object creator.
|
||||
///
|
||||
/// @see evmc_result_optional_data, evmc_get_optional_data().
|
||||
///
|
||||
/// Also extends the size of the evmc_result to 64 bytes (full cache line).
|
||||
/**
|
||||
* Reserved data that MAY be used by a evmc_result object creator.
|
||||
*
|
||||
* This reserved 4 bytes together with 20 bytes from create_address form
|
||||
* 24 bytes of memory called "optional data" within evmc_result struct
|
||||
* to be optionally used by the evmc_result object creator.
|
||||
*
|
||||
* @see evmc_result_optional_data, evmc_get_optional_data().
|
||||
*
|
||||
* Also extends the size of the evmc_result to 64 bytes (full cache line).
|
||||
*/
|
||||
uint8_t padding[4];
|
||||
};
|
||||
|
||||
|
||||
/// The union representing evmc_result "optional data".
|
||||
///
|
||||
/// The evmc_result struct contains 24 bytes of optional data that can be
|
||||
/// reused by the object creator if the object does not contain
|
||||
/// evmc_result::create_address.
|
||||
///
|
||||
/// An EVM implementation MAY use this memory to keep additional data
|
||||
/// when returning result from ::evmc_execute_fn.
|
||||
/// The host application MAY use this memory to keep additional data
|
||||
/// when returning result of performed calls from ::evmc_call_fn.
|
||||
///
|
||||
/// @see evmc_get_optional_data(), evmc_get_const_optional_data().
|
||||
/**
|
||||
* The union representing evmc_result "optional data".
|
||||
*
|
||||
* The evmc_result struct contains 24 bytes of optional data that can be
|
||||
* reused by the object creator if the object does not contain
|
||||
* evmc_result::create_address.
|
||||
*
|
||||
* An EVM implementation MAY use this memory to keep additional data
|
||||
* when returning result from ::evmc_execute_fn.
|
||||
* The host application MAY use this memory to keep additional data
|
||||
* when returning result of performed calls from ::evmc_call_fn.
|
||||
*
|
||||
* @see evmc_get_optional_data(), evmc_get_const_optional_data().
|
||||
*/
|
||||
union evmc_result_optional_data
|
||||
{
|
||||
uint8_t bytes[24]; ///< 24 bytes of optional data.
|
||||
void* pointer; ///< Optional pointer.
|
||||
uint8_t bytes[24]; /**< 24 bytes of optional data. */
|
||||
void* pointer; /**< Optional pointer. */
|
||||
};
|
||||
|
||||
/// Provides read-write access to evmc_result "optional data".
|
||||
static inline union evmc_result_optional_data* evmc_get_optional_data(
|
||||
struct evmc_result* result)
|
||||
/** Provides read-write access to evmc_result "optional data". */
|
||||
static inline union evmc_result_optional_data* evmc_get_optional_data(struct evmc_result* result)
|
||||
{
|
||||
return (union evmc_result_optional_data*) &result->create_address;
|
||||
return (union evmc_result_optional_data*)&result->create_address;
|
||||
}
|
||||
|
||||
/// Provides read-only access to evmc_result "optional data".
|
||||
/** Provides read-only access to evmc_result "optional data". */
|
||||
static inline const union evmc_result_optional_data* evmc_get_const_optional_data(
|
||||
const struct evmc_result* result)
|
||||
{
|
||||
return (const union evmc_result_optional_data*) &result->create_address;
|
||||
return (const union evmc_result_optional_data*)&result->create_address;
|
||||
}
|
||||
|
||||
|
||||
/// Check account existence callback function
|
||||
///
|
||||
/// This callback function is used by the EVM to check if
|
||||
/// there exists an account at given address.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evmc_context.
|
||||
/// @param address The address of the account the query is about.
|
||||
/// @return 1 if exists, 0 otherwise.
|
||||
/**
|
||||
* Check account existence callback function
|
||||
*
|
||||
* This callback function is used by the EVM to check if
|
||||
* there exists an account at given address.
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @see ::evmc_context.
|
||||
* @param address The address of the account the query is about.
|
||||
* @return 1 if exists, 0 otherwise.
|
||||
*/
|
||||
typedef int (*evmc_account_exists_fn)(struct evmc_context* context,
|
||||
const struct evmc_address* address);
|
||||
|
||||
/// Get storage callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to query the given contract
|
||||
/// storage entry.
|
||||
/// @param[out] result The returned storage value.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evmc_context.
|
||||
/// @param address The address of the contract.
|
||||
/// @param key The index of the storage entry.
|
||||
/**
|
||||
* Get storage callback function.
|
||||
*
|
||||
* This callback function is used by an EVM to query the given contract
|
||||
* storage entry.
|
||||
* @param[out] result The returned storage value.
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @see ::evmc_context.
|
||||
* @param address The address of the contract.
|
||||
* @param key The index of the storage entry.
|
||||
*/
|
||||
typedef void (*evmc_get_storage_fn)(struct evmc_uint256be* result,
|
||||
struct evmc_context* context,
|
||||
const struct evmc_address* address,
|
||||
const struct evmc_uint256be* key);
|
||||
|
||||
/// Set storage callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to update the given contract
|
||||
/// storage entry.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evmc_context.
|
||||
/// @param address The address of the contract.
|
||||
/// @param key The index of the storage entry.
|
||||
/// @param value The value to be stored.
|
||||
/**
|
||||
* Set storage callback function.
|
||||
*
|
||||
* This callback function is used by an EVM to update the given contract
|
||||
* storage entry.
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @see ::evmc_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 (*evmc_set_storage_fn)(struct evmc_context* context,
|
||||
const struct evmc_address* address,
|
||||
const struct evmc_uint256be* key,
|
||||
const struct evmc_uint256be* value);
|
||||
|
||||
/// 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.
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
typedef void (*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.
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
typedef size_t (*evmc_get_code_size_fn)(struct evmc_context* context,
|
||||
const struct evmc_address* address);
|
||||
|
||||
/// Copy code callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to request a copy of the code
|
||||
/// of the given account to the memory buffer provided by the EVM.
|
||||
/// The Client MUST copy the requested code, starting with the given offset,
|
||||
/// to the provided memory buffer up to the size of the buffer or the size of
|
||||
/// the code, whichever is smaller.
|
||||
///
|
||||
/// @param context The pointer to the Client execution context.
|
||||
/// @see ::evmc_context.
|
||||
/// @param address The address of the account.
|
||||
/// @param code_offset The offset of the code to copy.
|
||||
/// @param buffer_data The pointer to the memory buffer allocated by the EVM
|
||||
/// to store a copy of the requested code.
|
||||
/// @param buffer_size The size of the memory buffer.
|
||||
/// @return The number of bytes copied to the buffer by the Client.
|
||||
/**
|
||||
* Copy code callback function.
|
||||
*
|
||||
* This callback function is used by an EVM to request a copy of the code
|
||||
* of the given account to the memory buffer provided by the EVM.
|
||||
* The Client MUST copy the requested code, starting with the given offset,
|
||||
* to the provided memory buffer up to the size of the buffer or the size of
|
||||
* the code, whichever is smaller.
|
||||
*
|
||||
* @param context The pointer to the Client execution context.
|
||||
* @see ::evmc_context.
|
||||
* @param address The address of the account.
|
||||
* @param code_offset The offset of the code to copy.
|
||||
* @param buffer_data The pointer to the memory buffer allocated by the EVM
|
||||
* to store a copy of the requested code.
|
||||
* @param buffer_size The size of the memory buffer.
|
||||
* @return The number of bytes copied to the buffer by the Client.
|
||||
*/
|
||||
typedef size_t (*evmc_copy_code_fn)(struct evmc_context* context,
|
||||
const struct evmc_address* address,
|
||||
size_t code_offset,
|
||||
uint8_t* buffer_data,
|
||||
size_t buffer_size);
|
||||
|
||||
/// Selfdestruct callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to SELFDESTRUCT given contract.
|
||||
/// The execution of the contract will not be stopped, that is up to the EVM.
|
||||
///
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evmc_context.
|
||||
/// @param address The address of the contract to be selfdestructed.
|
||||
/// @param beneficiary The address where the remaining ETH is going to be
|
||||
/// transferred.
|
||||
/**
|
||||
* Selfdestruct callback function.
|
||||
*
|
||||
* This callback function is used by an EVM to SELFDESTRUCT given contract.
|
||||
* The execution of the contract will not be stopped, that is up to the EVM.
|
||||
*
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @see ::evmc_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 (*evmc_selfdestruct_fn)(struct evmc_context* context,
|
||||
const struct evmc_address* address,
|
||||
const struct evmc_address* beneficiary);
|
||||
|
||||
/// Log callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to inform about a LOG that happened
|
||||
/// during an EVM bytecode execution.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evmc_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.
|
||||
/**
|
||||
* Log callback function.
|
||||
*
|
||||
* This callback function is used by an EVM to inform about a LOG that happened
|
||||
* during an EVM bytecode execution.
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @see ::evmc_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 (*evmc_emit_log_fn)(struct evmc_context* context,
|
||||
const struct evmc_address* address,
|
||||
const uint8_t* data,
|
||||
@ -474,126 +543,140 @@ typedef void (*evmc_emit_log_fn)(struct evmc_context* context,
|
||||
const struct evmc_uint256be topics[],
|
||||
size_t topics_count);
|
||||
|
||||
/// Pointer to the callback function supporting EVM calls.
|
||||
///
|
||||
/// @param[out] result The result of the call. The result object is not
|
||||
/// initialized by the EVM, the Client MUST correctly
|
||||
/// initialize all expected fields of the structure.
|
||||
/// @param context The pointer to the Host execution context.
|
||||
/// @see ::evmc_context.
|
||||
/// @param msg Call parameters. @see ::evmc_message.
|
||||
/**
|
||||
* Pointer to the callback function supporting EVM calls.
|
||||
*
|
||||
* @param[out] result The result of the call. The result object is not
|
||||
* initialized by the EVM, the Client MUST correctly
|
||||
* initialize all expected fields of the structure.
|
||||
* @param context The pointer to the Host execution context.
|
||||
* @see ::evmc_context.
|
||||
* @param msg Call parameters. @see ::evmc_message.
|
||||
*/
|
||||
typedef void (*evmc_call_fn)(struct evmc_result* result,
|
||||
struct evmc_context* context,
|
||||
const struct evmc_message* msg);
|
||||
|
||||
/// The context interface.
|
||||
///
|
||||
/// The set of all callback functions expected by EVM instances. This is C
|
||||
/// realisation of vtable for OOP interface (only virtual methods, no data).
|
||||
/// Host implementations SHOULD create constant singletons of this (similarly
|
||||
/// to vtables) to lower the maintenance and memory management cost.
|
||||
struct evmc_context_fn_table {
|
||||
|
||||
/// Check account existence callback function.
|
||||
/**
|
||||
* The context interface.
|
||||
*
|
||||
* The set of all callback functions expected by EVM instances. This is C
|
||||
* realisation of vtable for OOP interface (only virtual methods, no data).
|
||||
* Host implementations SHOULD create constant singletons of this (similarly
|
||||
* to vtables) to lower the maintenance and memory management cost.
|
||||
*/
|
||||
struct evmc_context_fn_table
|
||||
{
|
||||
/** Check account existence callback function. */
|
||||
evmc_account_exists_fn account_exists;
|
||||
|
||||
/// Get storage callback function.
|
||||
/** Get storage callback function. */
|
||||
evmc_get_storage_fn get_storage;
|
||||
|
||||
/// Set storage callback function.
|
||||
/** Set storage callback function. */
|
||||
evmc_set_storage_fn set_storage;
|
||||
|
||||
/// Get balance callback function.
|
||||
/** Get balance callback function. */
|
||||
evmc_get_balance_fn get_balance;
|
||||
|
||||
/// Get code size callback function.
|
||||
/** Get code size callback function. */
|
||||
evmc_get_code_size_fn get_code_size;
|
||||
|
||||
/// Copy code callback function.
|
||||
/** Copy code callback function. */
|
||||
evmc_copy_code_fn copy_code;
|
||||
|
||||
/// Selfdestruct callback function.
|
||||
/** Selfdestruct callback function. */
|
||||
evmc_selfdestruct_fn selfdestruct;
|
||||
|
||||
/// Call callback function.
|
||||
/** Call callback function. */
|
||||
evmc_call_fn call;
|
||||
|
||||
/// Get transaction context callback function.
|
||||
/** Get transaction context callback function. */
|
||||
evmc_get_tx_context_fn get_tx_context;
|
||||
|
||||
/// Get block hash callback function.
|
||||
/** Get block hash callback function. */
|
||||
evmc_get_block_hash_fn get_block_hash;
|
||||
|
||||
/// Emit log callback function.
|
||||
/** Emit log callback function. */
|
||||
evmc_emit_log_fn emit_log;
|
||||
};
|
||||
|
||||
|
||||
/// Execution context managed by the Host.
|
||||
///
|
||||
/// The Host MUST pass the pointer to the execution context to
|
||||
/// ::evmc_execute_fn. The EVM MUST pass the same pointer back to the Host in
|
||||
/// every callback function.
|
||||
/// The context MUST contain at least the function table defining the context
|
||||
/// callback interface.
|
||||
/// Optionally, The Host MAY include in the context additional data.
|
||||
struct evmc_context {
|
||||
|
||||
/// Function table defining the context interface (vtable).
|
||||
/**
|
||||
* Execution context managed by the Host.
|
||||
*
|
||||
* The Host MUST pass the pointer to the execution context to
|
||||
* ::evmc_execute_fn. The EVM MUST pass the same pointer back to the Host in
|
||||
* every callback function.
|
||||
* The context MUST contain at least the function table defining the context
|
||||
* callback interface.
|
||||
* Optionally, The Host MAY include in the context additional data.
|
||||
*/
|
||||
struct evmc_context
|
||||
{
|
||||
/** Function table defining the context interface (vtable). */
|
||||
const struct evmc_context_fn_table* fn_table;
|
||||
};
|
||||
|
||||
|
||||
struct evmc_instance; ///< Forward declaration.
|
||||
/* Forward declaration. */
|
||||
struct evmc_instance;
|
||||
|
||||
/// Destroys the EVM instance.
|
||||
///
|
||||
/// @param evm The EVM instance to be destroyed.
|
||||
/**
|
||||
* Destroys the EVM instance.
|
||||
*
|
||||
* @param evm The EVM instance to be destroyed.
|
||||
*/
|
||||
typedef void (*evmc_destroy_fn)(struct evmc_instance* evm);
|
||||
|
||||
|
||||
/// Configures the EVM instance.
|
||||
///
|
||||
/// Allows modifying options of the EVM instance.
|
||||
/// Options:
|
||||
/// - code cache behavior: on, off, read-only, ...
|
||||
/// - optimizations,
|
||||
///
|
||||
/// @param evm The EVM instance to be configured.
|
||||
/// @param name The option name. NULL-terminated string. Cannot be NULL.
|
||||
/// @param value The new option value. NULL-terminated string. Cannot be NULL.
|
||||
/// @return 1 if the option set successfully, 0 otherwise.
|
||||
typedef int (*evmc_set_option_fn)(struct evmc_instance* evm,
|
||||
char const* name,
|
||||
char const* value);
|
||||
/**
|
||||
* Configures the EVM instance.
|
||||
*
|
||||
* Allows modifying options of the EVM instance.
|
||||
* Options:
|
||||
* - code cache behavior: on, off, read-only, ...
|
||||
* - optimizations,
|
||||
*
|
||||
* @param evm The EVM instance to be configured.
|
||||
* @param name The option name. NULL-terminated string. Cannot be NULL.
|
||||
* @param value The new option value. NULL-terminated string. Cannot be NULL.
|
||||
* @return 1 if the option set successfully, 0 otherwise.
|
||||
*/
|
||||
typedef int (*evmc_set_option_fn)(struct evmc_instance* evm, char const* name, char const* value);
|
||||
|
||||
|
||||
/// EVM revision.
|
||||
///
|
||||
/// The revision of the EVM specification based on the Ethereum
|
||||
/// upgrade / hard fork codenames.
|
||||
enum evmc_revision {
|
||||
/**
|
||||
* EVM revision.
|
||||
*
|
||||
* The revision of the EVM specification based on the Ethereum
|
||||
* upgrade / hard fork codenames.
|
||||
*/
|
||||
enum evmc_revision
|
||||
{
|
||||
EVMC_FRONTIER = 0,
|
||||
EVMC_HOMESTEAD = 1,
|
||||
EVMC_TANGERINE_WHISTLE = 2,
|
||||
EVMC_SPURIOUS_DRAGON = 3,
|
||||
EVMC_BYZANTIUM = 4,
|
||||
EVMC_CONSTANTINOPLE = 5,
|
||||
EVMC_CONSTANTINOPLE = 5
|
||||
};
|
||||
|
||||
|
||||
/// Generates and executes machine code for given EVM bytecode.
|
||||
///
|
||||
/// All the fun is here. This function actually does something useful.
|
||||
///
|
||||
/// @param instance A EVM instance.
|
||||
/// @param context The pointer to the Host execution context to be passed
|
||||
/// to callback functions. @see ::evmc_context.
|
||||
/// @param rev Requested EVM specification revision.
|
||||
/// @param msg Call parameters. @see ::evmc_message.
|
||||
/// @param code Reference to the bytecode to be executed.
|
||||
/// @param code_size The length of the bytecode.
|
||||
/// @return All execution results.
|
||||
/**
|
||||
* Generates and executes machine code for given EVM bytecode.
|
||||
*
|
||||
* All the fun is here. This function actually does something useful.
|
||||
*
|
||||
* @param instance A EVM instance.
|
||||
* @param context The pointer to the Host execution context to be passed
|
||||
* to callback functions. @see ::evmc_context.
|
||||
* @param rev Requested EVM specification revision.
|
||||
* @param msg Call parameters. @see ::evmc_message.
|
||||
* @param code Reference to the bytecode to be executed.
|
||||
* @param code_size The length of the bytecode.
|
||||
* @return All execution results.
|
||||
*/
|
||||
typedef struct evmc_result (*evmc_execute_fn)(struct evmc_instance* instance,
|
||||
struct evmc_context* context,
|
||||
enum evmc_revision rev,
|
||||
@ -602,54 +685,65 @@ typedef struct evmc_result (*evmc_execute_fn)(struct evmc_instance* instance,
|
||||
size_t code_size);
|
||||
|
||||
|
||||
/// The EVM instance.
|
||||
///
|
||||
/// Defines the base struct of the EVM implementation.
|
||||
/**
|
||||
* The EVM instance.
|
||||
*
|
||||
* Defines the base struct of the EVM implementation.
|
||||
*/
|
||||
struct evmc_instance
|
||||
{
|
||||
/// EVMC ABI version implemented by the EVM instance.
|
||||
///
|
||||
/// Used to detect ABI incompatibilities. The EVMC ABI version
|
||||
/// represented by this file is in ::EVMC_ABI_VERSION.
|
||||
/**
|
||||
* EVMC ABI version implemented by the EVM instance.
|
||||
*
|
||||
* Used to detect ABI incompatibilities. The EVMC ABI version
|
||||
* represented by this file is in ::EVMC_ABI_VERSION.
|
||||
*/
|
||||
const int abi_version;
|
||||
|
||||
/// The name of the EVMC VM implementation.
|
||||
///
|
||||
/// It MUST be a NULL-terminated not empty string.
|
||||
/**
|
||||
* The name of the EVMC VM implementation.
|
||||
*
|
||||
* It MUST be a NULL-terminated not empty string.
|
||||
*/
|
||||
const char* name;
|
||||
|
||||
/// The version of the EVMC VM implementation, e.g. "1.2.3b4".
|
||||
///
|
||||
/// It MUST be a NULL-terminated not empty string.
|
||||
/**
|
||||
* The version of the EVMC VM implementation, e.g. "1.2.3b4".
|
||||
*
|
||||
* It MUST be a NULL-terminated not empty string.
|
||||
*/
|
||||
const char* version;
|
||||
|
||||
/// Pointer to function destroying the EVM instance.
|
||||
/** Pointer to function destroying the EVM instance. */
|
||||
evmc_destroy_fn destroy;
|
||||
|
||||
/// Pointer to function executing a code by the EVM instance.
|
||||
/** Pointer to function executing a code by the EVM instance. */
|
||||
evmc_execute_fn execute;
|
||||
|
||||
/// Optional pointer to function modifying VM's options.
|
||||
///
|
||||
/// If the VM does not support this feature the pointer can be NULL.
|
||||
/**
|
||||
* Optional pointer to function modifying VM's options.
|
||||
*
|
||||
* If the VM does not support this feature the pointer can be NULL.
|
||||
*/
|
||||
evmc_set_option_fn set_option;
|
||||
};
|
||||
|
||||
// END Python CFFI declarations
|
||||
|
||||
/// Example of a function creating an instance of an example EVM implementation.
|
||||
///
|
||||
/// Each EVM implementation MUST provide a function returning an EVM instance.
|
||||
/// The function SHOULD be named `evmc_create_<vm-name>(void)`.
|
||||
///
|
||||
/// @return EVM instance or NULL indicating instance creation failure.
|
||||
///
|
||||
/// struct evmc_instance* evmc_create_examplevm(void);
|
||||
/* END Python CFFI declarations */
|
||||
|
||||
/**
|
||||
* Example of a function creating an instance of an example EVM implementation.
|
||||
*
|
||||
* Each EVM implementation MUST provide a function returning an EVM instance.
|
||||
* The function SHOULD be named `evmc_create_<vm-name>(void)`.
|
||||
*
|
||||
* @return EVM instance or NULL indicating instance creation failure.
|
||||
*
|
||||
* struct evmc_instance* evmc_create_examplevm(void);
|
||||
*/
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // EVMC_H
|
||||
/// @}
|
||||
#endif
|
||||
/** @} */
|
||||
|
@ -1,5 +1,6 @@
|
||||
# EVMC -- Ethereum Client-VM Connector API
|
||||
# EVMC: Ethereum Client-VM Connector API.
|
||||
# Copyright 2018 Pawel Bylica.
|
||||
# Licensed under the MIT License. See the LICENSE file.
|
||||
|
||||
add_subdirectory(integration)
|
||||
add_subdirectory(vmtester)
|
||||
|
5
test/integration/CMakeLists.txt
Normal file
5
test/integration/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
# EVMC: Ethereum Client-VM Connector API.
|
||||
# Copyright 2018 Pawel Bylica.
|
||||
# Licensed under the MIT License. See the LICENSE file.
|
||||
|
||||
add_subdirectory(compilation)
|
11
test/integration/compilation/CMakeLists.txt
Normal file
11
test/integration/compilation/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# EVMC: Ethereum Client-VM Connector API.
|
||||
# Copyright 2018 Pawel Bylica.
|
||||
# Licensed under the MIT License. See the LICENSE file.
|
||||
|
||||
add_library(test-compile-c99 STATIC compilation_test.c)
|
||||
target_link_libraries(test-compile-c99 PRIVATE evmc)
|
||||
set_target_properties(test-compile-c99 PROPERTIES C_STANDARD 99 C_EXTENSIONS OFF)
|
||||
|
||||
add_library(test-compile-c11 STATIC compilation_test.c)
|
||||
target_link_libraries(test-compile-c11 PRIVATE evmc)
|
||||
set_target_properties(test-compile-c11 PROPERTIES C_STANDARD 11 C_EXTENSIONS OFF)
|
7
test/integration/compilation/compilation_test.c
Normal file
7
test/integration/compilation/compilation_test.c
Normal file
@ -0,0 +1,7 @@
|
||||
/* EVMC: Ethereum Client-VM Connector API.
|
||||
* Copyright 2018 Pawel Bylica.
|
||||
* Licensed under the MIT License. See the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <evmc/evmc.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
# EVMC -- Ethereum Client-VM Connector API
|
||||
# EVMC: Ethereum Client-VM Connector API.
|
||||
# Copyright 2018 Pawel Bylica.
|
||||
# Licensed under the MIT License. See the LICENSE file.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user