From d9f7ff25f5a7a0485a7a418a1e89647db731cb78 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 20 Aug 2018 14:38:23 +0100 Subject: [PATCH 1/3] Add return code to get_block_hash_fn --- bindings/go/evmc/host.c | 4 ++-- bindings/go/evmc/host.go | 13 +++++++++++-- examples/example_host.cpp | 3 ++- include/evmc/evmc.h | 18 ++++++++++-------- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/bindings/go/evmc/host.c b/bindings/go/evmc/host.c index d9975c8f4..d007fa3a9 100644 --- a/bindings/go/evmc/host.c +++ b/bindings/go/evmc/host.c @@ -97,8 +97,8 @@ static inline void go_exported_functions_type_checks() tx_context = getTxContext(context); evmc_get_block_hash_fn get_block_hash_fn = NULL; - get_block_hash_fn(uint256be, context, number); - getBlockHash(uint256be, context, number); + status = get_block_hash_fn(uint256be, context, number); + status = getBlockHash(uint256be, context, number); evmc_emit_log_fn emit_log_fn = NULL; emit_log_fn(context, address, data, size, uint256be, size); diff --git a/bindings/go/evmc/host.go b/bindings/go/evmc/host.go index 992bc8d09..0f740f57a 100644 --- a/bindings/go/evmc/host.go +++ b/bindings/go/evmc/host.go @@ -182,11 +182,20 @@ func getTxContext(pCtx unsafe.Pointer) C.struct_evmc_tx_context { } //export getBlockHash -func getBlockHash(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, number int64) { +func getBlockHash(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, number int64) C.int { idx := int((*C.struct_extended_context)(pCtx).index) ctx := getHostContext(idx) - *pResult = evmcUint256be(ctx.GetBlockHash(number)) + blockhash := ctx.GetBlockHash(number) + + // FIXME: should we instead adjust `ctx.GetBlockHash`? + if blockhash == (common.Hash{}) { + // All zeroes hash is considered a failure in lookup. + return C.int(0) + } + + *pResult = evmcUint256be(blockhash) + return C.int(1) } //export emitLog diff --git a/examples/example_host.cpp b/examples/example_host.cpp index a24a174df..373af146c 100644 --- a/examples/example_host.cpp +++ b/examples/example_host.cpp @@ -107,11 +107,12 @@ static evmc_tx_context get_tx_context(evmc_context* context) return result; } -static void get_block_hash(evmc_uint256be* result, evmc_context* context, int64_t number) +static int get_block_hash(evmc_uint256be* result, evmc_context* context, int64_t number) { (void)result; (void)context; (void)number; + return 0; } static void emit_log(evmc_context* context, diff --git a/include/evmc/evmc.h b/include/evmc/evmc.h index fc4b6f11d..4d26d347f 100644 --- a/include/evmc/evmc.h +++ b/include/evmc/evmc.h @@ -153,17 +153,19 @@ typedef struct evmc_tx_context (*evmc_get_tx_context_fn)(struct evmc_context* co /** * Get block hash callback function. * - * This callback function is used by an EVM to query the block hash of - * a given block. + * This callback function is used by an VM to query the block hash of + * a given block. If the requested block is not found, then an appropriate + * result code is returned. * - * @param[out] result The returned block hash value. + * @param[out] result The returned block hash value. Only written to + * if the return value is 1 (information is avialable). * @param context The pointer to the Host execution context. - * @param number The block number. Must be a value between - * (and including) 0 and 255. + * @param number The block number. + * @return 1 if the information is available, 0 otherwise. */ -typedef void (*evmc_get_block_hash_fn)(struct evmc_uint256be* result, - struct evmc_context* context, - int64_t number); +typedef int (*evmc_get_block_hash_fn)(struct evmc_uint256be* result, + struct evmc_context* context, + int64_t number); /** * The execution status code. From d0bc50792ac624999189f7bd7657083d7833a993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 3 Sep 2018 16:49:01 +0200 Subject: [PATCH 2/3] go: Add error output to Host.GetBlockHash() --- bindings/go/evmc/host.go | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/bindings/go/evmc/host.go b/bindings/go/evmc/host.go index 0f740f57a..d9f787f51 100644 --- a/bindings/go/evmc/host.go +++ b/bindings/go/evmc/host.go @@ -79,7 +79,7 @@ type HostContext interface { Selfdestruct(addr common.Address, beneficiary common.Address) GetTxContext() (gasPrice common.Hash, origin common.Address, coinbase common.Address, number int64, timestamp int64, gasLimit int64, difficulty common.Hash) - GetBlockHash(number int64) common.Hash + GetBlockHash(number int64) (common.Hash, error) EmitLog(addr common.Address, topics []common.Hash, data []byte) Call(kind CallKind, destination common.Address, sender common.Address, value *big.Int, input []byte, gas int64, depth int, @@ -186,11 +186,8 @@ func getBlockHash(pResult *C.struct_evmc_uint256be, pCtx unsafe.Pointer, number idx := int((*C.struct_extended_context)(pCtx).index) ctx := getHostContext(idx) - blockhash := ctx.GetBlockHash(number) - - // FIXME: should we instead adjust `ctx.GetBlockHash`? - if blockhash == (common.Hash{}) { - // All zeroes hash is considered a failure in lookup. + blockhash, err := ctx.GetBlockHash(number) + if err != nil { return C.int(0) } From ced1c2676ffd154af20afb79daa7b8da5dea1a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 3 Sep 2018 17:24:15 +0200 Subject: [PATCH 3/3] examples: Better get_block_hash example --- examples/example_host.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/examples/example_host.cpp b/examples/example_host.cpp index 373af146c..105f316ea 100644 --- a/examples/example_host.cpp +++ b/examples/example_host.cpp @@ -9,6 +9,13 @@ #include +struct example_host_context : evmc_context +{ + example_host_context(); + + evmc_tx_context tx_context = {}; +}; + static evmc_uint256be balance(evmc_context* context, const evmc_address* address) { (void)context; @@ -109,10 +116,15 @@ static evmc_tx_context get_tx_context(evmc_context* context) static int get_block_hash(evmc_uint256be* result, evmc_context* context, int64_t number) { - (void)result; - (void)context; - (void)number; - return 0; + example_host_context* host = static_cast(context); + int64_t current_block_number = host->tx_context.block_number; + + if (number >= current_block_number || number < current_block_number - 256) + return 0; + + evmc_uint256be example_block_hash{}; + *result = example_block_hash; + return 1; } static void emit_log(evmc_context* context, @@ -135,10 +147,7 @@ static const evmc_host_interface interface = { copy_code, selfdestruct, call, get_tx_context, get_block_hash, emit_log, }; -struct example_host_context : evmc_context -{ - example_host_context() : evmc_context{&interface} {} -}; +example_host_context::example_host_context() : evmc_context{&interface} {} extern "C" {