From 190eb95f226e4efd4f0b25b5d35f7ad9ed9a3939 Mon Sep 17 00:00:00 2001 From: Kevin Pan Date: Thu, 5 Jan 2017 10:03:19 +0800 Subject: [PATCH 1/2] improve format diff, O(n^2) -> O(n) --- src/Common.h | 17 +++++++++++++++++ src/StratumSession.cc | 26 ++++---------------------- test/TestCommon.cc | 13 +++++++++++++ 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/Common.h b/src/Common.h index b59ae0c4c..bac111b55 100644 --- a/src/Common.h +++ b/src/Common.h @@ -151,4 +151,21 @@ inline void BitsToDifficulty(uint32 bits, uint64 *difficulty) { *difficulty = (uint64)diff; } +// diff must be 2^N +inline uint64_t formatDifficulty(const uint64_t diff) { + // set UINT64_MAX/2 as maximum difficulty + if (diff >= UINT64_MAX / 2) { + return UINT64_MAX / 2; + } + + uint64_t newDiff = 1; + int i = 0; + while (newDiff < diff) { + newDiff = newDiff << 1; + i++; + } + assert(i <= 63); + return 1ULL << i; +} + #endif diff --git a/src/StratumSession.cc b/src/StratumSession.cc index 9d9de0aa8..2986fe0c2 100644 --- a/src/StratumSession.cc +++ b/src/StratumSession.cc @@ -480,27 +480,16 @@ void StratumSession::_handleRequest_AuthorizePassword(const string &password) { } } + d = formatDifficulty(d); + md = formatDifficulty(md); + // set min diff first if (md >= DiffController::kMinDiff_) { - // diff must be 2^N - double i = 1; - while ((uint64_t)exp2(i) < md) { - i++; - } - md = (uint64_t)exp2(i); - diffController_.setMinDiff(md); } // than set current diff if (d >= DiffController::kMinDiff_) { - // diff must be 2^N - double i = 1; - while ((uint64_t)exp2(i) < d) { - i++; - } - d = (uint64_t)exp2(i); - diffController_.resetCurDiff(d); } } @@ -584,14 +573,7 @@ void StratumSession::handleExMessage_AuthorizeAgentWorker(const int64_t workerId } void StratumSession::_handleRequest_SetDifficulty(uint64_t suggestDiff) { - // suggestDiff must be 2^N - double i = 1; - while ((uint64_t)exp2(i) < suggestDiff) { - i++; - } - suggestDiff = (uint64_t)exp2(i); - - diffController_.resetCurDiff(suggestDiff); + diffController_.resetCurDiff(formatDifficulty(suggestDiff)); } void StratumSession::handleRequest_SuggestTarget(const string &idStr, diff --git a/test/TestCommon.cc b/test/TestCommon.cc index 64e551004..c1b160b0b 100644 --- a/test/TestCommon.cc +++ b/test/TestCommon.cc @@ -284,3 +284,16 @@ TEST(Common, BitsToDifficulty) { ASSERT_EQ((uint64_t)(d * 10000.0), 163074209ull); } +TEST(Common, formatDifficulty) { + ASSERT_EQ(formatDifficulty(UINT64_MAX), UINT64_MAX/2); + ASSERT_EQ(formatDifficulty(UINT64_MAX/2), UINT64_MAX/2); + + // 2^32 = UINT32_MAX + 1 + ASSERT_EQ(formatDifficulty(UINT32_MAX), (uint64_t)UINT32_MAX + 1); + ASSERT_EQ(formatDifficulty((uint64_t)UINT32_MAX + 1), (uint64_t)UINT32_MAX + 1); + + ASSERT_EQ(formatDifficulty(0), 1); + ASSERT_EQ(formatDifficulty(1), 1); + ASSERT_EQ(formatDifficulty(2), 2); + ASSERT_EQ(formatDifficulty(3), 4); +} From e13ab5bad668afcff0947b3fb186104498b27803 Mon Sep 17 00:00:00 2001 From: Kevin Pan Date: Thu, 5 Jan 2017 10:49:37 +0800 Subject: [PATCH 2/2] fixed: UINT64_MAX / 2 is not equal to 2^63 --- src/Common.h | 7 ++++--- test/TestCommon.cc | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Common.h b/src/Common.h index bac111b55..dd88c3340 100644 --- a/src/Common.h +++ b/src/Common.h @@ -153,9 +153,10 @@ inline void BitsToDifficulty(uint32 bits, uint64 *difficulty) { // diff must be 2^N inline uint64_t formatDifficulty(const uint64_t diff) { - // set UINT64_MAX/2 as maximum difficulty - if (diff >= UINT64_MAX / 2) { - return UINT64_MAX / 2; + // set 2^63 as maximum difficulty, 2^63 = 9223372036854775808 + const uint64_t kMaxDiff = 9223372036854775808ull; + if (diff >= kMaxDiff) { + return kMaxDiff; } uint64_t newDiff = 1; diff --git a/test/TestCommon.cc b/test/TestCommon.cc index c1b160b0b..9e39ba009 100644 --- a/test/TestCommon.cc +++ b/test/TestCommon.cc @@ -285,8 +285,7 @@ TEST(Common, BitsToDifficulty) { } TEST(Common, formatDifficulty) { - ASSERT_EQ(formatDifficulty(UINT64_MAX), UINT64_MAX/2); - ASSERT_EQ(formatDifficulty(UINT64_MAX/2), UINT64_MAX/2); + ASSERT_EQ(formatDifficulty(UINT64_MAX), 9223372036854775808ull); // 2^32 = UINT32_MAX + 1 ASSERT_EQ(formatDifficulty(UINT32_MAX), (uint64_t)UINT32_MAX + 1);