Merge pull request #127 from ethereum/evmc-query

EVM-C: Simplify callbacks
This commit is contained in:
Paweł Bylica 2017-08-18 15:09:32 +02:00 committed by GitHub
commit 4c2202ebcf
2 changed files with 68 additions and 89 deletions

View File

@ -24,28 +24,12 @@ static void print_address(const struct evm_uint160be* address)
printf("%x", address->bytes[i] & 0xff); printf("%x", address->bytes[i] & 0xff);
} }
static void query(union evm_variant* result, static int account_exists(struct evm_env* env,
struct evm_env* env, const struct evm_uint160be* address) {
enum evm_query_key key, printf("EVM-C: EXISTS @");
const struct evm_uint160be* address) { print_address(address);
printf("EVM-C: QUERY %d\n", key); printf("\n");
switch (key) { return 0;
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 void get_storage(struct evm_uint256be* result, static void get_storage(struct evm_uint256be* result,
@ -68,6 +52,26 @@ static void set_storage(struct evm_env* env,
printf("\n"); 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, static void selfdestruct(struct evm_env* env,
const struct evm_uint160be* address, const struct evm_uint160be* address,
const struct evm_uint160be* beneficiary) 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 = { static const struct evm_host example_host = {
query, account_exists,
get_storage, get_storage,
set_storage, set_storage,
get_balance,
get_code,
selfdestruct, selfdestruct,
call, call,
get_tx_context, get_tx_context,

View File

@ -183,73 +183,16 @@ struct evm_result {
} reserved; } reserved;
}; };
/// The query callback key. /// Check account existence callback function
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.
/// ///
/// Type-safety is lost around the code that uses this type. We should have /// This callback function is used by the EVM to check if
/// complete set of unit tests covering all possible cases. /// there exists an account at given address.
/// The size of the type is 64 bytes and should fit in single cache line. /// @param env Pointer to execution environment managed by the host
union evm_variant { /// application.
/// 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.
/// @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.
/// ## Types of queries typedef int (*evm_account_exists_fn)(struct evm_env* env,
/// const struct evm_uint160be* address);
/// - ::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);
/// Get storage callback function. /// 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* key,
const struct evm_uint256be* value); 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. /// Selfdestruct callback function.
/// ///
/// This callback function is used by an EVM to SELFDESTRUCT given contract. /// 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). /// 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 (similar
/// to vtables) to lower the maintenance and memory management cost. /// to vtables) to lower the maintenance and memory management cost.
///
/// @todo Merge evm_host with evm_env?
struct evm_host { struct evm_host {
evm_query_state_fn query; 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;
evm_get_balance_fn get_balance;
evm_get_code_fn get_code;
evm_selfdestruct_fn selfdestruct; evm_selfdestruct_fn selfdestruct;
evm_call_fn call; evm_call_fn call;
evm_get_tx_context_fn get_tx_context; evm_get_tx_context_fn get_tx_context;