Browse Source

Merge pull request #1 from Genoil/110

110
cl-refactor
kenshirothefist 9 years ago
committed by GitHub
parent
commit
05473d7ae2
  1. 2
      CMakeLists.txt
  2. 274
      ethminer/MinerAux.h
  3. 3
      libethash-cl/ethash_cl_miner.cpp
  4. 9
      libethash-cuda/ethash_cuda_miner.cpp
  5. 6
      libethash-cuda/ethash_cuda_miner.h
  6. 7
      libethash-cuda/ethash_cuda_miner_kernel.cu
  7. 3
      libethash-cuda/ethash_cuda_miner_kernel.h
  8. 2
      libethcore/EthashAux.cpp
  9. 2
      libethcore/EthashAux.h
  10. 38
      libethcore/EthashCUDAMiner.cpp
  11. 4
      libethcore/EthashCUDAMiner.h
  12. 26
      libethcore/EthashGPUMiner.cpp
  13. 4
      libethcore/EthashGPUMiner.h
  14. 2
      libethcore/EthashSealEngine.cpp
  15. 21
      libethcore/Farm.h
  16. 13
      libethcore/Miner.cpp
  17. 25
      libethcore/Miner.h
  18. 31
      libstratum/EthStratumClient.cpp
  19. 10
      libstratum/EthStratumClient.h
  20. 336
      libstratum/EthStratumClientV2.cpp
  21. 84
      libstratum/EthStratumClientV2.h
  22. BIN
      releases/ethminer-0.9.41-genoil-1.0.1.zip
  23. BIN
      releases/ethminer-0.9.41-genoil-1.0.2.zip
  24. BIN
      releases/ethminer-0.9.41-genoil-1.0.3.zip
  25. BIN
      releases/ethminer-0.9.41-genoil-1.0.4b3.zip
  26. BIN
      releases/ethminer-0.9.41-genoil-1.0.5.zip
  27. BIN
      releases/ethminer-0.9.41-genoil-1.0.6.zip
  28. BIN
      releases/ethminer-0.9.41-genoil-1.0.7.zip
  29. BIN
      releases/ethminer-0.9.41-genoil-1.1.4.zip
  30. BIN
      releases/ethminer-0.9.41-genoil-1.1.zip

2
CMakeLists.txt

@ -2,7 +2,7 @@
cmake_minimum_required(VERSION 2.8.12)
set(PROJECT_VERSION "0.9.41")
set(GENOIL_VERSION "1.1")
set(GENOIL_VERSION "1.1.4")
if (${CMAKE_VERSION} VERSION_GREATER 3.0)
cmake_policy(SET CMP0042 OLD) # fix MACOSX_RPATH
cmake_policy(SET CMP0048 NEW) # allow VERSION argument in project()

274
ethminer/MinerAux.h

