new difficulty algorithm

This commit is contained in:
XfedeX 2023-01-13 18:33:37 +01:00
parent c5487d72e3
commit ae8c8d6f55
4 changed files with 52 additions and 5 deletions

View file

@ -409,4 +409,37 @@ namespace cryptonote {
}
return next_D;
}
// based on original difficulty, but without difficulty_lag
difficulty_type next_difficulty_v6(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) {
size_t length = timestamps.size();
assert(length == cumulative_difficulties.size());
if (length <= 1) {
return 1;
}
if (HEIGHT <= DIFFICULTY_RESET_HEIGHT + DIFFICULTY_WINDOW && HEIGHT >= DIFFICULTY_RESET_HEIGHT) { return DIFFICULTY_RESET_LEVEL; }
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
assert(length <= DIFFICULTY_WINDOW);
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) {
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);
}
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>();
}
}

View file

@ -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_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_v6(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT);
std::string hex(difficulty_type v);
}

View file

@ -86,11 +86,14 @@
#define DIFFICULTY_WINDOW_V3 144
#define DIFFICULTY_WINDOW_V2 60
#define DIFFICULTY_WINDOW 720 // blocks
#define DIFFICULTY_WINDOW_V4 144 // 12 hours
#define DIFFICULTY_LAG 15 // !!!
#define DIFFICULTY_CUT 60 // timestamps to cut after sorting
#define DIFFICULTY_CUT_V2 10 // used by v6 difficulty with v4 blocks count
#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
#define DIFFICULTY_BLOCKS_COUNT_V4 DIFFICULTY_WINDOW_V4 + 1 // new difficulty doesn't have lag
#define DIFFICULTY_RESET_HEIGHT 331170// ~July 4, 2021 Pool Independence Day
#define DIFFICULTY_RESET_LEVEL 100000000 // 100 mill

View file

@ -875,7 +875,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,
@ -955,7 +955,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, HEIGHT);
} else if (version <= 17 && version >= 11) {
diff = next_difficulty_v5(timestamps, difficulties, HEIGHT);
} else if (version == 10) {
diff = next_difficulty_v4(timestamps, difficulties, HEIGHT);
@ -1049,7 +1051,9 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> 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, HEIGHT);
} 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);
@ -1369,7 +1373,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_diff = next_difficulty_v6(timestamps, cumulative_difficulties, target, HEIGHT);
} 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);
@ -1443,7 +1449,11 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
}
MDEBUG("Miner tx hash: " << get_transaction_hash(b.miner_tx));
if (hf_version >= HF_VERSION_FIXED_UNLOCK)
if (hf_version >= HF_VERSION_LONG_UNLOCK)
{
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_LONG, false, "coinbase transaction transaction has the wrong unlock time="
<< b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_LONG);
} else if (hf_version >= HF_VERSION_FIXED_UNLOCK)
{
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2, false, "coinbase transaction transaction has the wrong unlock time="
<< b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW_V2);