Browse Source

API changes requested by Gavin.

- Following this spec:
  https://github.com/ethereum/wiki/wiki/Ethash-C-API

- This breaks all but the cpp tests. OpenCL miner and go ethereum will
  be fixed in subsequent commits.
cl-refactor
Lefteris Karapetsas 10 years ago
parent
commit
d82b609449
  1. 174
      ethash.h
  2. 177
      internal.c
  3. 112
      internal.h
  4. 12
      io.h
  5. 16
      io_posix.c
  6. 16
      io_win32.c

174
ethash.h

@ -44,20 +44,6 @@ extern "C" {
/// Type of a seedhash/blockhash e.t.c. /// Type of a seedhash/blockhash e.t.c.
typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t; 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)
{
return hash->b[i];
}
static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
{
hash->b[i] = v;
}
static inline void ethash_h256_reset(ethash_h256_t* hash)
{
memset(hash, 0, 32);
}
// convenience macro to statically initialize an h256_t // convenience macro to statically initialize an h256_t
// usage: // usage:
@ -76,42 +62,17 @@ typedef int(*ethash_callback_t)(unsigned);
typedef struct ethash_return_value { typedef struct ethash_return_value {
ethash_h256_t result; ethash_h256_t result;
ethash_h256_t mix_hash; ethash_h256_t mix_hash;
bool success;
} ethash_return_value_t; } ethash_return_value_t;
uint64_t ethash_get_datasize(uint64_t const block_number);
uint64_t ethash_get_cachesize(uint64_t const block_number);
typedef struct ethash_cache {
void* mem;
uint64_t cache_size;
} ethash_cache_t;
/**
* Allocate and initialize a new ethash_cache object
*
* @param cache_size The size of the cache in bytes
* @param seed Block seedhash to be used during the computation of the
* cache nodes
* @return Newly allocated ethash_cache on success or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
*/
ethash_cache_t* ethash_cache_new(uint64_t cache_size, ethash_h256_t const* seed);
/**
* Frees a previously allocated ethash_cache
* @param c The object to free
*/
void ethash_cache_delete(ethash_cache_t* c);
/** /**
* Allocate and initialize a new ethash_light handler * Allocate and initialize a new ethash_light handler
* *
* @param cache_size The size of the cache in bytes * @param block_number The block number for which to create the handler
* @param seed Block seedhash to be used during the computation of the
* cache nodes
* @return Newly allocated ethash_light handler or NULL in case of * @return Newly allocated ethash_light handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes() * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
*/ */
ethash_light_t ethash_light_new(uint64_t cache_size, ethash_h256_t const* seed); ethash_light_t ethash_light_new(uint64_t const block_number);
/** /**
* Frees a previously allocated ethash_light handler * Frees a previously allocated ethash_light handler
* @param light The light handler to free * @param light The light handler to free
@ -120,48 +81,21 @@ void ethash_light_delete(ethash_light_t light);
/** /**
* Calculate the light client data * Calculate the light client data
* *
* @param ret An object of ethash_return_value to hold the return value
* @param light The light client handler * @param light The light client handler
* @param full_size The size of the full data in bytes.
* @param header_hash The header hash to pack into the mix * @param header_hash The header hash to pack into the mix
* @param nonce The nonce to pack into the mix * @param nonce The nonce to pack into the mix
* @return true if all went well and false if there were invalid * @return an object of ethash_return_value_t holding the return values
* parameters given.
*/ */
bool ethash_light_compute( ethash_return_value_t ethash_light_compute(
ethash_return_value_t* ret,
ethash_light_t light, ethash_light_t light,
uint64_t full_size, const ethash_h256_t header_hash,
const ethash_h256_t* header_hash,
uint64_t const nonce uint64_t const nonce
); );
/**
* Get a pointer to the cache object held by the light client
*
* @param light The light client whose cache to request
* @return A pointer to the cache held by the light client or NULL if
* there was no cache in the first place
*/
ethash_cache_t* ethash_light_get_cache(ethash_light_t light);
/**
* Move the memory ownership of the cache somewhere else
*
* @param light The light client whose cache's memory ownership to acquire.
* After this function concludes it will no longer have a cache.
* @return A pointer to the moved cache or NULL if there was no cache in the first place
*/
ethash_cache_t* ethash_light_acquire_cache(ethash_light_t light);
/** /**
* Allocate and initialize a new ethash_full handler * Allocate and initialize a new ethash_full handler
* *
* @param dirname The directory in which to put the DAG file. * @param dirname The light handler containing the cache.
* @param seedhash The seed hash of the block. Used in the DAG file naming.
* @param full_size The size of the full data in bytes.
* @param cache A cache object to use that was allocated with @ref ethash_cache_new().
* Iff this function succeeds the ethash_full_t will take memory
* memory ownership of the cache and free it at deletion. If
* not then the user still has to handle freeing of the cache himself.
* @param callback A callback function with signature of @ref ethash_callback_t * @param callback A callback function with signature of @ref ethash_callback_t
* It accepts an unsigned with which a progress of DAG calculation * It accepts an unsigned with which a progress of DAG calculation
* can be displayed. If all goes well the callback should return 0. * can be displayed. If all goes well the callback should return 0.
@ -169,13 +103,8 @@ ethash_cache_t* ethash_light_acquire_cache(ethash_light_t light);
* @return Newly allocated ethash_full handler or NULL in case of * @return Newly allocated ethash_full handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data() * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
*/ */
ethash_full_t ethash_full_new( ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback);
char const* dirname,
ethash_h256_t const* seed_hash,
uint64_t full_size,
ethash_cache_t const* cache,
ethash_callback_t callback
);
/** /**
* Frees a previously allocated ethash_full handler * Frees a previously allocated ethash_full handler
* @param full The light handler to free * @param full The light handler to free
@ -184,98 +113,29 @@ void ethash_full_delete(ethash_full_t full);
/** /**
* Calculate the full client data * Calculate the full client data
* *
* @param ret An object of ethash_return_value to hold the return value
* @param full The full client handler * @param full The full client handler
* @param header_hash The header hash to pack into the mix * @param header_hash The header hash to pack into the mix
* @param nonce The nonce to pack into the mix * @param nonce The nonce to pack into the mix
* @return true if all went well and false if there were invalid * @return An object of ethash_return_value to hold the return value
* parameters given or if there was a callback given and
* at some point return a non-zero value
*/ */
bool ethash_full_compute( ethash_return_value_t ethash_full_compute(
ethash_return_value_t* ret,
ethash_full_t full, ethash_full_t full,
ethash_h256_t const* header_hash, ethash_h256_t const header_hash,
uint64_t const nonce uint64_t const nonce
); );
/** /**
* Get a pointer to the full DAG data * Get a pointer to the full DAG data
*/ */
void *ethash_full_data(ethash_full_t full); void const* ethash_full_dag(ethash_full_t full);
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,
ethash_h256_t const* difficulty
)
{
// Difficulty is big endian
for (int i = 0; i < 32; i++) {
if (ethash_h256_get(hash, i) == ethash_h256_get(difficulty, i)) {
continue;
}
return ethash_h256_get(hash, i) < ethash_h256_get(difficulty, i);
}
return 1;
}
int ethash_quick_check_difficulty(
ethash_h256_t const* header_hash,
uint64_t const nonce,
ethash_h256_t const* mix_hash,
ethash_h256_t const* difficulty
);
/** /**
* Compute the memory data for a full node's memory * Get the size of the DAG data
*
* @param mem A pointer to an ethash full's memory
* @param full_size The size of the full data in bytes
* @param cache A cache object to use in the calculation
* @return true if all went fine and false for invalid parameters
*/ */
bool ethash_compute_full_data(void* mem, uint64_t full_size, ethash_cache_t const* cache); uint64_t ethash_full_dag_size(ethash_full_t full);
/** /**
* ========================= * Calculate the seedhash for a given block number
* = DEPRECATED API =
* =========================
*
* Kept for backwards compatibility with whoever still uses it. Please consider
* switching to the new API (look above)
*/ */
typedef struct ethash_params { void ethash_get_seedhash(ethash_h256_t *seedhash, uint64_t const block_number);
/// Size of full data set (in bytes, multiple of mix size (128)).
uint64_t full_size;
/// Size of compute cache (in bytes, multiple of node size (64)).
uint64_t cache_size;
} ethash_params;
// initialize the parameters
static inline void ethash_params_init(ethash_params* params, uint32_t const block_number)
{
params->full_size = ethash_get_datasize(block_number);
params->cache_size = ethash_get_cachesize(block_number);
}
void ethash_mkcache(ethash_cache_t* cache, ethash_params const* params, ethash_h256_t const* seed);
void ethash_full(
ethash_return_value_t* ret,
void const* full_mem,
ethash_params const* params,
ethash_h256_t const* header_hash,
uint64_t const nonce
);
void ethash_light(
ethash_return_value_t* ret,
ethash_cache_t const* cache,
ethash_params const* params,
ethash_h256_t const* header_hash,
uint64_t const nonce
);
#ifdef __cplusplus #ifdef __cplusplus
} }