@ -60,6 +60,7 @@
#endif
#if ETH_STRATUM || !ETH_TRUE
#include <libstratum/EthStratumClient.h>
#include <libstratum/EthStratumClientV2.h>
#endif
using namespace std;
using namespace dev;
@ -187,6 +188,19 @@ public:
if (p + 1 <= userpass.length())
m_pass = userpass.substr(p+1);
}
else if ((arg == "-SV" || arg == "--stratum-version") && i + 1 < argc)
{
try {
m_stratumClientVersion = atoi(argv[++i]);
if (m_stratumClientVersion > 2) m_stratumClientVersion = 2;
else if (m_stratumClientVersion < 1) m_stratumClientVersion = 1;
}
catch (...)
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
BOOST_THROW_EXCEPTION(BadArgument());
}
}
else if ((arg == "-FO" || arg == "--failover-userpass") && i + 1 < argc)
{
string userpass = string(argv[++i]);
@ -311,6 +325,18 @@ public:
else if (arg == "--cuda-streams" && i + 1 < argc)
m_numStreams = stol(argv[++i]);
#endif
else if ((arg == "-L" || arg == "--dag-load-mode") && i + 1 < argc)
{
string mode = argv[++i];
if (mode == "parallel") m_dagLoadMode = DAG_LOAD_MODE_PARALLEL;
else if (mode == "sequential") m_dagLoadMode = DAG_LOAD_MODE_SEQUENTIAL;
else
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
BOOST_THROW_EXCEPTION(BadArgument());
}
}
/*
else if (arg == "--phone-home" && i + 1 < argc)
{
string m = argv[++i];
@ -324,6 +350,7 @@ public:
BOOST_THROW_EXCEPTION(BadArgument());
}
}
*/
else if (arg == "--benchmark-warmup" && i + 1 < argc)
try {
m_benchmarkWarmup = stol(argv[++i]);
@ -360,43 +387,13 @@ public:
{
m_minerType = MinerType::CUDA;
}
else if (arg == "--current-block" && i + 1 < argc)
m_currentBlock = stol(argv[++i]);
/*
else if ((arg == "-R" || arg == "--dag-dir") && i + 1 < argc)
else if (arg == "-X" || arg == "--cuda-opencl")
{
strcpy(s_dagDir, argv[++i]);
m_minerType = MinerType::Mixed;
}
else if ((arg == "-E" || arg == "--erase-dags") && i + 1 < argc)
{
string m = string(argv[++i]);
if (m == "none") m_eraseMode = DAGEraseMode::None;
else if (m == "old") m_eraseMode = DAGEraseMode::Old;
else if (m == "bench") m_eraseMode = DAGEraseMode::Bench;
else if (m == "all") m_eraseMode = DAGEraseMode::All;
else
{
cerr << "Bad " << arg << " option: " << argv[i] << endl;
BOOST_THROW_EXCEPTION(BadArgument());
}
}
else if (arg == "--no-precompute")
m_precompute = false;
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
{
string m = boost::to_lower_copy(string(argv[++i]));
mode = OperationMode::DAGInit;
try
{
m_initDAG = stol(m);
}
catch (...)
{
cerr << "Bad " << arg << " option: " << m << endl;
BOOST_THROW_EXCEPTION(BadArgument());
}
}
*/
/*
else if (arg == "--current-block" && i + 1 < argc)
m_currentBlock = stol(argv[++i]);
else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc)
{
string m;
@ -434,6 +431,7 @@ public:
BOOST_THROW_EXCEPTION(BadArgument());
}
}
*/
else if (arg == "-M" || arg == "--benchmark")
{
mode = OperationMode::Benchmark;
@ -496,24 +494,14 @@ public:
void execute()
{
/*
EthashAux::setDAGDirName(s_dagDir);
EthashAux::setDAGEraseMode(m_eraseMode);
EthashAux::eraseDAGs();
if (m_eraseMode == DAGEraseMode::All)
{
m_eraseMode = DAGEraseMode::None;
}
*/
if (m_shouldListDevices)
{
#if ETH_ETHASHCL || !ETH_TRUE
if (m_minerType == MinerType::CL)
if (m_minerType == MinerType::CL || m_minerType == MinerType::Mixed)
EthashGPUMiner::listDevices();
#endif
#if ETH_ETHASHCUDA || !ETH_TRUE
if (m_minerType == MinerType::CUDA)
if (m_minerType == MinerType::CUDA || m_minerType == MinerType::Mixed)
EthashCUDAMiner::listDevices();
#endif
if (m_minerType == MinerType::CPU)
@ -522,8 +510,11 @@ public:
}
if (m_minerType == MinerType::CPU)
EthashCPUMiner::setNumInstances(m_miningThreads);
else if (m_minerType == MinerType::CL)
{
cout << "CPU mining is no longer supported in this miner. Use -G (opencl) or -U (cuda) flag to select GPU platform." << endl;
exit(0);
}
else if (m_minerType == MinerType::CL || m_minerType == MinerType::Mixed)
{
#if ETH_ETHASHCL || !ETH_TRUE
if (m_openclDeviceCount > 0)
@ -539,7 +530,8 @@ public:
m_openclDevice,
m_clAllowCPU,
m_extraGPUMemory,
m_currentBlock
0,
m_dagLoadMode
))
exit(1);
EthashGPUMiner::setNumInstances(m_miningThreads);
@ -548,7 +540,7 @@ public:
exit(1);
#endif
}
else if (m_minerType == MinerType::CUDA)
else if (m_minerType == MinerType::CUDA || m_minerType == MinerType::Mixed)
{
#if ETH_ETHASHCUDA || !ETH_TRUE
if (m_cudaDeviceCount > 0)
@ -564,7 +556,8 @@ public:
m_numStreams,
m_extraGPUMemory,
m_cudaSchedule,
m_currentBlock
0,
m_dagLoadMode
))
exit(1);
#else
@ -572,9 +565,7 @@ public:
exit(1);
#endif
}
if (mode == OperationMode::DAGInit)
doInitDAG(m_initDAG);
else if (mode == OperationMode::Benchmark)
if (mode == OperationMode::Benchmark)
doBenchmark(m_minerType, m_phoneHome, m_benchmarkWarmup, m_benchmarkTrial, m_benchmarkTrials);
else if (mode == OperationMode::Farm)
doFarm(m_minerType, m_activeFarmURL, m_farmRecheckPeriod);
@ -601,13 +592,11 @@ public:
<< " -O, --userpass <username.workername:password> Stratum login credentials" << endl
<< " -FO, --failover-userpass <username.workername:password> Failover stratum login credentials (optional, will use normal credentials when omitted)" << endl
<< " --work-timeout <n> reconnect/failover after n seconds of working on the same (stratum) job. Defaults to 180. Don't set lower than max. avg. block time" << endl
<< " -SV, --stratum-version <n> Stratum client version. Defaults to 1 (async client). Use 2 to test new synchronous client."
#endif
#if ETH_JSONRPC || ETH_STRATUM || !ETH_TRUE
<< " --farm-recheck <n> Leave n ms between checks for changed work (default: 500). When using stratum, use a high value (i.e. 2000) to get more stable hashrate output" << endl
<< " --no-precompute Don't precompute the next epoch's DAG." << endl
#endif
<< "Ethash verify mode:" << endl
<< " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl
<< endl
<< "Benchmarking mode:" << endl
<< " -M [<n>],--benchmark [<n>] Benchmark for mining and exit; Optionally specify block number to benchmark against specific DAG." << endl
@ -616,28 +605,19 @@ public:
<< " --benchmark-trials <n> Set the duration of warmup for the benchmark tests (default: 5)." << endl
<< "Simulation mode:" << endl
<< " -Z [<n>],--simulation [<n>] Mining test mode. Used to validate kernel optimizations. Optionally specify block number." << endl
#if ETH_JSONRPC || !ETH_TRUE
<< " --phone-home <on/off> When benchmarking, publish results (default: off)" << endl
#endif
// << "DAG file management:" << endl
// << " -D,--create-dag <number> Create the DAG in preparation for mining on given block and exit." << endl
// << " -R <s>, --dag-dir <s> Store/Load DAG files in/from the specified directory. Useful for running multiple instances with different configurations." << endl
// << " -E <mode>, --erase-dags <mode> Erase unneeded DAG files. Default is 'none'. Possible values are:" << endl
// << " none - don't erase DAG files (default)" << endl
// << " old - erase all DAG files older than current epoch" << endl
// << " bench - like old, but keep epoch 0 for benchmarking" << endl
// << " all - erase all DAG files. After deleting all files, setting changes to none." << endl
<< "Mining configuration:" << endl
<< " -C,--cpu When mining, use the CPU." << endl
<< " -G,--opencl When mining use the GPU via OpenCL." << endl
<< " -U,--cuda When mining use the GPU via CUDA." << endl
<< " -X,--cuda-opencl Use OpenCL + CUDA in a system with mixed AMD/Nvidia cards. May require setting --opencl-platform 1" << endl
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl
<< " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl
<< " --opencl-devices <0 1 ..n> Select which OpenCL devices to mine on. Default is to use all" << endl
<< " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl
<< " --allow-opencl-cpu Allows CPU to be considered as an OpenCL device if the OpenCL platform supports it." << endl
<< " --list-devices List the detected OpenCL/CUDA devices and exit. Should be combined with -G or -U flag" << endl
<< " --current-block Let the miner know the current block number at configuration time. Will help determine DAG size and required GPU memory." << endl
<< " -L, --dag-load-mode <mode> DAG generation mode." << endl
<< " parallel - load DAG on all GPUs at the same time (default)" << endl
<< " sequential - load DAG on GPUs one after another. Use this when the miner crashes during DAG generation" << endl
#if ETH_ETHASHCL || !ETH_TRUE
<< " --cl-extragpu-mem Set the memory (in MB) you believe your GPU requires for stuff other than mining. default: 0" << endl
<< " --cl-local-work Set the OpenCL local work size. Default is " << toString(ethash_cl_miner::c_defaultLocalWorkSize) << endl
@ -659,7 +639,6 @@ public:
}
MinerType minerType() const { return m_minerType; }
bool shouldPrecompute() const { return m_precompute; }
private:
void doInitDAG(unsigned _n)
@ -700,11 +679,11 @@ private:
genesis.setDifficulty(u256(1) << 63);
f.setWork(genesis);
if (_m == MinerType::CPU)
f.start("cpu");
f.start("cpu", false);
else if (_m == MinerType::CL)
f.start("opencl");
f.start("opencl", false);
else if (_m == MinerType::CUDA)
f.start("cuda");
f.start("cuda", false);
map<uint64_t, WorkingProgress> results;
uint64_t mean = 0;
@ -784,11 +763,11 @@ private:
f.setWork(genesis);
if (_m == MinerType::CPU)
f.start("cpu");
f.start("cpu", false);
else if (_m == MinerType::CL)
f.start("opencl");
f.start("opencl", false);
else if (_m == MinerType::CUDA)
f.start("cuda");
f.start("cuda", false);
int time = 0;
@ -810,13 +789,7 @@ private:
this_thread::sleep_for(chrono::milliseconds(1000));
time++;
}
//cnote << "Solution found";
cnote << "Difficulty:" << difficulty << " Nonce:" << solution.nonce.hex();
//cnote << " Mixhash:" << solution.mixHash.hex();
//cnote << " Header-hash:" << current.headerHash.hex();
//cnote << " Seedhash:" << current.seedHash.hex();
//cnote << " Target: " << h256(current.boundary).hex();
//cnote << " Ethash: " << h256(EthashAux::eval(current.seedHash, current.headerHash, solution.nonce).value).hex();
if (EthashAux::eval(current.seedHash, current.headerHash, solution.nonce).value < current.boundary)
{
cnote << "SUCCESS: GPU gave correct result!";
@ -873,11 +846,11 @@ private:
GenericFarm<EthashProofOfWork> f;
f.setSealers(sealers);
if (_m == MinerType::CPU)
f.start("cpu");
f.start("cpu", false);
else if (_m == MinerType::CL)
f.start("opencl");
f.start("opencl", false);
else if (_m == MinerType::CUDA)
f.start("cuda");
f.start("cuda", false);
EthashProofOfWork::WorkPackage current, previous;
boost::mutex x_current;
EthashAux::FullType dag;
@ -915,20 +888,7 @@ private:
Json::Value v = prpc->eth_getWork();
h256 hh(v[0].asString());
h256 newSeedHash(v[1].asString());
/*
if (current.seedHash != newSeedHash)
{
minelog << "Grabbing DAG for" << newSeedHash;
}
if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; })))
{
BOOST_THROW_EXCEPTION(DAGCreationFailure());
}
if (m_precompute)
{
EthashAux::computeFull(sha3(newSeedHash), true);
}
*/
if (hh != current.headerHash)
{
x_current.lock();
@ -939,8 +899,6 @@ private:
current.seedHash = newSeedHash;
current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight);
minelog << "Got work package: #" + current.headerHash.hex().substr(0,8);
//minelog << " Seedhash:" << current.seedHash.hex();
//minelog << " Target: " << h256(current.boundary).hex();
f.setWork(current);
x_current.unlock();
}
@ -948,11 +906,6 @@ private:
}
cnote << "Solution found; Submitting to" << _remote << "...";
cnote << " Nonce:" << solution.nonce.hex();
//cnote << " Mixhash:" << solution.mixHash.hex();
//cnote << " Header-hash:" << current.headerHash.hex();
//cnote << " Seedhash:" << solved.seedHash.hex();
//cnote << " Target: " << h256(solved.boundary).hex();
//cnote << " Ethash: " << h256(EthashAux::eval(solved.seedHash, solved.headerHash, solution.nonce).value).hex();
if (EthashAux::eval(current.seedHash, current.headerHash, solution.nonce).value < current.boundary)
{
bool ok = prpc->eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash));
@ -1036,45 +989,89 @@ private:
m_farmRecheckPeriod = m_defaultStratumFarmRecheckPeriod;
GenericFarm<EthashProofOfWork> f;
EthStratumClient client(&f, m_minerType, m_farmURL, m_port, m_user, m_pass, m_maxFarmRetries, m_worktimeout, m_precompute);
if (m_farmFailOverURL != "")
{
if (m_fuser != "")
// this is very ugly, but if Stratum Client V2 tunrs out to be a success, V1 will be completely removed anyway
if (m_stratumClientVersion == 1) {
EthStratumClient client(&f, m_minerType, m_farmURL, m_port, m_user, m_pass, m_maxFarmRetries, m_worktimeout);
if (m_farmFailOverURL != "")
{
client.setFailover(m_farmFailOverURL, m_fport, m_fuser, m_fpass);
if (m_fuser != "")
{
client.setFailover(m_farmFailOverURL, m_fport, m_fuser, m_fpass);
}
else
{
client.setFailover(m_farmFailOverURL, m_fport);
}
}
else
f.setSealers(sealers);
f.onSolutionFound([&](EthashProofOfWork::Solution sol)
{
client.setFailover(m_farmFailOverURL, m_fport);
if (client.isConnected()) {
client.submit(sol);
}
else {
cwarn << "Can't submit solution: Not connected";
}
return false;
});
while (client.isRunning())
{
auto mp = f.miningProgress();
f.resetMiningProgress();
if (client.isConnected())
{
if (client.current())
minelog << "Mining on PoWhash" << "#" + (client.currentHeaderHash().hex().substr(0, 8)) << ": " << mp << f.getSolutionStats();
else if (client.waitState() == MINER_WAIT_STATE_WORK)
minelog << "Waiting for work package...";
}
this_thread::sleep_for(chrono::milliseconds(m_farmRecheckPeriod));
}
}
f.setSealers(sealers);
else if (m_stratumClientVersion == 2) {
EthStratumClientV2 client(&f, m_minerType, m_farmURL, m_port, m_user, m_pass, m_maxFarmRetries, m_worktimeout);
if (m_farmFailOverURL != "")
{
if (m_fuser != "")
{
client.setFailover(m_farmFailOverURL, m_fport, m_fuser, m_fpass);
}
else
{
client.setFailover(m_farmFailOverURL, m_fport);
}
}
f.setSealers(sealers);
f.onSolutionFound([&](EthashProofOfWork::Solution sol)
{
client.submit(sol);
return false;
});
while (client.isRunning())
{
auto mp = f.miningProgress();
f.resetMiningProgress();
if (client.isConnected())
f.onSolutionFound([&](EthashProofOfWork::Solution sol)
{
if (client.current())
minelog << "Mining on PoWhash" << "#"+(client.currentHeaderHash().hex().substr(0,8)) << ": " << mp << f.getSolutionStats();
else if (client.waitState() == MINER_WAIT_STATE_WORK)
minelog << "Waiting for work package...";
client.submit(sol);
return false;
});
while (client.isRunning())
{
auto mp = f.miningProgress();
f.resetMiningProgress();
if (client.isConnected())
{
if (client.current())
minelog << "Mining on PoWhash" << "#" + (client.currentHeaderHash().hex().substr(0, 8)) << ": " << mp << f.getSolutionStats();
else if (client.waitState() == MINER_WAIT_STATE_WORK)
minelog << "Waiting for work package...";
}
this_thread::sleep_for(chrono::milliseconds(m_farmRecheckPeriod));
}
this_thread::sleep_for(chrono::milliseconds(m_farmRecheckPeriod));
}
}
#endif
/// Operating mode.
OperationMode mode;
DAGEraseMode m_eraseMode = DAGEraseMode::None;
/// Mining options
bool m_running = true;
@ -1100,14 +1097,9 @@ private:
unsigned m_numStreams = ethash_cuda_miner::c_defaultNumStreams;
unsigned m_cudaSchedule = 4; // sync
#endif
uint64_t m_currentBlock = 0;
static char s_dagDir[256];
// default value was 350MB of GPU memory for other stuff (windows system rendering, e.t.c.)
unsigned m_extraGPUMemory = 0;// 350000000; don't assume miners run desktops...
/// DAG initialisation param.
unsigned m_initDAG = 0;
unsigned m_dagLoadMode = 0; // parallel
/// Benchmarking params
bool m_phoneHome = false;
unsigned m_benchmarkWarmup = 15;
@ -1126,9 +1118,9 @@ private:
unsigned m_defaultStratumFarmRecheckPeriod = 2000;
bool m_farmRecheckSet = false;
int m_worktimeout = 180;
bool m_precompute = true;
#if ETH_STRATUM || !ETH_TRUE
int m_stratumClientVersion = 1;
string m_user;
string m_pass;
string m_port;
@ -1137,5 +1129,3 @@ private:
#endif
string m_fport = "";
};
char MinerCLI::s_dagDir[256] = "";

