1 // ethash: C/C++ implementation of Ethash, the Ethereum Proof of Work algorithm.
2 // Copyright 2018 Pawel Bylica.
3 // Licensed under the Apache License, Version 2.0. See the LICENSE file.
4 
5 /// @file
6 /// Contains declarations of internal ethash functions to allow them to be
7 /// unit-tested.
8 
9 #pragma once
10 
11 #include <ethash/ethash.hpp>
12 
13 #include "endianness.hpp"
14 
15 #include <memory>
16 #include <vector>
17 
18 extern "C" struct ethash_epoch_context_full : ethash_epoch_context
19 {
20     ethash_hash1024* full_dataset;
21 
ethash_epoch_context_fullethash_epoch_context_full22     constexpr ethash_epoch_context_full(int epoch_number, int light_cache_num_items,
23         const ethash_hash512* light_cache, const uint32_t* l1_cache, int full_dataset_num_items,
24         ethash_hash1024* full_dataset) noexcept
25       : ethash_epoch_context{epoch_number, light_cache_num_items, light_cache, l1_cache,
26             full_dataset_num_items},
27         full_dataset{full_dataset}
28     {}
29 };
30 
31 namespace ethash
32 {
is_less_or_equal(const hash256 & a,const hash256 & b)33 inline bool is_less_or_equal(const hash256& a, const hash256& b) noexcept
34 {
35     for (size_t i = 0; i < (sizeof(a) / sizeof(a.word64s[0])); ++i)
36     {
37         if (be::uint64(a.word64s[i]) > be::uint64(b.word64s[i]))
38             return false;
39         if (be::uint64(a.word64s[i]) < be::uint64(b.word64s[i]))
40             return true;
41     }
42     return true;
43 }
44 
is_equal(const hash256 & a,const hash256 & b)45 inline bool is_equal(const hash256& a, const hash256& b) noexcept
46 {
47     return std::memcmp(a.bytes, b.bytes, sizeof(a)) == 0;
48 }
49 
50 void build_light_cache(hash512 cache[], int num_items, const hash256& seed) noexcept;
51 
52 hash512 calculate_dataset_item_512(const epoch_context& context, int64_t index) noexcept;
53 hash1024 calculate_dataset_item_1024(const epoch_context& context, uint32_t index) noexcept;
54 hash2048 calculate_dataset_item_2048(const epoch_context& context, uint32_t index) noexcept;
55 
56 namespace generic
57 {
58 using hash_fn_512 = hash512 (*)(const uint8_t* data, size_t size);
59 using build_light_cache_fn = void (*)(hash512 cache[], int num_items, const hash256& seed);
60 
61 void build_light_cache(
62     hash_fn_512 hash_fn, hash512 cache[], int num_items, const hash256& seed) noexcept;
63 
64 epoch_context_full* create_epoch_context(
65     build_light_cache_fn build_fn, int epoch_number, bool full) noexcept;
66 
67 }  // namespace generic
68 
69 }  // namespace ethash
70