177
internal.c

@ -90,46 +90,14 @@ bool static ethash_compute_cache_nodes(
return true; return true;
} }
ethash_cache_t* ethash_cache_new(uint64_t cache_size, ethash_h256_t const* seed)
{
ethash_cache_t* ret;
ret = malloc(sizeof(*ret));
if (!ret) {
return NULL;
}
ret->mem = malloc((size_t)cache_size);
if (!ret->mem) {
goto fail_free_cache;
}
node* nodes = (node*)ret->mem;
if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
goto fail_free_cache_mem;
}
ret->cache_size = cache_size;
return ret;
fail_free_cache_mem:
free(ret->mem);
fail_free_cache:
free(ret);
return NULL;
}
void ethash_cache_delete(ethash_cache_t* c)
{
free(c->mem);
free(c);
}
void ethash_calculate_dag_item( void ethash_calculate_dag_item(
node* const ret, node* const ret,
const unsigned node_index, const unsigned node_index,
ethash_cache_t const* cache ethash_light_t const light
) )
{ {
uint32_t num_parent_nodes = (uint32_t) (cache->cache_size / sizeof(node)); uint32_t num_parent_nodes = (uint32_t) (light->cache_size / sizeof(node));
node const* cache_nodes = (node const *) cache->mem; node const* cache_nodes = (node const *) light->cache;
node const* init = &cache_nodes[node_index % num_parent_nodes]; node const* init = &cache_nodes[node_index % num_parent_nodes];
memcpy(ret, init, sizeof(node)); memcpy(ret, init, sizeof(node));
ret->words[0] ^= node_index; ret->words[0] ^= node_index;
@ -174,7 +142,7 @@ void ethash_calculate_dag_item(
SHA3_512(ret->bytes, ret->bytes, sizeof(node)); SHA3_512(ret->bytes, ret->bytes, sizeof(node));
} }
bool ethash_compute_full_data(void* mem, uint64_t full_size, ethash_cache_t const* cache) bool ethash_compute_full_data(void* mem, uint64_t full_size, ethash_light_t const light)
{ {
if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 || if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 ||
(full_size % sizeof(node)) != 0) { (full_size % sizeof(node)) != 0) {
@ -183,7 +151,7 @@ bool ethash_compute_full_data(void* mem, uint64_t full_size, ethash_cache_t cons
node* full_nodes = mem; node* full_nodes = mem;
// now compute full nodes // now compute full nodes
for (unsigned n = 0; n != (full_size / sizeof(node)); ++n) { for (unsigned n = 0; n != (full_size / sizeof(node)); ++n) {
ethash_calculate_dag_item(&(full_nodes[n]), n, cache); ethash_calculate_dag_item(&(full_nodes[n]), n, light);
} }
return true; return true;
} }
@ -191,9 +159,9 @@ bool ethash_compute_full_data(void* mem, uint64_t full_size, ethash_cache_t cons
static bool ethash_hash( static bool ethash_hash(
ethash_return_value_t* ret, ethash_return_value_t* ret,
node const* full_nodes, node const* full_nodes,
ethash_cache_t const* cache, ethash_light_t const light,
uint64_t full_size, uint64_t full_size,
ethash_h256_t const* header_hash, ethash_h256_t const header_hash,
uint64_t const nonce, uint64_t const nonce,
ethash_callback_t callback ethash_callback_t callback
) )
@ -205,7 +173,7 @@ static bool ethash_hash(
// pack hash and nonce together into first 40 bytes of s_mix // pack hash and nonce together into first 40 bytes of s_mix
assert(sizeof(node) * 8 == 512); assert(sizeof(node) * 8 == 512);
node s_mix[MIX_NODES + 1]; node s_mix[MIX_NODES + 1];
memcpy(s_mix[0].bytes, header_hash, 32); memcpy(s_mix[0].bytes, &header_hash, 32);
fix_endian64(s_mix[0].double_words[4], nonce); fix_endian64(s_mix[0].double_words[4], nonce);
// compute sha3-512 hash and replicate across mix // compute sha3-512 hash and replicate across mix
@ -236,7 +204,7 @@ static bool ethash_hash(
dag_node = &full_nodes[MIX_NODES * index + n]; dag_node = &full_nodes[MIX_NODES * index + n];
} else { } else {
node tmp_node; node tmp_node;
ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, cache); ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, light);
dag_node = &tmp_node; dag_node = &tmp_node;
} }
@ -295,7 +263,7 @@ void ethash_quick_hash(
SHA3_256(return_hash, buf, 64 + 32); SHA3_256(return_hash, buf, 64 + 32);
} }
void ethash_get_seedhash(ethash_h256_t* seedhash, const uint32_t block_number) void ethash_get_seedhash(ethash_h256_t* seedhash, uint64_t const block_number)
{ {
ethash_h256_reset(seedhash); ethash_h256_reset(seedhash);
const uint32_t epochs = block_number / ETHASH_EPOCH_LENGTH; const uint32_t epochs = block_number / ETHASH_EPOCH_LENGTH;
@ -316,44 +284,61 @@ int ethash_quick_check_difficulty(
return ethash_check_difficulty(&return_hash, difficulty); return ethash_check_difficulty(&return_hash, difficulty);
} }
ethash_light_t ethash_light_new(uint64_t cache_size, ethash_h256_t const* seed) ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed)
{ {
struct ethash_light *ret; struct ethash_light *ret;
ret = calloc(sizeof(*ret), 1); ret = calloc(sizeof(*ret), 1);
if (!ret) { if (!ret) {
return NULL; return NULL;
} }
ret->cache = ethash_cache_new(cache_size, seed); ret->cache = malloc((size_t)cache_size);
if (!ret->cache) { if (!ret->cache) {
goto fail_free_light; goto fail_free_light;
} }
node* nodes = (node*)ret->cache;
if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
goto fail_free_cache_mem;
}
ret->cache_size = cache_size;
return ret; return ret;
fail_free_cache_mem:
free(ret->cache);
fail_free_light: fail_free_light:
free(ret); free(ret);
return NULL; return NULL;
} }
ethash_light_t ethash_light_new(uint64_t const block_number)
{
ethash_h256_t seedhash;
ethash_light_t ret;
ethash_get_seedhash(&seedhash, block_number);
ret = ethash_light_new_internal(ethash_get_cachesize(block_number), &seedhash);
ret->block_number = block_number;
return ret;
}
void ethash_light_delete(ethash_light_t light) void ethash_light_delete(ethash_light_t light)
{ {
if (light->cache) { if (light->cache) {
ethash_cache_delete(light->cache); free(light->cache);
} }
free(light); free(light);
} }
bool ethash_light_compute( bool ethash_light_compute_internal(
ethash_return_value_t* ret, ethash_return_value_t* ret,
ethash_light_t light, ethash_light_t light,
uint64_t full_size, uint64_t full_size,
const ethash_h256_t* header_hash, const ethash_h256_t header_hash,
uint64_t const nonce uint64_t const nonce
) )
{ {
return ethash_hash( return ethash_hash(
ret, ret,
NULL, NULL,
light->cache, light,
full_size, full_size,
header_hash, header_hash,
nonce, nonce,
@ -361,18 +346,23 @@ bool ethash_light_compute(
); );
} }
ethash_cache_t *ethash_light_get_cache(ethash_light_t light) ethash_return_value_t ethash_light_compute(
{ ethash_light_t light,
return light->cache; const ethash_h256_t header_hash,
} uint64_t const nonce
)
ethash_cache_t *ethash_light_acquire_cache(ethash_light_t light)
{ {
ethash_cache_t* ret = light->cache; ethash_return_value_t ret;
light->cache = 0; ret.success = true;
uint64_t full_size = ethash_get_datasize(light->block_number);
if (!ethash_light_compute_internal(&ret, light, full_size, header_hash, nonce)) {
ret.success = false;
}
return ret; return ret;
} }
static bool ethash_mmap(struct ethash_full* ret, FILE* f) static bool ethash_mmap(struct ethash_full* ret, FILE* f)
{ {
int fd; int fd;
@ -391,11 +381,11 @@ static bool ethash_mmap(struct ethash_full* ret, FILE* f)
return ret->data != MAP_FAILED; return ret->data != MAP_FAILED;
} }
ethash_full_t ethash_full_new( ethash_full_t ethash_full_new_internal(
char const* dirname, char const* dirname,
ethash_h256_t const* seed_hash, ethash_h256_t const* seed_hash,
uint64_t full_size, uint64_t full_size,
ethash_cache_t const* cache, ethash_light_t const light,
ethash_callback_t callback ethash_callback_t callback
) )
{ {
@ -427,7 +417,7 @@ ethash_full_t ethash_full_new(
break; break;
} }
if (!ethash_compute_full_data(ret->data, full_size, cache)) { if (!ethash_compute_full_data(ret->data, full_size, light)) {
goto fail_free_full_data; goto fail_free_full_data;
} }
ret->callback = callback; ret->callback = callback;
@ -443,6 +433,18 @@ fail_free_full:
return NULL; return NULL;
} }
ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback)
{
char strbuf[256];
if (!ethash_get_default_dirname(strbuf, 256)) {
return NULL;
}
uint64_t full_size = ethash_get_datasize(light->block_number);
ethash_h256_t seedhash;
ethash_get_seedhash(&seedhash, light->block_number);
return ethash_full_new_internal(strbuf, &seedhash, full_size, light, callback);
}
void ethash_full_delete(ethash_full_t full) void ethash_full_delete(ethash_full_t full)
{ {
// could check that munmap(..) == 0 but even if it did not can't really do anything here // could check that munmap(..) == 0 but even if it did not can't really do anything here
@ -453,64 +455,33 @@ void ethash_full_delete(ethash_full_t full)
free(full); free(full);
} }
bool ethash_full_compute( ethash_return_value_t ethash_full_compute(
ethash_return_value_t* ret,
ethash_full_t full, ethash_full_t full,
ethash_h256_t const* header_hash, ethash_h256_t const header_hash,
uint64_t const nonce uint64_t const nonce
) )
{ {
return ethash_hash( ethash_return_value_t ret;
ret, ret.success = true;
if (!ethash_hash(
&ret,
(node const*)full->data, (node const*)full->data,
NULL, NULL,
full->file_size, full->file_size,
header_hash, header_hash,
nonce, nonce,
full->callback full->callback)) {
); ret.success = false;
}
return ret;
} }
void *ethash_full_data(ethash_full_t full) void const* ethash_full_dag(ethash_full_t full)
{ {
return full->data; return full->data;
} }
/** uint64_t ethash_full_dag_size(ethash_full_t full)
* =========================
* = DEPRECATED API =
* =========================
*
* Kept for backwards compatibility with whoever still uses it. Please consider
* switching to the new API (look above)
*/
void ethash_mkcache(
ethash_cache_t* cache,
ethash_params const* params,
ethash_h256_t const* seed
)
{
node* nodes = (node*) cache->mem;
ethash_compute_cache_nodes(nodes, params->cache_size, seed);
}
void ethash_full(
ethash_return_value_t* ret,
void const* full_mem,
ethash_params const* params,
ethash_h256_t const* header_hash,
uint64_t const nonce
)
{
ethash_hash(ret, (node const *) full_mem, NULL, params->full_size, header_hash, nonce, NULL);
}
void ethash_light(
ethash_return_value_t* ret,
ethash_cache_t const* cache,
ethash_params const* params,
ethash_h256_t const* header_hash,
uint64_t const nonce
)
{ {
ethash_hash(ret, NULL, cache, params->full_size, header_hash, nonce, NULL); return full->file_size;
} }

