mirror of https://github.com/status-im/evmc.git
Merge pull request #127 from ethereum/evmc-query
EVM-C: Simplify callbacks
This commit is contained in:
commit
4c2202ebcf
|
@ -24,28 +24,12 @@ static void print_address(const struct evm_uint160be* address)
|
|||
printf("%x", address->bytes[i] & 0xff);
|
||||
}
|
||||
|
||||
static void query(union evm_variant* result,
|
||||
struct evm_env* env,
|
||||
enum evm_query_key key,
|
||||
const struct evm_uint160be* address) {
|
||||
printf("EVM-C: QUERY %d\n", key);
|
||||
switch (key) {
|
||||
case EVM_CODE_BY_ADDRESS:
|
||||
result->data = NULL;
|
||||
result->data_size = 0;
|
||||
break;
|
||||
|
||||
case EVM_BALANCE:
|
||||
result->uint256be = balance(env, address);
|
||||
break;
|
||||
|
||||
case EVM_ACCOUNT_EXISTS:
|
||||
result->int64 = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
result->int64 = 0;
|
||||
}
|
||||
static int account_exists(struct evm_env* env,
|
||||
const struct evm_uint160be* address) {
|
||||
printf("EVM-C: EXISTS @");
|
||||
print_address(address);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_storage(struct evm_uint256be* result,
|
||||
|
@ -68,6 +52,26 @@ static void set_storage(struct evm_env* env,
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
static void get_balance(struct evm_uint256be* result,
|
||||
struct evm_env* env,
|
||||
const struct evm_uint160be* address)
|
||||
{
|
||||
printf("EVM-C: BALANCE @");
|
||||
print_address(address);
|
||||
printf("\n");
|
||||
*result = balance(env, address);
|
||||
}
|
||||
|
||||
static size_t get_code(const uint8_t** code,
|
||||
struct evm_env* env,
|
||||
const struct evm_uint160be* address)
|
||||
{
|
||||
printf("EVM-C: CODE @");
|
||||
print_address(address);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void selfdestruct(struct evm_env* env,
|
||||
const struct evm_uint160be* address,
|
||||
const struct evm_uint160be* beneficiary)
|
||||
|
@ -109,9 +113,11 @@ static void evm_log(struct evm_env* env, const struct evm_uint160be* address,
|
|||
}
|
||||
|
||||
static const struct evm_host example_host = {
|
||||
query,
|
||||
account_exists,
|
||||
get_storage,
|
||||
set_storage,
|
||||
get_balance,
|
||||
get_code,
|
||||
selfdestruct,
|
||||
call,
|
||||
get_tx_context,
|
||||
|
|
105
include/evm.h
105
include/evm.h
|
@ -183,73 +183,16 @@ struct evm_result {
|
|||
} reserved;
|
||||
};
|
||||
|
||||
/// The query callback key.
|
||||
enum evm_query_key {
|
||||
EVM_CODE_BY_ADDRESS = 10, ///< Code by an address for EXTCODECOPY.
|
||||
EVM_CODE_SIZE = 11, ///< Code size by an address for EXTCODESIZE.
|
||||
EVM_BALANCE = 12, ///< Balance of a given address for BALANCE.
|
||||
EVM_ACCOUNT_EXISTS = 14, ///< Check if an account exists.
|
||||
};
|
||||
|
||||
|
||||
/// Variant type to represent possible types of values used in EVM.
|
||||
/// Check account existence callback function
|
||||
///
|
||||
/// Type-safety is lost around the code that uses this type. We should have
|
||||
/// complete set of unit tests covering all possible cases.
|
||||
/// The size of the type is 64 bytes and should fit in single cache line.
|
||||
union evm_variant {
|
||||
/// A host-endian 64-bit integer.
|
||||
int64_t int64;
|
||||
|
||||
/// A big-endian 256-bit integer or hash.
|
||||
struct evm_uint256be uint256be;
|
||||
|
||||
/// A memory reference.
|
||||
struct {
|
||||
/// Pointer to the data.
|
||||
uint8_t const* data;
|
||||
|
||||
/// Size of the referenced memory/data.
|
||||
size_t data_size;
|
||||
};
|
||||
};
|
||||
|
||||
/// Query callback function.
|
||||
///
|
||||
/// This callback function is used by the EVM to query the host application
|
||||
/// about additional information about accounts in the state required to
|
||||
/// execute EVM code.
|
||||
/// @param[out] result The result of the query.
|
||||
/// @param env Pointer to execution environment managed by the host
|
||||
/// application.
|
||||
/// @param key The kind of the query. See evm_query_key
|
||||
/// and details below.
|
||||
/// 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 address The address of the account the query is about.
|
||||
///
|
||||
/// ## Types of queries
|
||||
///
|
||||
/// - ::EVM_CODE_BY_ADDRESS
|
||||
/// @result evm_variant::data The appropriate code for the given address or NULL if not found.
|
||||
///
|
||||
/// - ::EVM_CODE_SIZE
|
||||
/// @result evm_variant::int64 The appropriate code size for the given address or 0 if not found.
|
||||
///
|
||||
/// - ::EVM_BALANCE
|
||||
/// @result evm_variant::uint256be The appropriate balance for the given address or 0 if not found.
|
||||
///
|
||||
/// - ::EVM_ACCOUNT_EXISTS
|
||||
/// @result evm_variant::int64 1 if exists, 0 if not.
|
||||
///
|
||||
///
|
||||
/// @todo
|
||||
/// - Consider swapping key and address arguments,
|
||||
/// e.g. `query(result, env, addr, EVM_SLOAD, k)`.
|
||||
/// - Consider renaming key argument to something else. Key is confusing
|
||||
/// especially for SSTORE and SLOAD. Maybe "kind"?
|
||||
typedef void (*evm_query_state_fn)(union evm_variant* result,
|
||||
struct evm_env* env,
|
||||
enum evm_query_key key,
|
||||
const struct evm_uint160be* address);
|
||||
/// @return 1 if exists, 0 otherwise.
|
||||
typedef int (*evm_account_exists_fn)(struct evm_env* env,
|
||||
const struct evm_uint160be* address);
|
||||
|
||||
/// Get storage callback function.
|
||||
///
|
||||
|
@ -279,6 +222,32 @@ typedef void (*evm_set_storage_fn)(struct evm_env* env,
|
|||
const struct evm_uint256be* key,
|
||||
const struct evm_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 env Pointer to execution environment managed by the host
|
||||
/// application.
|
||||
/// @param address The address.
|
||||
typedef void (*evm_get_balance_fn)(struct evm_uint256be* result,
|
||||
struct evm_env* env,
|
||||
const struct evm_uint160be* address);
|
||||
|
||||
/// Get code callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to get the code of a contract of
|
||||
/// given address.
|
||||
/// @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 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,
|
||||
const struct evm_uint160be* address);
|
||||
|
||||
/// Selfdestruct callback function.
|
||||
///
|
||||
/// This callback function is used by an EVM to SELFDESTRUCT given contract.
|
||||
|
@ -327,10 +296,14 @@ typedef void (*evm_call_fn)(
|
|||
/// realisation of OOP interface (only virtual methods, no data).
|
||||
/// Host implementations SHOULD create constant singletons of this (similar
|
||||
/// to vtables) to lower the maintenance and memory management cost.
|
||||
///
|
||||
/// @todo Merge evm_host with evm_env?
|
||||
struct evm_host {
|
||||
evm_query_state_fn query;
|
||||
evm_account_exists_fn account_exists;
|
||||
evm_get_storage_fn get_storage;
|
||||
evm_set_storage_fn set_storage;
|
||||
evm_get_balance_fn get_balance;
|
||||
evm_get_code_fn get_code;
|
||||
evm_selfdestruct_fn selfdestruct;
|
||||
evm_call_fn call;
|
||||
evm_get_tx_context_fn get_tx_context;
|
||||
|
|
Loading…
Reference in New Issue