Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1001/** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has1002* at most count entries.1003*/1004void FindNextBlocksToDownload(const Peer& peer, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller) EXCLUSIVE_LOCKS_REQUIRED(cs_main);1006/** Request blocks for the background chainstate, if one is in use. */1007void TryDownloadingHistoricalBlocks(const Peer& peer, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, const CBlockIndex* from_tip, const CBlockIndex* target_block) EXCLUSIVE_LOCKS_REQUIRED(cs_main);1009/**1010* \brief Find next blocks to download from a peer after a starting block.1011*1012* \param vBlocks Vector of blocks to download which will be appended to.1013* \param peer Peer which blocks will be downloaded from.1014* \param state Pointer to the state of the peer.1015* \param pindexWalk Pointer to the starting block to add to vBlocks.1016* \param count Maximum number of blocks to allow in vBlocks. No more1017* blocks will be added if it reaches this size.1018* \param nWindowEnd Maximum height of blocks to allow in vBlocks. No1019* blocks will be added above this height.1020* \param activeChain Optional pointer to a chain to compare against. If1021* provided, any next blocks which are already contained1022* in this chain will not be appended to vBlocks, but1023* instead will be used to update the1024* state->pindexLastCommonBlock pointer.1025* \param nodeStaller Optional pointer to a NodeId variable that will receive1026* the ID of another peer that might be causing this peer1027* to stall. This is set to the ID of the peer which1028* first requested the first in-flight block in the1029* download window. It is only set if vBlocks is empty at1030* the end of this function call and if increasing1031* nWindowEnd by 1 would cause it to be non-empty (which1032* indicates the download might be stalled because every1033* block in the window is in flight and no other peer is1034* trying to download the next block).1035*/1036void FindNextBlocks(std::vector<const CBlockIndex*>& vBlocks, const Peer& peer, CNodeState *state, const CBlockIndex *pindexWalk, unsigned int count, int nWindowEnd, const CChain* activeChain=nullptr, NodeId* nodeStaller=nullptr) EXCLUSIVE_LOCKS_REQUIRED(cs_main);1038/* Multimap used to preserve insertion order */1039typedef std::multimap<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator>> BlockDownloadMap;1040BlockDownloadMap mapBlocksInFlight GUARDED_BY(cs_main);1042/** When our tip was last updated. */1043std::atomic<std::chrono::seconds> m_last_tip_update{0s};1045/** Determine whether or not a peer can request a transaction, and return it (or nullptr if not found or not allowed). */1046CTransactionRef FindTxForGetData(const Peer::TxRelay& tx_relay, const GenTxid& gtxid)1047EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, !tx_relay.m_tx_inventory_mutex);1049void ProcessGetData(CNode& pfrom, Peer& peer, const std::atomic<bool>& interruptMsgProc)1050EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex, peer.m_getdata_requests_mutex, NetEventsInterface::g_msgproc_mutex)1051LOCKS_EXCLUDED(::cs_main);1053/** Process a new block. Perform any post-processing housekeeping */1054void ProcessBlock(CNode& node, const std::shared_ptr<const CBlock>& block, bool force_processing, bool min_pow_checked);1056/** Process compact block txns */1057void ProcessCompactBlockTxns(CNode& pfrom, Peer& peer, const BlockTransactions& block_transactions)1058EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex, !m_most_recent_block_mutex);1060/**1061* Schedule an INV for a transaction to be sent to the given peer (via `PushMessage()`).1062* The transaction is picked from the list of transactions for private broadcast.1063* It is assumed that the connection to the peer is `ConnectionType::PRIVATE_BROADCAST`.1064* Avoid calling this for other peers since it will degrade privacy.1065*/1066void PushPrivateBroadcastTx(CNode& node) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex, !m_most_recent_block_mutex);1068/**1069* When a peer sends us a valid block, instruct it to announce blocks to us1070* using CMPCTBLOCK if possible by adding its nodeid to the end of1071* lNodesAnnouncingHeaderAndIDs, and keeping that list under a certain size by1072* removing the first element if necessary.1073*/1074void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_peer_mutex);1076/** Stack of nodes which we have set to announce using compact blocks */1077std::list<NodeId> lNodesAnnouncingHeaderAndIDs GUARDED_BY(cs_main);1079/** Number of peers from which we're downloading blocks. */1080int m_peers_downloading_from GUARDED_BY(cs_main) = 0;1082void AddToCompactExtraTransactions(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);1084/** Orphan/conflicted/etc transactions that are kept for compact block reconstruction.1085* The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN of1086* these are kept in a ring buffer */1087std::vector<std::pair<Wtxid, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);1088/** Offset into vExtraTxnForCompact to insert the next tx */1089size_t vExtraTxnForCompactIt GUARDED_BY(g_msgproc_mutex) = 0;1091/** Check whether the last unknown block a peer advertised is not yet known. */1092void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);1093/** Update tracking information about which blocks a peer is assumed to have. */1094void UpdateBlockAvailability(NodeId nodeid, const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);1095bool CanDirectFetch() EXCLUSIVE_LOCKS_REQUIRED(cs_main);1097/**1098* Estimates the distance, in blocks, between the best-known block and the network chain tip.1099* Utilizes the best-block time and the chainparams blocks spacing to approximate it.1100*/1101int64_t ApproximateBestBlockDepth() const;1103/**1104* To prevent fingerprinting attacks, only send blocks/headers outside of1105* the active chain if they are no more than a month older (both in time,1106* and in best equivalent proof of work) than the best header chain we know1107* about and we fully-validated them at some point.1108*/1109bool BlockRequestAllowed(const CBlockIndex& block_index) EXCLUSIVE_LOCKS_REQUIRED(cs_main);1110bool AlreadyHaveBlock(const uint256& block_hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);1111void ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv& inv)1112EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex, !m_most_recent_block_mutex);1114/**1115* Validation logic for compact filters request handling.1116*1117* May disconnect from the peer in the case of a bad request.1118*1119* @param[in] node The node that we received the request from1120* @param[in] peer The peer that we received the request from1121* @param[in] filter_type The filter type the request is for. Must be basic filters.1122* @param[in] start_height The start height for the request1123* @param[in] stop_hash The stop_hash for the request1124* @param[in] max_height_diff The maximum number of items permitted to request, as specified in BIP 1571125* @param[out] stop_index The CBlockIndex for the stop_hash block, if the request can be serviced.1126* @param[out] filter_index The filter index, if the request can be serviced.1127* @return True if the request can be serviced.1128*/1129bool PrepareBlockFilterRequest(CNode& node, Peer& peer,1130BlockFilterType filter_type, uint32_t start_height,1131const uint256& stop_hash, uint32_t max_height_diff,1132const CBlockIndex*& stop_index,1133BlockFilterIndex*& filter_index);1135/**1136* Handle a cfilters request.1137*1138* May disconnect from the peer in the case of a bad request.1139*1140* @param[in] node The node that we received the request from1141* @param[in] peer The peer that we received the request from1142* @param[in] vRecv The raw message received1143*/1144void ProcessGetCFilters(CNode& node, Peer& peer, DataStream& vRecv);1146/**1147* Handle a cfheaders request.1148*1149* May disconnect from the peer in the case of a bad request.1150*1151* @param[in] node The node that we received the request from1152* @param[in] peer The peer that we received the request from1153* @param[in] vRecv The raw message received1154*/1155void ProcessGetCFHeaders(CNode& node, Peer& peer, DataStream& vRecv);1157/**1158* Handle a getcfcheckpt request.1159*1160* May disconnect from the peer in the case of a bad request.1161*1162* @param[in] node The node that we received the request from1163* @param[in] peer The peer that we received the request from1164* @param[in] vRecv The raw message received1165*/1166void ProcessGetCFCheckPt(CNode& node, Peer& peer, DataStream& vRecv);1168void ProcessPong(CNode& pfrom, Peer& peer, NodeClock::time_point ping_end, DataStream& vRecv);1170/** Checks if address relay is permitted with peer. If needed, initializes1171* the m_addr_known bloom filter and sets m_addr_relay_enabled to true.1172*1173* @return True if address relay is enabled with peer1174* False if address relay is disallowed1175*/1176bool SetupAddressRelay(const CNode& node, Peer& peer) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);1178void ProcessAddrs(std::string_view msg_type, CNode& pfrom, Peer& peer, std::vector<CAddress>&& vAddr, const std::atomic<bool>& interruptMsgProc)1179EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex, !m_peer_mutex);1181void AddAddressKnown(Peer& peer, const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);1182void PushAddress(Peer& peer, const CAddress& addr) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);1184void LogBlockHeader(const CBlockIndex& index, const CNode& peer, bool via_compact_block);1186/// The transactions to be broadcast privately.1187PrivateBroadcast m_tx_for_private_broadcast;1189mutable Mutex m_inv_to_send_mutex ACQUIRED_BEFORE(m_mempool.cs);1190InvToSendBucket m_inbound_inv_bucket GUARDED_BY(m_inv_to_send_mutex);1191InvToSendBucket m_outbound_inv_bucket GUARDED_BY(m_inv_to_send_mutex);1192std::atomic<NodeClock::time_point> m_next_inv_bucket_check{NodeClock::time_point::min()};1193std::optional<NodeClock::time_point> m_next_inv_bucket_heartbeat GUARDED_BY(m_inv_to_send_mutex);1195void ProcessInvBacklog(NodeClock::time_point now, bool backlog_bumped=false) EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_inv_to_send_mutex);1196};1198const CNodeState* PeerManagerImpl::State(NodeId pnode) const1199{1200std::map<NodeId, CNodeState>::const_iterator it = m_node_states.find(pnode);1201if (it == m_node_states.end())1202return nullptr;1203return &it->second;1204}1206CNodeState* PeerManagerImpl::State(NodeId pnode)1207{1208return const_cast<CNodeState*>(std::as_const(*this).State(pnode));1209}1211/**1212* Whether the peer supports the address. For example, a peer that does not1213* implement BIP155 cannot receive Tor v3 addresses because it requires1214* ADDRv2 (BIP155) encoding.1215*/1216static bool IsAddrCompatible(const Peer& peer, const CAddress& addr)1217{1218return peer.m_wants_addrv2 || addr.IsAddrV1Compatible();1219}1221void PeerManagerImpl::AddAddressKnown(Peer& peer, const CAddress& addr)1222{1223assert(peer.m_addr_known);1224peer.m_addr_known->insert(addr.GetKey());1225}1227void PeerManagerImpl::PushAddress(Peer& peer, const CAddress& addr)1228{1229// Known checking here is only to save space from duplicates.1230// Before sending, we'll filter it again for known addresses that were1231// added after addresses were pushed.1232assert(peer.m_addr_known);1233if (addr.IsValid() && !peer.m_addr_known->contains(addr.GetKey()) && IsAddrCompatible(peer, addr)) {1234if (peer.m_addrs_to_send.size() >= MAX_ADDR_TO_SEND) {1235peer.m_addrs_to_send[m_rng.randrange(peer.m_addrs_to_send.size())] = addr;1236} else {1237peer.m_addrs_to_send.push_back(addr);1238}1239}1240}1242static void AddKnownTx(Peer& peer, const uint256& hash)1243{1244auto tx_relay = peer.GetTxRelay();1245if (!tx_relay) return;1247LOCK(tx_relay->m_tx_inventory_mutex);1248tx_relay->m_tx_inventory_known_filter.insert(hash);1249}