From 693c88e21c78304dca8ffe0a68986ab024608067 Mon Sep 17 00:00:00 2001 From: wowario Date: Wed, 20 Aug 2025 10:50:52 +0300 Subject: [PATCH] add nettype to diff algo --- src/cryptonote_basic/difficulty.cpp | 49 +++++++++++++++++++--------- src/cryptonote_basic/difficulty.h | 13 ++++---- src/cryptonote_core/blockchain.cpp | 50 ++++++++++++++--------------- src/cryptonote_core/blockchain.h | 2 +- src/rpc/core_rpc_server.cpp | 6 ++-- src/rpc/daemon_handler.cpp | 2 +- 6 files changed, 71 insertions(+), 51 deletions(-) diff --git a/src/cryptonote_basic/difficulty.cpp b/src/cryptonote_basic/difficulty.cpp index 048dc5e8d..42346a384 100644 --- a/src/cryptonote_basic/difficulty.cpp +++ b/src/cryptonote_basic/difficulty.cpp @@ -201,7 +201,10 @@ namespace cryptonote { return check_hash_128(hash, difficulty); } - difficulty_type next_difficulty(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) { + difficulty_type next_difficulty(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT, network_type nettype) { + if ((nettype == TESTNET || nettype == STAGENET) && HEIGHT <= DIFFICULTY_WINDOW) { + return 100; + } //cutoff DIFFICULTY_LAG if(timestamps.size() > DIFFICULTY_WINDOW) { @@ -216,7 +219,8 @@ namespace cryptonote { return 1; } // reset difficulty for solo mining to 100 million - if (HEIGHT <= 331170 + DIFFICULTY_WINDOW && HEIGHT >= 331170) { return 100000000; } + if (nettype == MAINNET && HEIGHT <= 331170 + DIFFICULTY_WINDOW && HEIGHT >= 331170) { return 100000000; } + static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small"); assert(length <= DIFFICULTY_WINDOW); sort(timestamps.begin(), timestamps.end()); @@ -260,9 +264,12 @@ 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, uint64_t HEIGHT) { + difficulty_type next_difficulty_v2(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT, network_type nettype) { const int64_t T = static_cast(target_seconds); size_t N = DIFFICULTY_WINDOW_V2; + if ((nettype == TESTNET || nettype == STAGENET) && HEIGHT <= DIFFICULTY_WINDOW) { + return 100; + } if (timestamps.size() < 4) { return 1; } else if ( timestamps.size() < N+1 ) { @@ -293,10 +300,13 @@ namespace cryptonote { } // LWMA-2 - difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT) { + difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT, network_type nettype) { 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; + if ((nettype == TESTNET || nettype == STAGENET) && HEIGHT <= DIFFICULTY_WINDOW) { + return 100; + } assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= static_cast(N+1) ); for ( int64_t i = 1; i <= N; i++ ) { ST = static_cast(timestamps[i]) - static_cast(timestamps[i-1]); @@ -316,12 +326,15 @@ namespace cryptonote { } // LWMA-4 - difficulty_type next_difficulty_v4(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, network_type nettype) { 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; + if ((nettype == TESTNET || nettype == STAGENET) && HEIGHT <= DIFFICULTY_WINDOW) { + return 100; + } assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 ); - if (HEIGHT <= 63469 + 1) { return 100000069; } + if (nettype == MAINNET && HEIGHT <= 63469 + 1) { return 100000069; } std::vectorTS(N+1); TS[0] = timestamps[0]; for ( i = 1; i <= N; i++) { @@ -363,21 +376,24 @@ 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 HEIGHT) { + difficulty_type next_difficulty_v5(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT, network_type nettype) { uint64_t T = DIFFICULTY_TARGET_V2; uint64_t N = DIFFICULTY_WINDOW_V3; + if ((nettype == TESTNET || nettype == STAGENET) && HEIGHT <= DIFFICULTY_WINDOW) { + return 100; + } assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 ); - if (HEIGHT >= 81769 && HEIGHT < 81769 + N) { return 10000000; } + if (nettype == MAINNET && HEIGHT >= 81769 && HEIGHT < 81769 + N) { return 10000000; } assert(timestamps.size() == N+1); // hardcoding previously erroneously calculated difficulty entries - if(HEIGHT == 307686) return 25800000; - if(HEIGHT == 307692) return 1890000; - if(HEIGHT == 307735) return 17900000; - if(HEIGHT == 307742) return 21300000; - if(HEIGHT == 307750) return 10900000; - if(HEIGHT == 307766) return 2960000; + if(nettype == MAINNET && HEIGHT == 307686) return 25800000; + if(nettype == MAINNET && HEIGHT == 307692) return 1890000; + if(nettype == MAINNET && HEIGHT == 307735) return 17900000; + if(nettype == MAINNET && HEIGHT == 307742) return 21300000; + if(nettype == MAINNET && HEIGHT == 307750) return 10900000; + if(nettype == MAINNET && HEIGHT == 307766) return 2960000; uint64_t i, this_timestamp(0), previous_timestamp(0); difficulty_type L(0), next_D, avg_D; @@ -411,7 +427,10 @@ namespace cryptonote { return next_D; } - difficulty_type next_difficulty_v6(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds) { + difficulty_type next_difficulty_v6(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT, network_type nettype) { + if ((nettype == TESTNET || nettype == STAGENET) && HEIGHT <= DIFFICULTY_WINDOW) { + return 100; + } if(timestamps.size() > DIFFICULTY_WINDOW_V3) { timestamps.resize(DIFFICULTY_WINDOW_V3); diff --git a/src/cryptonote_basic/difficulty.h b/src/cryptonote_basic/difficulty.h index c315bb2f8..ba555e6bc 100644 --- a/src/cryptonote_basic/difficulty.h +++ b/src/cryptonote_basic/difficulty.h @@ -35,6 +35,7 @@ #include #include #include "crypto/hash.h" +#include "cryptonote_config.h" namespace cryptonote { @@ -57,12 +58,12 @@ 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, uint64_t HEIGHT); - difficulty_type next_difficulty_v2(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT); - 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); + difficulty_type next_difficulty(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT, cryptonote::network_type nettype); + difficulty_type next_difficulty_v2(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT, cryptonote::network_type nettype); + difficulty_type next_difficulty_v3(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT, cryptonote::network_type nettype); + difficulty_type next_difficulty_v4(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT, cryptonote::network_type nettype); + difficulty_type next_difficulty_v5(std::vector timestamps, std::vector cumulative_difficulties, uint64_t HEIGHT, cryptonote::network_type nettype); + difficulty_type next_difficulty_v6(std::vector timestamps, std::vector cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT, cryptonote::network_type nettype); std::string hex(difficulty_type v); } diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 9eb6255a4..3ba8df555 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -386,7 +386,7 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline load_compiled_in_block_hashes(get_checkpoints); #endif - MINFO("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block()); + MINFO("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block(m_nettype)); rtxn_guard.stop(); @@ -852,7 +852,7 @@ bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk, bool *orph // last DIFFICULTY_BLOCKS_COUNT blocks and passes them to next_difficulty, // returning the result of that call. Ignores the genesis block, and can use // less blocks than desired if there aren't enough. -difficulty_type Blockchain::get_difficulty_for_next_block() +difficulty_type Blockchain::get_difficulty_for_next_block(const network_type nettype) { if (m_fixed_difficulty) { @@ -930,17 +930,17 @@ difficulty_type Blockchain::get_difficulty_for_next_block() uint64_t HEIGHT = m_db->height(); difficulty_type diff; if (version >= 20) { - diff = next_difficulty_v6(timestamps, difficulties, target); + diff = next_difficulty_v6(timestamps, difficulties, target, HEIGHT, m_nettype); } else if (version <= 17 && version >= 11) { - diff = next_difficulty_v5(timestamps, difficulties, HEIGHT); + diff = next_difficulty_v5(timestamps, difficulties, HEIGHT, m_nettype); } else if (version == 10) { - diff = next_difficulty_v4(timestamps, difficulties, HEIGHT); + diff = next_difficulty_v4(timestamps, difficulties, HEIGHT, m_nettype); } else if (version == 9) { - diff = next_difficulty_v3(timestamps, difficulties, HEIGHT); + diff = next_difficulty_v3(timestamps, difficulties, HEIGHT, m_nettype); } else if (version == 8) { - diff = next_difficulty_v2(timestamps, difficulties, target, HEIGHT); + diff = next_difficulty_v2(timestamps, difficulties, target, HEIGHT, m_nettype); } else { - diff = next_difficulty(timestamps, difficulties, target, HEIGHT); + diff = next_difficulty(timestamps, difficulties, target, HEIGHT, m_nettype); } CRITICAL_REGION_LOCAL1(m_difficulty_lock); @@ -1002,17 +1002,17 @@ size_t Blockchain::recalculate_difficulties(boost::optional start_heig uint64_t HEIGHT = m_db->height(); difficulty_type recalculated_diff; if (version >= 20) { - recalculated_diff = next_difficulty_v6(timestamps, difficulties, target); + recalculated_diff = next_difficulty_v6(timestamps, difficulties, target, HEIGHT, m_nettype); } else if (version <= 17 && version >= 11) { - recalculated_diff = next_difficulty_v5(timestamps, difficulties, HEIGHT); + recalculated_diff = next_difficulty_v5(timestamps, difficulties, HEIGHT, m_nettype); } else if (version == 10) { - recalculated_diff = next_difficulty_v4(timestamps, difficulties, HEIGHT); + recalculated_diff = next_difficulty_v4(timestamps, difficulties, HEIGHT, m_nettype); } else if (version == 9) { - recalculated_diff = next_difficulty_v3(timestamps, difficulties, HEIGHT); + recalculated_diff = next_difficulty_v3(timestamps, difficulties, HEIGHT, m_nettype); } else if (version == 8) { - recalculated_diff = next_difficulty_v2(timestamps, difficulties, target, HEIGHT); + recalculated_diff = next_difficulty_v2(timestamps, difficulties, target, HEIGHT, m_nettype); } else { - recalculated_diff = next_difficulty(timestamps, difficulties, target, HEIGHT); + recalculated_diff = next_difficulty(timestamps, difficulties, target, HEIGHT, m_nettype); } boost::multiprecision::uint256_t recalculated_cum_diff_256 = boost::multiprecision::uint256_t(recalculated_diff) + last_cum_diff; @@ -1323,17 +1323,17 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std: uint64_t HEIGHT = m_db->height(); difficulty_type next_diff; if (version >= 20) { - next_diff = next_difficulty_v6(timestamps, cumulative_difficulties, target); + next_diff = next_difficulty_v6(timestamps, cumulative_difficulties, target, HEIGHT, m_nettype); } else if (version <= 17 && version >= 11) { - next_diff = next_difficulty_v5(timestamps, cumulative_difficulties, HEIGHT); + next_diff = next_difficulty_v5(timestamps, cumulative_difficulties, HEIGHT, m_nettype); } else if (version == 10) { - next_diff = next_difficulty_v4(timestamps, cumulative_difficulties, HEIGHT); + next_diff = next_difficulty_v4(timestamps, cumulative_difficulties, HEIGHT, m_nettype); } else if (version == 9) { - next_diff = next_difficulty_v3(timestamps, cumulative_difficulties, HEIGHT); + next_diff = next_difficulty_v3(timestamps, cumulative_difficulties, HEIGHT, m_nettype); } else if (version == 8) { - next_diff = next_difficulty_v2(timestamps, cumulative_difficulties, target, HEIGHT); + next_diff = next_difficulty_v2(timestamps, cumulative_difficulties, target, HEIGHT, m_nettype); } else { - next_diff = next_difficulty(timestamps, cumulative_difficulties, target, HEIGHT); + next_diff = next_difficulty(timestamps, cumulative_difficulties, target, HEIGHT, m_nettype); } return next_diff; } @@ -1659,7 +1659,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, b.minor_version = m_hardfork->get_ideal_version(); b.prev_id = get_tail_id(); median_weight = m_current_block_cumul_weight_limit / 2; - diffic = get_difficulty_for_next_block(); + diffic = get_difficulty_for_next_block(m_nettype); already_generated_coins = m_db->get_block_already_generated_coins(height - 1); if (m_hardfork->get_current_version() >= RX_BLOCK_VERSION) { @@ -1826,7 +1826,7 @@ bool Blockchain::get_miner_data(uint8_t& major_version, uint64_t& height, crypto seed_hash = get_block_id_by_height(seed_height); } - difficulty = get_difficulty_for_next_block(); + difficulty = get_difficulty_for_next_block(m_nettype); median_weight = m_current_block_cumul_weight_median; already_generated_coins = m_db->get_block_already_generated_coins(height - 1); @@ -4162,7 +4162,7 @@ leave: // so we need to check the return type. // FIXME: get_difficulty_for_next_block can also assert, look into // changing this to throwing exceptions instead so we can clean up. - difficulty_type current_diffic = get_difficulty_for_next_block(); + difficulty_type current_diffic = get_difficulty_for_next_block(m_nettype); CHECK_AND_ASSERT_MES(current_diffic, false, "!!!!!!!!! difficulty overhead !!!!!!!!!"); TIME_MEASURE_FINISH(target_calculating_time); @@ -4558,7 +4558,7 @@ leave: // appears to be a NOP *and* is called elsewhere. wat? m_tx_pool.on_blockchain_inc(new_height, id); - get_difficulty_for_next_block(); // just to cache it + get_difficulty_for_next_block(m_nettype); // just to cache it invalidate_block_template_cache(); const uint8_t new_hf_version = get_current_hard_fork_version(); @@ -5814,7 +5814,7 @@ void Blockchain::send_miner_notifications(uint64_t height, const crypto::hash &s return; const uint8_t major_version = m_hardfork->get_ideal_version(height); - const difficulty_type diff = get_difficulty_for_next_block(); + const difficulty_type diff = get_difficulty_for_next_block(m_nettype); const uint64_t median_weight = m_current_block_cumul_weight_median; std::vector tx_backlog; diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 0fd81f4ba..bb221e977 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -335,7 +335,7 @@ namespace cryptonote * * @return the target */ - difficulty_type get_difficulty_for_next_block(); + difficulty_type get_difficulty_for_next_block(const network_type nettype); /** * @brief check currently stored difficulties against difficulty checkpoints diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 583e5711a..82a58d425 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -521,7 +521,7 @@ namespace cryptonote ++res.height; // turn top block height into blockchain height res.top_block_hash = string_tools::pod_to_hex(top_hash); res.target_height = m_p2p.get_payload_object().is_synchronized() ? 0 : m_core.get_target_blockchain_height(); - store_difficulty(m_core.get_blockchain_storage().get_difficulty_for_next_block(), res.difficulty, res.wide_difficulty, res.difficulty_top64); + store_difficulty(m_core.get_blockchain_storage().get_difficulty_for_next_block(m_core.get_nettype()), res.difficulty, res.wide_difficulty, res.difficulty_top64); res.target = m_core.get_blockchain_storage().get_difficulty_target(); res.tx_count = m_core.get_blockchain_storage().get_total_transactions() - res.height; //without coinbase res.tx_pool_size = m_core.get_pool_transactions_count(!restricted); @@ -1475,7 +1475,7 @@ namespace cryptonote const miner& lMiner = m_core.get_miner(); res.active = lMiner.is_mining(); res.is_background_mining_enabled = lMiner.get_is_background_mining_enabled(); - store_difficulty(m_core.get_blockchain_storage().get_difficulty_for_next_block(), res.difficulty, res.wide_difficulty, res.difficulty_top64); + store_difficulty(m_core.get_blockchain_storage().get_difficulty_for_next_block(m_core.get_nettype()), res.difficulty, res.wide_difficulty, res.difficulty_top64); res.block_target = m_core.get_blockchain_storage().get_current_hard_fork_version() < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; if ( lMiner.is_mining() ) { @@ -3567,7 +3567,7 @@ namespace cryptonote if (!stale) { // it might be a valid block! - const difficulty_type current_difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block(); + const difficulty_type current_difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block(m_core.get_nettype()); if (check_hash(hash, current_difficulty)) { MINFO("This payment meets the current network difficulty"); diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index c1e4c10bf..0fdaf5bc0 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -524,7 +524,7 @@ namespace rpc auto& chain = m_core.get_blockchain_storage(); - res.info.wide_difficulty = chain.get_difficulty_for_next_block(); + res.info.wide_difficulty = chain.get_difficulty_for_next_block(m_core.get_nettype()); res.info.difficulty = (res.info.wide_difficulty & 0xffffffffffffffff).convert_to(); res.info.target = chain.get_difficulty_target();