25 #include <boost/algorithm/string/case_conv.hpp> 30 #include <jsonrpccpp/client/connectors/httpclient.h> 62 return _m ==
"on" || _m ==
"yes" || _m ==
"true" || _m ==
"1";
67 return _m ==
"off" || _m ==
"no" || _m ==
"false" || _m ==
"0";
72 std::ostringstream out;
75 <<
" By cpp-ethereum contributors, (c) 2013-2016." << endl
76 <<
" See the README for contributors and credits." << endl;
84 static const int verbosity = 2;
85 static const bool debug =
false;
87 #define minelog clog(MiningChannel) 104 BasicAuthority::init();
109 string arg = argv[i];
110 if ((arg ==
"-F" || arg ==
"--farm") && i + 1 < argc)
112 mode = OperationMode::Farm;
113 m_farmURL = argv[++i];
115 else if (arg ==
"--farm-recheck" && i + 1 < argc)
117 m_farmRecheckPeriod = stol(argv[++i]);
121 cerr <<
"Bad " << arg <<
" option: " << argv[i] << endl;
124 else if (arg ==
"--benchmark-warmup" && i + 1 < argc)
126 m_benchmarkWarmup = stol(argv[++i]);
130 cerr <<
"Bad " << arg <<
" option: " << argv[i] << endl;
133 else if (arg ==
"--benchmark-trial" && i + 1 < argc)
135 m_benchmarkTrial = stol(argv[++i]);
139 cerr <<
"Bad " << arg <<
" option: " << argv[i] << endl;
142 else if (arg ==
"--benchmark-trials" && i + 1 < argc)
144 m_benchmarkTrials = stol(argv[++i]);
148 cerr <<
"Bad " << arg <<
" option: " << argv[i] << endl;
151 else if (arg ==
"-C" || arg ==
"--cpu")
153 else if (arg ==
"--current-block" && i + 1 < argc)
154 m_currentBlock = stol(argv[++i]);
155 else if (arg ==
"--no-precompute")
157 m_precompute =
false;
159 else if ((arg ==
"-D" || arg ==
"--create-dag") && i + 1 < argc)
161 string m = boost::to_lower_copy(
string(argv[++i]));
162 mode = OperationMode::DAGInit;
169 cerr <<
"Bad " << arg <<
" option: " << m << endl;
173 else if ((arg ==
"-w" || arg ==
"--check-pow") && i + 4 < argc)
179 m = boost::to_lower_copy(
string(argv[++i]));
181 m = boost::to_lower_copy(
string(argv[++i]));
183 if (m.size() == 64 || m.size() == 66)
186 seedHash = EthashAux::seedHash(stol(m));
187 m = boost::to_lower_copy(
string(argv[++i]));
189 auto boundary = Ethash::boundary(bi);
190 m = boost::to_lower_copy(
string(argv[++i]));
191 Ethash::setNonce(bi,
h64(m));
192 auto r = EthashAux::eval(seedHash, powHash,
h64(m));
193 bool valid = r.value < boundary;
194 cout << (valid ?
"VALID :-)" :
"INVALID :-(") << endl;
195 cout << r.value << (valid ?
" < " :
" >= ") << boundary << endl;
196 cout <<
" where " << boundary <<
" = 2^256 / " << bi.
difficulty() << endl;
197 cout <<
" and " << r.value <<
" = ethash(" << powHash <<
", " <<
h64(m) <<
")" << endl;
198 cout <<
" with seed as " << seedHash << endl;
200 cout <<
"(mixHash = " << r.mixHash <<
")" << endl;
201 cout <<
"SHA3( light(seed) ) = " <<
sha3(EthashAux::light(Ethash::seedHash(bi))->
data()) << endl;
206 cerr <<
"Bad " << arg <<
" option: " << m << endl;
210 else if (arg ==
"-M" || arg ==
"--benchmark")
211 mode = OperationMode::Benchmark;
212 else if ((arg ==
"-t" || arg ==
"--mining-threads") && i + 1 < argc)
215 m_miningThreads = stol(argv[++i]);
219 cerr <<
"Bad " << arg <<
" option: " << argv[i] << endl;
223 else if (arg ==
"--disable-submit-hashrate")
224 m_submitHashrate =
false;
232 if (m_minerType ==
"cpu")
233 EthashCPUMiner::setNumInstances(m_miningThreads);
234 if (
mode == OperationMode::DAGInit)
235 doInitDAG(m_initDAG);
236 else if (
mode == OperationMode::Benchmark)
237 doBenchmark(m_minerType, m_benchmarkWarmup, m_benchmarkTrial, m_benchmarkTrials);
238 else if (
mode == OperationMode::Farm)
239 doFarm(m_minerType, m_farmURL, m_farmRecheckPeriod);
245 <<
"Work farming mode:" << endl
246 <<
" -F,--farm <url> Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8545)" << endl
247 <<
" --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl
248 <<
" --no-precompute Don't precompute the next epoch's DAG." << endl
249 <<
"Ethash verify mode:" << endl
250 <<
" -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl
252 <<
"Benchmarking mode:" << endl
253 <<
" -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl
254 <<
" --benchmark-warmup <seconds> Set the duration of warmup for the benchmark tests (default: 3)." << endl
255 <<
" --benchmark-trial <seconds> Set the duration for each trial for the benchmark tests (default: 3)." << endl
256 <<
" --benchmark-trials <n> Set the number of trials for the benchmark tests (default: 5)." << endl
257 <<
"DAG creation mode:" << endl
258 <<
" -D,--create-dag <number> Create the DAG in preparation for mining on given block and exit." << endl
259 <<
"Mining configuration:" << endl
260 <<
" -C,--cpu When mining, use the CPU." << endl
261 <<
" -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl
262 <<
" --current-block Let the miner know the current block number at configuration time. Will help determine DAG size and required GPU memory." << endl
263 <<
" --disable-submit-hashrate When mining, don't submit hashrate to node." << endl;
272 h256 seedHash = EthashAux::seedHash(_n);
273 cout <<
"Initializing DAG for epoch beginning #" << (_n / 30000 * 30000) <<
" (seedhash " << seedHash.
abridged() <<
"). This will take a while." << endl;
274 EthashAux::full(seedHash,
true);
278 void doBenchmark(std::string _m,
unsigned _warmupDuration = 15,
unsigned _trialDuration = 3,
unsigned _trials = 5)
282 cdebug << Ethash::boundary(genesis);
285 map<string, GenericFarm<EthashProofOfWork>::SealerDescriptor> sealers;
290 string platformInfo = EthashCPUMiner::platformInfo();
291 cout <<
"Benchmarking on platform: " << platformInfo << endl;
293 cout <<
"Preparing DAG..." << endl;
294 Ethash::ensurePrecomputed(0);
300 map<u256, WorkingProgress> results;
303 for (
unsigned i = 0; i <= _trials; ++i)
306 cout <<
"Warming up..." << endl;
308 cout <<
"Trial " << i <<
"... " << flush;
309 this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration));
315 auto rate = mp.rate();
317 cout << rate << endl;
323 for (
auto const& r: results)
324 if (++j > 0 && j < (
int)_trials - 1)
325 innerMean += r.second.rate();
326 innerMean /= (_trials - 2);
327 cout <<
"min/mean/max: " << results.begin()->second.rate() <<
"/" << (mean / _trials) <<
"/" << results.rbegin()->second.rate() <<
" H/s" << endl;
328 cout <<
"inner mean: " << innerMean <<
" H/s" << endl;
334 void doFarm(std::string _m,
string const& _remote,
unsigned _recheckPeriod)
336 map<string, GenericFarm<EthashProofOfWork>::SealerDescriptor> sealers;
340 (void)_recheckPeriod;
341 jsonrpc::HttpClient client(_remote);
343 h256 id = h256::random();
354 bool completed =
false;
370 minelog <<
"Getting work package...";
372 if (m_submitHashrate)
374 auto rate = mp.rate();
379 catch (jsonrpc::JsonRpcException
const& _e)
381 cwarn <<
"Failed to submit hashrate.";
382 cwarn << boost::diagnostic_information(_e);
391 if (current.
seedHash != newSeedHash)
392 minelog <<
"Grabbing DAG for" << newSeedHash;
393 if (!(dag = EthashAux::full(newSeedHash,
true, [&](
unsigned _pc){ cout <<
"\rCreating DAG. " << _pc <<
"% done..." << flush;
return 0; })))
394 BOOST_THROW_EXCEPTION(DAGCreationFailure());
396 EthashAux::computeFull(
sha3(newSeedHash),
true);
402 minelog <<
"Got work package:";
408 this_thread::sleep_for(chrono::milliseconds(_recheckPeriod));
410 cnote <<
"Solution found; Submitting to" << _remote <<
"...";
421 cnote <<
"B-) Submitted and accepted.";
423 cwarn <<
":-( Not accepted.";
426 cwarn <<
"FAILURE: GPU gave incorrect result!";
429 catch (jsonrpc::JsonRpcException&)
431 for (
auto i = 3; --i; this_thread::sleep_for(chrono::seconds(1)))
432 cerr <<
"JSON-RPC problem. Probably couldn't connect. Retrying in " << i <<
"... \r";
437 this_thread::sleep_for(chrono::milliseconds(100));
446 std::string m_minerType =
"cpu";
447 unsigned m_miningThreads = UINT_MAX;
448 uint64_t m_currentBlock = 0;
451 unsigned m_initDAG = 0;
454 unsigned m_benchmarkWarmup = 3;
455 unsigned m_benchmarkTrial = 3;
456 unsigned m_benchmarkTrials = 5;
459 string m_farmURL =
"http://127.0.0.1:8545";
460 unsigned m_farmRecheckPeriod = 500;
461 bool m_precompute =
true;
462 bool m_submitHashrate =
true;
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
void setSealers(std::map< std::string, SealerDescriptor > const &_sealers)
MinerCLI(OperationMode _mode=OperationMode::None)
WorkingProgress const & miningProgress() const
Get information on the progress of mining this work package.
std::shared_ptr< FullAllocation > FullType
bool eth_submitWork(const std::string ¶m1, const std::string ¶m2, const std::string ¶m3)
void doBenchmark(std::string _m, unsigned _warmupDuration=15, unsigned _trialDuration=3, unsigned _trials=5)
void stop()
Stop all mining activities.
std::hash for asio::adress
EXPORT void debug(uint64_t a, uint64_t b, uint64_t c, uint64_t d, char z)
static void streamHelp(ostream &_out)
std::string toString(string32 const &_s)
Make normal string from fixed-length string.
void resetMiningProgress()
Reset the mining progess counter.
Json::Value eth_getWork()
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
void onSolutionFound(SolutionFound const &_handler)
Provides a valid header based upon that received previously with setWork().
Base class for all exceptions.
This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY!
std::string toJS(FixedHash< S > const &_h)
std::string minerType() const
bool interpretOption(int &i, int argc, char **argv)
bool start(std::string const &_sealer)
Start a number of miners.
bool eth_submitHashrate(const std::string ¶m1, const std::string ¶m2)
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
void setWork(WorkPackage const &_wp)
Sets the current mining mission.
void doInitDAG(unsigned _n)
OperationMode mode
Operating mode.
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
std::string abridged() const
bool shouldPrecompute() const
The default logging channels.
A miner - a member and adoptee of the Farm.
This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY!
h256 headerHash
When h256() means "pause until notified a new work package is available".
static const char * name()
void doFarm(std::string _m, string const &_remote, unsigned _recheckPeriod)
bool isFalse(std::string const &_m)
std::string asString(bytes const &_b)
Converts byte array to a string containing the same (binary) data.
bool isTrue(std::string const &_m)