123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #pragma once
- #include "compiler.h"
- #include "endian.h"
- #include "ethash.h"
- #include <stdio.h>
- #define ENABLE_SSE 0
- #if defined(_M_X64) && ENABLE_SSE
- #include <smmintrin.h>
- #elif defined(__MIC__)
- #include <immintrin.h>
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- // compile time settings
- #define NODE_WORDS (64/4)
- #define MIX_WORDS (ETHASH_MIX_BYTES/4)
- #define MIX_NODES (MIX_WORDS / NODE_WORDS)
- #include <stdint.h>
- typedef union node {
- uint8_t bytes[NODE_WORDS * 4];
- uint32_t words[NODE_WORDS];
- uint64_t double_words[NODE_WORDS / 2];
- #if defined(_M_X64) && ENABLE_SSE
- __m128i xmm[NODE_WORDS/4];
- #elif defined(__MIC__)
- __m512i zmm[NODE_WORDS/16];
- #endif
- } 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 boundary (2^256/difficulty)
- static inline bool ethash_check_difficulty(
- ethash_h256_t const* hash,
- ethash_h256_t const* boundary
- )
- {
- // Boundary is big endian
- for (int i = 0; i < 32; i++) {
- if (ethash_h256_get(hash, i) == ethash_h256_get(boundary, i)) {
- continue;
- }
- return ethash_h256_get(hash, i) < ethash_h256_get(boundary, i);
- }
- return true;
- }
- /**
- * Difficulty quick check for POW preverification
- *
- * @param header_hash The hash of the header
- * @param nonce The block's nonce
- * @param mix_hash The mix digest hash
- * @param boundary The boundary is defined as (2^256 / difficulty)
- * @return true for succesful pre-verification and false otherwise
- */
- bool ethash_quick_check_difficulty(
- ethash_h256_t const* header_hash,
- uint64_t const nonce,
- ethash_h256_t const* mix_hash,
- ethash_h256_t const* boundary
- );
- struct ethash_light {
- 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 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 The resulting hash.
- */
- ethash_return_value_t ethash_light_compute_internal(
- ethash_light_t light,
- uint64_t full_size,
- ethash_h256_t const header_hash,
- uint64_t nonce
- );
- struct ethash_full {
- FILE* file;
- uint64_t file_size;
- node* data;
- };
- /**
- * 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(
- node* const ret,
- uint32_t node_index,
- ethash_light_t const cache
- );
- void ethash_quick_hash(
- ethash_h256_t* return_hash,
- ethash_h256_t const* header_hash,
- const uint64_t nonce,
- 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
- * @param callback The callback function. Check @ref ethash_full_new() for details.
- * @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 light,
- ethash_callback_t callback
- );
- #ifdef __cplusplus
- }
- #endif
|