3
libethash-cl/ethash_cl_miner.cpp

@ -205,6 +205,7 @@ bool ethash_cl_miner::configureGPU(
s_initialGlobalWorkSize = _globalWorkSize;
s_allowCPU = _allowCPU;
s_extraRequiredGPUMem = _extraGPUMemory;
// by default let's only consider the DAG of the first epoch
uint64_t dagSize = ethash_get_datasize(_currentBlock);
uint64_t requiredSize = dagSize + _extraGPUMemory;
@ -485,7 +486,7 @@ bool ethash_cl_miner::init(
m_dagKernel.setArg(0, i * m_globalWorkSize);
m_queue.enqueueNDRangeKernel(m_dagKernel, cl::NullRange, m_globalWorkSize, s_workgroupSize);
m_queue.finish();
printf("%.0f%%\n", 100.0f * (float)i / (float)fullRuns);
printf("OPENCL#%d: %.0f%%\n", _deviceId, 100.0f * (float)i / (float)fullRuns);
}
}

9
libethash-cuda/ethash_cuda_miner.cpp

@ -231,15 +231,12 @@ bool ethash_cuda_miner::init(ethash_light_t _light, uint8_t const* _lightData, u
// create buffer for cache
hash64_t * light;
CUDA_SAFE_CALL(cudaMalloc(reinterpret_cast<void**>(&light), _lightSize));
// copy dag to CPU.
// copy dag cache to CPU.
CUDA_SAFE_CALL(cudaMemcpy(reinterpret_cast<void*>(light), _lightData, _lightSize, cudaMemcpyHostToDevice));
// create buffer for dag
hash128_t * dag;
CUDA_SAFE_CALL(cudaMalloc(reinterpret_cast<void**>(&dag), dagSize));
// copy dag to CPU.
//CUDA_SAFE_CALL(cudaMemcpy(reinterpret_cast<void*>(dag), _dag, _dagSize, cudaMemcpyHostToDevice));
// create mining buffers
for (unsigned i = 0; i != s_numStreams; ++i)
@ -256,8 +253,8 @@ bool ethash_cuda_miner::init(ethash_light_t _light, uint8_t const* _lightData, u
m_sharedBytes = device_props.major * 100 < SHUFFLE_MIN_VER ? (64 * s_blockSize) / 8 : 0 ;
cout << "Generating DAG..." << endl;
ethash_generate_dag(dagSize, s_gridSize, s_blockSize, m_streams[0]);
cout << "Generating DAG for GPU #" << device_num << endl;
ethash_generate_dag(dagSize, s_gridSize, s_blockSize, m_streams[0], device_num);
return true;
}

6
libethash-cuda/ethash_cuda_miner.h

@ -34,11 +34,7 @@ public:
unsigned _scheduleFlag,
uint64_t _currentBlock
);
/*bool init(
uint8_t const* _dag,
uint64_t _dagSize,
unsigned _deviceId = 0
);*/
bool init(ethash_light_t _light, uint8_t const* _lightData, uint64_t _lightSize, unsigned _deviceId);
void finish();

