From f6533856df242758797d247afd20aa4c997ee623 Mon Sep 17 00:00:00 2001 From: wowario Date: Mon, 21 Sep 2020 16:29:14 +0300 Subject: [PATCH 1/2] refactor diff --- src/checkpoints/checkpoints.cpp | 11 ++++ src/cryptonote_basic/difficulty.cpp | 71 ++++++++---------------- src/cryptonote_basic/difficulty.h | 11 ++-- src/cryptonote_core/blockchain.cpp | 83 +++++++++++++++-------------- 4 files changed, 80 insertions(+), 96 deletions(-) diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp index 57d6cc2b6..b6948c089 100644 --- a/src/checkpoints/checkpoints.cpp +++ b/src/checkpoints/checkpoints.cpp @@ -182,6 +182,17 @@ namespace cryptonote { if (nettype == TESTNET) { + ADD_CHECKPOINT2(1, "c47b8effcc84e22ddd1b876d059c8fbd3e26e4bdffb6bed8b8f4fe283104a7af", "0x2"); + ADD_CHECKPOINT2(5, "292add330f6cf5f3845dc4cd2f28ce8d211dd487ddcfe1b5d1d545d7b90ff7d1", "0x5df"); //Hard fork to v8 + ADD_CHECKPOINT2(10, "fbdf7d812aa6dd4c5915aadcbf023e722eab1d8ad47c24a230634e688d314798", "0xfa3"); //Hard fork to v9 + ADD_CHECKPOINT2(15, "9b86e40b959d7cfe75366686dfd2657699e85b8c658aa8c20b23f7bc01b38af0", "0x1967"); //Hard fork to v10 + ADD_CHECKPOINT2(20, "8f65c309ba3ed2bf25df2b7d91e1db40c864230aa3caaf823db81bc19e0bd6a3", "0x232b"); //Hard fork to v11 + ADD_CHECKPOINT2(25, "35f2957fdba45d5421561ba2f126a61ec0101b5c2eb79b9e296310acbbdbbe58", "0x2cef"); //Hard fork to v12 + ADD_CHECKPOINT2(30, "32cc5aacce8bea10ae869313e194ba51a30720810f3665433ffeea2818938429", "0x36b3"); //Hard fork to v13 + ADD_CHECKPOINT2(35, "7f1cdd2c4a6002772343ad9de6c5dba743a0be1d326a6f63924511f08b15863a", "0x4077"); //Hard fork to v14 + ADD_CHECKPOINT2(40, "63cf4f703489a881baf63bacd6a3af2b5bde79b558ce123e97313890be6f747f", "0x4a3b"); //Hard fork to v15 + ADD_CHECKPOINT2(45, "65da4c966ae02983c6c8b7ab9b959df612863c379c5e48669061cbbb1e02a3ab", "0x53ff"); //Hard fork to v16 + ADD_CHECKPOINT2(50, "8c68a444b6743a14152f130357be9751e42e82a84f69f25320eda532a830c7b0", "0x5dc3"); //Hard fork to v17 return true; } if (nettype == STAGENET) diff --git a/src/cryptonote_basic/difficulty.cpp b/src/cryptonote_basic/difficulty.cpp index 4189acb35..76d182369 100644 --- a/src/cryptonote_basic/difficulty.cpp +++ b/src/cryptonote_basic/difficulty.cpp @@ -201,20 +201,19 @@ namespace cryptonote { return check_hash_128(hash, difficulty); } - difficulty_type next_difficulty(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds) { + difficulty_type next_difficulty(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) { //cutoff DIFFICULTY_LAG if(timestamps.size() > DIFFICULTY_WINDOW) { timestamps.resize(DIFFICULTY_WINDOW); cumulative_difficulties.resize(DIFFICULTY_WINDOW); } - - size_t length = timestamps.size(); assert(length == cumulative_difficulties.size()); if (length <= 1) { return 1; } + if (HEIGHT < 200 && HEIGHT > 2 && m_nettype == TESTNET) { return 500; } static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small"); assert(length <= DIFFICULTY_WINDOW); sort(timestamps.begin(), timestamps.end()); @@ -258,18 +257,21 @@ namespace cryptonote { // LWMA difficulty algorithm // Background: https://github.com/zawy12/difficulty-algorithms/issues/3 // Copyright (c) 2017-2018 Zawy - difficulty_type next_difficulty_v2(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds) { + difficulty_type next_difficulty_v2(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) { const int64_t T = static_cast(target_seconds); size_t N = DIFFICULTY_WINDOW_V2; - if (timestamps.size() < 4) { - return 1; - } else if ( timestamps.size() < N+1 ) { - N = timestamps.size() - 1; - } else { - timestamps.resize(N+1); - cumulative_difficulties.resize(N+1); + if (m_nettype == MAINNET) { + if (timestamps.size() < 4) { + return 1; + } else if ( timestamps.size() < N+1 ) { + N = timestamps.size() - 1; + } else { + timestamps.resize(N+1); + cumulative_difficulties.resize(N+1); + } } + if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; } const double adjust = 0.998; const double k = N * (N + 1) / 2; double LWMA(0), sum_inverse_D(0), harmonic_mean_D(0), nextDifficulty(0); @@ -292,12 +294,13 @@ namespace cryptonote { } // LWMA-2 - difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties) { + difficulty_type next_difficulty_v3(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, uint64_t HEIGHT) { int64_t T = DIFFICULTY_TARGET_V2; int64_t N = DIFFICULTY_WINDOW_V2; int64_t L(0), ST, sum_3_ST(0), next_D, prev_D; assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= static_cast(N+1) ); + if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; } for ( int64_t i = 1; i <= N; i++ ) { ST = static_cast(timestamps[i]) - static_cast(timestamps[i-1]); ST = std::max(-4*T, std::min(ST, 6*T)); @@ -316,13 +319,14 @@ namespace cryptonote { } // LWMA-4 - difficulty_type next_difficulty_v4(std::vector timestamps, std::vector cumulative_difficulties, size_t height) { + difficulty_type next_difficulty_v4(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, uint64_t HEIGHT) { uint64_t T = DIFFICULTY_TARGET_V2; uint64_t N = DIFFICULTY_WINDOW_V2; uint64_t L(0), ST(0), next_D, prev_D, avg_D, i; assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 ); - if ( height <= 63469 + 1 ) { return 100000069; } + if (HEIGHT <= 63469 + 1 && m_nettype == MAINNET) { return 100000069; } + if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; } std::vectorTS(N+1); TS[0] = timestamps[0]; for ( i = 1; i <= N; i++) { @@ -364,44 +368,11 @@ namespace cryptonote { // LWMA-1 difficulty algorithm // Copyright (c) 2017-2019 Zawy, MIT License // https://github.com/zawy12/difficulty-algorithms/issues/3 - difficulty_type next_difficulty_v5(std::vector timestamps, std::vector cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT) { - assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 ); - - if (HEIGHT >= 81769 && HEIGHT < 81769 + N) { return 10000000; } - assert(timestamps.size() == N+1); - - uint64_t L(0), next_D, i, this_timestamp(0), previous_timestamp(0), avg_D; - - previous_timestamp = timestamps[0]-T; - for ( i = 1; i <= N; i++) { - // Safely prevent out-of-sequence timestamps - if ( timestamps[i] > previous_timestamp ) { this_timestamp = timestamps[i]; } - else { this_timestamp = previous_timestamp+1; } - L += i*std::min(6*T ,this_timestamp - previous_timestamp); - previous_timestamp = this_timestamp; - } - if (L < N*N*T/20 ) { L = N*N*T/20; } - avg_D = static_cast(( cumulative_difficulties[N] - cumulative_difficulties[0] )/ N); - - // Prevent round off error for small D and overflow for large D. - if (avg_D > 2000000*N*N*T) { - next_D = (avg_D/(200*L))*(N*(N+1)*T*99); - } - else { next_D = (avg_D*N*(N+1)*T*99)/(200*L); } - - // Make all insignificant digits zero for easy reading. - i = 1000000000; - while (i > 1) { - if ( next_D > i*100 ) { next_D = ((next_D+i/2)/i)*i; break; } - else { i /= 10; } - } - return next_D; - } - - difficulty_type next_difficulty_test(std::vector timestamps, std::vector cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT) { + difficulty_type next_difficulty_v5(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT) { assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 ); - if (HEIGHT < N) { return 100; } + if (HEIGHT >= 81769 && HEIGHT < 81769 + N && m_nettype == MAINNET) { return 10000000; } + if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; } assert(timestamps.size() == N+1); uint64_t L(0), next_D, i, this_timestamp(0), previous_timestamp(0), avg_D; diff --git a/src/cryptonote_basic/difficulty.h b/src/cryptonote_basic/difficulty.h index ddaae4610..d8d2612d5 100644 --- a/src/cryptonote_basic/difficulty.h +++ b/src/cryptonote_basic/difficulty.h @@ -57,12 +57,11 @@ namespace cryptonote bool check_hash_128(const crypto::hash &hash, difficulty_type difficulty); bool check_hash(const crypto::hash &hash, difficulty_type difficulty); - difficulty_type next_difficulty(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds); - difficulty_type next_difficulty_v2(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds); - difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties); - difficulty_type next_difficulty_v4(std::vector timestamps, std::vector cumulative_difficulties, size_t height); - difficulty_type next_difficulty_v5(std::vector timestamps, std::vector cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT); - difficulty_type next_difficulty_test(std::vector timestamps, std::vector cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT); + difficulty_type next_difficulty(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT); + difficulty_type next_difficulty_v2(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT); + difficulty_type next_difficulty_v3(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, uint64_t HEIGHT); + difficulty_type next_difficulty_v4(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, uint64_t HEIGHT); + difficulty_type next_difficulty_v5(std::vector timestamps, network_type m_nettype, std::vector cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT); std::string hex(difficulty_type v); } diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 93204b96c..384c30bbf 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -946,37 +946,31 @@ start: uint64_t N = DIFFICULTY_WINDOW_V3; uint64_t HEIGHT = m_db->height(); - difficulty_type diff = next_difficulty(timestamps, difficulties, target); - - if (m_nettype == MAINNET) { - if (version >= 11) { - diff = next_difficulty_v5(timestamps, difficulties, T, N, HEIGHT); - } else if (version == 10) { - diff = next_difficulty_v4(timestamps, difficulties, height); - } else if (version == 9) { - diff = next_difficulty_v3(timestamps, difficulties); - } else if (version == 8) { - diff = next_difficulty_v2(timestamps, difficulties, target); - } else { - diff = next_difficulty(timestamps, difficulties, target); - } - } - - if (m_nettype == TESTNET) { - diff = next_difficulty_test(timestamps, difficulties, T, N, HEIGHT); + difficulty_type diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT); + + if (version >= 11) { + diff = next_difficulty_v5(timestamps, m_nettype, difficulties, T, N, HEIGHT); + } else if (version == 10) { + diff = next_difficulty_v4(timestamps, m_nettype, difficulties, HEIGHT); + } else if (version == 9) { + diff = next_difficulty_v3(timestamps, m_nettype, difficulties, HEIGHT); + } else if (version == 8) { + diff = next_difficulty_v2(timestamps, m_nettype, difficulties, target, HEIGHT); + } else { + diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT); } CRITICAL_REGION_LOCAL1(m_difficulty_lock); m_difficulty_for_next_block_top_hash = top_hash; m_difficulty_for_next_block = diff; - if (D && D != diff) + if (D && D != diff && m_nettype == MAINNET) { ss << "XXX Mismatch at " << height << "/" << top_hash << "/" << get_tail_id() << ": cached " << D << ", real " << diff << std::endl; print = true; } ++done; - if (done == 1 && D && D != diff) + if (done == 1 && D && D != diff && m_nettype == MAINNET) { print = true; ss << "Might be a race. Let's see what happens if we try again..." << std::endl; @@ -984,12 +978,12 @@ start: goto start; } ss << "Diff for " << top_hash << ": " << diff << std::endl; - if (print) + if (print && m_nettype == MAINNET) { MGINFO("START DUMP"); MGINFO(ss.str()); MGINFO("END DUMP"); - MGINFO("Please send moneromooo on Freenode the contents of this log, from a couple dozen lines before START DUMP to END DUMP"); + MGINFO("Please send wowario on Freenode #wownero-dev the contents of this log, from a couple dozen lines before START DUMP to END DUMP"); } return diff; } @@ -1041,8 +1035,23 @@ size_t Blockchain::recalculate_difficulties(boost::optional start_heig std::vector new_cumulative_difficulties; for (uint64_t height = start_height; height <= top_height; ++height) { + uint64_t T = DIFFICULTY_TARGET_V2; + uint64_t N = DIFFICULTY_WINDOW_V3; + uint64_t HEIGHT = m_db->height(); size_t target = get_ideal_hard_fork_version(height) < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; - difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target); + difficulty_type recalculated_diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT); + + if (version >= 11) { + recalculated_diff = next_difficulty_v5(timestamps, m_nettype, difficulties, T, N, HEIGHT); + } else if (version == 10) { + recalculated_diff = next_difficulty_v4(timestamps, m_nettype, difficulties, HEIGHT); + } else if (version == 9) { + recalculated_diff = next_difficulty_v3(timestamps, m_nettype, difficulties, HEIGHT); + } else if (version == 8) { + recalculated_diff = next_difficulty_v2(timestamps, m_nettype, difficulties, target, HEIGHT); + } else { + recalculated_diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT); + } boost::multiprecision::uint256_t recalculated_cum_diff_256 = boost::multiprecision::uint256_t(recalculated_diff) + last_cum_diff; CHECK_AND_ASSERT_THROW_MES(recalculated_cum_diff_256 <= std::numeric_limits::max(), "Difficulty overflow!"); @@ -1346,24 +1355,18 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std: uint64_t HEIGHT = m_db->height(); // calculate the difficulty target for the block and return it - if (m_nettype == MAINNET) { - if (version >= 11) { - return next_difficulty_v5(timestamps, cumulative_difficulties, T, N, HEIGHT); - } else if (version == 10) { - return next_difficulty_v4(timestamps, cumulative_difficulties, height); - } else if (version == 9) { - return next_difficulty_v3(timestamps, cumulative_difficulties); - } else if (version == 8) { - return next_difficulty_v2(timestamps, cumulative_difficulties, target); - } else { - return next_difficulty(timestamps, cumulative_difficulties, target); - } - } - - if (m_nettype == TESTNET) { - return next_difficulty_test(timestamps, cumulative_difficulties, T, N, HEIGHT); + if (version >= 11) { + return next_difficulty_v5(timestamps, m_nettype, cumulative_difficulties, T, N, HEIGHT); + } else if (version == 10) { + return next_difficulty_v4(timestamps, m_nettype, cumulative_difficulties, HEIGHT); + } else if (version == 9) { + return next_difficulty_v3(timestamps, m_nettype, cumulative_difficulties, HEIGHT); + } else if (version == 8) { + return next_difficulty_v2(timestamps, m_nettype, cumulative_difficulties, target, HEIGHT); + } else { + return next_difficulty(timestamps, m_nettype, cumulative_difficulties, target, HEIGHT); } - return next_difficulty(timestamps, cumulative_difficulties, target); + return next_difficulty(timestamps, m_nettype, cumulative_difficulties, target, HEIGHT); } //------------------------------------------------------------------ // This function does a sanity check on basic things that all miner From 2a6d817ea1b548028da5f5a2bd303e22250ea454 Mon Sep 17 00:00:00 2001 From: wowario Date: Mon, 21 Sep 2020 23:47:19 +0300 Subject: [PATCH 2/2] declare version --- src/cryptonote_core/blockchain.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 384c30bbf..92f58c19e 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1035,6 +1035,7 @@ size_t Blockchain::recalculate_difficulties(boost::optional start_heig std::vector new_cumulative_difficulties; for (uint64_t height = start_height; height <= top_height; ++height) { + uint8_t version = get_current_hard_fork_version(); uint64_t T = DIFFICULTY_TARGET_V2; uint64_t N = DIFFICULTY_WINDOW_V3; uint64_t HEIGHT = m_db->height();