mirror of
https://git.wownero.com/wownero/wownero.git
synced 2024-08-15 01:03:23 +00:00
Merge pull request '12-hour difficulty adjustment window' (#451) from wowario/wownero:diff-v6 into dev
Reviewed-on: https://git.wownero.com/wownero/wownero/pulls/451
This commit is contained in:
commit
7c47b97984
4 changed files with 61 additions and 15 deletions
|
@ -122,10 +122,10 @@ namespace cryptonote {
|
||||||
|
|
||||||
uint64_t next_difficulty_64(std::vector<std::uint64_t> timestamps, std::vector<uint64_t> cumulative_difficulties, size_t target_seconds) {
|
uint64_t next_difficulty_64(std::vector<std::uint64_t> timestamps, std::vector<uint64_t> cumulative_difficulties, size_t target_seconds) {
|
||||||
|
|
||||||
if(timestamps.size() > DIFFICULTY_WINDOW)
|
if(timestamps.size() > DIFFICULTY_WINDOW_V3)
|
||||||
{
|
{
|
||||||
timestamps.resize(DIFFICULTY_WINDOW);
|
timestamps.resize(DIFFICULTY_WINDOW_V3);
|
||||||
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
|
cumulative_difficulties.resize(DIFFICULTY_WINDOW_V3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,17 +134,17 @@ namespace cryptonote {
|
||||||
if (length <= 1) {
|
if (length <= 1) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
|
static_assert(DIFFICULTY_WINDOW_V3 >= 2, "Window is too small");
|
||||||
assert(length <= DIFFICULTY_WINDOW);
|
assert(length <= DIFFICULTY_WINDOW_V3);
|
||||||
sort(timestamps.begin(), timestamps.end());
|
sort(timestamps.begin(), timestamps.end());
|
||||||
size_t cut_begin, cut_end;
|
size_t cut_begin, cut_end;
|
||||||
static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large");
|
static_assert(2 * DIFFICULTY_CUT_V2 <= DIFFICULTY_WINDOW_V3 - 2, "Cut length is too large");
|
||||||
if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) {
|
if (length <= DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) {
|
||||||
cut_begin = 0;
|
cut_begin = 0;
|
||||||
cut_end = length;
|
cut_end = length;
|
||||||
} else {
|
} else {
|
||||||
cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2;
|
cut_begin = (length - (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2) + 1) / 2;
|
||||||
cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT);
|
cut_end = cut_begin + (DIFFICULTY_WINDOW_V3 - 2 * DIFFICULTY_CUT_V2);
|
||||||
}
|
}
|
||||||
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
|
assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length);
|
||||||
uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
|
uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin];
|
||||||
|
@ -409,4 +409,40 @@ namespace cryptonote {
|
||||||
}
|
}
|
||||||
return next_D;
|
return next_D;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
difficulty_type next_difficulty_v6(std::vector<uint64_t> timestamps, std::vector<difficulty_type> 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<difficulty_type>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ namespace cryptonote
|
||||||
difficulty_type next_difficulty_v3(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
difficulty_type next_difficulty_v3(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||||
difficulty_type next_difficulty_v4(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
difficulty_type next_difficulty_v4(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||||
difficulty_type next_difficulty_v5(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
difficulty_type next_difficulty_v5(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||||
|
difficulty_type next_difficulty_v6(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
|
||||||
|
|
||||||
std::string hex(difficulty_type v);
|
std::string hex(difficulty_type v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,8 +85,11 @@
|
||||||
#define DIFFICULTY_WINDOW_V3 144
|
#define DIFFICULTY_WINDOW_V3 144
|
||||||
#define DIFFICULTY_WINDOW_V2 60
|
#define DIFFICULTY_WINDOW_V2 60
|
||||||
#define DIFFICULTY_WINDOW 720 // blocks
|
#define DIFFICULTY_WINDOW 720 // blocks
|
||||||
|
#define DIFFICULTY_LAG_V2 3
|
||||||
#define DIFFICULTY_LAG 15 // !!!
|
#define DIFFICULTY_LAG 15 // !!!
|
||||||
|
#define DIFFICULTY_CUT_V2 12
|
||||||
#define DIFFICULTY_CUT 60 // timestamps to cut after sorting
|
#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_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_V2 DIFFICULTY_WINDOW_V2 + 1 // added +1 to make N=N
|
||||||
#define DIFFICULTY_BLOCKS_COUNT DIFFICULTY_WINDOW + DIFFICULTY_LAG
|
#define DIFFICULTY_BLOCKS_COUNT DIFFICULTY_WINDOW + DIFFICULTY_LAG
|
||||||
|
|
|
@ -874,7 +874,7 @@ start:
|
||||||
ss << "Re-locked, height " << height << ", tail id " << new_top_hash << (new_top_hash == top_hash ? "" : " (different)") << std::endl;
|
ss << "Re-locked, height " << height << ", tail id " << new_top_hash << (new_top_hash == top_hash ? "" : " (different)") << std::endl;
|
||||||
top_hash = new_top_hash;
|
top_hash = new_top_hash;
|
||||||
uint8_t version = get_current_hard_fork_version();
|
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
|
// ND: Speedup
|
||||||
// 1. Keep a list of the last 735 (or less) blocks that is used to compute difficulty,
|
// 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();
|
uint64_t HEIGHT = m_db->height();
|
||||||
difficulty_type diff = next_difficulty(timestamps, difficulties, target, 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);
|
diff = next_difficulty_v5(timestamps, difficulties, HEIGHT);
|
||||||
} else if (version == 10) {
|
} else if (version == 10) {
|
||||||
diff = next_difficulty_v4(timestamps, difficulties, HEIGHT);
|
diff = next_difficulty_v4(timestamps, difficulties, HEIGHT);
|
||||||
|
@ -1021,7 +1023,7 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
||||||
const uint64_t top_height = m_db->height() - 1;
|
const uint64_t top_height = m_db->height() - 1;
|
||||||
MGINFO("Recalculating difficulties from height " << start_height << " to height " << top_height);
|
MGINFO("Recalculating difficulties from height " << start_height << " to height " << top_height);
|
||||||
uint8_t version = get_current_hard_fork_version();
|
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<uint64_t> timestamps;
|
std::vector<uint64_t> timestamps;
|
||||||
std::vector<difficulty_type> difficulties;
|
std::vector<difficulty_type> difficulties;
|
||||||
timestamps.reserve(difficulty_blocks_count + 1);
|
timestamps.reserve(difficulty_blocks_count + 1);
|
||||||
|
@ -1048,7 +1050,9 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
||||||
size_t target = DIFFICULTY_TARGET_V2;
|
size_t target = DIFFICULTY_TARGET_V2;
|
||||||
difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target, HEIGHT);
|
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);
|
recalculated_diff = next_difficulty_v5(timestamps, difficulties, HEIGHT);
|
||||||
} else if (version == 10) {
|
} else if (version == 10) {
|
||||||
recalculated_diff = next_difficulty_v4(timestamps, difficulties, HEIGHT);
|
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<difficulty_type> cumulative_difficulties;
|
std::vector<difficulty_type> cumulative_difficulties;
|
||||||
|
|
||||||
uint8_t version = get_current_hard_fork_version();
|
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
|
// 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
|
// 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
|
// calculate the difficulty target for the block and return it
|
||||||
difficulty_type next_diff = next_difficulty(timestamps, cumulative_difficulties, target, HEIGHT);
|
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);
|
next_diff = next_difficulty_v5(timestamps, cumulative_difficulties, HEIGHT);
|
||||||
} else if (version == 10) {
|
} else if (version == 10) {
|
||||||
next_diff = next_difficulty_v4(timestamps, cumulative_difficulties, HEIGHT);
|
next_diff = next_difficulty_v4(timestamps, cumulative_difficulties, HEIGHT);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue