From 0c80b03d764c81524c6145b4ebb837c795f563fe Mon Sep 17 00:00:00 2001 From: wowario Date: Sun, 15 Jan 2023 20:20:36 +0300 Subject: [PATCH] Diff algo v6 --- src/cryptonote_basic/difficulty.cpp | 54 ++++++++++++++++++++++++----- src/cryptonote_basic/difficulty.h | 1 + src/cryptonote_config.h | 3 ++ src/cryptonote_core/blockchain.cpp | 18 ++++++---- 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/cryptonote_basic/difficulty.cpp b/src/cryptonote_basic/difficulty.cpp index b5913dc27..fa4f3eff9 100644 --- a/src/cryptonote_basic/difficulty.cpp +++ b/src/cryptonote_basic/difficulty.cpp @@ -122,10 +122,10 @@ namespace cryptonote { uint64_t next_difficulty_64(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds) { - if(timestamps.size() > DIFFICULTY_WINDOW) + if(timestamps.size() > DIFFICULTY_WINDOW_V3) { - timestamps.resize(DIFFICULTY_WINDOW); - cumulative_difficulties.resize(DIFFICULTY_WINDOW); + timestamps.resize(DIFFICULTY_WINDOW_V3); + cumulative_difficulties.resize(DIFFICULTY_WINDOW_V3); } @@ -134,17 +134,17 @@ namespace cryptonote { if (length <= 1) { return 1; } - static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small"); - assert(length <= DIFFICULTY_WINDOW); + static_assert(DIFFICULTY_WINDOW_V3 >= 2, "Window is too small"); + assert(length <= DIFFICULTY_WINDOW_V3); sort(timestamps.begin(), timestamps.end()); size_t cut_begin, cut_end; - static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large"); - if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) { + static_assert(2 * DIFFICULTY_CUT_V2 <= DIFFICULTY_WINDOW_V3 - 2, "Cut length is too large"); + if (length <= DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) { cut_begin = 0; cut_end = length; } else { - cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2; - cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT); + cut_begin = (length - (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) + 1) / 2; + cut_end = cut_begin + (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2); } assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length); uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin]; @@ -409,4 +409,40 @@ namespace cryptonote { } return next_D; } + + difficulty_type next_difficulty_v6(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds) { + if(timestamps.size() > DIFFICULTY_WINDOW_V3) + { + timestamps.resize(DIFFICULTY_WINDOW_V3); + cumulative_difficulties.resize(DIFFICULTY_WINDOW_V3); + } + size_t length = timestamps.size(); + assert(length == cumulative_difficulties.size()); + if (length <= 1) { + return 1; + } + static_assert(DIFFICULTY_WINDOW_V3 >= 2, "Window is too small"); + assert(length <= DIFFICULTY_WINDOW_V3); + sort(timestamps.begin(), timestamps.end()); + size_t cut_begin, cut_end; + static_assert(2 * DIFFICULTY_CUT_V2 <= DIFFICULTY_WINDOW_V3 - 2, "Cut length is too large"); + if (length <= DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) { + cut_begin = 0; + cut_end = length; + } else { + cut_begin = (length - (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) + 1) / 2; + cut_end = cut_begin + (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2); + } + assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length); + uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin]; + if (time_span == 0) { + time_span = 1; + } + difficulty_type total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin]; + assert(total_work > 0); + boost::multiprecision::uint256_t res = (boost::multiprecision::uint256_t(total_work) * target_seconds + time_span - 1) / time_span; + if(res > max128bit) + return 0; // to behave like previous implementation, may be better return max128bit? + return res.convert_to(); + } } diff --git a/src/cryptonote_basic/difficulty.h b/src/cryptonote_basic/difficulty.h index 3a4edb5e6..c315bb2f8 100644 --- a/src/cryptonote_basic/difficulty.h +++ b/src/cryptonote_basic/difficulty.h @@ -62,6 +62,7 @@ namespace cryptonote difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT); difficulty_type next_difficulty_v4(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT); difficulty_type next_difficulty_v5(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT); + difficulty_type next_difficulty_v6(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds); std::string hex(difficulty_type v); } diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index d80d1d19f..551bba288 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -85,8 +85,11 @@ #define DIFFICULTY_WINDOW_V3 144 #define DIFFICULTY_WINDOW_V2 60 #define DIFFICULTY_WINDOW 720 // blocks +#define DIFFICULTY_LAG_V2 3 #define DIFFICULTY_LAG 15 // !!! +#define DIFFICULTY_CUT_V2 12 #define DIFFICULTY_CUT 60 // timestamps to cut after sorting +#define DIFFICULTY_BLOCKS_COUNT_V4 DIFFICULTY_WINDOW_V3 + DIFFICULTY_LAG_V2 #define DIFFICULTY_BLOCKS_COUNT_V3 DIFFICULTY_WINDOW_V3 + 1 // added +1 to make N=N #define DIFFICULTY_BLOCKS_COUNT_V2 DIFFICULTY_WINDOW_V2 + 1 // added +1 to make N=N #define DIFFICULTY_BLOCKS_COUNT DIFFICULTY_WINDOW + DIFFICULTY_LAG diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index cc8bb5d26..ab9777fa2 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -874,7 +874,7 @@ start: ss << "Re-locked, height " << height << ", tail id " << new_top_hash << (new_top_hash == top_hash ? "" : " (different)") << std::endl; top_hash = new_top_hash; uint8_t version = get_current_hard_fork_version(); - uint64_t difficulty_blocks_count = version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT; + uint64_t difficulty_blocks_count = version >= 20 ? DIFFICULTY_BLOCKS_COUNT_V4 : version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT; // ND: Speedup // 1. Keep a list of the last 735 (or less) blocks that is used to compute difficulty, @@ -954,7 +954,9 @@ start: uint64_t HEIGHT = m_db->height(); difficulty_type diff = next_difficulty(timestamps, difficulties, target, HEIGHT); - if (version <= 17 && version >= 11) { + if (version >= 20) { + diff = next_difficulty_v6(timestamps, difficulties, target); + } else if (version <= 17 && version >= 11) { diff = next_difficulty_v5(timestamps, difficulties, HEIGHT); } else if (version == 10) { diff = next_difficulty_v4(timestamps, difficulties, HEIGHT); @@ -1021,7 +1023,7 @@ size_t Blockchain::recalculate_difficulties(boost::optional start_heig const uint64_t top_height = m_db->height() - 1; MGINFO("Recalculating difficulties from height " << start_height << " to height " << top_height); uint8_t version = get_current_hard_fork_version(); - uint64_t difficulty_blocks_count = version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT; + uint64_t difficulty_blocks_count = version >= 20 ? DIFFICULTY_BLOCKS_COUNT_V4 : version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT; std::vector timestamps; std::vector difficulties; timestamps.reserve(difficulty_blocks_count + 1); @@ -1048,7 +1050,9 @@ size_t Blockchain::recalculate_difficulties(boost::optional start_heig size_t target = DIFFICULTY_TARGET_V2; difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target, HEIGHT); - if (version <= 17 && version >= 11) { + if (version >= 20) { + recalculated_diff = next_difficulty_v6(timestamps, difficulties, target); + } else if (version <= 17 && version >= 11) { recalculated_diff = next_difficulty_v5(timestamps, difficulties, HEIGHT); } else if (version == 10) { recalculated_diff = next_difficulty_v4(timestamps, difficulties, HEIGHT); @@ -1310,7 +1314,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std: std::vector cumulative_difficulties; uint8_t version = get_current_hard_fork_version(); - size_t difficulty_blocks_count = version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT; + size_t difficulty_blocks_count = version >= 20 ? DIFFICULTY_BLOCKS_COUNT_V4 : version <= 17 && version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT; // if the alt chain isn't long enough to calculate the difficulty target // based on its blocks alone, need to get more blocks from the main chain @@ -1368,7 +1372,9 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std: // calculate the difficulty target for the block and return it difficulty_type next_diff = next_difficulty(timestamps, cumulative_difficulties, target, HEIGHT); - if (version <= 17 && version >= 11) { + if (version >= 20) { + next_difficulty_v6(timestamps, cumulative_difficulties, target); + } else if (version <= 17 && version >= 11) { next_diff = next_difficulty_v5(timestamps, cumulative_difficulties, HEIGHT); } else if (version == 10) { next_diff = next_difficulty_v4(timestamps, cumulative_difficulties, HEIGHT);