From afc1b382d727ff9e1a0ec5913987735c03d3b8ea Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 7 Apr 2015 17:48:52 +0200 Subject: [PATCH] Start of new C API implementation - For more details look at: https://github.com/ethereum/wiki/wiki/Ethash-C-API - The functions of the API have all been implemented but are not yet used or tested --- ethash.h | 67 ++++++++++++++++++------------------------- internal.c | 83 +++++++++++++++++++++++++++++++++++++++++++++--------- internal.h | 11 ++++++++ 3 files changed, 108 insertions(+), 53 deletions(-) diff --git a/ethash.h b/ethash.h index ba5d63c8a..ebe89a9f5 100644 --- a/ethash.h +++ b/ethash.h @@ -47,7 +47,7 @@ typedef struct ethash_params { uint64_t cache_size; // Size of compute cache (in bytes, multiple of node size (64)). } ethash_params; -/// Type of a blockhash +/// Type of a seedhash/blockhash e.t.c. typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t; static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i) { @@ -64,6 +64,13 @@ static inline void ethash_h256_reset(ethash_h256_t *hash) memset(hash, 0, 32); } +struct ethash_light; +typedef struct ethash_light* ethash_light_t; +struct ethash_full; +typedef struct ethash_full* ethash_full_t; +typedef int(*ethash_callback_t)(unsigned); + +// LTODO: for consistency's sake maybe use ethash_return_value_t? typedef struct ethash_return_value { ethash_h256_t result; ethash_h256_t mix_hash; @@ -84,47 +91,27 @@ typedef struct ethash_cache { void ethash_mkcache(ethash_cache *cache, ethash_params const *params, ethash_h256_t const *seed); void ethash_compute_full_data(void *mem, ethash_params const *params, ethash_cache const *cache); -void ethash_full(ethash_return_value *ret, - void const *full_mem, - ethash_params const *params, - ethash_h256_t const *header_hash, - const uint64_t nonce); -void ethash_light(ethash_return_value *ret, - ethash_cache const *cache, - ethash_params const *params, - ethash_h256_t const *header_hash, - const uint64_t nonce); -void ethash_get_seedhash(ethash_h256_t *seedhash, const uint32_t block_number); -static inline void ethash_prep_light(void *cache, ethash_params const *params, ethash_h256_t const* seed) -{ - ethash_cache c; - c.mem = cache; - ethash_mkcache(&c, params, seed); -} - -static inline void ethash_compute_light(ethash_return_value *ret, void const *cache, ethash_params const *params, ethash_h256_t const *header_hash, const uint64_t nonce) -{ - ethash_cache c; - c.mem = (void *) cache; - ethash_light(ret, &c, params, header_hash, nonce); -} +ethash_light_t ethash_new_light(ethash_params const *params, ethash_h256_t const *seed); +void ethash_delete_light(ethash_light_t light); +void ethash_compute_light(ethash_return_value *ret, + ethash_light_t light, + ethash_params const *params, + const ethash_h256_t *header_hash, + const uint64_t nonce); + +ethash_full_t ethash_new_full(ethash_params const* params, + void const* cache, + const ethash_h256_t *seed, + ethash_callback_t callback); +void ethash_delete_full(ethash_full_t full); +void ethash_compute_full(ethash_return_value *ret, + ethash_full_t full, + ethash_params const *params, + const ethash_h256_t *header_hash, + const uint64_t nonce); -static inline void ethash_prep_full(void *full, ethash_params const *params, void const *cache) -{ - ethash_cache c; - c.mem = (void *) cache; - ethash_compute_full_data(full, params, &c); -} - -static inline void ethash_compute_full(ethash_return_value *ret, - void const *full, - ethash_params const *params, - ethash_h256_t const *header_hash, - const uint64_t nonce) -{ - ethash_full(ret, full, params, header_hash, nonce); -} +void ethash_get_seedhash(ethash_h256_t *seedhash, const uint32_t block_number); // Returns if hash is less than or equal to difficulty static inline int ethash_check_difficulty(ethash_h256_t const *hash, diff --git a/internal.c b/internal.c index 93df9badb..9248f78ed 100644 --- a/internal.c +++ b/internal.c @@ -86,7 +86,7 @@ void static ethash_compute_cache_nodes(node *const nodes, void ethash_mkcache(ethash_cache *cache, ethash_params const *params, - ethash_h256_t const* seed) + ethash_h256_t const *seed) { node *nodes = (node *) cache->mem; ethash_compute_cache_nodes(nodes, params, seed); @@ -291,20 +291,77 @@ int ethash_quick_check_difficulty(ethash_h256_t const *header_hash, return ethash_check_difficulty(&return_hash, difficulty); } -void ethash_full(ethash_return_value *ret, - void const *full_mem, - ethash_params const *params, - ethash_h256_t const *header_hash, - const uint64_t nonce) +ethash_light_t ethash_new_light(ethash_params const *params, ethash_h256_t const *seed) { - ethash_hash(ret, (node const *) full_mem, NULL, params, header_hash, nonce); + struct ethash_light *ret; + ret = malloc(sizeof(*ret)); + if (!ret) { + return NULL; + } + ret->cache.mem = malloc(params->cache_size); + if (!ret->cache.mem) { + goto fail_free_light; + } + ethash_mkcache(ret->cache.mem, params, seed); + return ret; + +fail_free_light: + free(ret); + return NULL; +} + +void ethash_delete_light(ethash_light_t light) +{ + free(light->cache.mem); + free(light); +} + +void ethash_compute_light(ethash_return_value *ret, + ethash_light_t light, + ethash_params const *params, + const ethash_h256_t *header_hash, + const uint64_t nonce) +{ + ethash_hash(ret, NULL, &light->cache, params, header_hash, nonce); +} + +ethash_full_t ethash_new_full(ethash_params const* params, + void const* cache, + const ethash_h256_t *seed, + ethash_callback_t callback) +{ + struct ethash_full *ret; + ret = malloc(sizeof(*ret)); + if (!ret) { + return NULL; + } + ret->cache.mem = (void*)cache; + ret->data = malloc(params->full_size); + if (!ret->data) { + goto fail_free_full; + } + ethash_compute_full_data(ret->data, params, cache); + ret->seed = seed; + ret->callback = callback; + return ret; + +fail_free_full: + free(ret); + return NULL; +} + +void ethash_delete_full(ethash_full_t full) +{ + // should the cache be freed here? Does ethash_full_t take ownership of the cache? + free(full->data); + free(full); } -void ethash_light(ethash_return_value *ret, - ethash_cache const *cache, - ethash_params const *params, - ethash_h256_t const *header_hash, - const uint64_t nonce) +void ethash_compute_full(ethash_return_value *ret, + ethash_full_t full, + ethash_params const *params, + const ethash_h256_t *header_hash, + const uint64_t nonce) { - ethash_hash(ret, NULL, cache, params, header_hash, nonce); + ethash_hash(ret, (node const*)full->data, NULL, params, header_hash, nonce); } diff --git a/internal.h b/internal.h index 34f2d5ba0..8fc7df243 100644 --- a/internal.h +++ b/internal.h @@ -30,6 +30,17 @@ typedef union node { } node; +struct ethash_light { + ethash_cache cache; +}; + +struct ethash_full { + ethash_cache cache; + node *data; + const ethash_h256_t* seed; + ethash_callback_t callback; +}; + void ethash_calculate_dag_item(node *const ret, const unsigned node_index, ethash_params const *params,