7
libethash-cuda/ethash_cuda_miner_kernel.cu

@ -114,7 +114,8 @@ void ethash_generate_dag(
uint64_t dag_size,
uint32_t blocks,
uint32_t threads,
cudaStream_t stream
cudaStream_t stream,
int device
)
{
uint32_t const work = (uint32_t)(dag_size / sizeof(hash64_t));
@ -126,9 +127,9 @@ void ethash_generate_dag(
{
ethash_calculate_dag_item <<<blocks, threads, 0, stream >>>(i * blocks * threads);
CUDA_SAFE_CALL(cudaDeviceSynchronize());
printf("%.0f%%\n",100.0f * (float)i / (float)fullRuns);
printf("CUDA#%d: %.0f%%\n",device, 100.0f * (float)i / (float)fullRuns);
}
//printf("GPU#%d 100%%\n");
CUDA_SAFE_CALL(cudaGetLastError());
}

3
libethash-cuda/ethash_cuda_miner_kernel.h

@ -59,7 +59,8 @@ void ethash_generate_dag(
uint64_t dag_size,
uint32_t blocks,
uint32_t threads,
cudaStream_t stream
cudaStream_t stream,
int device
);

2
libethcore/EthashAux.cpp

@ -52,6 +52,8 @@ const unsigned EthashProofOfWork::defaultGlobalWorkSizeMultiplier = 4096; // * C
const unsigned EthashProofOfWork::defaultMSPerBatch = 0;
const EthashProofOfWork::WorkPackage EthashProofOfWork::NullWorkPackage = EthashProofOfWork::WorkPackage();
//unsigned EthashProofOfWork::s_dagLoadMode = 0;
EthashAux::~EthashAux()
{
}

2
libethcore/EthashAux.h

@ -32,6 +32,7 @@ namespace dev
namespace eth
{
struct DAGChannel: public LogChannel { static const char* name(); static const int verbosity = 1; };
/// Proof of work definition for Ethash.
@ -73,6 +74,7 @@ struct EthashProofOfWork
static const unsigned defaultGlobalWorkSizeMultiplier;
/// Default value of the milliseconds per global work size (per batch)
static const unsigned defaultMSPerBatch;
};
enum class DAGEraseMode

38
libethcore/EthashCUDAMiner.cpp

@ -144,6 +144,13 @@ void EthashCUDAMiner::workLoop()
cnote << "set work; seed: " << "#" + w.seedHash.hex().substr(0, 8) + ", target: " << "#" + w.boundary.hex().substr(0, 16);
if (!m_miner || m_minerSeed != w.seedHash)
{
if (s_dagLoadMode == DAG_LOAD_MODE_SEQUENTIAL)
{
while (s_dagLoadIndex < index()) {
this_thread::sleep_for(chrono::seconds(1));
}
}
cnote << "Initialising miner...";
m_minerSeed = w.seedHash;
@ -152,30 +159,13 @@ void EthashCUDAMiner::workLoop()
unsigned device = s_devices[index()] > -1 ? s_devices[index()] : index();
/*
EthashAux::FullType dag;
while (true)
{
if ((dag = EthashAux::full(w.seedHash, true)))
break;
if (shouldStop())
{
delete m_miner;
m_miner = nullptr;
return;
}
cnote << "Awaiting DAG";
this_thread::sleep_for(chrono::milliseconds(500));
}
*/
EthashAux::LightType light;
light = EthashAux::light(w.seedHash);
//bytesConstRef dagData = dag->data();
bytesConstRef lightData = light->data();
m_miner->init(light->light, lightData.data(), lightData.size(), device);
s_dagLoadIndex++;
}
uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192);
@ -216,17 +206,13 @@ bool EthashCUDAMiner::configureGPU(
unsigned _numStreams,
unsigned _extraGPUMemory,
unsigned _scheduleFlag,
uint64_t _currentBlock
uint64_t _currentBlock,
unsigned _dagLoadMode
)
{
s_dagLoadMode = _dagLoadMode;
_blockSize = ((_blockSize + 7) / 8) * 8;
/*
if (_blockSize != 32 && _blockSize != 64 && _blockSize != 128)
{
cout << "Given localWorkSize of " << toString(_blockSize) << "is invalid. Must be either 32,64 or 128" << endl;
return false;
}
*/
if (!ethash_cuda_miner::configureGPU(
s_devices,
_blockSize,

4
libethcore/EthashCUDAMiner.h

@ -53,7 +53,8 @@ namespace eth
unsigned _numStreams,
unsigned _extraGPUMemory,
unsigned _scheduleFlag,
uint64_t _currentBlock
uint64_t _currentBlock,
unsigned _dagLoadMode
);
static void setNumInstances(unsigned _instances)
{
@ -84,6 +85,7 @@ namespace eth
static unsigned s_deviceId;
static unsigned s_numInstances;
static int s_devices[16];
};
}
}

