From bf546a200bba2879d0c65531e0f9b1dcef49a6ec Mon Sep 17 00:00:00 2001 From: DCG-Claude Date: Sun, 18 Oct 2026 01:10:41 -0500 Subject: [PATCH 1/2] Merge bitcoin/bitcoin#26140: refactor: Move CNodeState members guarded by g_msgproc_mutex to Peer 3a060ae7b67cc28fc60cf28cbc518fa1df24f545 scripted-diff: Rename nUnconnectingHeaders and fPreferHeaders (dergoegge) 279c53d7e4e920d3d09da74689761a2961b1a636 [net processing] Move m_recently_announced_invs from CNodeState to Peer (dergoegge) 938a8e2566bf2f819adeb75a08c0c8ba9a85fe1c [net processing] Annotate m_recently_announced_invs as guarded by g_msgproc_mutex (dergoegge) 8a2cb1f749ade31bb0655567cd0062db8a7164e5 [net processing] Move fPreferHeaders from CNodeState to Peer (dergoegge) 3605011e79d0d43ff532a2c3cc9cad4cc48eb06c [net processing] Annotate fPreferHeaders as guarded by g_msgproc_mutex (dergoegge) 4b84e502f5ba69d650191ce8f2e20b86c1d427ed [net processing] Move m_headers_sync_timeout from CNodeState to Peer (dergoegge) 689b747fc34a5670a24bb5c4b1986dd8670b55ef [net processing] Annotate m_headers_sync_timeout as guarded by g_msgproc_mutex (dergoegge) d8c0d1c345546c6066274edbf3bf4fb5d6f75419 [net processing] Move nUnconnectingHeaders from CNodeState to Peer (dergoegge) 5f80d8d1eec14253407ceed1a813619d3e5a0fe4 [net processing] Annotate nUnconnectingHeaders as guarded by g_msgproc_mutex (dergoegge) 1d87137227ee125018006935d55164a72265c935 [validation] Annotate ChainstateManager::m_best_header as guarded by cs_main (dergoegge) Pull request description: `nUnconnectingHeaders`, `m_headers_sync_timeout`, `fPreferHeaders` and `m_recently_announced_headers` are currently all `CNodeState` members even though they are only ever accessed from the message processing thread (therefore sufficiently guarded exclusively by `g_msgproc_mutex`). `CNodeState` exists purely to hold validation-specific state guarded by `cs_main` that is accessed by multiple threads. This PR adds thread-safety annotations for the above mentioned `CNodeState` members and moves them to `Peer`. ACKs for top commit: glozow: code review ACK 3a060ae7b67cc28fc60cf28cbc518fa1df24f545, as in I am convinced these members shouldn't be guarded by cs_main and belong in Peer/TxRelay. clang checked the annotations for me. hebasto: ACK 3a060ae7b67cc28fc60cf28cbc518fa1df24f545 Tree-SHA512: 2db27c03f2c6ed36ad7dfbb4f862eeed3c3e57f845cf8abb9e7cada36f976257311892020bbcff513fbe662a881c93270e3a126946ceb0c3f94213b546bcaa81 Dash adaptations: - src/net_processing.cpp: FindTxForGetData takes (const Peer&, const uint256& txid) not GenTxid; Dash has no wtxid relay and keeps its asset-unlock instance-hash lookup - src/net_processing.cpp: upstream's new `const TxRelay* GetTxRelay() const` is dropped; Dash already has one (respecting m_can_tx_relay) and m_tx_relay_mutex is already mutable - src/net_processing.cpp: HandleFewUnconnectingHeaders keeps Dash's GETHEADERS/GETHEADERS2 choice and the msg_type in its log line, now using the cs_main-snapshotted best_header - src/net_processing.cpp: UpdatePeerStateForReceivedHeaders call keeps Dash's GetHeadersLimit(pfrom, uses_compressed) in place of MAX_HEADERS_RESULTS - src/net_processing.cpp: Dash's DSTX-aware tx announcement loop inserts announce_hash into tx_relay->m_recently_announced_invs, not the CNodeState copy - src/net_processing.cpp: Dash-only fPreferHeadersCompressed (SENDHEADERS2) and m_recent_object_requests stay in CNodeState; upstream only moves fPreferHeaders - src/net_processing.cpp: the headers-sync timeout check keeps Dash's max_tip_age condition; only state.m_headers_sync_timeout becomes peer->m_headers_sync_timeout - test/functional/p2p_sendheaders_compressed.py: same MAX_UNCONNECTING_HEADERS -> MAX_NUM_UNCONNECTING_HEADERS_MSGS rename as in Dash's fork of p2p_sendheaders.py --- src/net_processing.cpp | 108 +++++++++--------- src/validation.h | 2 +- test/functional/p2p_sendheaders.py | 10 +- test/functional/p2p_sendheaders_compressed.py | 10 +- 4 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 9ca230901f5f..6bccb711b2ba 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -174,7 +174,7 @@ static constexpr double BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 0.5; /** Maximum number of headers to announce when relaying blocks with headers message.*/ static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8; /** Maximum number of unconnecting headers announcements before DoS score */ -static const int MAX_UNCONNECTING_HEADERS = 10; +static const int MAX_NUM_UNCONNECTING_HEADERS_MSGS = 10; /** Minimum blocks required to signal NODE_NETWORK_LIMITED */ static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS = 288; /** Average delay between local address broadcasts */ @@ -316,6 +316,9 @@ struct Peer { /** A bloom filter for which transactions to announce to the peer. See BIP37. */ std::unique_ptr m_bloom_filter PT_GUARDED_BY(m_bloom_filter_mutex) GUARDED_BY(m_bloom_filter_mutex){nullptr}; + /** A rolling bloom filter of all announced tx CInvs to this peer */ + CRollingBloomFilter m_recently_announced_invs GUARDED_BY(NetEventsInterface::g_msgproc_mutex){INVENTORY_MAX_RECENT_RELAY, 0.000001}; + mutable RecursiveMutex m_tx_inventory_mutex; /** A filter of all the txids that the peer has announced to * us or we have announced to the peer. We use this to avoid announcing @@ -445,6 +448,18 @@ struct Peer { /** Time of the last getheaders message to this peer */ NodeClock::time_point m_last_getheaders_timestamp GUARDED_BY(NetEventsInterface::g_msgproc_mutex){}; + /** Length of current-streak of unconnecting headers announcements */ + int m_num_unconnecting_headers_msgs GUARDED_BY(NetEventsInterface::g_msgproc_mutex){0}; + + /** When to potentially disconnect peer for stalling headers download */ + std::chrono::microseconds m_headers_sync_timeout GUARDED_BY(NetEventsInterface::g_msgproc_mutex){0us}; + + /** Whether this peer wants invs or headers (when possible) for block announcements */ + bool m_prefers_headers GUARDED_BY(NetEventsInterface::g_msgproc_mutex){false}; + + /** Whether this peer wants invs or compressed headers (when possible) for block announcements */ + bool m_prefers_headers_compressed GUARDED_BY(NetEventsInterface::g_msgproc_mutex){false}; + explicit Peer(NodeId id, ServiceFlags our_services) : m_id(id) , m_our_services{our_services} @@ -492,12 +507,8 @@ struct CNodeState { const CBlockIndex* pindexLastCommonBlock{nullptr}; //! The best header we have sent our peer. const CBlockIndex* pindexBestHeaderSent{nullptr}; - //! Length of current-streak of unconnecting headers announcements - int nUnconnectingHeaders{0}; //! Whether we've started headers synchronization with this peer. bool fSyncStarted{false}; - //! When to potentially disconnect peer for stalling headers download - std::chrono::microseconds m_headers_sync_timeout{0us}; //! Since when we're stalling block download progress (in microseconds), or 0. std::chrono::microseconds m_stalling_since{0us}; std::list vBlocksInFlight; @@ -505,10 +516,6 @@ struct CNodeState { std::chrono::microseconds m_downloading_since{0us}; //! Whether we consider this a preferred download peer. bool fPreferredDownload{false}; - //! Whether this peer wants invs or headers (when possible) for block announcements. - bool fPreferHeaders{false}; - //! Whether this peer wants invs or compressed headers (when possible) for block announcements. - bool fPreferHeadersCompressed{false}; /** Whether this peer wants invs or cmpctblocks (when possible) for block announcements. */ bool m_requested_hb_cmpctblocks{false}; /** Whether this peer will send us cmpctblocks if we request them. */ @@ -557,9 +564,6 @@ struct CNodeState { //! Whether this peer is an inbound connection const bool m_is_inbound; - //! A rolling bloom filter of all announced tx CInvs to this peer. - CRollingBloomFilter m_recently_announced_invs = CRollingBloomFilter{INVENTORY_MAX_RECENT_RELAY, 0.000001}; - //! The GETDATA-only objects (see IsGetDataOnlyObject) we have recently asked this peer for. The //! tracker cannot answer "did we ever ask?" on its own: an announcement is erased once it //! expires as the sole one for its hash, or once the object is accepted from anywhere. @@ -807,7 +811,8 @@ class PeerManagerImpl final : public PeerManager /** Potentially fetch blocks from this peer upon receipt of a new headers tip */ void HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, const CBlockIndex& last_header); /** Update peer state based on received headers message */ - void UpdatePeerStateForReceivedHeaders(CNode& pfrom, const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers); + void UpdatePeerStateForReceivedHeaders(CNode& pfrom, Peer& peer, const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers) + EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex); void SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req); @@ -1095,10 +1100,12 @@ class PeerManagerImpl final : public PeerManager std::atomic m_last_tip_update{0s}; /** Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed). */ - CTransactionRef FindTxForGetData(const CNode* peer, const uint256& txid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) LOCKS_EXCLUDED(cs_main); + CTransactionRef FindTxForGetData(const Peer& peer, const uint256& txid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) + LOCKS_EXCLUDED(cs_main) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface::g_msgproc_mutex); void ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic& interruptMsgProc) - EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, peer.m_getdata_requests_mutex) LOCKS_EXCLUDED(::cs_main); + EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, peer.m_getdata_requests_mutex, NetEventsInterface::g_msgproc_mutex) + LOCKS_EXCLUDED(::cs_main); /** Process a new block. Perform any post-processing housekeeping */ void ProcessBlock(CNode& from, const std::shared_ptr& pblock, bool force_processing); @@ -2911,7 +2918,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& } //! Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed). -CTransactionRef PeerManagerImpl::FindTxForGetData(const CNode* peer, const uint256& txid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) +CTransactionRef PeerManagerImpl::FindTxForGetData(const Peer& peer, const uint256& txid, const std::chrono::seconds mempool_req, const std::chrono::seconds now) { auto txinfo = m_mempool.info(txid); if (!txinfo.tx) { @@ -2933,7 +2940,7 @@ CTransactionRef PeerManagerImpl::FindTxForGetData(const CNode* peer, const uint2 LOCK(cs_main); // Otherwise, the transaction must have been announced recently. - if (State(peer->GetId())->m_recently_announced_invs.contains(txid)) { + if (Assume(peer.GetTxRelay())->m_recently_announced_invs.contains(txid)) { // If it was, it can be relayed from either the mempool... if (txinfo.tx) return std::move(txinfo.tx); // ... or the relay pool. @@ -2987,7 +2994,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic bool push = false; if (inv.IsGenTxMsg()) { - CTransactionRef tx = FindTxForGetData(&pfrom, inv.hash, mempool_req, now); + CTransactionRef tx = FindTxForGetData(peer, inv.hash, mempool_req, now); if (tx) { CCoinJoinBroadcastTx dstx; if (inv.IsMsgDstx()) { @@ -3020,8 +3027,7 @@ void PeerManagerImpl::ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic for (const uint256& parent_txid : parent_ids_to_add) { // Relaying a transaction with a recent but unconfirmed parent. if (WITH_LOCK(tx_relay->m_tx_inventory_mutex, return !tx_relay->m_tx_inventory_known_filter.contains(parent_txid))) { - LOCK(cs_main); - State(pfrom.GetId())->m_recently_announced_invs.insert(parent_txid); + tx_relay->m_recently_announced_invs.insert(parent_txid); } } } @@ -3142,38 +3148,37 @@ void PeerManagerImpl::SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlo * * We'll send a getheaders message in response to try to connect the chain. * - * The peer can send up to MAX_UNCONNECTING_HEADERS in a row that + * The peer can send up to MAX_NUM_UNCONNECTING_HEADERS_MSGS in a row that * don't connect before given DoS points. * * Once a headers message is received that is valid and does connect, - * nUnconnectingHeaders gets reset back to 0. + * m_num_unconnecting_headers_msgs gets reset back to 0. */ void PeerManagerImpl::HandleFewUnconnectingHeaders(CNode& pfrom, Peer& peer, const std::vector& headers) { - LOCK(cs_main); - CNodeState *nodestate = State(pfrom.GetId()); - - nodestate->nUnconnectingHeaders++; + peer.m_num_unconnecting_headers_msgs++; // Try to fill in the missing headers. std::string msg_type = UsesCompressedHeaders(peer) ? NetMsgType::GETHEADERS2 : NetMsgType::GETHEADERS; - if (MaybeSendGetHeaders(pfrom, msg_type, GetLocator(m_chainman.m_best_header), peer)) { - LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending %s (%d) to end (peer=%d, nUnconnectingHeaders=%d)\n", + const CBlockIndex* best_header{WITH_LOCK(cs_main, return m_chainman.m_best_header)}; + if (MaybeSendGetHeaders(pfrom, msg_type, GetLocator(best_header), peer)) { + LogPrint(BCLog::NET, "received header %s: missing prev block %s, sending %s (%d) to end (peer=%d, m_num_unconnecting_headers_msgs=%d)\n", headers[0].GetHash().ToString(), headers[0].hashPrevBlock.ToString(), msg_type, - m_chainman.m_best_header->nHeight, - pfrom.GetId(), nodestate->nUnconnectingHeaders); + best_header->nHeight, + pfrom.GetId(), peer.m_num_unconnecting_headers_msgs); } + // Set hashLastUnknownBlock for this peer, so that if we // eventually get the headers - even from a different peer - // we can use this peer to download. - UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()); + WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash())); // The peer may just be broken, so periodically assign DoS points if this // condition persists. - if (nodestate->nUnconnectingHeaders % MAX_UNCONNECTING_HEADERS == 0) { - Misbehaving(peer, 20, strprintf("%d non-connecting headers", nodestate->nUnconnectingHeaders)); + if (peer.m_num_unconnecting_headers_msgs % MAX_NUM_UNCONNECTING_HEADERS_MSGS == 0) { + Misbehaving(peer, 20, strprintf("%d non-connecting headers", peer.m_num_unconnecting_headers_msgs)); } } @@ -3277,15 +3282,16 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const Peer& peer, c * whether that header was new and whether the headers message was full, * update the state we keep for the peer. */ -void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom, +void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom, Peer& peer, const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers) { + if (peer.m_num_unconnecting_headers_msgs > 0) { + LogPrint(BCLog::NET, "peer=%d: resetting m_num_unconnecting_headers_msgs (%d -> 0)\n", pfrom.GetId(), peer.m_num_unconnecting_headers_msgs); + } + peer.m_num_unconnecting_headers_msgs = 0; + LOCK(cs_main); CNodeState *nodestate = State(pfrom.GetId()); - if (nodestate->nUnconnectingHeaders > 0) { - LogPrint(BCLog::NET, "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.GetId(), nodestate->nUnconnectingHeaders); - } - nodestate->nUnconnectingHeaders = 0; UpdateBlockAvailability(pfrom.GetId(), last_header.GetBlockHash()); @@ -3390,7 +3396,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, } } - UpdatePeerStateForReceivedHeaders(pfrom, *pindexLast, received_new_header, nCount == GetHeadersLimit(pfrom, uses_compressed)); + UpdatePeerStateForReceivedHeaders(pfrom, peer, *pindexLast, received_new_header, nCount == GetHeadersLimit(pfrom, uses_compressed)); // Consider immediately downloading blocks. HeadersDirectFetchBlocks(pfrom, peer, *pindexLast); @@ -4293,14 +4299,12 @@ void PeerManagerImpl::ProcessMessage( } if (msg_type == NetMsgType::SENDHEADERS) { - LOCK(cs_main); - State(pfrom.GetId())->fPreferHeaders = true; + peer->m_prefers_headers = true; return; } if (msg_type == NetMsgType::SENDHEADERS2) { - LOCK(cs_main); - State(pfrom.GetId())->fPreferHeadersCompressed = true; + peer->m_prefers_headers_compressed = true; return; } @@ -6457,7 +6461,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) LogPrint(BCLog::NET, "initial %s (%d) to peer=%d (startheight:%d)\n", msg_type, pindexStart->nHeight, pto->GetId(), peer->m_starting_height); state.fSyncStarted = true; - state.m_headers_sync_timeout = current_time + HEADERS_DOWNLOAD_TIMEOUT_BASE + + peer->m_headers_sync_timeout = current_time + HEADERS_DOWNLOAD_TIMEOUT_BASE + ( // Convert HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER to microseconds before scaling // to maintain precision @@ -6482,7 +6486,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) // add all to the inv queue. LOCK(peer->m_block_inv_mutex); std::vector vHeaders; - bool fRevertToInv = ((!state.fPreferHeaders && !state.fPreferHeadersCompressed && + bool fRevertToInv = ((!peer->m_prefers_headers && !peer->m_prefers_headers_compressed && (!state.m_requested_hb_cmpctblocks || peer->m_blocks_for_headers_relay.size() > 1)) || peer->m_blocks_for_headers_relay.size() > MAX_BLOCKS_TO_ANNOUNCE); const CBlockIndex *pBestIndex = nullptr; // last header queued for delivery @@ -6568,7 +6572,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock)); } state.pindexBestHeaderSent = pBestIndex; - } else if (state.fPreferHeadersCompressed) { + } else if (peer->m_prefers_headers_compressed) { std::vector vHeadersCompressed; std::list last_unique_versions; @@ -6582,7 +6586,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) // Push message to peer m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::HEADERS2, vHeadersCompressed)); state.pindexBestHeaderSent = pBestIndex; - } else if (state.fPreferHeaders) { + } else if (peer->m_prefers_headers) { if (vHeaders.size() > 1) { LogPrint(BCLog::NET, "%s: %u headers, range (%s, %s), to peer=%d\n", __func__, vHeaders.size(), @@ -6777,7 +6781,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto) nInvType = MSG_DSTX; } // Send - State(pto->GetId())->m_recently_announced_invs.insert(announce_hash); + tx_relay->m_recently_announced_invs.insert(announce_hash); nRelayedTransactions++; { // Expire old relay messages @@ -6854,10 +6858,10 @@ bool PeerManagerImpl::SendMessages(CNode* pto) } } // Check for headers sync timeouts - if (state.fSyncStarted && state.m_headers_sync_timeout < std::chrono::microseconds::max()) { + if (state.fSyncStarted && peer->m_headers_sync_timeout < std::chrono::microseconds::max()) { // Detect whether this is a stalling initial-headers-sync peer if (m_chainman.m_best_header->Time() <= NodeClock::now() - m_chainman.m_options.max_tip_age) { - if (current_time > state.m_headers_sync_timeout && nSyncStarted == 1 && (m_num_preferred_download_peers - state.fPreferredDownload >= 1)) { + if (current_time > peer->m_headers_sync_timeout && nSyncStarted == 1 && (m_num_preferred_download_peers - state.fPreferredDownload >= 1)) { // Disconnect a peer (without NetPermissionFlags::NoBan permission) if it is our only sync peer, // and we have others we could be using instead. // Note: If all our peers are inbound, then we won't @@ -6876,13 +6880,13 @@ bool PeerManagerImpl::SendMessages(CNode* pto) // this peer (eventually). state.fSyncStarted = false; nSyncStarted--; - state.m_headers_sync_timeout = 0us; + peer->m_headers_sync_timeout = 0us; } } } else { // After we've caught up once, reset the timeout so we can't trigger // disconnect later. - state.m_headers_sync_timeout = std::chrono::microseconds::max(); + peer->m_headers_sync_timeout = std::chrono::microseconds::max(); } } diff --git a/src/validation.h b/src/validation.h index 566837c4b1fc..fb672d7621ac 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1046,7 +1046,7 @@ class ChainstateManager std::set m_failed_blocks; /** Best header we've seen so far (used for getheaders queries' starting points). */ - CBlockIndex* m_best_header = nullptr; + CBlockIndex* m_best_header GUARDED_BY(::cs_main){nullptr}; //! The total number of bytes available for us to use across all in-memory //! coins caches. This will be split somehow across chainstates. diff --git a/test/functional/p2p_sendheaders.py b/test/functional/p2p_sendheaders.py index e853d20c5b3a..a8ae9685e534 100755 --- a/test/functional/p2p_sendheaders.py +++ b/test/functional/p2p_sendheaders.py @@ -545,15 +545,15 @@ def test_nonnull_locators(self, test_node, inv_node): blocks = [] # Now we test that if we repeatedly don't send connecting headers, we # don't go into an infinite loop trying to get them to connect. - MAX_UNCONNECTING_HEADERS = 10 - for _ in range(MAX_UNCONNECTING_HEADERS + 1): + MAX_NUM_UNCONNECTING_HEADERS_MSGS = 10 + for _ in range(MAX_NUM_UNCONNECTING_HEADERS_MSGS + 1): blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 height += 1 - for i in range(1, MAX_UNCONNECTING_HEADERS): + for i in range(1, MAX_NUM_UNCONNECTING_HEADERS_MSGS): # Send a header that doesn't connect, check that we get a getheaders. with p2p_lock: test_node.last_message.pop("getheaders2" if test_node.nServices & NODE_HEADERS_COMPRESSED else "getheaders", None) @@ -567,8 +567,8 @@ def test_nonnull_locators(self, test_node, inv_node): blocks = blocks[2:] # Now try to see how many unconnecting headers we can send - # before we get disconnected. Should be 5*MAX_UNCONNECTING_HEADERS - for i in range(5 * MAX_UNCONNECTING_HEADERS - 1): + # before we get disconnected. Should be 5*MAX_NUM_UNCONNECTING_HEADERS_MSGS + for i in range(5 * MAX_NUM_UNCONNECTING_HEADERS_MSGS - 1): # Send a header that doesn't connect, check that we get a getheaders. with p2p_lock: test_node.last_message.pop("getheaders2" if test_node.nServices & NODE_HEADERS_COMPRESSED else "getheaders", None) diff --git a/test/functional/p2p_sendheaders_compressed.py b/test/functional/p2p_sendheaders_compressed.py index 3a6d17d624df..4d0f005efdbb 100755 --- a/test/functional/p2p_sendheaders_compressed.py +++ b/test/functional/p2p_sendheaders_compressed.py @@ -554,15 +554,15 @@ def test_nonnull_locators(self, test_node, inv_node): blocks = [] # Now we test that if we repeatedly don't send connecting headers, we # don't go into an infinite loop trying to get them to connect. - MAX_UNCONNECTING_HEADERS = 10 - for _ in range(MAX_UNCONNECTING_HEADERS + 1): + MAX_NUM_UNCONNECTING_HEADERS_MSGS = 10 + for _ in range(MAX_NUM_UNCONNECTING_HEADERS_MSGS + 1): blocks.append(create_block(tip, create_coinbase(height), block_time)) blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 height += 1 - for i in range(1, MAX_UNCONNECTING_HEADERS): + for i in range(1, MAX_NUM_UNCONNECTING_HEADERS_MSGS): # Send a header that doesn't connect, check that we get a getheaders. with p2p_lock: test_node.last_message.pop("getheaders2", None) @@ -576,8 +576,8 @@ def test_nonnull_locators(self, test_node, inv_node): blocks = blocks[2:] # Now try to see how many unconnecting headers we can send - # before we get disconnected. Should be 5*MAX_UNCONNECTING_HEADERS - for i in range(5 * MAX_UNCONNECTING_HEADERS - 1): + # before we get disconnected. Should be 5*MAX_NUM_UNCONNECTING_HEADERS_MSGS + for i in range(5 * MAX_NUM_UNCONNECTING_HEADERS_MSGS - 1): # Send a header that doesn't connect, check that we get a getheaders. with p2p_lock: test_node.last_message.pop("getheaders2", None) From 290ab768cbc0acc467bba38ff253c8ba1dbed1d2 Mon Sep 17 00:00:00 2001 From: DCG-Claude Date: Sun, 18 Oct 2026 01:10:41 -0500 Subject: [PATCH 2/2] Merge bitcoin/bitcoin#27482: kernel: chainparams updates for 25.x a2bef805c11a4ab391f4ea635bfde7dd2ec9ce81 kernel: update m_assumed_* chain params for 25.x (fanquake) 4128e01dbaa630396b0e7576ee8a1987267f77b9 kernel: update chainTxData for 25.x (fanquake) 00b2b114b442835c863e7772348cb1d1881ba0f2 kernel: update nMinimumChainWork & defaultAssumeValid for 25.x (fanquake) 07fcc0a82cfd08c991f61c2340630f0c4659a3a0 doc: update references to kernel/chainparams.cpp (fanquake) Pull request description: Update chainparams pre `25.x` branch off. Co-Author in the commits as a PR (#27223) had previously been opened too-early to do the same. Note: Remember that some variance is expected in the `m_assumed_*` sizes. ACKs for top commit: achow101: ACK a2bef805c11a4ab391f4ea635bfde7dd2ec9ce81 josibake: ACK https://github.com/bitcoin/bitcoin/pull/27482/commits/a2bef805c11a4ab391f4ea635bfde7dd2ec9ce81 gruve-p: ACK https://github.com/bitcoin/bitcoin/pull/27482/commits/a2bef805c11a4ab391f4ea635bfde7dd2ec9ce81 dergoegge: ACK a2bef805c11a4ab391f4ea635bfde7dd2ec9ce81 on the new mainnet params Tree-SHA512: 0b19c2ef15c6b15863d6a560a1053ee223057c7bfb617ffd3400b1734cee8f75bc6fd7f04d8f8e3f5af6220659a1987951a1b36945d6fe17d06972004fd62610 Dash adaptations: - doc/release-process.md: fixes the chainparams.cpp path in both of Dash's checklist items, since Dash splits upstream's single item into minor/major-release steps - src/kernel/chainparams.cpp: keeps Dash's own nMinimumChainWork, defaultAssumeValid, m_assumed_* and chainTxData values instead of upstream's Bitcoin 25.x values Not applicable to Dash (intentionally omitted): - src/kernel/chainparams.cpp: Bitcoin 25.x chain data (main/test/signet chainwork, assumevalid, sizes, txstats); Dash has its own chain, values and release-time updates, and no signet --- contrib/seeds/generate-seeds.py | 2 +- doc/release-process.md | 4 ++-- src/test/validation_tests.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/seeds/generate-seeds.py b/contrib/seeds/generate-seeds.py index 05ad6e6021c0..70d01bec71bb 100755 --- a/contrib/seeds/generate-seeds.py +++ b/contrib/seeds/generate-seeds.py @@ -3,7 +3,7 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. ''' -Script to generate list of seed nodes for chainparams.cpp. +Script to generate list of seed nodes for kernel/chainparams.cpp. This script expects two text files in the directory that is passed as an argument: diff --git a/doc/release-process.md b/doc/release-process.md index ae76bf26fa21..956b2754d406 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -12,7 +12,7 @@ Before every minor and major release: * [ ] Update version in `configure.ac` (don't forget to set `CLIENT_VERSION_IS_RELEASE` to `true`) * [ ] Write release notes (see below). To clear the release notes: `cp doc/release-notes-empty-template.md doc/release-notes.md` * [ ] Update flatpak [metainfo file](contrib/flatpak/org.dash.dash-core.metainfo.xml) with latest release tag and estimated release date -* [ ] Update the following variables in [`src/chainparams.cpp`](/src/chainparams.cpp) for mainnet and testnet: +* [ ] Update the following variables in [`src/kernel/chainparams.cpp`](/src/kernel/chainparams.cpp) for mainnet and testnet: - `nMinimumChainWork` with the "chainwork" value of RPC `getblockheader` using the same height as that selected for the previous step. - `defaultAssumeValid` with the output of RPC `getblockhash` using the `height` of `window_final_block_height` above (and update the block height comment with that height), taking into account the following: @@ -29,7 +29,7 @@ Before every minor and major release: Before every major release: * [ ] Update hardcoded [seeds](/contrib/seeds/README.md), see [this pull request](https://github.com/dashpay/dash/pull/5914) for an example. -* [ ] Update the following variables in [`src/chainparams.cpp`](/src/chainparams.cpp) for mainnet and testnet: +* [ ] Update the following variables in [`src/kernel/chainparams.cpp`](/src/kernel/chainparams.cpp) for mainnet and testnet: - `m_assumed_blockchain_size` and `m_assumed_chain_state_size` with the current size plus some overhead (see [this](#how-to-calculate-assumed-blockchain-and-chain-state-size) for information on how to calculate them). - `chainTxData` with statistics about the transaction count and rate. Use the output of the `getchaintxstats` RPC with an diff --git a/src/test/validation_tests.cpp b/src/test/validation_tests.cpp index c2f4bb7472e1..f7a938196eec 100644 --- a/src/test/validation_tests.cpp +++ b/src/test/validation_tests.cpp @@ -24,7 +24,7 @@ BOOST_AUTO_TEST_CASE(test_assumeutxo) const auto params = CreateChainParams(*m_node.args, CBaseChainParams::REGTEST); // These heights don't have assumeutxo configurations associated, per the contents - // of chainparams.cpp. + // of kernel/chainparams.cpp. std::vector bad_heights{0, 100, 111, 115, 209, 211}; for (auto empty : bad_heights) {