112
internal.h

@ -31,10 +31,80 @@ typedef union node {
} node; } node;
static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i)
{
return hash->b[i];
}
static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
{
hash->b[i] = v;
}
static inline void ethash_h256_reset(ethash_h256_t* hash)
{
memset(hash, 0, 32);
}
// Returns if hash is less than or equal to difficulty
static inline int ethash_check_difficulty(
ethash_h256_t const* hash,
ethash_h256_t const* difficulty
)
{
// Difficulty is big endian
for (int i = 0; i < 32; i++) {
if (ethash_h256_get(hash, i) == ethash_h256_get(difficulty, i)) {
continue;
}
return ethash_h256_get(hash, i) < ethash_h256_get(difficulty, i);
}
return 1;
}
int ethash_quick_check_difficulty(
ethash_h256_t const* header_hash,
uint64_t const nonce,
ethash_h256_t const* mix_hash,
ethash_h256_t const* difficulty
);
struct ethash_light { struct ethash_light {
ethash_cache_t* cache; void* cache;
uint64_t cache_size;
uint64_t block_number;
}; };
/**
* Allocate and initialize a new ethash_light handler. Internal version
*
* @param cache_size The size of the cache in bytes
* @param seed Block seedhash to be used during the computation of the
* cache nodes
* @return Newly allocated ethash_light handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
*/
ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed);
/**
* Calculate the light client data. Internal version.
*
* @param ret An object of ethash_return_value to hold the return value
* @param light The light client handler
* @param full_size The size of the full data in bytes.
* @param header_hash The header hash to pack into the mix
* @param nonce The nonce to pack into the mix
* @return true if all went well and false if there were invalid
* parameters given.
*/
bool ethash_light_compute_internal(
ethash_return_value_t* ret,
ethash_light_t light,
uint64_t full_size,
const ethash_h256_t header_hash,
uint64_t const nonce
);
struct ethash_full { struct ethash_full {
FILE* file; FILE* file;
uint64_t file_size; uint64_t file_size;
@ -42,10 +112,35 @@ struct ethash_full {
ethash_callback_t callback; ethash_callback_t callback;
}; };
/**
* Allocate and initialize a new ethash_full handler. Internal version.
*
* @param dirname The directory in which to put the DAG file.
* @param seedhash The seed hash of the block. Used in the DAG file naming.
* @param full_size The size of the full data in bytes.
* @param cache A cache object to use that was allocated with @ref ethash_cache_new().
* Iff this function succeeds the ethash_full_t will take memory
* memory ownership of the cache and free it at deletion. If
* not then the user still has to handle freeing of the cache himself.
* @param callback A callback function with signature of @ref ethash_callback_t
* It accepts an unsigned with which a progress of DAG calculation
* can be displayed. If all goes well the callback should return 0.
* If a non-zero value is returned then DAG generation will stop.
* @return Newly allocated ethash_full handler or NULL in case of
* ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
*/
ethash_full_t ethash_full_new_internal(
char const* dirname,
ethash_h256_t const* seed_hash,
uint64_t full_size,
ethash_light_t const light,
ethash_callback_t callback
);
void ethash_calculate_dag_item( void ethash_calculate_dag_item(
node* const ret, node* const ret,
const unsigned node_index, const unsigned node_index,
ethash_cache_t const* cache ethash_light_t const cache
); );
void ethash_quick_hash( void ethash_quick_hash(
@ -55,6 +150,19 @@ void ethash_quick_hash(
ethash_h256_t const* mix_hash ethash_h256_t const* mix_hash
); );
uint64_t ethash_get_datasize(uint64_t const block_number);
uint64_t ethash_get_cachesize(uint64_t const block_number);
/**
* Compute the memory data for a full node's memory
*
* @param mem A pointer to an ethash full's memory
* @param full_size The size of the full data in bytes
* @param cache A cache object to use in the calculation
* @return true if all went fine and false for invalid parameters
*/
bool ethash_compute_full_data(void* mem, uint64_t full_size, ethash_light_t const cache);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

12
io.h

@ -154,6 +154,18 @@ char* ethash_io_create_filename(
size_t filename_length size_t filename_length
); );
/**
* Gets the default directory name for the DAG depending on the system
*
* The spec defining this directory is here: https://github.com/ethereum/wiki/wiki/Ethash-DAG
*
* @param[out] strbuf A string buffer of sufficient size to keep the
* null termninated string of the directory name
* @param[in] buffsize Size of @a strbuf in bytes
* @return true for success and false otherwise
*/
bool ethash_get_default_dirname(char* strbuf, size_t buffsize);
static inline bool ethash_io_mutable_name( static inline bool ethash_io_mutable_name(
uint32_t revision, uint32_t revision,
ethash_h256_t const* seed_hash, ethash_h256_t const* seed_hash,

16
io_posix.c

@ -83,3 +83,19 @@ bool ethash_file_size(FILE* f, size_t* ret_size)
*ret_size = st.st_size; *ret_size = st.st_size;
return true; return true;
} }
bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
{
strbuf[0] = '\n';
char* home_dir = getenv("HOME");
size_t len = strlen(home_dir);
if (!ethash_strncat(strbuf, buffsize, home_dir, len)) {
return false;
}
if (home_dir[len] != '/') {
if (!ethash_strncat(strbuf, buffsize, "/", 1)) {
return false;
}
}
return ethash_strncat(strbuf, buffsize, ".ethash/", 8);
}

16
io_win32.c

@ -83,3 +83,19 @@ bool ethash_file_size(FILE* f, size_t* ret_size)
*ret_size = st.st_size; *ret_size = st.st_size;
return true; return true;
} }
bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
{
strbuf[0] = '\n';
if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, (WCHAR*)strbuf))) {
return false;
}
if (!ethash_strncat(strbuf, buffsize, home_dir, len)) {
return false;
}
if (!ethash_strncat(strbuf, buffsize, "\\", 1)) {
return false;
}
return ethash_strncat(strbuf, buffsize, "Appdata\\Ethash\\", 14);
}

Loading…
Cancel
Save