26
libethcore/EthashGPUMiner.cpp

@ -107,7 +107,7 @@ int EthashGPUMiner::s_devices[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
EthashGPUMiner::EthashGPUMiner(ConstructionInfo const& _ci):
GenericMiner<EthashProofOfWork>(_ci),
Worker("gpuminer" + toString(index())),
Worker("openclminer" + toString(index())),
m_hook(new EthashCLHook(this))
{
}
@ -142,6 +142,13 @@ void EthashGPUMiner::workLoop()
cnote << "set work; seed: " << "#" + w.seedHash.hex().substr(0, 8) + ", target: " << "#" + w.boundary.hex().substr(0, 16);
if (!m_miner || m_minerSeed != w.seedHash)
{
if (s_dagLoadMode == DAG_LOAD_MODE_SEQUENTIAL)
{
while (s_dagLoadIndex < index()) {
this_thread::sleep_for(chrono::seconds(1));
}
}
cnote << "Initialising miner...";
m_minerSeed = w.seedHash;
@ -172,6 +179,7 @@ void EthashGPUMiner::workLoop()
bytesConstRef lightData = light->data();
m_miner->init(light->light, lightData.data(), lightData.size(), s_platformId, device);
s_dagLoadIndex++;
}
uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192);
@ -213,27 +221,25 @@ bool EthashGPUMiner::configureGPU(
unsigned _deviceId,
bool _allowCPU,
unsigned _extraGPUMemory,
uint64_t _currentBlock
uint64_t _currentBlock,
unsigned _dagLoadMode
)
{
s_dagLoadMode = _dagLoadMode;
s_platformId = _platformId;
s_deviceId = _deviceId;
_localWorkSize = ((_localWorkSize + 7) / 8) * 8;
/*
if (_localWorkSize != 32 && _localWorkSize != 64 && _localWorkSize != 128 && _localWorkSize != 256)
{
cout << "Given localWorkSize of " << toString(_localWorkSize) << "is invalid. Must be either 32,64,128 or 256" << endl;
return false;
}
*/
if (!ethash_cl_miner::configureGPU(
_platformId,
_localWorkSize,
_globalWorkSizeMultiplier * _localWorkSize,
_allowCPU,
_extraGPUMemory,
_currentBlock)
_currentBlock
)
)
{
cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl;

4
libethcore/EthashGPUMiner.h

@ -52,7 +52,8 @@ public:
unsigned _deviceId,
bool _allowCPU,
unsigned _extraGPUMemory,
uint64_t _currentBlock
uint64_t _currentBlock,
unsigned _dagLoadMode
);
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, getNumDevices()); }
static void setDevices(unsigned * _devices, unsigned _selectedDeviceCount)
@ -81,6 +82,7 @@ private:
static unsigned s_deviceId;
static unsigned s_numInstances;
static int s_devices[16];
};
}

