Fabcoin Core  0.16.2
P2P Digital Currency
EthashCPUMiner.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
24 #include "EthashCPUMiner.h"
25 #include <thread>
26 #include <chrono>
27 #include <boost/algorithm/string.hpp>
28 #include <random>
29 #if ETH_CPUID
30 #define HAVE_STDINT_H
31 #include <libcpuid/libcpuid.h>
32 #endif // ETH_CPUID
33 using namespace std;
34 using namespace dev;
35 using namespace eth;
36 
37 unsigned EthashCPUMiner::s_numInstances = 0;
38 
39 #if ETH_CPUID
40 static string jsonEncode(map<string, string> const& _m)
41 {
42  string ret = "{";
43 
44  for (auto const& i: _m)
45  {
46  string k = boost::replace_all_copy(boost::replace_all_copy(i.first, "\\", "\\\\"), "'", "\\'");
47  string v = boost::replace_all_copy(boost::replace_all_copy(i.second, "\\", "\\\\"), "'", "\\'");
48  if (ret.size() > 1)
49  ret += ", ";
50  ret += "\"" + k + "\":\"" + v + "\"";
51  }
52 
53  return ret + "}";
54 }
55 #endif // ETH_CPUID
56 
57 EthashCPUMiner::EthashCPUMiner(GenericMiner<EthashProofOfWork>::ConstructionInfo const& _ci):
58  GenericMiner<EthashProofOfWork>(_ci), Worker("miner" + toString(index()))
59 {
60 }
61 
63 {
64 }
65 
67 {
68  stopWorking();
69  startWorking();
70 }
71 
73 {
74  stopWorking();
75 }
76 
78 {
79  auto tid = std::this_thread::get_id();
80  static std::mt19937_64 s_eng((utcTime() + std::hash<decltype(tid)>()(tid)));
81 
82  uint64_t tryNonce = s_eng();
83  ethash_return_value ethashReturn;
84 
85  WorkPackage w = work();
86 
88  while (!shouldStop() && !dag)
89  {
90  while (!shouldStop() && EthashAux::computeFull(w.seedHash, true) != 100)
91  this_thread::sleep_for(chrono::milliseconds(500));
92  dag = EthashAux::full(w.seedHash, false);
93  }
94 
95  h256 boundary = w.boundary;
96  unsigned hashCount = 1;
97  for (; !shouldStop(); tryNonce++, hashCount++)
98  {
99  ethashReturn = ethash_full_compute(dag->full, *(ethash_h256_t*)w.headerHash.data(), tryNonce);
100  h256 value = h256((uint8_t*)&ethashReturn.result, h256::ConstructFromPointer);
101  if (value <= boundary && submitProof(EthashProofOfWork::Solution{(h64)(u64)tryNonce, h256((uint8_t*)&ethashReturn.mix_hash, h256::ConstructFromPointer)}))
102  break;
103  if (!(hashCount % 100))
104  accumulateHashes(100);
105  }
106 }
107 
109 {
110  string baseline = toString(std::thread::hardware_concurrency()) + "-thread CPU";
111 
112 #if ETH_CPUID
113  if (!cpuid_present())
114  return baseline;
115  struct cpu_raw_data_t raw;
116  struct cpu_id_t data;
117  if (cpuid_get_raw_data(&raw) < 0)
118  return baseline;
119  if (cpu_identify(&raw, &data) < 0)
120  return baseline;
121  map<string, string> m;
122  m["vendor"] = data.vendor_str;
123  m["codename"] = data.cpu_codename;
124  m["brand"] = data.brand_str;
125  m["L1 cache"] = toString(data.l1_data_cache);
126  m["L2 cache"] = toString(data.l2_cache);
127  m["L3 cache"] = toString(data.l3_cache);
128  m["cores"] = toString(data.num_cores);
129  m["threads"] = toString(data.num_logical_cpus);
130  m["clocknominal"] = toString(cpu_clock_by_os());
131  m["clocktested"] = toString(cpu_clock_measure(200, 0));
132  /*
133  printf(" MMX : %s\n", data.flags[CPU_FEATURE_MMX] ? "present" : "absent");
134  printf(" MMX-extended: %s\n", data.flags[CPU_FEATURE_MMXEXT] ? "present" : "absent");
135  printf(" SSE : %s\n", data.flags[CPU_FEATURE_SSE] ? "present" : "absent");
136  printf(" SSE2 : %s\n", data.flags[CPU_FEATURE_SSE2] ? "present" : "absent");
137  printf(" 3DNow! : %s\n", data.flags[CPU_FEATURE_3DNOW] ? "present" : "absent");
138  */
139  return jsonEncode(m);
140 #else
141  return baseline;
142 #endif // ETH_CPUID
143 }
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
void pause() override
No work left to be done.
Proof of work definition for Ethash.
bool submitProof(Solution const &_s)
Notes that the Miner found a solution.
Definition: GenericMiner.h:136
uint64_t utcTime()
Get the current time in seconds since the epoch in UTC.
Definition: Common.cpp:64
std::shared_ptr< FullAllocation > FullType
Definition: EthashAux.h:68
ethash_h256_t result
Definition: ethash.h:65
FixedHash< 8 > h64
Definition: FixedHash.h:343
std::hash for asio::adress
Definition: Common.h:323
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
Definition: CommonData.cpp:141
bool shouldStop() const
Definition: Worker.h:86
static FullType full(h256 const &_seedHash, bool _createIfMissing=false, std::function< int(unsigned)> const &_f=std::function< int(unsigned)>())
Kicks off generation of DAG for _blocknumber and blocks until ready;.
Definition: EthashAux.cpp:176
void stopWorking()
Stop worker thread; causes call to stopWorking().
Definition: Worker.cpp:85
void workLoop() override
Overrides doWork(); should call shouldStop() often and exit when true.
FixedHash< 32 > h256
Definition: FixedHash.h:340
void startWorking()
Starts worker thread; causes startedWorking() to be called.
Definition: Worker.cpp:30
Type of a seedhash/blockhash e.t.c.
Definition: ethash.h:48
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u64
Definition: Common.h:123
static unsigned computeFull(h256 const &_seedHash, bool _createIfMissing=true)
Kicks off generation of DAG for _seedHash and.
Definition: EthashAux.cpp:202
void kickOff() override
Begin working on a given work package, discarding any previous work.
ethash_return_value_t ethash_full_compute(ethash_full_t full, ethash_h256_t const header_hash, uint64_t nonce)
Calculate the full client data.
Definition: internal.c:575
A miner - a member and adoptee of the Farm.
Definition: GenericMiner.h:43
static std::string platformInfo()
typename EthashProofOfWork::WorkPackage WorkPackage
Definition: GenericMiner.h:76
ethash_h256_t mix_hash
Definition: ethash.h:66