From 4a2bec3f2987f9d455a4c5375fd41651574b53f2 Mon Sep 17 00:00:00 2001 From: Matt Hess Date: Tue, 9 Dec 2025 18:52:32 +0000 Subject: [PATCH] Add sync mode to prevent mining during sidechain load - Added m_readyToMine flag to SideChain - Display LOADING SIDECHAIN banner at startup - Delay stratum server and mining until sidechain sync completes - Display MINING IS NOW ENABLED when ready - Prevents premature mining that caused peer bans and chain splits P2PServer starts immediately for sync, but stratum port doesn't open until sidechain is fully loaded and after pruning completes --- src/p2pool.cpp | 11 +++++++++++ src/side_chain.cpp | 9 +++++++++ src/side_chain.h | 5 +++++ 3 files changed, 25 insertions(+) diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 9ba215d..4a1f11d 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -1417,6 +1417,17 @@ void p2pool::download_block_headers4(uint64_t start_height, uint64_t current_hei update_median_timestamp(); if (m_serversStarted.exchange(1) == 0) { m_p2pServer = new P2PServer(this); + + // Display loading banner + LOGINFO(0, log::LightCyan() << "########################################################"); + LOGINFO(0, log::LightCyan() << "LOADING SIDECHAIN - MINING MAY NOT OCCUR UNTIL COMPLETE"); + LOGINFO(0, log::LightCyan() << "########################################################"); + + // Wait for sidechain to be ready before starting stratum/mining + while (!m_sideChain->is_ready_to_mine()) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } + m_stratumServer = new StratumServer(this); #if defined(WITH_RANDOMX) && !defined(P2POOL_UNIT_TESTS) if (m_params->m_minerThreads) { diff --git a/src/side_chain.cpp b/src/side_chain.cpp index ac35eb3..0476f3d 100644 --- a/src/side_chain.cpp +++ b/src/side_chain.cpp @@ -2447,6 +2447,15 @@ void SideChain::prune_old_blocks() } #endif } + + // If side-chain started pruning blocks it means the initial sync is complete + // It's now safe to delete cached blocks + if (!m_readyToMine.load()) { + m_readyToMine.store(true); + LOGINFO(0, log::LightGreen() << "########################################"); + LOGINFO(0, log::LightGreen() << "SIDECHAIN LOADED - MINING IS NOW ENABLED"); + LOGINFO(0, log::LightGreen() << "########################################"); + } } void SideChain::get_missing_blocks(unordered_set& missing_blocks) const diff --git a/src/side_chain.h b/src/side_chain.h index bd4ed03..962c3c5 100644 --- a/src/side_chain.h +++ b/src/side_chain.h @@ -88,6 +88,8 @@ public: [[nodiscard]] FORCEINLINE uint64_t miner_count() const { ReadLock lock(m_seenDataLock); return m_seenWallets.size(); } [[nodiscard]] FORCEINLINE uint64_t onion_pubkeys_count() const { ReadLock lock(m_seenDataLock); return m_seenOnionPubkeys.size(); } [[nodiscard]] uint64_t last_updated() const; + [[nodiscard]] bool is_ready_to_mine() const { return m_readyToMine.load(); } + void set_ready_to_mine(bool ready) { m_readyToMine.store(ready); } [[nodiscard]] bool is_default() const; [[nodiscard]] bool is_mini() const; [[nodiscard]] bool is_nano() const; @@ -141,6 +143,9 @@ private: mutable uint64_t m_adoptedGenesisHeight{ 0 }; mutable uint64_t m_adoptedGenesisTime{ 0 }; + // Sync state - prevents mining/bans during startup + std::atomic m_readyToMine{ false }; + std::map> m_blocksByHeight; unordered_map m_blocksById; unordered_map m_blocksByMerkleRoot;