From c8d41b5e4a792c16bef2157d15edd60d2b88d059 Mon Sep 17 00:00:00 2001 From: sowle Date: Wed, 30 Apr 2025 05:46:25 +0300 Subject: [PATCH] non-pruning via special flag (WIP) --- src/currency_core/blockchain_storage.cpp | 14 +++---- src/currency_core/connection_context.h | 2 +- .../currency_protocol_defs.h | 4 +- .../currency_protocol_handler.inl | 40 +++++++++++++------ 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 2e867f1f..63bee8a0 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -754,15 +754,12 @@ bool blockchain_storage::pop_block_from_blockchain(transactions_map& onboard_tra //------------------------------------------------------------------ bool blockchain_storage::set_checkpoints(checkpoints&& chk_pts) { - if (m_non_pruning_mode_enabled) - return true; - m_checkpoints = chk_pts; try { m_db.begin_transaction(); if (m_db_blocks.size() < m_checkpoints.get_top_checkpoint_height()) - m_is_in_checkpoint_zone = true; + m_is_in_checkpoint_zone = !m_non_pruning_mode_enabled; // set to true unless non-pruning mode is on prune_ring_signatures_and_attachments_if_need(); m_db.commit_transaction(); return true; @@ -785,6 +782,7 @@ bool blockchain_storage::set_checkpoints(checkpoints&& chk_pts) bool blockchain_storage::prune_ring_signatures_and_attachments(uint64_t height, uint64_t& transactions_pruned, uint64_t& signatures_pruned, uint64_t& attachments_pruned) { CRITICAL_REGION_LOCAL(m_read_lock); + CHECK_AND_ASSERT_MES(!m_non_pruning_mode_enabled, false, "cannot prune while non-pruning mode is enabled"); CHECK_AND_ASSERT_MES(height < m_db_blocks.size(), false, "prune_ring_signatures called with wrong parameter: " << height << ", m_blocks.size() = " << m_db_blocks.size()); auto vptr = m_db_blocks[height]; @@ -818,7 +816,9 @@ bool blockchain_storage::prune_ring_signatures_and_attachments(uint64_t height, bool blockchain_storage::prune_ring_signatures_and_attachments_if_need() { CRITICAL_REGION_LOCAL(m_read_lock); - CHECK_AND_ASSERT_MES(!m_non_pruning_mode_enabled, false, "cannot prune while non-pruning mode is enabled"); + + if (m_non_pruning_mode_enabled) + return true; uint64_t top_block_height = get_top_block_height(); uint64_t pruning_end_height = m_checkpoints.get_checkpoint_before_height(top_block_height); @@ -2091,7 +2091,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto:: } else { - m_is_in_checkpoint_zone = true; + m_is_in_checkpoint_zone = !m_non_pruning_mode_enabled; // set to true unless non-pruning mode is on if (!m_checkpoints.check_block(abei.height, id)) { LOG_ERROR("CHECKPOINT VALIDATION FAILED"); @@ -6947,7 +6947,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt if (m_checkpoints.is_in_checkpoint_zone(get_current_blockchain_size())) { - m_is_in_checkpoint_zone = true; + m_is_in_checkpoint_zone = !m_non_pruning_mode_enabled; // set to true unless non-pruning mode is on if (!m_checkpoints.check_block(get_current_blockchain_size(), id)) { LOG_ERROR("CHECKPOINT VALIDATION FAILED @ " << height); diff --git a/src/currency_core/connection_context.h b/src/currency_core/connection_context.h index 43f372c5..5e094477 100644 --- a/src/currency_core/connection_context.h +++ b/src/currency_core/connection_context.h @@ -49,7 +49,7 @@ namespace currency }; state m_state; - uint64_t m_remote_blockchain_height; + uint64_t m_remote_blockchain_size; // height of the top block + 1 uint64_t m_last_response_height; int64_t m_time_delta; std::string m_remote_version; diff --git a/src/currency_protocol/currency_protocol_defs.h b/src/currency_protocol/currency_protocol_defs.h index b1ee93bc..190b2082 100644 --- a/src/currency_protocol/currency_protocol_defs.h +++ b/src/currency_protocol/currency_protocol_defs.h @@ -122,7 +122,7 @@ namespace currency std::list txs; std::list blocks; std::list missed_ids; - uint64_t current_blockchain_height; + uint64_t current_blockchain_height; // height of the top block + 1 BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(txs) @@ -140,6 +140,7 @@ namespace currency uint64_t last_checkpoint_height; uint64_t core_time; std::string client_version; + bool non_pruning_mode_enabled; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(current_height) @@ -147,6 +148,7 @@ namespace currency KV_SERIALIZE(last_checkpoint_height) KV_SERIALIZE(core_time) KV_SERIALIZE(client_version) + KV_SERIALIZE(non_pruning_mode_enabled) END_KV_SERIALIZE_MAP() }; diff --git a/src/currency_protocol/currency_protocol_handler.inl b/src/currency_protocol/currency_protocol_handler.inl index 959e963c..3d5710b6 100644 --- a/src/currency_protocol/currency_protocol_handler.inl +++ b/src/currency_protocol/currency_protocol_handler.inl @@ -181,16 +181,29 @@ namespace currency LOG_PRINT_L0("wtf"); } + if (m_core.get_blockchain_storage().is_non_pruning_mode_enabled()) + { + // if non-pruning mode is enabled, allow syncronization iff the remote is also in non-pruning mode, + // or if this node top height above the last checkpoint height of the remote + if (!hshd.non_pruning_mode_enabled && m_core.get_top_block_height() < hshd.last_checkpoint_height) + { + LOG_PRINT_YELLOW("Non-pruning mode: current top block height (" << m_core.get_top_block_height() << ") is less than the remote's most recent checkpoint height (" << hshd.last_checkpoint_height << + ") and the remove isn't in non-pruning mode, disconnecting.", LOG_LEVEL_0); + return false; + } + } + int64_t diff = static_cast(hshd.current_height) - static_cast(m_core.get_current_blockchain_size()); LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, (is_inital ? "Inital ":"Idle ") << "sync data returned unknown top block (" << hshd.top_id << "): " << m_core.get_top_block_height() << " -> " << hshd.current_height - 1 << " [" << std::abs(diff) << " blocks (" << diff / (24 * 60 * 60 / DIFFICULTY_TOTAL_TARGET ) << " days) " << (0 <= diff ? std::string("behind") : std::string("ahead")) << "] " << ENDL << "SYNCHRONIZATION started", (is_inital ? LOG_LEVEL_0 : LOG_LEVEL_1), (is_inital ? epee::log_space::console_color_yellow : epee::log_space::console_color_magenta)); - LOG_PRINT_L1("Remote top block height: " << hshd.current_height << ", id: " << hshd.top_id); + LOG_PRINT_L1("Remote top block height: " << hshd.current_height - 1 << ", id: " << hshd.top_id); + /*check if current height is in remote's checkpoints zone*/ if(hshd.last_checkpoint_height && m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() < hshd.last_checkpoint_height - && m_core.get_current_blockchain_size() < hshd.last_checkpoint_height ) + && m_core.get_top_block_height() < hshd.last_checkpoint_height ) { LOG_PRINT_RED("Remote node has longer checkpoints zone (" << hshd.last_checkpoint_height << ") " << "than local (" << m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() << "). " << @@ -199,7 +212,7 @@ namespace currency return false; } - if (!m_core.get_blockchain_storage().is_non_pruning_mode_enabled() && m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() < hshd.last_checkpoint_height) + if (m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() < hshd.last_checkpoint_height) { LOG_PRINT_MAGENTA("Remote node has longer checkpoints zone (" << hshd.last_checkpoint_height << ") " << "than local (" << m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height() << "). " << @@ -207,7 +220,7 @@ namespace currency } context.m_state = currency_connection_context::state_synchronizing; - context.m_remote_blockchain_height = hshd.current_height; + context.m_remote_blockchain_size = hshd.current_height; context.m_priv.m_last_fetched_block_ids.clear(); //let the socket to send response to handshake, but request callback, to let send request data after response LOG_PRINT_L3("requesting callback"); @@ -243,6 +256,7 @@ namespace currency hshd.last_checkpoint_height = m_core.get_blockchain_storage().get_checkpoints().get_top_checkpoint_height(); hshd.core_time = m_core.get_blockchain_storage().get_core_runtime_config().get_core_time(); hshd.client_version = PROJECT_VERSION_LONG; + hshd.non_pruning_mode_enabled = m_core.get_blockchain_storage().is_non_pruning_mode_enabled(); return true; } //------------------------------------------------------------------------------------------------------------------------ @@ -523,7 +537,7 @@ namespace currency return 1; } - context.m_remote_blockchain_height = arg.current_blockchain_height; + context.m_remote_blockchain_size = arg.current_blockchain_height; uint64_t total_blocks_parsing_time = 0; size_t count = 0; @@ -665,9 +679,9 @@ namespace currency } uint64_t current_size = m_core.get_blockchain_storage().get_current_blockchain_size(); LOG_PRINT_YELLOW(">>>>>>>>> sync progress: " << arg.blocks.size() << " blocks added, now have " - << current_size << " of " << context.m_remote_blockchain_height - << " ( " << std::fixed << std::setprecision(2) << current_size * 100.0 / context.m_remote_blockchain_height << "% ) and " - << context.m_remote_blockchain_height - current_size << " blocks left" + << current_size << " of " << context.m_remote_blockchain_size + << " ( " << std::fixed << std::setprecision(2) << current_size * 100.0 / context.m_remote_blockchain_size << "% ) and " + << context.m_remote_blockchain_size - current_size << " blocks left" , LOG_LEVEL_0); request_missing_objects(context, true); @@ -744,7 +758,7 @@ namespace currency LOG_PRINT_L2("[NOTIFY]NOTIFY_REQUEST_GET_OBJECTS(req_missing): requested_cumulative_size=" << requested_cumulative_size << ", blocks.size()=" << req.blocks.size() << ", txs.size()=" << req.txs.size()); LOG_PRINT_L3("[NOTIFY]NOTIFY_REQUEST_GET_OBJECTS(req_missing): " << ENDL << currency::print_kv_structure(req)); post_notify(req, context); - }else if(context.m_last_response_height < context.m_remote_blockchain_height-1) + }else if(context.m_last_response_height < context.m_remote_blockchain_size-1) {//we have to fetch more objects ids, request blockchain entry NOTIFY_REQUEST_CHAIN::request r = boost::value_initialized(); @@ -784,11 +798,11 @@ namespace currency }else { - CHECK_AND_ASSERT_MES(context.m_last_response_height == context.m_remote_blockchain_height-1 + CHECK_AND_ASSERT_MES(context.m_last_response_height == context.m_remote_blockchain_size-1 && !context.m_priv.m_needed_objects.size() && !context.m_priv.m_requested_objects.size(), false, "request_missing_blocks final condition failed!" << "\r\nm_last_response_height=" << context.m_last_response_height - << "\r\nm_remote_blockchain_height=" << context.m_remote_blockchain_height + << "\r\nm_remote_blockchain_size=" << context.m_remote_blockchain_size << "\r\nm_needed_objects.size()=" << context.m_priv.m_needed_objects.size() << "\r\nm_requested_objects.size()=" << context.m_priv.m_requested_objects.size() << "\r\non connection [" << epee::net_utils::print_connection_context_short(context)<< "]"); @@ -999,9 +1013,9 @@ namespace currency return 1; } - context.m_remote_blockchain_height = arg.total_height; + context.m_remote_blockchain_size = arg.total_height; context.m_last_response_height = arg.start_height + arg.m_block_ids.size()-1; - if(context.m_last_response_height > context.m_remote_blockchain_height) + if(context.m_last_response_height > context.m_remote_blockchain_size) { LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_CHAIN_ENTRY, with \r\nm_total_height=" << arg.total_height << "\r\nm_start_height=" << arg.start_height