diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index ffda8983..c844b7b1 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -2046,9 +2046,18 @@ bool blockchain_storage::is_reorganize_required(const block_extended_info& main_ wide_difficulty_type main_pow_diff_begin = get_last_alt_x_block_cumulative_precise_adj_difficulty(alt_chain_type(), connection_point.height - 1, false); main_cumul_diff.pow_diff = main_pow_diff_end - main_pow_diff_begin; - //TODO: measurement of precise cumulative difficult - boost::multiprecision::uint1024_t alt = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, alt_cumul_diff, main_cumul_diff); - boost::multiprecision::uint1024_t main = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, main_cumul_diff, alt_cumul_diff); + boost::multiprecision::uint1024_t alt = 0; + boost::multiprecision::uint1024_t main = 0; + if (m_core_runtime_config.is_hardfork_active_for_height(ZANO_HARDFORK_04_ZARCANUM, alt_chain_bei.height)) + { + alt = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, alt_cumul_diff, main_cumul_diff); + main = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, main_cumul_diff, alt_cumul_diff); + } + else + { + alt = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, alt_cumul_diff, main_cumul_diff); + main = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, main_cumul_diff, alt_cumul_diff); + } LOG_PRINT_L1("[FORK_CHOICE]: " << ENDL << "difficulty_pow_at_split_point:" << difficulty_pow_at_split_point << ENDL << "difficulty_pos_at_split_point:" << difficulty_pos_at_split_point << ENDL @@ -6515,11 +6524,12 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt bvc.m_verification_failed = true; return false; } - - bei.cumulative_diff_adjusted += cumulative_diff_delta; + //this used only in pre-hardfork 1 + bei.cumulative_diff_adjusted += cumulative_diff_delta; ////////////////////////////////////////////////////////////////////////// // rebuild cumulative_diff_precise_adjusted for whole period + // cumulative_diff_precise_adjusted - native cumulative difficulty adjusted ONLY by sequence_factor wide_difficulty_type diff_precise_adj = correct_difficulty_with_sequence_factor(sequence_factor, current_diffic); bei.cumulative_diff_precise_adjusted = last_x_h ? m_db_blocks[last_x_h]->cumulative_diff_precise_adjusted + diff_precise_adj : diff_precise_adj; @@ -6612,7 +6622,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt LOG_PRINT_L1("+++++ BLOCK SUCCESSFULLY ADDED " << (is_pos_bl ? "[PoS]" : "[PoW]") << "["<< static_cast(bei.bl.major_version) << "." << static_cast(bei.bl.minor_version) << "] "<< " Sq: " << sequence_factor << ENDL << "id:\t" << id << timestamp_str_entry.str() << ENDL << powpos_str_entry.str() - << ENDL << "HEIGHT " << bei.height << ", difficulty: " << current_diffic << ", cumul_diff_precise: " << bei.cumulative_diff_precise << ", cumul_diff_adj: " << bei.cumulative_diff_adjusted << " (+" << cumulative_diff_delta << ")" + << ENDL << "HEIGHT " << bei.height << ", difficulty: " << current_diffic << ", cumul_diff_precise: " << bei.cumulative_diff_precise << ", cumul_diff_precise_adj: " << bei.cumulative_diff_precise_adjusted << " (+" << cumulative_diff_delta << ")" << ENDL << "block reward: " << print_money_brief(base_reward + fee_summary) << " (" << print_money_brief(base_reward) << " + " << print_money_brief(fee_summary) << ")" << ", coinbase_blob_size: " << coinbase_blob_size << ", cumulative size: " << cumulative_block_size << ", tx_count: " << bei.bl.tx_hashes.size() << ", timing: " << block_processing_time_0_ms << "ms" diff --git a/src/currency_core/blockchain_storage_basic.h b/src/currency_core/blockchain_storage_basic.h index 0ecf53bd..75d8f3ce 100644 --- a/src/currency_core/blockchain_storage_basic.h +++ b/src/currency_core/blockchain_storage_basic.h @@ -48,9 +48,9 @@ namespace currency block bl; uint64_t height; uint64_t block_cumulative_size; - wide_difficulty_type cumulative_diff_adjusted; + wide_difficulty_type cumulative_diff_adjusted; // used only before hardfork 1 wide_difficulty_type cumulative_diff_precise; - wide_difficulty_type cumulative_diff_precise_adjusted; + wide_difficulty_type cumulative_diff_precise_adjusted; //used after hardfork 1 (cumulative difficulty adjusted only by sequence factor) wide_difficulty_type difficulty; boost::multiprecision::uint128_t already_generated_coins; crypto::hash stake_hash; //TODO: unused field for PoW blocks, subject for refactoring diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index 0ff7c36f..7797956c 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -4429,8 +4429,6 @@ namespace currency a.k_image == b.k_image; } //-------------------------------------------------------------------------------- - - boost::multiprecision::uint1024_t get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point, const wide_difficulty_type& difficulty_pow_at_split_point, const difficulties& a_diff, @@ -4463,6 +4461,51 @@ namespace currency return res; CATCH_ENTRY_WITH_FORWARDING_EXCEPTION(); } + //-------------------------------------------------------------------------------- + // Note: we adjust formula and introduce multiplier, + // that let us never dive into floating point calculations (which we can't use in consensus) + // this multiplier should be greater than max multiprecision::uint128_t power 2 + + boost::multiprecision::uint1024_t get_adjuster_for_fork_choice_rule_hf4() + { + return boost::multiprecision::uint1024_t(std::numeric_limits::max()) * 10 * std::numeric_limits::max(); + } + + const boost::multiprecision::uint1024_t adjusting_multiplier = get_adjuster_for_fork_choice_rule_hf4(); + + boost::multiprecision::uint1024_t get_a_to_b_relative_cumulative_difficulty_hf4(const wide_difficulty_type& difficulty_pos_at_split_point, + const wide_difficulty_type& difficulty_pow_at_split_point, + const difficulties& a_diff, + const difficulties& b_diff) + { + static const wide_difficulty_type difficulty_pos_starter = DIFFICULTY_POS_STARTER; + static const wide_difficulty_type difficulty_pow_starter = DIFFICULTY_POW_STARTER; + const wide_difficulty_type& a_pos_cumulative_difficulty = a_diff.pos_diff > 0 ? a_diff.pos_diff : difficulty_pos_starter; + const wide_difficulty_type& b_pos_cumulative_difficulty = b_diff.pos_diff > 0 ? b_diff.pos_diff : difficulty_pos_starter; + const wide_difficulty_type& a_pow_cumulative_difficulty = a_diff.pow_diff > 0 ? a_diff.pow_diff : difficulty_pow_starter; + const wide_difficulty_type& b_pow_cumulative_difficulty = b_diff.pow_diff > 0 ? b_diff.pow_diff : difficulty_pow_starter; + + boost::multiprecision::uint1024_t basic_sum_ = boost::multiprecision::uint1024_t(a_pow_cumulative_difficulty) + (boost::multiprecision::uint1024_t(a_pos_cumulative_difficulty)*difficulty_pow_at_split_point) / difficulty_pos_at_split_point; + boost::multiprecision::uint1024_t basic_sum_pow_minus2 = adjusting_multiplier /(basic_sum_ * basic_sum_); + boost::multiprecision::uint1024_t res = + (basic_sum_pow_minus2 * a_pow_cumulative_difficulty * a_pos_cumulative_difficulty) / (boost::multiprecision::uint1024_t(b_pow_cumulative_difficulty)*b_pos_cumulative_difficulty); + + // if (res > boost::math::tools::max_value()) + // { + // ASSERT_MES_AND_THROW("[INTERNAL ERROR]: Failed to get_a_to_b_relative_cumulative_difficulty, res = " << res << ENDL + // << ", difficulty_pos_at_split_point: " << difficulty_pos_at_split_point << ENDL + // << ", difficulty_pow_at_split_point:" << difficulty_pow_at_split_point << ENDL + // << ", a_pos_cumulative_difficulty:" << a_pos_cumulative_difficulty << ENDL + // << ", b_pos_cumulative_difficulty:" << b_pos_cumulative_difficulty << ENDL + // << ", a_pow_cumulative_difficulty:" << a_pow_cumulative_difficulty << ENDL + // << ", b_pow_cumulative_difficulty:" << b_pow_cumulative_difficulty << ENDL + // ); + // } + TRY_ENTRY(); + // wide_difficulty_type short_res = res.convert_to(); + return res; + CATCH_ENTRY_WITH_FORWARDING_EXCEPTION(); + } diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 96cb7c3b..f5b101f9 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -933,6 +933,13 @@ namespace currency const difficulties& b_diff ); + boost::multiprecision::uint1024_t get_a_to_b_relative_cumulative_difficulty_hf4(const wide_difficulty_type& difficulty_pos_at_split_point, + const wide_difficulty_type& difficulty_pow_at_split_point, + const difficulties& a_diff, + const difficulties& b_diff + ); + + struct rpc_tx_payload_handler : public boost::static_visitor { tx_extra_rpc_entry& tv; diff --git a/tests/unit_tests/fork_choice_rule.cpp b/tests/unit_tests/fork_choice_rule.cpp index 582c9c39..33014781 100644 --- a/tests/unit_tests/fork_choice_rule.cpp +++ b/tests/unit_tests/fork_choice_rule.cpp @@ -69,8 +69,81 @@ TEST(fork_choice_rule_test, fork_choice_rule_test_1) ASSERT_FALSE(res); res = if_alt_chain_stronger(200000, 14000); ASSERT_TRUE(res); - - - - +} + + +bool if_alt_chain_stronger_hf4(const currency::wide_difficulty_type& pos, const currency::wide_difficulty_type& pow) +{ + currency::difficulties main_cumul_diff; + main_cumul_diff.pos_diff.assign("1605973467987652534120344647"); + main_cumul_diff.pow_diff.assign("3011264554002844981"); + currency::difficulties alt_cumul_diff; + alt_cumul_diff.pow_diff = pow; + alt_cumul_diff.pos_diff = pos; + currency::wide_difficulty_type difficulty_pos_at_split_point = main_cumul_diff.pos_diff; + currency::wide_difficulty_type difficulty_pow_at_split_point = main_cumul_diff.pow_diff; + boost::multiprecision::uint1024_t main = currency::get_a_to_b_relative_cumulative_difficulty_hf4(difficulty_pos_at_split_point, difficulty_pow_at_split_point, main_cumul_diff, alt_cumul_diff); + boost::multiprecision::uint1024_t alt = currency::get_a_to_b_relative_cumulative_difficulty_hf4(difficulty_pos_at_split_point, difficulty_pow_at_split_point, alt_cumul_diff, main_cumul_diff); + if (alt > main) + return true; + return false; +} +TEST(fork_choice_rule_test, fork_choice_rule_test_hf4) +{ + std::stringstream ss; + currency::wide_difficulty_type pos_start, pos_end, pos_step, pos_diveder; + pos_start.assign("16059734679876525341203446"); + pos_end.assign ("16059734679876525341203446400"); + pos_step.assign ("50000000000000000000000000"); + pos_diveder.assign("100000000000000000000000"); + + currency::wide_difficulty_type pow_start, pow_end, pow_step, pow_diveder; + pow_start.assign("301126455400284498"); + pow_end.assign ("30112645540028449810"); + pow_step.assign ("500000000000000000"); + pow_diveder.assign("1000000000000000"); + + + for (currency::wide_difficulty_type pos = pos_start; pos < pos_end; pos += pos_step) + { + for (currency::wide_difficulty_type pow = pow_start; pow < pow_end; pow += pow_step) + { + bool r = if_alt_chain_stronger_hf4(pos, pow); + if(r) + ss << pos/ pos_diveder << "\t" << pow / pow_diveder << std::endl; + //ss << pos << "\t" << pow << "\t" << (r ? "1" : "0") << std::endl; + } + } + bool r = epee::file_io_utils::save_string_to_file("stat_hf4.txt", ss.str()); + + + bool res = false; + res = if_alt_chain_stronger_hf4(1000000, 1000); + ASSERT_FALSE(res); + res = if_alt_chain_stronger_hf4(1000000, 1500); + ASSERT_TRUE(res); + res = if_alt_chain_stronger_hf4(800000, 1700); + ASSERT_FALSE(res); + res = if_alt_chain_stronger_hf4(800000, 2000); + ASSERT_TRUE(res); + res = if_alt_chain_stronger_hf4(600000, 2200); + ASSERT_FALSE(res); + res = if_alt_chain_stronger_hf4(600000, 2800); + ASSERT_TRUE(res); + res = if_alt_chain_stronger_hf4(400000, 3999); + ASSERT_FALSE(res); + res = if_alt_chain_stronger_hf4(400000, 4001); + ASSERT_TRUE(res); + res = if_alt_chain_stronger_hf4(200000, 7000); + ASSERT_FALSE(res); + res = if_alt_chain_stronger_hf4(200000, 7700); + ASSERT_TRUE(res); + res = if_alt_chain_stronger_hf4(200000, 7000); + ASSERT_FALSE(res); + res = if_alt_chain_stronger_hf4(200000, 7700); + ASSERT_TRUE(res); + res = if_alt_chain_stronger_hf4(100000, 10000); + ASSERT_FALSE(res); + res = if_alt_chain_stronger_hf4(200000, 14000); + ASSERT_TRUE(res); }