From 65839b5ac1056e94699f4c423b53ccae8879ff64 Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Sun, 1 Oct 2023 13:40:06 +0100 Subject: [PATCH 1/2] Fix: long term block weight cache The long term block weight cache was doing a wrong calculation when adding a new block to the cache. --- src/cryptonote_core/blockchain.cpp | 35 ++---------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 8036c84cd2..7c9bd91637 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -4615,40 +4615,9 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti } else { - const uint64_t block_weight = m_db->get_block_weight(db_height - 1); + const uint64_t nblocks = std::min(m_long_term_block_weights_window, db_height); + const uint64_t long_term_median = get_long_term_block_weight_median(db_height - nblocks, nblocks); - uint64_t long_term_median; - if (db_height == 1) - { - long_term_median = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5; - } - else - { - uint64_t nblocks = std::min(m_long_term_block_weights_window, db_height); - if (nblocks == db_height) - --nblocks; - long_term_median = get_long_term_block_weight_median(db_height - nblocks - 1, nblocks); - } - - m_long_term_effective_median_block_weight = std::max(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median); - - uint64_t short_term_constraint = m_long_term_effective_median_block_weight; - if (hf_version >= HF_VERSION_2021_SCALING) - short_term_constraint += m_long_term_effective_median_block_weight * 7 / 10; - else - short_term_constraint += m_long_term_effective_median_block_weight * 2 / 5; - uint64_t long_term_block_weight = std::min(block_weight, short_term_constraint); - - if (db_height == 1) - { - long_term_median = long_term_block_weight; - } - else - { - m_long_term_block_weights_cache_tip_hash = m_db->get_block_hash_from_height(db_height - 1); - m_long_term_block_weights_cache_rolling_median.insert(long_term_block_weight); - long_term_median = m_long_term_block_weights_cache_rolling_median.median(); - } m_long_term_effective_median_block_weight = std::max(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median); std::vector weights; From bb33daab1bbed5f3542963e7b9b6c90f1619e29d Mon Sep 17 00:00:00 2001 From: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com> Date: Mon, 2 Oct 2023 01:38:10 +0100 Subject: [PATCH 2/2] add a test for the long term weight cache --- tests/unit_tests/long_term_block_weight.cpp | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/unit_tests/long_term_block_weight.cpp b/tests/unit_tests/long_term_block_weight.cpp index e52bd19559..5d954bf0ca 100644 --- a/tests/unit_tests/long_term_block_weight.cpp +++ b/tests/unit_tests/long_term_block_weight.cpp @@ -400,3 +400,38 @@ TEST(long_term_block_weight, long_growth_spike_and_drop) ASSERT_GT(long_term_effective_median_block_weight, 300000 * 1.07); ASSERT_LT(long_term_effective_median_block_weight, 300000 * 1.09); } + +TEST(long_term_block_weight, cache_matches_true_value) +{ + PREFIX(16); + + // Add big blocks to increase the block weight limit + for (uint64_t h = 0; h <= 2000; ++h) + { + size_t w = bc->get_current_cumulative_block_weight_limit(); + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}); + bc->update_next_cumulative_weight_limit(); + } + + ASSERT_GT(bc->get_current_cumulative_block_weight_limit() * 10/17 , 300000); + + // Add small blocks to the top of the chain + for (uint64_t h = 2000; h <= 5001; ++h) + { + size_t w = (bc->get_current_cumulative_block_weight_median() * 10/17) - 1000; + uint64_t ltw = bc->get_next_long_term_block_weight(w); + bc->get_db().add_block(std::make_pair(cryptonote::block(), ""), w, ltw, h, h, {}); + bc->update_next_cumulative_weight_limit(); + } + + // get the weight limit + uint64_t weight_limit = bc->get_current_cumulative_block_weight_limit(); + // refresh the cache + bc->m_long_term_block_weights_cache_rolling_median.clear(); + bc->get_long_term_block_weight_median(bc->get_db().height() - TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW, TEST_LONG_TERM_BLOCK_WEIGHT_WINDOW); + bc->update_next_cumulative_weight_limit(); + + // make sure the weight limit is the same + ASSERT_EQ(weight_limit, bc->get_current_cumulative_block_weight_limit()); +}