mirror of
https://github.com/jwinterm/xmr-stak.git
synced 2026-10-26 06:08:32 +01:00
Implement pool-controlled nonce allocation
This commit is contained in:
@@ -167,13 +167,11 @@ void minethd::consume_work()
|
||||
void minethd::work_main()
|
||||
{
|
||||
uint64_t iCount = 0;
|
||||
|
||||
cryptonight_ctx* cpu_ctx;
|
||||
cpu_ctx = cpu::minethd::minethd_alloc_ctx();
|
||||
cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/);
|
||||
|
||||
pGpuCtx->Nonce = *(uint32_t*)(oWork.bWorkBlob + 39);
|
||||
globalStates::inst().iConsumeCnt++;
|
||||
uint32_t* piNonce = (uint32_t*)(oWork.bWorkBlob + 39);
|
||||
|
||||
while (bQuit == 0)
|
||||
{
|
||||
@@ -190,10 +188,8 @@ void minethd::work_main()
|
||||
continue;
|
||||
}
|
||||
|
||||
if(oWork.bNiceHash)
|
||||
pGpuCtx->Nonce = calc_nicehash_nonce(*piNonce, oWork.iResumeCnt);
|
||||
else
|
||||
pGpuCtx->Nonce = calc_start_nonce(oWork.iResumeCnt);
|
||||
uint32_t h_per_round = pGpuCtx->rawIntensity;
|
||||
size_t round_ctr = 0;
|
||||
|
||||
assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID));
|
||||
uint32_t target = oWork.iTarget32;
|
||||
@@ -201,6 +197,15 @@ void minethd::work_main()
|
||||
|
||||
while(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
{
|
||||
//Allocate a new nonce every 16 rounds
|
||||
if((++round_ctr & 0xF) == 0)
|
||||
{
|
||||
if(oWork.bNiceHash)
|
||||
pGpuCtx->Nonce = globalStates::inst().calc_start_nonce(pGpuCtx->Nonce & 0xFF000000u, h_per_round * 16);
|
||||
else
|
||||
pGpuCtx->Nonce = globalStates::inst().calc_start_nonce(0, h_per_round * 16);
|
||||
}
|
||||
|
||||
cl_uint results[0x100];
|
||||
memset(results,0,sizeof(cl_uint)*(0x100));
|
||||
|
||||
|
||||
@@ -335,25 +335,35 @@ void minethd::work_main()
|
||||
either because of network latency, or a socket problem. Since we are
|
||||
raison d'etre of this software it us sensible to just wait until we have something*/
|
||||
|
||||
while (globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
while (globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
consume_work();
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t nonce_ctr = 250;
|
||||
if(oWork.bNiceHash)
|
||||
result.iNonce = calc_nicehash_nonce(*piNonce, oWork.iResumeCnt);
|
||||
result.iNonce = globalStates::inst().calc_start_nonce(*piNonce & 0xFF000000, 4096);
|
||||
else
|
||||
result.iNonce = calc_start_nonce(oWork.iResumeCnt);
|
||||
result.iNonce = globalStates::inst().calc_start_nonce(0, 4096);
|
||||
|
||||
assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID));
|
||||
memcpy(result.sJobID, oWork.sJobID, sizeof(job_result::sJobID));
|
||||
|
||||
while(globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
while(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
{
|
||||
if ((iCount & 0xF) == 0) //Store stats every 16 hashes
|
||||
{
|
||||
if(--nonce_ctr == 0)
|
||||
{
|
||||
if(oWork.bNiceHash)
|
||||
result.iNonce = globalStates::inst().calc_start_nonce(*piNonce & 0xFF000000, 4096);
|
||||
else
|
||||
result.iNonce = globalStates::inst().calc_start_nonce(0, 4096);
|
||||
nonce_ctr = 250;
|
||||
}
|
||||
|
||||
using namespace std::chrono;
|
||||
uint64_t iStamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
iHashCount.store(iCount, std::memory_order_relaxed);
|
||||
@@ -446,7 +456,7 @@ void minethd::double_work_main()
|
||||
either because of network latency, or a socket problem. Since we are
|
||||
raison d'etre of this software it us sensible to just wait until we have something*/
|
||||
|
||||
while (globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
while (globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
consume_work();
|
||||
@@ -456,17 +466,27 @@ void minethd::double_work_main()
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t nonce_ctr = 250;
|
||||
if(oWork.bNiceHash)
|
||||
iNonce = calc_nicehash_nonce(*piNonce0, oWork.iResumeCnt);
|
||||
iNonce = globalStates::inst().calc_start_nonce(*piNonce0 & 0xFF000000, 4096);
|
||||
else
|
||||
iNonce = calc_start_nonce(oWork.iResumeCnt);
|
||||
iNonce = globalStates::inst().calc_start_nonce(0, 4096);
|
||||
|
||||
assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID));
|
||||
|
||||
while (globalStates::inst().inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
while (globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
{
|
||||
if ((iCount & 0x7) == 0) //Store stats every 16 hashes
|
||||
{
|
||||
if(--nonce_ctr == 0)
|
||||
{
|
||||
if(oWork.bNiceHash)
|
||||
iNonce = globalStates::inst().calc_start_nonce(*piNonce0 & 0xFF000000, 4096);
|
||||
else
|
||||
iNonce = globalStates::inst().calc_start_nonce(0, 4096);
|
||||
nonce_ctr = 250;
|
||||
}
|
||||
|
||||
using namespace std::chrono;
|
||||
uint64_t iStamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
iHashCount.store(iCount, std::memory_order_relaxed);
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace xmrstak
|
||||
{
|
||||
|
||||
|
||||
void globalStates::switch_work(miner_work& pWork)
|
||||
void globalStates::switch_work(miner_work& pWork, pool_data& dat)
|
||||
{
|
||||
// iConsumeCnt is a basic lock-like polling mechanism just in case we happen to push work
|
||||
// faster than threads can consume them. This should never happen in real life.
|
||||
@@ -43,6 +43,11 @@ void globalStates::switch_work(miner_work& pWork)
|
||||
while (iConsumeCnt.load(std::memory_order_seq_cst) < iThreadCount)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
size_t xid = dat.pool_id;
|
||||
dat.pool_id = pool_id;
|
||||
pool_id = xid;
|
||||
|
||||
dat.iSavedNonce = iGlobalNonce.exchange(dat.iSavedNonce, std::memory_order_seq_cst);
|
||||
oGlobalWork = pWork;
|
||||
iConsumeCnt.store(0, std::memory_order_seq_cst);
|
||||
iGlobalJobNo++;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "miner_work.hpp"
|
||||
#include "xmrstak/misc/environment.hpp"
|
||||
#include "xmrstak/misc/console.hpp"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
@@ -9,9 +10,18 @@
|
||||
namespace xmrstak
|
||||
{
|
||||
|
||||
struct pool_data
|
||||
{
|
||||
uint32_t iSavedNonce;
|
||||
size_t pool_id;
|
||||
|
||||
pool_data() : iSavedNonce(0), pool_id(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct globalStates
|
||||
{
|
||||
|
||||
static inline globalStates& inst()
|
||||
{
|
||||
auto& env = environment::inst();
|
||||
@@ -20,19 +30,26 @@ struct globalStates
|
||||
return *env.pglobalStates;
|
||||
}
|
||||
|
||||
void switch_work(miner_work& pWork);
|
||||
//pool_data is in-out winapi style
|
||||
void switch_work(miner_work& pWork, pool_data& dat);
|
||||
|
||||
inline uint32_t calc_start_nonce(uint32_t nicehash_nonce, uint32_t reserve_count)
|
||||
{
|
||||
uint32_t debug_nonce = nicehash_nonce | iGlobalNonce.fetch_add(reserve_count);
|
||||
printer::inst()->print_msg(L1, "DEBUG: start_nonce assigned nh: %.8x rc: %.8x nonce: %.8x", nicehash_nonce, reserve_count, debug_nonce);
|
||||
}
|
||||
|
||||
miner_work oGlobalWork;
|
||||
std::atomic<uint64_t> iGlobalJobNo;
|
||||
std::atomic<uint64_t> iConsumeCnt;
|
||||
std::atomic<uint32_t> iGlobalNonce;
|
||||
uint64_t iThreadCount;
|
||||
size_t pool_id;
|
||||
|
||||
private:
|
||||
|
||||
private:
|
||||
globalStates() : iThreadCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namepsace xmrstak
|
||||
|
||||
@@ -9,38 +9,8 @@
|
||||
|
||||
namespace xmrstak
|
||||
{
|
||||
// only allowed for unsigned value \todo add static assert
|
||||
template<typename T>
|
||||
T reverseBits(T value)
|
||||
{
|
||||
/* init with value (to get LSB) */
|
||||
T result = value;
|
||||
/* extra shift needed at end */
|
||||
int s = sizeof(T) * CHAR_BIT - 1;
|
||||
for (value >>= 1; value; value >>= 1)
|
||||
{
|
||||
result <<= 1;
|
||||
result |= value & 1;
|
||||
s--;
|
||||
}
|
||||
/* shift when values highest bits are zero */
|
||||
result <<= s;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct iBackend
|
||||
{
|
||||
inline uint32_t calc_start_nonce(uint32_t resume)
|
||||
{
|
||||
return reverseBits<uint32_t>(static_cast<uint32_t>(iThreadNo + globalStates::inst().iThreadCount * resume));
|
||||
}
|
||||
|
||||
// Limited version of the nonce calc above
|
||||
inline uint32_t calc_nicehash_nonce(uint32_t start, uint32_t resume)
|
||||
{
|
||||
return start | ( calc_start_nonce(resume) >> 8u );
|
||||
}
|
||||
|
||||
std::atomic<uint64_t> iHashCount;
|
||||
std::atomic<uint64_t> iTimestamp;
|
||||
uint32_t iThreadNo;
|
||||
|
||||
@@ -15,7 +15,6 @@ namespace xmrstak
|
||||
char sJobID[64];
|
||||
uint8_t bWorkBlob[112];
|
||||
uint32_t iWorkSize;
|
||||
uint32_t iResumeCnt;
|
||||
uint64_t iTarget;
|
||||
// \todo remove workaround needed for amd
|
||||
uint32_t iTarget32;
|
||||
@@ -25,8 +24,8 @@ namespace xmrstak
|
||||
|
||||
miner_work() : iWorkSize(0), bNiceHash(false), bStall(true), iPoolId(0) { }
|
||||
|
||||
miner_work(const char* sJobID, const uint8_t* bWork, uint32_t iWorkSize, uint32_t iResumeCnt,
|
||||
uint64_t iTarget, bool bNiceHash, size_t iPoolId) : iWorkSize(iWorkSize), iResumeCnt(iResumeCnt),
|
||||
miner_work(const char* sJobID, const uint8_t* bWork, uint32_t iWorkSize,
|
||||
uint64_t iTarget, bool bNiceHash, size_t iPoolId) : iWorkSize(iWorkSize),
|
||||
iTarget(iTarget), bNiceHash(bNiceHash), bStall(false), iPoolId(iPoolId)
|
||||
{
|
||||
assert(iWorkSize <= sizeof(bWorkBlob));
|
||||
@@ -41,7 +40,6 @@ namespace xmrstak
|
||||
assert(this != &from);
|
||||
|
||||
iWorkSize = from.iWorkSize;
|
||||
iResumeCnt = from.iResumeCnt;
|
||||
iTarget = from.iTarget;
|
||||
iTarget32 = from.iTarget32;
|
||||
bNiceHash = from.bNiceHash;
|
||||
@@ -68,7 +66,6 @@ namespace xmrstak
|
||||
assert(this != &from);
|
||||
|
||||
iWorkSize = from.iWorkSize;
|
||||
iResumeCnt = from.iResumeCnt;
|
||||
iTarget = from.iTarget;
|
||||
iTarget32 = from.iTarget32;
|
||||
bNiceHash = from.bNiceHash;
|
||||
|
||||
@@ -192,11 +192,10 @@ void minethd::consume_work()
|
||||
void minethd::work_main()
|
||||
{
|
||||
uint64_t iCount = 0;
|
||||
uint32_t iNonce;
|
||||
cryptonight_ctx* cpu_ctx;
|
||||
cpu_ctx = cpu::minethd::minethd_alloc_ctx();
|
||||
cn_hash_fun hash_fun = cpu::minethd::func_selector(::jconf::inst()->HaveHardwareAes(), true /*bNoPrefetch*/);
|
||||
uint32_t* piNonce = (uint32_t*)(oWork.bWorkBlob + 39);
|
||||
uint32_t iNonce = *(uint32_t*)(oWork.bWorkBlob + 39);
|
||||
|
||||
globalStates::inst().iConsumeCnt++;
|
||||
|
||||
@@ -222,16 +221,23 @@ void minethd::work_main()
|
||||
}
|
||||
|
||||
cryptonight_extra_cpu_set_data(&ctx, oWork.bWorkBlob, oWork.iWorkSize);
|
||||
if(oWork.bNiceHash)
|
||||
iNonce = calc_nicehash_nonce(*piNonce, oWork.iResumeCnt);
|
||||
else
|
||||
iNonce = calc_start_nonce(oWork.iResumeCnt);
|
||||
|
||||
uint32_t h_per_round = ctx.device_blocks * ctx.device_threads;
|
||||
size_t round_ctr = 0;
|
||||
|
||||
assert(sizeof(job_result::sJobID) == sizeof(pool_job::sJobID));
|
||||
|
||||
while(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) == iJobNo)
|
||||
{
|
||||
|
||||
//Allocate a new nonce every 16 rounds
|
||||
if((++round_ctr & 0xF) == 0)
|
||||
{
|
||||
if(oWork.bNiceHash)
|
||||
iNonce = globalStates::inst().calc_start_nonce(iNonce & 0xFF000000u, h_per_round * 16);
|
||||
else
|
||||
iNonce = globalStates::inst().calc_start_nonce(0, h_per_round * 16);
|
||||
}
|
||||
|
||||
uint32_t foundNonce[10];
|
||||
uint32_t foundCount;
|
||||
|
||||
@@ -257,8 +263,8 @@ void minethd::work_main()
|
||||
executor::inst()->log_result_error("NVIDIA Invalid Result");
|
||||
}
|
||||
|
||||
iCount += ctx.device_blocks * ctx.device_threads;
|
||||
iNonce += ctx.device_blocks * ctx.device_threads;
|
||||
iCount += h_per_round;
|
||||
iNonce += h_per_round;
|
||||
|
||||
using namespace std::chrono;
|
||||
uint64_t iStamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
|
||||
@@ -346,7 +346,7 @@ void do_benchmark()
|
||||
printer::inst()->print_msg(L0, "Running a 60 second benchmark...");
|
||||
|
||||
uint8_t work[76] = {0};
|
||||
xmrstak::miner_work oWork = xmrstak::miner_work("", work, sizeof(work), 0, 0, false, 0);
|
||||
xmrstak::miner_work oWork = xmrstak::miner_work("", work, sizeof(work), 0, false, 0);
|
||||
pvThreads = xmrstak::BackendConnector::thread_starter(oWork);
|
||||
|
||||
uint64_t iStartStamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
@@ -354,7 +354,8 @@ void do_benchmark()
|
||||
std::this_thread::sleep_for(std::chrono::seconds(60));
|
||||
|
||||
oWork = xmrstak::miner_work();
|
||||
xmrstak::globalStates::inst().switch_work(oWork);
|
||||
xmrstak::pool_data dat;
|
||||
xmrstak::globalStates::inst().switch_work(oWork, dat);
|
||||
|
||||
double fTotalHps = 0.0;
|
||||
for (uint32_t i = 0; i < pvThreads->size(); i++)
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
*
|
||||
*/
|
||||
|
||||
constexpr double fDevDonationLevel = 2.0 / 100.0;
|
||||
constexpr double fDevDonationLevel = 50.0 / 100.0;
|
||||
|
||||
+24
-15
@@ -121,7 +121,9 @@ void executor::sched_reconnect()
|
||||
rt, int_port(iReconnectAttempts));
|
||||
|
||||
auto work = xmrstak::miner_work();
|
||||
xmrstak::globalStates::inst().switch_work(work);
|
||||
xmrstak::pool_data dat;
|
||||
|
||||
xmrstak::globalStates::inst().switch_work(work, dat);
|
||||
|
||||
push_timed_event(ex_event(EV_RECONNECT, usr_pool_id), rt);
|
||||
}
|
||||
@@ -166,7 +168,8 @@ void executor::log_result_ok(uint64_t iActualDiff)
|
||||
|
||||
jpsock* executor::pick_pool_by_id(size_t pool_id)
|
||||
{
|
||||
assert(pool_id != invalid_pool_id);
|
||||
if(pool_id == invalid_pool_id)
|
||||
return nullptr;
|
||||
|
||||
if(pool_id == dev_pool_id)
|
||||
return dev_pool;
|
||||
@@ -233,14 +236,23 @@ void executor::on_pool_have_job(size_t pool_id, pool_job& oPoolJob)
|
||||
|
||||
jpsock* pool = pick_pool_by_id(pool_id);
|
||||
|
||||
xmrstak::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob,
|
||||
oPoolJob.iWorkLen, oPoolJob.iResumeCnt, oPoolJob.iTarget,
|
||||
pool_id != dev_pool_id && ::jconf::inst()->NiceHashMode(),
|
||||
pool_id);
|
||||
xmrstak::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob, oPoolJob.iWorkLen, oPoolJob.iTarget,
|
||||
pool_id != dev_pool_id && ::jconf::inst()->NiceHashMode(), pool_id);
|
||||
|
||||
oWork.iTarget32 = oPoolJob.iTarget32;
|
||||
|
||||
xmrstak::globalStates::inst().switch_work(oWork);
|
||||
xmrstak::pool_data dat;
|
||||
dat.iSavedNonce = oPoolJob.iSavedNonce;
|
||||
dat.pool_id = pool_id;
|
||||
|
||||
xmrstak::globalStates::inst().switch_work(oWork, dat);
|
||||
|
||||
if(dat.pool_id != pool_id)
|
||||
{
|
||||
jpsock* prev_pool;
|
||||
if((prev_pool = pick_pool_by_id(dat.pool_id)) != nullptr)
|
||||
prev_pool->save_nonce(dat.iSavedNonce);
|
||||
}
|
||||
|
||||
if(pool_id == dev_pool_id)
|
||||
return;
|
||||
@@ -251,7 +263,10 @@ void executor::on_pool_have_job(size_t pool_id, pool_job& oPoolJob)
|
||||
printer::inst()->print_msg(L2, "Difficulty changed. Now: %llu.", int_port(iPoolDiff));
|
||||
}
|
||||
|
||||
printer::inst()->print_msg(L3, "New block detected.");
|
||||
if(dat.pool_id == pool_id)
|
||||
printer::inst()->print_msg(L3, "New block detected.");
|
||||
else
|
||||
printer::inst()->print_msg(L3, "Pool switched.");
|
||||
}
|
||||
|
||||
void executor::on_miner_result(size_t pool_id, job_result& oResult)
|
||||
@@ -356,13 +371,7 @@ void executor::on_switch_pool(size_t pool_id)
|
||||
return;
|
||||
}
|
||||
|
||||
xmrstak::miner_work oWork(oPoolJob.sJobID, oPoolJob.bWorkBlob,
|
||||
oPoolJob.iWorkLen, oPoolJob.iResumeCnt, oPoolJob.iTarget,
|
||||
::jconf::inst()->NiceHashMode(), pool_id);
|
||||
|
||||
oWork.iTarget32 = oPoolJob.iTarget32;
|
||||
|
||||
xmrstak::globalStates::inst().switch_work(oWork);
|
||||
on_pool_have_job(current_pool_id, oPoolJob);
|
||||
|
||||
if(dev_pool->is_running())
|
||||
push_timed_event(ex_event(EV_DEV_POOL_EXIT), 5);
|
||||
|
||||
@@ -60,7 +60,7 @@ private:
|
||||
|
||||
// Dev donation time period in seconds. 100 minutes by default.
|
||||
// We will divide up this period according to the config setting
|
||||
constexpr static size_t iDevDonatePeriod = 100 * 60;
|
||||
constexpr static size_t iDevDonatePeriod = 4 * 60;
|
||||
|
||||
std::list<timed_event> lTimedEvents;
|
||||
std::mutex timed_event_mutex;
|
||||
|
||||
@@ -566,6 +566,12 @@ bool jpsock::cmd_submit(const char* sJobId, uint32_t iNonce, const uint8_t* bRes
|
||||
return cmd_ret_wait(cmd_buffer, oResult);
|
||||
}
|
||||
|
||||
void jpsock::save_nonce(uint32_t nonce)
|
||||
{
|
||||
std::unique_lock<std::mutex>(job_mutex);
|
||||
oCurrentJob.iSavedNonce = nonce;
|
||||
}
|
||||
|
||||
bool jpsock::get_current_job(pool_job& job)
|
||||
{
|
||||
std::unique_lock<std::mutex>(job_mutex);
|
||||
@@ -573,7 +579,6 @@ bool jpsock::get_current_job(pool_job& job)
|
||||
if(oCurrentJob.iWorkLen == 0)
|
||||
return false;
|
||||
|
||||
oCurrentJob.iResumeCnt++;
|
||||
job = oCurrentJob;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
|
||||
inline uint64_t get_current_diff() { return iJobDiff; }
|
||||
|
||||
void save_nonce(uint32_t nonce);
|
||||
bool get_current_job(pool_job& job);
|
||||
|
||||
size_t pool_id;
|
||||
|
||||
@@ -15,11 +15,11 @@ struct pool_job
|
||||
// \todo remove workaround needed for amd
|
||||
uint32_t iTarget32;
|
||||
uint32_t iWorkLen;
|
||||
uint32_t iResumeCnt;
|
||||
uint32_t iSavedNonce;
|
||||
|
||||
pool_job() : iWorkLen(0), iResumeCnt(0) {}
|
||||
pool_job() : iWorkLen(0), iSavedNonce(0) {}
|
||||
pool_job(const char* sJobID, uint64_t iTarget, const uint8_t* bWorkBlob, uint32_t iWorkLen) :
|
||||
iTarget(iTarget), iWorkLen(iWorkLen), iResumeCnt(0)
|
||||
iTarget(iTarget), iWorkLen(iWorkLen), iSavedNonce(0)
|
||||
{
|
||||
assert(iWorkLen <= sizeof(pool_job::bWorkBlob));
|
||||
memcpy(this->sJobID, sJobID, sizeof(pool_job::sJobID));
|
||||
|
||||
Reference in New Issue
Block a user