2
libethcore/EthashSealEngine.cpp

@ -59,7 +59,7 @@ void EthashSealEngine::generateSeal(BlockInfo const& _bi)
{
m_sealing = Ethash::BlockHeader(_bi);
m_farm.setWork(m_sealing);
m_farm.start(m_sealer);
m_farm.start(m_sealer, false);
m_farm.setWork(m_sealing); // TODO: take out one before or one after...
bytes shouldPrecompute = option("precomputeDAG");
if (!shouldPrecompute.empty() && shouldPrecompute[0] == 1)

21
libethcore/Farm.h

@ -80,7 +80,7 @@ public:
/**
* @brief Start a number of miners.
*/
bool start(std::string const& _sealer)
bool start(std::string const& _sealer, bool mixed)
{
WriteGuard l(x_minerWork);
if (!m_miners.empty() && m_lastSealer == _sealer)
@ -88,10 +88,23 @@ public:
if (!m_sealers.count(_sealer))
return false;
m_miners.clear();
if (!mixed)
{
m_miners.clear();
}
auto ins = m_sealers[_sealer].instances();
m_miners.reserve(ins);
for (unsigned i = 0; i < ins; ++i)
unsigned start = 0;
if (!mixed)
{
m_miners.reserve(ins);
}
else
{
start = m_miners.size();
ins += start;
m_miners.reserve(ins);
}
for (unsigned i = start; i < ins; ++i)
{
m_miners.push_back(std::shared_ptr<Miner>(m_sealers[_sealer].create(std::make_pair(this, i))));
m_miners.back()->setWork(m_work);

13
libethcore/Miner.cpp

@ -0,0 +1,13 @@
#include "Miner.h"
#include "EthashAux.h"
using namespace dev;
using namespace eth;
template <>
unsigned dev::eth::GenericMiner<dev::eth::EthashProofOfWork>::s_dagLoadMode = 0;
template <>
unsigned dev::eth::GenericMiner<dev::eth::EthashProofOfWork>::s_dagLoadIndex = 0;

25
libethcore/Miner.h

@ -24,6 +24,7 @@
#include <thread>
#include <list>
#include <atomic>
#include <string>
#include <boost/timer.hpp>
#include <libdevcore/Common.h>
#include <libdevcore/Log.h>
@ -34,6 +35,20 @@
#define MINER_WAIT_STATE_WORK 1
#define MINER_WAIT_STATE_DAG 2
#define DAG_LOAD_MODE_PARALLEL 0
#define DAG_LOAD_MODE_SEQUENTIAL 1
using namespace std;
typedef struct {
string host;
string port;
string user;
string pass;
} cred_t;
namespace dev
{
@ -44,7 +59,8 @@ enum class MinerType
{
CPU,
CL,
CUDA
CUDA,
Mixed
};
struct MineInfo: public WorkingProgress {};
@ -91,6 +107,7 @@ inline std::ostream& operator<<(std::ostream& os, SolutionStats s)
template <class PoW> class GenericMiner;
/**
* @brief Class for hosting one or more Miners.
* @warning Must be implemented in a threadsafe manner since it will be called from multiple
@ -162,6 +179,7 @@ public:
protected:
// REQUIRED TO BE REIMPLEMENTED BY A SUBCLASS:
/**
@ -199,6 +217,8 @@ protected:
void accumulateHashes(unsigned _n) { m_hashCount += _n; }
static unsigned s_dagLoadMode;
static unsigned s_dagLoadIndex;
private:
FarmFace* m_farm = nullptr;
unsigned m_index;
@ -207,6 +227,9 @@ private:
WorkPackage m_work;
mutable Mutex x_work;
bool m_dagLoaded = false;
};
}

31
libstratum/EthStratumClient.cpp

@ -1,10 +1,10 @@
#include "EthStratumClient.h"
#include <libdevcore/Log.h>
using boost::asio::ip::tcp;
EthStratumClient::EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout, bool const & precompute)
EthStratumClient::EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout)
: m_socket(m_io_service)
{
m_minerType = m;
@ -17,7 +17,6 @@ EthStratumClient::EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType
m_authorized = false;
m_connected = false;
m_precompute = precompute;
m_pending = 0;
m_maxRetries = retries;
m_worktimeout = worktimeout;
@ -144,11 +143,15 @@ void EthStratumClient::connect_handler(const boost::system::error_code& ec, tcp:
{
cnote << "Starting farm";
if (m_minerType == MinerType::CPU)
p_farm->start("cpu");
p_farm->start("cpu", false);
else if (m_minerType == MinerType::CL)
p_farm->start("opencl");
p_farm->start("opencl", false);
else if (m_minerType == MinerType::CUDA)
p_farm->start("cuda");
p_farm->start("cuda", false);
else if (m_minerType == MinerType::Mixed) {
p_farm->start("cuda", false);
p_farm->start("opencl", true);
}
}
std::ostream os(&m_requestBuffer);
os << "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": []}\n";
@ -303,22 +306,6 @@ void EthStratumClient::processReponse(Json::Value& responseObject)
h256 seedHash = h256(sSeedHash);
h256 headerHash = h256(sHeaderHash);
EthashAux::FullType dag;
/*
if (seedHash != m_current.seedHash)
{
cnote << "Grabbing DAG for" << seedHash;
}
if (!(dag = EthashAux::full(seedHash, true, [&](unsigned _pc){ m_waitState = _pc < 100 ? MINER_WAIT_STATE_DAG : MINER_WAIT_STATE_WORK; cnote << "Creating DAG. " << _pc << "% done..."; return 0; })))
{
BOOST_THROW_EXCEPTION(DAGCreationFailure());
}
if (m_precompute)
{
EthashAux::computeFull(sha3(seedHash), true);
}
*/
if (headerHash != m_current.headerHash)
{

10
libstratum/EthStratumClient.h

@ -17,24 +17,18 @@ using boost::asio::ip::tcp;
using namespace dev;
using namespace dev::eth;
typedef struct {
string host;
string port;
string user;
string pass;
} cred_t;
class EthStratumClient
{
public:
EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout, bool const & precompute);
EthStratumClient(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout);
~EthStratumClient();
void setFailover(string const & host, string const & port);
void setFailover(string const & host, string const & port, string const & user, string const & pass);
bool isRunning() { return m_running; }
bool isConnected() { return m_connected; }
bool isConnected() { return m_connected && m_authorized; }
h256 currentHeaderHash() { return m_current.headerHash; }
bool current() { return m_current; }
unsigned waitState() { return m_waitState; }

336
libstratum/EthStratumClientV2.cpp

@ -0,0 +1,336 @@
#include "EthStratumClientV2.h"
#include <libdevcore/Log.h>
using boost::asio::ip::tcp;
EthStratumClientV2::EthStratumClientV2(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout)
: Worker("stratum"),
m_socket(m_io_service)
{
m_minerType = m;
m_primary.host = host;
m_primary.port = port;
m_primary.user = user;
m_primary.pass = pass;
p_active = &m_primary;
m_authorized = false;
m_connected = false;
m_maxRetries = retries;
m_worktimeout = worktimeout;
p_farm = f;
p_worktimer = nullptr;
startWorking();
}
EthStratumClientV2::~EthStratumClientV2()
{
}
void EthStratumClientV2::setFailover(string const & host, string const & port)
{
setFailover(host, port, p_active->user, p_active->pass);
}
void EthStratumClientV2::setFailover(string const & host, string const & port, string const & user, string const & pass)
{
m_failover.host = host;
m_failover.port = port;
m_failover.user = user;
m_failover.pass = pass;
}
void EthStratumClientV2::workLoop()
{
while (m_running)
{
try {
if (!m_connected)
{
//m_io_service.run();
//boost::thread t(boost::bind(&boost::asio::io_service::run, &m_io_service));
connect();
}
read_until(m_socket, m_responseBuffer, "\n");
std::istream is(&m_responseBuffer);
std::string response;
getline(is, response);
if (response.front() == '{' && response.back() == '}')
{
Json::Value responseObject;
Json::Reader reader;
if (reader.parse(response.c_str(), responseObject))
{
processReponse(responseObject);
m_response = response;
}
else
{
cwarn << "Parse response failed: " << reader.getFormattedErrorMessages();
}
}
else
{
cwarn << "Discarding incomplete response";
}
}
catch (std::exception const& _e) {
cwarn << _e.what();
reconnect();
}
}
}
void EthStratumClientV2::connect()
{
cnote << "Connecting to stratum server " << p_active->host + ":" + p_active->port;
tcp::resolver r(m_io_service);
tcp::resolver::query q(p_active->host, p_active->port);
tcp::resolver::iterator endpoint_iterator = r.resolve(q);
tcp::resolver::iterator end;
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
m_socket.close();
m_socket.connect(*endpoint_iterator++, error);
}
if (error)
{
cerr << "Could not connect to stratum server " << p_active->host + ":" + p_active->port + ", " << error.message();
reconnect();
}
else
{
cnote << "Connected!";
m_connected = true;
if (!p_farm->isMining())
{
cnote << "Starting farm";
if (m_minerType == MinerType::CPU)
p_farm->start("cpu", false);
else if (m_minerType == MinerType::CL)
p_farm->start("opencl", false);
else if (m_minerType == MinerType::CUDA)
p_farm->start("cuda", false);
else if (m_minerType == MinerType::Mixed) {
p_farm->start("cuda", false);
p_farm->start("opencl", true);
}
}
std::ostream os(&m_requestBuffer);
os << "{\"id\": 1, \"method\": \"mining.subscribe\", \"params\": []}\n";
write(m_socket, m_requestBuffer);
}
}
void EthStratumClientV2::reconnect()
{
if (p_worktimer) {
p_worktimer->cancel();
p_worktimer = nullptr;
}
//m_io_service.reset();
//m_socket.close(); // leads to crashes on Linux
m_authorized = false;
m_connected = false;
if (!m_failover.host.empty())
{
m_retries++;
if (m_retries > m_maxRetries)
{
if (m_failover.host == "exit") {
disconnect();
return;
}
else if (p_active == &m_primary)
{
p_active = &m_failover;
}
else {
p_active = &m_primary;
}
m_retries = 0;
}
}
cnote << "Reconnecting in 3 seconds...";
boost::asio::deadline_timer timer(m_io_service, boost::posix_time::seconds(3));
timer.wait();
}
void EthStratumClientV2::disconnect()
{
cnote << "Disconnecting";
m_connected = false;
m_running = false;
if (p_farm->isMining())
{
cnote << "Stopping farm";
p_farm->stop();
}
m_socket.close();
//m_io_service.stop();
}
void EthStratumClientV2::processReponse(Json::Value& responseObject)
{
Json::Value error = responseObject.get("error", new Json::Value);
if (error.isArray())
{
string msg = error.get(1, "Unknown error").asString();
cnote << msg;
}
std::ostream os(&m_requestBuffer);
Json::Value params;
int id = responseObject.get("id", Json::Value::null).asInt();
switch (id)
{
case 1:
cnote << "Subscribed to stratum server";
os << "{\"id\": 2, \"method\": \"mining.authorize\", \"params\": [\"" << p_active->user << "\",\"" << p_active->pass << "\"]}\n";
write(m_socket, m_requestBuffer);
break;
case 2:
m_authorized = responseObject.get("result", Json::Value::null).asBool();
if (!m_authorized)
{
cnote << "Worker not authorized:" << p_active->user;
disconnect();
return;
}
cnote << "Authorized worker " << p_active->user;
break;
case 4:
if (responseObject.get("result", false).asBool()) {
cnote << "B-) Submitted and accepted.";
p_farm->acceptedSolution(m_stale);
}
else {
cwarn << ":-( Not accepted.";
p_farm->rejectedSolution(m_stale);
}
break;
default:
string method = responseObject.get("method", "").asString();
if (method == "mining.notify")
{
params = responseObject.get("params", Json::Value::null);
if (params.isArray())
{
string job = params.get((Json::Value::ArrayIndex)0, "").asString();
string sHeaderHash = params.get((Json::Value::ArrayIndex)1, "").asString();
string sSeedHash = params.get((Json::Value::ArrayIndex)2, "").asString();
string sShareTarget = params.get((Json::Value::ArrayIndex)3, "").asString();
//bool cleanJobs = params.get((Json::Value::ArrayIndex)4, "").asBool();
// coinmine.pl fix
int l = sShareTarget.length();
if (l < 66)
sShareTarget = "0x" + string(66 - l, '0') + sShareTarget.substr(2);
if (sHeaderHash != "" && sSeedHash != "" && sShareTarget != "")
{
cnote << "Received new job #" + job.substr(0,8);
h256 seedHash = h256(sSeedHash);
h256 headerHash = h256(sHeaderHash);
if (headerHash != m_current.headerHash)
{
//x_current.lock();
//if (p_worktimer)
// p_worktimer->cancel();
m_previous.headerHash = m_current.headerHash;
m_previous.seedHash = m_current.seedHash;
m_previous.boundary = m_current.boundary;
m_previousJob = m_job;
m_current.headerHash = h256(sHeaderHash);
m_current.seedHash = seedHash;
m_current.boundary = h256(sShareTarget);
m_job = job;
p_farm->setWork(m_current);
//x_current.unlock();
//p_worktimer = new boost::asio::deadline_timer(m_io_service, boost::posix_time::seconds(m_worktimeout));
//p_worktimer->async_wait(boost::bind(&EthStratumClientV2::work_timeout_handler, this, boost::asio::placeholders::error));
}
}
}
}
else if (method == "mining.set_difficulty")
{
}
else if (method == "client.get_version")
{
os << "{\"error\": null, \"id\" : " << id << ", \"result\" : \"" << ETH_PROJECT_VERSION << "\"}\n";
write(m_socket, m_requestBuffer);
}
break;
}
}
void EthStratumClientV2::work_timeout_handler(const boost::system::error_code& ec) {
if (!ec) {
cnote << "No new work received in" << m_worktimeout << "seconds.";
reconnect();
}
}
bool EthStratumClientV2::submit(EthashProofOfWork::Solution solution) {
x_current.lock();
EthashProofOfWork::WorkPackage tempWork(m_current);
string temp_job = m_job;
EthashProofOfWork::WorkPackage tempPreviousWork(m_previous);
string temp_previous_job = m_previousJob;
x_current.unlock();
cnote << "Solution found; Submitting to" << p_active->host << "...";
cnote << " Nonce:" << "0x" + solution.nonce.hex();
if (EthashAux::eval(tempWork.seedHash, tempWork.headerHash, solution.nonce).value < tempWork.boundary)
{
string json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + p_active->user + "\",\"" + temp_job + "\",\"0x" + solution.nonce.hex() + "\",\"0x" + tempWork.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n";
std::ostream os(&m_requestBuffer);
os << json;
m_stale = false;
write(m_socket, m_requestBuffer);
return true;
}
else if (EthashAux::eval(tempPreviousWork.seedHash, tempPreviousWork.headerHash, solution.nonce).value < tempPreviousWork.boundary)
{
string json = "{\"id\": 4, \"method\": \"mining.submit\", \"params\": [\"" + p_active->user + "\",\"" + temp_previous_job + "\",\"0x" + solution.nonce.hex() + "\",\"0x" + tempPreviousWork.headerHash.hex() + "\",\"0x" + solution.mixHash.hex() + "\"]}\n";
std::ostream os(&m_requestBuffer);
os << json;
m_stale = true;
cwarn << "Submitting stale solution.";
write(m_socket, m_requestBuffer);
return true;
}
else {
m_stale = false;
cwarn << "FAILURE: GPU gave incorrect result!";
p_farm->failedSolution();
}
return false;
}

84
libstratum/EthStratumClientV2.h

@ -0,0 +1,84 @@
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <json/json.h>
#include <libdevcore/Log.h>
#include <libdevcore/FixedHash.h>
#include <libdevcore/Worker.h>
#include <libethcore/Farm.h>
#include <libethcore/EthashAux.h>
#include <libethcore/Miner.h>
#include "BuildInfo.h"
using namespace std;
using namespace boost::asio;
using boost::asio::ip::tcp;
using namespace dev;
using namespace dev::eth;
class EthStratumClientV2 : public Worker
{
public:
EthStratumClientV2(GenericFarm<EthashProofOfWork> * f, MinerType m, string const & host, string const & port, string const & user, string const & pass, int const & retries, int const & worktimeout);
~EthStratumClientV2();
void setFailover(string const & host, string const & port);
void setFailover(string const & host, string const & port, string const & user, string const & pass);
bool isRunning() { return m_running; }
bool isConnected() { return m_connected && m_authorized; }
h256 currentHeaderHash() { return m_current.headerHash; }
bool current() { return m_current; }
unsigned waitState() { return m_waitState; }
bool submit(EthashProofOfWork::Solution solution);
void reconnect();
private:
void workLoop() override;
void connect();
void disconnect();
void work_timeout_handler(const boost::system::error_code& ec);
void processReponse(Json::Value& responseObject);
MinerType m_minerType;
cred_t * p_active;
cred_t m_primary;
cred_t m_failover;
bool m_authorized;
bool m_connected;
bool m_running = true;
int m_retries = 0;
int m_maxRetries;
int m_worktimeout = 60;
int m_waitState = MINER_WAIT_STATE_WORK;
string m_response;
GenericFarm<EthashProofOfWork> * p_farm;
mutex x_current;
EthashProofOfWork::WorkPackage m_current;
EthashProofOfWork::WorkPackage m_previous;
bool m_stale = false;
string m_job;
string m_previousJob;
EthashAux::FullType m_dag;
boost::asio::io_service m_io_service;
tcp::socket m_socket;
boost::asio::streambuf m_requestBuffer;
boost::asio::streambuf m_responseBuffer;
boost::asio::deadline_timer * p_worktimer;
};

BIN
releases/ethminer-0.9.41-genoil-1.0.1.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.0.2.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.0.3.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.0.4b3.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.0.5.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.0.6.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.0.7.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.1.4.zip

Binary file not shown.

BIN
releases/ethminer-0.9.41-genoil-1.1.zip

Binary file not shown.
Loading…
Cancel
Save