internal.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /*
  2. This file is part of ethash.
  3. ethash is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. ethash is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file internal.c
  15. * @author Tim Hughes <tim@twistedfury.com>
  16. * @author Matthew Wampler-Doty
  17. * @date 2015
  18. */
  19. #include <assert.h>
  20. #include <inttypes.h>
  21. #include <stddef.h>
  22. #include <errno.h>
  23. #include <math.h>
  24. #include "mmap.h"
  25. #include "ethash.h"
  26. #include "fnv.h"
  27. #include "endian.h"
  28. #include "internal.h"
  29. #include "data_sizes.h"
  30. #include "io.h"
  31. #ifdef WITH_CRYPTOPP
  32. #include "sha3_cryptopp.h"
  33. #else
  34. #include "sha3.h"
  35. #endif // WITH_CRYPTOPP
  36. uint64_t ethash_get_datasize(uint64_t const block_number)
  37. {
  38. assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
  39. return dag_sizes[block_number / ETHASH_EPOCH_LENGTH];
  40. }
  41. uint64_t ethash_get_cachesize(uint64_t const block_number)
  42. {
  43. assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
  44. return cache_sizes[block_number / ETHASH_EPOCH_LENGTH];
  45. }
  46. // Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014)
  47. // https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf
  48. // SeqMemoHash(s, R, N)
  49. static bool ethash_compute_cache_nodes(
  50. node* const nodes,
  51. uint64_t cache_size,
  52. ethash_h256_t const* seed
  53. )
  54. {
  55. if (cache_size % sizeof(node) != 0) {
  56. return false;
  57. }
  58. uint32_t const num_nodes = (uint32_t) (cache_size / sizeof(node));
  59. SHA3_512(nodes[0].bytes, (uint8_t*)seed, 32);
  60. for (uint32_t i = 1; i != num_nodes; ++i) {
  61. SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
  62. }
  63. for (uint32_t j = 0; j != ETHASH_CACHE_ROUNDS; j++) {
  64. for (uint32_t i = 0; i != num_nodes; i++) {
  65. uint32_t const idx = nodes[i].words[0] % num_nodes;
  66. node data;
  67. data = nodes[(num_nodes - 1 + i) % num_nodes];
  68. for (uint32_t w = 0; w != NODE_WORDS; ++w) {
  69. data.words[w] ^= nodes[idx].words[w];
  70. }
  71. SHA3_512(nodes[i].bytes, data.bytes, sizeof(data));
  72. }
  73. }
  74. // now perform endian conversion
  75. fix_endian_arr32(nodes->words, num_nodes * NODE_WORDS);
  76. return true;
  77. }
  78. void ethash_calculate_dag_item(
  79. node* const ret,
  80. uint32_t node_index,
  81. ethash_light_t const light
  82. )
  83. {
  84. uint32_t num_parent_nodes = (uint32_t) (light->cache_size / sizeof(node));
  85. node const* cache_nodes = (node const *) light->cache;
  86. node const* init = &cache_nodes[node_index % num_parent_nodes];
  87. memcpy(ret, init, sizeof(node));
  88. ret->words[0] ^= node_index;
  89. SHA3_512(ret->bytes, ret->bytes, sizeof(node));
  90. #if defined(__MIC__)
  91. __m512i const fnv_prime = _mm512_set1_epi32(FNV_PRIME);
  92. __m512i zmm0 = ret->zmm[0];
  93. #endif
  94. // why is this being defined?
  95. // for (uint32_t i = 0; i != ETHASH_DATASET_PARENTS; ++i) {
  96. // uint32_t parent_index = fnv_hash(node_index ^ i, ret->words[i % NODE_WORDS]) % num_parent_nodes;
  97. // node const *parent = &cache_nodes[parent_index];
  98. // }
  99. SHA3_512(ret->bytes, ret->bytes, sizeof(node));
  100. }
  101. bool ethash_compute_full_data(
  102. void* mem,
  103. uint64_t full_size,
  104. ethash_light_t const light,
  105. ethash_callback_t callback
  106. )
  107. {
  108. if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 ||
  109. (full_size % sizeof(node)) != 0) {
  110. return false;
  111. }
  112. uint32_t const max_n = (uint32_t)(full_size / sizeof(node));
  113. node* full_nodes = mem;
  114. double const progress_change = 1.0f / max_n;
  115. double progress = 0.0f;
  116. // now compute full nodes
  117. for (uint32_t n = 0; n != max_n; ++n) {
  118. if (callback &&
  119. n % (max_n / 100) == 0 &&
  120. callback((unsigned int)(ceil(progress * 100.0f))) != 0) {
  121. return false;
  122. }
  123. progress += progress_change;
  124. ethash_calculate_dag_item(&(full_nodes[n]), n, light);
  125. }
  126. return true;
  127. }
  128. static bool ethash_hash(
  129. ethash_return_value_t* ret,
  130. node const* full_nodes,
  131. ethash_light_t const light,
  132. uint64_t full_size,
  133. ethash_h256_t const header_hash,
  134. uint64_t const nonce
  135. )
  136. {
  137. if (light==0)
  138. {
  139. printf("light is null\n");
  140. }
  141. else
  142. {
  143. printf("light is not null\n");
  144. }
  145. if (full_nodes==0)
  146. {
  147. printf("full nodes is null\n");
  148. }
  149. else
  150. {
  151. printf("full nodes not null\n");
  152. }
  153. if (full_size % MIX_WORDS != 0) {
  154. return false;
  155. }
  156. // pack hash and nonce together into first 40 bytes of s_mix
  157. assert(sizeof(node) * 8 == 512);
  158. node s_mix[MIX_NODES + 1];
  159. memcpy(s_mix[0].bytes, &header_hash, 32);
  160. fix_endian64(s_mix[0].double_words[4], nonce);
  161. // compute sha3-512 hash and replicate across mix
  162. SHA3_512(s_mix->bytes, s_mix->bytes, 40);
  163. fix_endian_arr32(s_mix[0].words, 16);
  164. node* const mix = s_mix + 1;
  165. for (uint32_t w = 0; w != MIX_WORDS; ++w) {
  166. mix->words[w] = s_mix[0].words[w % NODE_WORDS];
  167. }
  168. // what is this for?
  169. // unsigned const page_size = sizeof(uint32_t) * MIX_WORDS;
  170. // unsigned const num_full_pages = (unsigned) (full_size / page_size);
  171. // for (unsigned i = 0; i != ETHASH_ACCESSES; ++i) {
  172. // uint32_t const index = fnv_hash(s_mix->words[0] ^ i, mix->words[i % MIX_WORDS]) % num_full_pages;
  173. // for (unsigned n = 0; n != MIX_NODES; ++n) {
  174. // node const* dag_node;
  175. // if (full_nodes) {
  176. // dag_node = &full_nodes[MIX_NODES * index + n];
  177. // } else {
  178. // node tmp_node;
  179. // ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, light);
  180. // dag_node = &tmp_node;
  181. // }
  182. // }
  183. // }
  184. // Workaround for a GCC regression which causes a bogus -Warray-bounds warning.
  185. // The regression was introduced in GCC 4.8.4, fixed in GCC 5.0.0 and backported to GCC 4.9.3 but
  186. // never to the GCC 4.8.x line.
  187. //
  188. // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56273
  189. //
  190. // This regression is affecting Debian Jesse (8.5) builds of cpp-ethereum (GCC 4.9.2) and also
  191. // manifests in the doublethinkco armel v5 cross-builds, which use crosstool-ng and resulting
  192. // in the use of GCC 4.8.4. The Tizen runtime wants an even older GLIBC version - the one from
  193. // GCC 4.6.0!
  194. #if defined(__GNUC__) && (__GNUC__ < 5)
  195. #pragma GCC diagnostic push
  196. #pragma GCC diagnostic ignored "-Warray-bounds"
  197. #endif // define (__GNUC__)
  198. // compress mix
  199. for (uint32_t w = 0; w != MIX_WORDS; w += 4) {
  200. uint32_t reduction = mix->words[w + 0];
  201. reduction = reduction * FNV_PRIME ^ mix->words[w + 1];
  202. reduction = reduction * FNV_PRIME ^ mix->words[w + 2];
  203. reduction = reduction * FNV_PRIME ^ mix->words[w + 3];
  204. mix->words[w / 4] = reduction;
  205. }
  206. #if defined(__GNUC__) && (__GNUC__ < 5)
  207. #pragma GCC diagnostic pop
  208. #endif // define (__GNUC__)
  209. fix_endian_arr32(mix->words, MIX_WORDS / 4);
  210. memcpy(&ret->mix_hash, mix->bytes, 32);
  211. // final Keccak hash
  212. SHA3_256(&ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix)
  213. return true;
  214. }
  215. void ethash_quick_hash(
  216. ethash_h256_t* return_hash,
  217. ethash_h256_t const* header_hash,
  218. uint64_t const nonce,
  219. ethash_h256_t const* mix_hash
  220. )
  221. {
  222. uint8_t buf[64 + 32];
  223. memcpy(buf, header_hash, 32);
  224. fix_endian64_same(nonce);
  225. memcpy(&(buf[32]), &nonce, 8);
  226. SHA3_512(buf, buf, 40);
  227. memcpy(&(buf[64]), mix_hash, 32);
  228. SHA3_256(return_hash, buf, 64 + 32);
  229. }
  230. ethash_h256_t ethash_get_seedhash(uint64_t block_number)
  231. {
  232. ethash_h256_t ret;
  233. ethash_h256_reset(&ret);
  234. uint64_t const epochs = block_number / ETHASH_EPOCH_LENGTH;
  235. for (uint32_t i = 0; i < epochs; ++i)
  236. SHA3_256(&ret, (uint8_t*)&ret, 32);
  237. return ret;
  238. }
  239. bool ethash_quick_check_difficulty(
  240. ethash_h256_t const* header_hash,
  241. uint64_t const nonce,
  242. ethash_h256_t const* mix_hash,
  243. ethash_h256_t const* boundary
  244. )
  245. {
  246. ethash_h256_t return_hash;
  247. ethash_quick_hash(&return_hash, header_hash, nonce, mix_hash);
  248. return ethash_check_difficulty(&return_hash, boundary);
  249. }
  250. ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed)
  251. {
  252. struct ethash_light *ret;
  253. ret = calloc(sizeof(*ret), 1);
  254. if (!ret) {
  255. return NULL;
  256. }
  257. #if defined(__MIC__)
  258. ret->cache = _mm_malloc((size_t)cache_size, 64);
  259. #else
  260. ret->cache = malloc((size_t)cache_size);
  261. #endif
  262. if (!ret->cache) {
  263. goto fail_free_light;
  264. }
  265. node* nodes = (node*)ret->cache;
  266. if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
  267. goto fail_free_cache_mem;
  268. }
  269. ret->cache_size = cache_size;
  270. return ret;
  271. fail_free_cache_mem:
  272. #if defined(__MIC__)
  273. _mm_free(ret->cache);
  274. #else
  275. free(ret->cache);
  276. #endif
  277. fail_free_light:
  278. free(ret);
  279. return NULL;
  280. }
  281. ethash_light_t ethash_light_new(uint64_t block_number)
  282. {
  283. ethash_h256_t seedhash = ethash_get_seedhash(block_number);
  284. ethash_light_t ret;
  285. ret = ethash_light_new_internal(ethash_get_cachesize(block_number), &seedhash);
  286. ret->block_number = block_number;
  287. return ret;
  288. }
  289. void ethash_light_delete(ethash_light_t light)
  290. {
  291. if (light->cache) {
  292. free(light->cache);
  293. }
  294. free(light);
  295. }
  296. ethash_return_value_t ethash_light_compute_internal(
  297. ethash_light_t light,
  298. uint64_t full_size,
  299. ethash_h256_t const header_hash,
  300. uint64_t nonce
  301. )
  302. {
  303. ethash_return_value_t ret;
  304. ret.success = true;
  305. if (!ethash_hash(&ret, NULL, light, full_size, header_hash, nonce)) {
  306. ret.success = false;
  307. }
  308. return ret;
  309. }
  310. ethash_return_value_t ethash_light_compute(
  311. ethash_light_t light,
  312. ethash_h256_t const header_hash,
  313. uint64_t nonce
  314. )
  315. {
  316. uint64_t full_size = ethash_get_datasize(light->block_number);
  317. return ethash_light_compute_internal(light, full_size, header_hash, nonce);
  318. }
  319. static bool ethash_mmap(struct ethash_full* ret, FILE* f)
  320. {
  321. int fd;
  322. char* mmapped_data;
  323. errno = 0;
  324. ret->file = f;
  325. if ((fd = ethash_fileno(ret->file)) == -1) {
  326. return false;
  327. }
  328. mmapped_data = mmap(
  329. NULL,
  330. (size_t)ret->file_size + ETHASH_DAG_MAGIC_NUM_SIZE,
  331. PROT_READ | PROT_WRITE,
  332. MAP_SHARED,
  333. fd,
  334. 0
  335. );
  336. if (mmapped_data == MAP_FAILED) {
  337. return false;
  338. }
  339. ret->data = (node*)(mmapped_data + ETHASH_DAG_MAGIC_NUM_SIZE);
  340. return true;
  341. }
  342. ethash_full_t ethash_full_new_internal(
  343. char const* dirname,
  344. ethash_h256_t const seed_hash,
  345. uint64_t full_size,
  346. ethash_light_t const light,
  347. ethash_callback_t callback
  348. )
  349. {
  350. struct ethash_full* ret;
  351. FILE *f = NULL;
  352. ret = calloc(sizeof(*ret), 1);
  353. if (!ret) {
  354. return NULL;
  355. }
  356. ret->file_size = (size_t)full_size;
  357. switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) {
  358. case ETHASH_IO_FAIL:
  359. // ethash_io_prepare will do all ETHASH_CRITICAL() logging in fail case
  360. goto fail_free_full;
  361. case ETHASH_IO_MEMO_MATCH:
  362. if (!ethash_mmap(ret, f)) {
  363. ETHASH_CRITICAL("mmap failure()");
  364. goto fail_close_file;
  365. }
  366. #if defined(__MIC__)
  367. node* tmp_nodes = _mm_malloc((size_t)full_size, 64);
  368. //copy all nodes from ret->data
  369. //mmapped_nodes are not aligned properly
  370. uint32_t const countnodes = (uint32_t) ((size_t)ret->file_size / sizeof(node));
  371. //fprintf(stderr,"ethash_full_new_internal:countnodes:%d",countnodes);
  372. for (uint32_t i = 1; i != countnodes; ++i) {
  373. tmp_nodes[i] = ret->data[i];
  374. }
  375. ret->data = tmp_nodes;
  376. #endif
  377. return ret;
  378. case ETHASH_IO_MEMO_SIZE_MISMATCH:
  379. // if a DAG of same filename but unexpected size is found, silently force new file creation
  380. if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) {
  381. ETHASH_CRITICAL("Could not recreate DAG file after finding existing DAG with unexpected size.");
  382. goto fail_free_full;
  383. }
  384. __attribute__((fallthrough));
  385. case ETHASH_IO_MEMO_MISMATCH:
  386. if (!ethash_mmap(ret, f)) {
  387. ETHASH_CRITICAL("mmap failure()");
  388. goto fail_close_file;
  389. }
  390. break;
  391. }
  392. #if defined(__MIC__)
  393. ret->data = _mm_malloc((size_t)full_size, 64);
  394. #endif
  395. if (!ethash_compute_full_data(ret->data, full_size, light, callback)) {
  396. ETHASH_CRITICAL("Failure at computing DAG data.");
  397. goto fail_free_full_data;
  398. }
  399. // after the DAG has been filled then we finalize it by writting the magic number at the beginning
  400. if (fseek(f, 0, SEEK_SET) != 0) {
  401. ETHASH_CRITICAL("Could not seek to DAG file start to write magic number.");
  402. goto fail_free_full_data;
  403. }
  404. uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM;
  405. if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
  406. ETHASH_CRITICAL("Could not write magic number to DAG's beginning.");
  407. goto fail_free_full_data;
  408. }
  409. if (fflush(f) != 0) {// make sure the magic number IS there
  410. ETHASH_CRITICAL("Could not flush memory mapped data to DAG file. Insufficient space?");
  411. goto fail_free_full_data;
  412. }
  413. return ret;
  414. fail_free_full_data:
  415. // could check that munmap(..) == 0 but even if it did not can't really do anything here
  416. munmap(ret->data, (size_t)full_size);
  417. #if defined(__MIC__)
  418. _mm_free(ret->data);
  419. #endif
  420. fail_close_file:
  421. fclose(ret->file);
  422. fail_free_full:
  423. free(ret);
  424. return NULL;
  425. }
  426. ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback)
  427. {
  428. char strbuf[256];
  429. if (!ethash_get_default_dirname(strbuf, 256)) {
  430. return NULL;
  431. }
  432. uint64_t full_size = ethash_get_datasize(light->block_number);
  433. ethash_h256_t seedhash = ethash_get_seedhash(light->block_number);
  434. return ethash_full_new_internal(strbuf, seedhash, full_size, light, callback);
  435. }
  436. void ethash_full_delete(ethash_full_t full)
  437. {
  438. // could check that munmap(..) == 0 but even if it did not can't really do anything here
  439. munmap(full->data, (size_t)full->file_size);
  440. if (full->file) {
  441. fclose(full->file);
  442. }
  443. free(full);
  444. }
  445. ethash_return_value_t ethash_full_compute(
  446. ethash_full_t full,
  447. ethash_h256_t const header_hash,
  448. uint64_t nonce
  449. )
  450. {
  451. ethash_return_value_t ret;
  452. ret.success = true;
  453. if (!ethash_hash(
  454. &ret,
  455. (node const*)full->data,
  456. NULL,
  457. full->file_size,
  458. header_hash,
  459. nonce)) {
  460. ret.success = false;
  461. }
  462. return ret;
  463. }
  464. void const* ethash_full_dag(ethash_full_t full)
  465. {
  466. return full->data;
  467. }
  468. uint64_t ethash_full_dag_size(ethash_full_t full)
  469. {
  470. return full->file_size;
  471. }