internal.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #pragma once
  2. #include "compiler.h"
  3. #include "endian.h"
  4. #include "ethash.h"
  5. #include <stdio.h>
  6. #define ENABLE_SSE 0
  7. #if defined(_M_X64) && ENABLE_SSE
  8. #include <smmintrin.h>
  9. #elif defined(__MIC__)
  10. #include <immintrin.h>
  11. #endif
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. // compile time settings
  16. #define NODE_WORDS (64/4)
  17. #define MIX_WORDS (ETHASH_MIX_BYTES/4)
  18. #define MIX_NODES (MIX_WORDS / NODE_WORDS)
  19. #include <stdint.h>
  20. typedef union node {
  21. uint8_t bytes[NODE_WORDS * 4];
  22. uint32_t words[NODE_WORDS];
  23. uint64_t double_words[NODE_WORDS / 2];
  24. #if defined(_M_X64) && ENABLE_SSE
  25. __m128i xmm[NODE_WORDS/4];
  26. #elif defined(__MIC__)
  27. __m512i zmm[NODE_WORDS/16];
  28. #endif
  29. } node;
  30. static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i)
  31. {
  32. return hash->b[i];
  33. }
  34. static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
  35. {
  36. hash->b[i] = v;
  37. }
  38. static inline void ethash_h256_reset(ethash_h256_t* hash)
  39. {
  40. memset(hash, 0, 32);
  41. }
  42. // Returns if hash is less than or equal to boundary (2^256/difficulty)
  43. static inline bool ethash_check_difficulty(
  44. ethash_h256_t const* hash,
  45. ethash_h256_t const* boundary
  46. )
  47. {
  48. // Boundary is big endian
  49. for (int i = 0; i < 32; i++) {
  50. if (ethash_h256_get(hash, i) == ethash_h256_get(boundary, i)) {
  51. continue;
  52. }
  53. return ethash_h256_get(hash, i) < ethash_h256_get(boundary, i);
  54. }
  55. return true;
  56. }
  57. /**
  58. * Difficulty quick check for POW preverification
  59. *
  60. * @param header_hash The hash of the header
  61. * @param nonce The block's nonce
  62. * @param mix_hash The mix digest hash
  63. * @param boundary The boundary is defined as (2^256 / difficulty)
  64. * @return true for succesful pre-verification and false otherwise
  65. */
  66. bool ethash_quick_check_difficulty(
  67. ethash_h256_t const* header_hash,
  68. uint64_t const nonce,
  69. ethash_h256_t const* mix_hash,
  70. ethash_h256_t const* boundary
  71. );
  72. struct ethash_light {
  73. void* cache;
  74. uint64_t cache_size;
  75. uint64_t block_number;
  76. };
  77. /**
  78. * Allocate and initialize a new ethash_light handler. Internal version
  79. *
  80. * @param cache_size The size of the cache in bytes
  81. * @param seed Block seedhash to be used during the computation of the
  82. * cache nodes
  83. * @return Newly allocated ethash_light handler or NULL in case of
  84. * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
  85. */
  86. ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed);
  87. /**
  88. * Calculate the light client data. Internal version.
  89. *
  90. * @param light The light client handler
  91. * @param full_size The size of the full data in bytes.
  92. * @param header_hash The header hash to pack into the mix
  93. * @param nonce The nonce to pack into the mix
  94. * @return The resulting hash.
  95. */
  96. ethash_return_value_t ethash_light_compute_internal(
  97. ethash_light_t light,
  98. uint64_t full_size,
  99. ethash_h256_t const header_hash,
  100. uint64_t nonce
  101. );
  102. struct ethash_full {
  103. FILE* file;
  104. uint64_t file_size;
  105. node* data;
  106. };
  107. /**
  108. * Allocate and initialize a new ethash_full handler. Internal version.
  109. *
  110. * @param dirname The directory in which to put the DAG file.
  111. * @param seedhash The seed hash of the block. Used in the DAG file naming.
  112. * @param full_size The size of the full data in bytes.
  113. * @param cache A cache object to use that was allocated with @ref ethash_cache_new().
  114. * Iff this function succeeds the ethash_full_t will take memory
  115. * memory ownership of the cache and free it at deletion. If
  116. * not then the user still has to handle freeing of the cache himself.
  117. * @param callback A callback function with signature of @ref ethash_callback_t
  118. * It accepts an unsigned with which a progress of DAG calculation
  119. * can be displayed. If all goes well the callback should return 0.
  120. * If a non-zero value is returned then DAG generation will stop.
  121. * @return Newly allocated ethash_full handler or NULL in case of
  122. * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
  123. */
  124. ethash_full_t ethash_full_new_internal(
  125. char const* dirname,
  126. ethash_h256_t const seed_hash,
  127. uint64_t full_size,
  128. ethash_light_t const light,
  129. ethash_callback_t callback
  130. );
  131. void ethash_calculate_dag_item(
  132. node* const ret,
  133. uint32_t node_index,
  134. ethash_light_t const cache
  135. );
  136. void ethash_quick_hash(
  137. ethash_h256_t* return_hash,
  138. ethash_h256_t const* header_hash,
  139. const uint64_t nonce,
  140. ethash_h256_t const* mix_hash
  141. );
  142. uint64_t ethash_get_datasize(uint64_t const block_number);
  143. uint64_t ethash_get_cachesize(uint64_t const block_number);
  144. /**
  145. * Compute the memory data for a full node's memory
  146. *
  147. * @param mem A pointer to an ethash full's memory
  148. * @param full_size The size of the full data in bytes
  149. * @param cache A cache object to use in the calculation
  150. * @param callback The callback function. Check @ref ethash_full_new() for details.
  151. * @return true if all went fine and false for invalid parameters
  152. */
  153. bool ethash_compute_full_data(
  154. void* mem,
  155. uint64_t full_size,
  156. ethash_light_t const light,
  157. ethash_callback_t callback
  158. );
  159. #ifdef __cplusplus
  160. }
  161. #endif