From 32e7041def694245e41e6e651159861b7469e4f7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 3 Jul 2017 03:34:23 +0300 Subject: [PATCH] Fix possibility duplicate share for short donation intervals. --- src/net/JobResult.h | 13 ++++++ src/workers/DoubleWorker.cpp | 86 ++++++++++++++++++++++++++++-------- src/workers/DoubleWorker.h | 11 +++-- src/workers/SingleWorker.cpp | 33 ++++++++++++-- src/workers/SingleWorker.h | 3 ++ 5 files changed, 119 insertions(+), 27 deletions(-) diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 0279b8be4..9ced3cac8 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -29,6 +29,9 @@ #include +#include "Job.h" + + class JobResult { public: @@ -39,6 +42,16 @@ public: memcpy(this->result, result, sizeof(this->result)); } + + inline JobResult &operator=(const Job &job) { + memcpy(jobId, job.id(), sizeof(jobId)); + poolId = job.poolId(); + diff = job.diff(); + + return *this; + } + + char jobId[64]; int poolId; uint32_t diff; diff --git a/src/workers/DoubleWorker.cpp b/src/workers/DoubleWorker.cpp index 86dbd13db..1ce29760d 100644 --- a/src/workers/DoubleWorker.cpp +++ b/src/workers/DoubleWorker.cpp @@ -30,11 +30,33 @@ #include "workers/Workers.h" -DoubleWorker::DoubleWorker(Handle *handle) - : Worker(handle), - m_nonce1(0), - m_nonce2(0) +class DoubleWorker::State { +public: + inline State() : + nonce1(0), + nonce2(0) + {} + + Job job; + uint32_t nonce1; + uint32_t nonce2; + uint8_t blob[84 * 2]; +}; + + +DoubleWorker::DoubleWorker(Handle *handle) + : Worker(handle) +{ + m_state = new State(); + m_pausedState = new State(); +} + + +DoubleWorker::~DoubleWorker() +{ + delete m_state; + delete m_pausedState; } @@ -56,17 +78,17 @@ void DoubleWorker::start() } m_count += 2; - *Job::nonce(m_blob) = ++m_nonce1; - *Job::nonce(m_blob + m_job.size()) = ++m_nonce2; + *Job::nonce(m_state->blob) = ++m_state->nonce1; + *Job::nonce(m_state->blob + m_state->job.size()) = ++m_state->nonce2; - CryptoNight::hash(m_blob, m_job.size(), m_hash, m_ctx); + CryptoNight::hash(m_state->blob, m_state->job.size(), m_hash, m_ctx); - if (*reinterpret_cast(m_hash + 24) < m_job.target()) { - Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce1, m_hash, m_job.diff())); + if (*reinterpret_cast(m_hash + 24) < m_state->job.target()) { + Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce1, m_hash, m_state->job.diff())); } - if (*reinterpret_cast(m_hash + 32 + 24) < m_job.target()) { - Workers::submit(JobResult(m_job.poolId(), m_job.id(), m_nonce2, m_hash + 32, m_job.diff())); + if (*reinterpret_cast(m_hash + 32 + 24) < m_state->job.target()) { + Workers::submit(JobResult(m_state->job.poolId(), m_state->job.id(), m_state->nonce2, m_hash + 32, m_state->job.diff())); } std::this_thread::yield(); @@ -77,20 +99,46 @@ void DoubleWorker::start() } +bool DoubleWorker::resume(const Job &job) +{ + if (m_state->job.poolId() == -1 && job.poolId() >= 0 && memcmp(job.id(), m_pausedState->job.id(), 64) == 0) { + *m_state = *m_pausedState; + return true; + } + + return false; +} + + void DoubleWorker::consumeJob() { - m_job = Workers::job(); + Job job = Workers::job(); m_sequence = Workers::sequence(); - memcpy(m_blob, m_job.blob(), m_job.size()); - memcpy(m_blob + m_job.size(), m_job.blob(), m_job.size()); + save(job); - if (m_job.isNicehash()) { - m_nonce1 = (*Job::nonce(m_blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id); - m_nonce2 = (*Job::nonce(m_blob + m_job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads)); + if (resume(job)) { + return; + } + + m_state->job = std::move(job); + memcpy(m_state->blob, m_state->job.blob(), m_state->job.size()); + memcpy(m_state->blob + m_state->job.size(), m_state->job.blob(), m_state->job.size()); + + if (m_state->job.isNicehash()) { + m_state->nonce1 = (*Job::nonce(m_state->blob) & 0xff000000U) + (0xffffffU / (m_threads * 2) * m_id); + m_state->nonce2 = (*Job::nonce(m_state->blob + m_state->job.size()) & 0xff000000U) + (0xffffffU / (m_threads * 2) * (m_id + m_threads)); } else { - m_nonce1 = 0xffffffffU / (m_threads * 2) * m_id; - m_nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads); + m_state->nonce1 = 0xffffffffU / (m_threads * 2) * m_id; + m_state->nonce2 = 0xffffffffU / (m_threads * 2) * (m_id + m_threads); + } +} + + +void DoubleWorker::save(const Job &job) +{ + if (job.poolId() == -1 && m_state->job.poolId() >= 0) { + *m_pausedState = *m_state; } } diff --git a/src/workers/DoubleWorker.h b/src/workers/DoubleWorker.h index d062dac0c..711f4bd1c 100644 --- a/src/workers/DoubleWorker.h +++ b/src/workers/DoubleWorker.h @@ -38,17 +38,20 @@ class DoubleWorker : public Worker { public: DoubleWorker(Handle *handle); + ~DoubleWorker(); void start() override; private: + bool resume(const Job &job); void consumeJob(); + void save(const Job &job); + + class State; - Job m_job; - uint32_t m_nonce1; - uint32_t m_nonce2; uint8_t m_hash[64]; - uint8_t m_blob[84 * 2]; + State *m_state; + State *m_pausedState; }; diff --git a/src/workers/SingleWorker.cpp b/src/workers/SingleWorker.cpp index 68ff21b70..10931fb90 100644 --- a/src/workers/SingleWorker.cpp +++ b/src/workers/SingleWorker.cpp @@ -68,15 +68,32 @@ void SingleWorker::start() } +bool SingleWorker::resume(const Job &job) +{ + if (m_job.poolId() == -1 && job.poolId() >= 0 && memcmp(job.id(), m_paused.id(), 64) == 0) { + m_job = m_paused; + m_result = m_job; + m_result.nonce = *m_job.nonce(); + return true; + } + + return false; +} + void SingleWorker::consumeJob() { - m_job = Workers::job(); + Job job = Workers::job(); m_sequence = Workers::sequence(); - memcpy(m_result.jobId, m_job.id(), sizeof(m_result.jobId)); - m_result.poolId = m_job.poolId(); - m_result.diff = m_job.diff(); + save(job); + + if (resume(job)) { + return; + } + + m_job = std::move(job); + m_result = m_job; if (m_job.isNicehash()) { m_result.nonce = (*m_job.nonce() & 0xff000000U) + (0xffffffU / m_threads * m_id); @@ -85,3 +102,11 @@ void SingleWorker::consumeJob() m_result.nonce = 0xffffffffU / m_threads * m_id; } } + + +void SingleWorker::save(const Job &job) +{ + if (job.poolId() == -1 && m_job.poolId() >= 0) { + m_paused = m_job; + } +} diff --git a/src/workers/SingleWorker.h b/src/workers/SingleWorker.h index 6ba59468a..08ab1857e 100644 --- a/src/workers/SingleWorker.h +++ b/src/workers/SingleWorker.h @@ -41,9 +41,12 @@ public: void start() override; private: + bool resume(const Job &job); void consumeJob(); + void save(const Job &job); Job m_job; + Job m_paused; JobResult m_result; };