Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
net_processing.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <net_processing.h>
7
8#include <addrman.h>
11#include <avalanche/processor.h>
12#include <avalanche/proof.h>
16#include <banman.h>
17#include <blockencodings.h>
18#include <blockfilter.h>
19#include <blockvalidity.h>
20#include <chain.h>
21#include <chainparams.h>
22#include <config.h>
23#include <consensus/amount.h>
25#include <hash.h>
26#include <headerssync.h>
28#include <invrequest.h>
30#include <merkleblock.h>
31#include <netbase.h>
32#include <netmessagemaker.h>
33#include <node/blockstorage.h>
34#include <policy/fees.h>
35#include <policy/policy.h>
36#include <policy/settings.h>
37#include <primitives/block.h>
39#include <random.h>
40#include <reverse_iterator.h>
41#include <scheduler.h>
42#include <streams.h>
43#include <timedata.h>
44#include <tinyformat.h>
45#include <txmempool.h>
46#include <txorphanage.h>
47#include <util/check.h> // For NDEBUG compile time check
48#include <util/strencodings.h>
49#include <util/trace.h>
50#include <validation.h>
51
52#include <algorithm>
53#include <atomic>
54#include <chrono>
55#include <functional>
56#include <future>
57#include <memory>
58#include <numeric>
59#include <typeinfo>
60
62static constexpr auto RELAY_TX_CACHE_TIME = 15min;
67static constexpr auto UNCONDITIONAL_RELAY_DELAY = 2min;
72static constexpr auto HEADERS_DOWNLOAD_TIMEOUT_BASE = 15min;
73static constexpr auto HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER = 1ms;
75static constexpr auto HEADERS_RESPONSE_TIME{2min};
82static constexpr auto CHAIN_SYNC_TIMEOUT{20min};
84static constexpr auto STALE_CHECK_INTERVAL{10min};
86static constexpr auto EXTRA_PEER_CHECK_INTERVAL{45s};
91static constexpr auto MINIMUM_CONNECT_TIME{30s};
93static constexpr uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL;
96static constexpr int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60;
99static constexpr int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60;
103static constexpr auto PING_INTERVAL{2min};
105static const unsigned int MAX_LOCATOR_SZ = 101;
107static const unsigned int MAX_INV_SZ = 50000;
108static_assert(MAX_PROTOCOL_MESSAGE_LENGTH > MAX_INV_SZ * sizeof(CInv),
109 "Max protocol message length must be greater than largest "
110 "possible INV message");
111
113static constexpr auto GETAVAADDR_INTERVAL{2min};
114
119static constexpr auto AVALANCHE_AVAPROOFS_TIMEOUT{2min};
120
128
138
140 const std::chrono::seconds nonpref_peer_delay;
141
146 const std::chrono::seconds overloaded_peer_delay;
147
152 const std::chrono::microseconds getdata_interval;
153
159};
160
162 100, // max_peer_request_in_flight
163 5000, // max_peer_announcements
164 std::chrono::seconds(2), // nonpref_peer_delay
165 std::chrono::seconds(2), // overloaded_peer_delay
166 std::chrono::seconds(60), // getdata_interval
167 NetPermissionFlags::Relay, // bypass_request_limits_permissions
168};
169
171 100, // max_peer_request_in_flight
172 5000, // max_peer_announcements
173 std::chrono::seconds(2), // nonpref_peer_delay
174 std::chrono::seconds(2), // overloaded_peer_delay
175 std::chrono::seconds(60), // getdata_interval
177 BypassProofRequestLimits, // bypass_request_limits_permissions
178};
179
184static const unsigned int MAX_GETDATA_SZ = 1000;
188static const int MAX_BLOCKS_IN_TRANSIT_PER_PEER = 16;
194static constexpr auto BLOCK_STALLING_TIMEOUT_DEFAULT{2s};
196static constexpr auto BLOCK_STALLING_TIMEOUT_MAX{64s};
201static const int MAX_CMPCTBLOCK_DEPTH = 5;
206static const int MAX_BLOCKTXN_DEPTH = 10;
214static const unsigned int BLOCK_DOWNLOAD_WINDOW = 1024;
219static constexpr double BLOCK_DOWNLOAD_TIMEOUT_BASE = 1;
223static constexpr double BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 0.5;
228static const unsigned int MAX_BLOCKS_TO_ANNOUNCE = 8;
232static const unsigned int NODE_NETWORK_LIMITED_MIN_BLOCKS = 288;
240static constexpr auto AVG_ADDRESS_BROADCAST_INTERVAL{30s};
242static constexpr auto ROTATE_ADDR_RELAY_DEST_INTERVAL{24h};
247static constexpr auto INBOUND_INVENTORY_BROADCAST_INTERVAL{5s};
252static constexpr unsigned int INVENTORY_BROADCAST_PER_SECOND = 7;
254static constexpr unsigned int INVENTORY_BROADCAST_MAX_PER_MB =
258static constexpr unsigned int INVENTORY_MAX_RECENT_RELAY = 3500;
267 std::chrono::seconds{1},
268 "INVENTORY_RELAY_MAX too low");
269
273static constexpr auto AVG_FEEFILTER_BROADCAST_INTERVAL{10min};
277static constexpr auto MAX_FEEFILTER_CHANGE_DELAY{5min};
282static constexpr uint32_t MAX_GETCFILTERS_SIZE = 1000;
287static constexpr uint32_t MAX_GETCFHEADERS_SIZE = 2000;
292static constexpr size_t MAX_PCT_ADDR_TO_SEND = 23;
297static constexpr double MAX_ADDR_RATE_PER_SECOND{0.1};
305static constexpr uint64_t CMPCTBLOCKS_VERSION{1};
306
307// Internal stuff
308namespace {
312struct QueuedBlock {
317 const CBlockIndex *pindex;
319 std::unique_ptr<PartiallyDownloadedBlock> partialBlock;
320};
321
335struct Peer {
337 const NodeId m_id{0};
338
354 const ServiceFlags m_our_services;
355
357 std::atomic<ServiceFlags> m_their_services{NODE_NONE};
358
360 Mutex m_misbehavior_mutex;
362 int m_misbehavior_score GUARDED_BY(m_misbehavior_mutex){0};
365 bool m_should_discourage GUARDED_BY(m_misbehavior_mutex){false};
366
368 Mutex m_block_inv_mutex;
374 std::vector<BlockHash> m_blocks_for_inv_relay GUARDED_BY(m_block_inv_mutex);
380 std::vector<BlockHash>
381 m_blocks_for_headers_relay GUARDED_BY(m_block_inv_mutex);
382
389 BlockHash m_continuation_block GUARDED_BY(m_block_inv_mutex){};
390
392 std::atomic<int> m_starting_height{-1};
393
395 std::atomic<uint64_t> m_ping_nonce_sent{0};
397 std::atomic<std::chrono::microseconds> m_ping_start{0us};
399 std::atomic<bool> m_ping_queued{false};
400
408 Amount::zero()};
409 std::chrono::microseconds m_next_send_feefilter
411
412 struct TxRelay {
413 mutable RecursiveMutex m_bloom_filter_mutex;
422 bool m_relay_txs GUARDED_BY(m_bloom_filter_mutex){false};
427 std::unique_ptr<CBloomFilter>
428 m_bloom_filter PT_GUARDED_BY(m_bloom_filter_mutex)
429 GUARDED_BY(m_bloom_filter_mutex){nullptr};
430
434 0.000001};
435
436 mutable RecursiveMutex m_tx_inventory_mutex;
443 GUARDED_BY(m_tx_inventory_mutex){50000, 0.000001};
449 std::set<TxId> m_tx_inventory_to_send GUARDED_BY(m_tx_inventory_mutex);
455 bool m_send_mempool GUARDED_BY(m_tx_inventory_mutex){false};
457 std::atomic<std::chrono::seconds> m_last_mempool_req{0s};
462 std::chrono::microseconds
463 m_next_inv_send_time GUARDED_BY(m_tx_inventory_mutex){0};
464
469 std::atomic<Amount> m_fee_filter_received{Amount::zero()};
470 };
471
472 /*
473 * Initializes a TxRelay struct for this peer. Can be called at most once
474 * for a peer.
475 */
476 TxRelay *SetTxRelay() EXCLUSIVE_LOCKS_REQUIRED(!m_tx_relay_mutex) {
477 LOCK(m_tx_relay_mutex);
479 m_tx_relay = std::make_unique<Peer::TxRelay>();
480 return m_tx_relay.get();
481 };
482
483 TxRelay *GetTxRelay() EXCLUSIVE_LOCKS_REQUIRED(!m_tx_relay_mutex) {
484 return WITH_LOCK(m_tx_relay_mutex, return m_tx_relay.get());
485 };
486 const TxRelay *GetTxRelay() const
487 EXCLUSIVE_LOCKS_REQUIRED(!m_tx_relay_mutex) {
488 return WITH_LOCK(m_tx_relay_mutex, return m_tx_relay.get());
489 };
490
491 struct ProofRelay {
492 mutable RecursiveMutex m_proof_inventory_mutex;
493 std::set<avalanche::ProofId>
494 m_proof_inventory_to_send GUARDED_BY(m_proof_inventory_mutex);
495 // Prevent sending proof invs if the peer already knows about them
497 GUARDED_BY(m_proof_inventory_mutex){10000, 0.000001};
503 0.000001};
504 std::chrono::microseconds m_next_inv_send_time{0};
505
507 sharedProofs;
508 std::atomic<std::chrono::seconds> lastSharedProofsUpdate{0s};
509 std::atomic<bool> compactproofs_requested{false};
510 };
511
516 const std::unique_ptr<ProofRelay> m_proof_relay;
517
521 std::vector<CAddress>
533 std::unique_ptr<CRollingBloomFilter>
551 std::atomic_bool m_addr_relay_enabled{false};
555 mutable Mutex m_addr_send_times_mutex;
557 std::chrono::microseconds
558 m_next_addr_send GUARDED_BY(m_addr_send_times_mutex){0};
560 std::chrono::microseconds
561 m_next_local_addr_send GUARDED_BY(m_addr_send_times_mutex){0};
566 std::atomic_bool m_wants_addrv2{false};
570 mutable Mutex m_addr_token_bucket_mutex;
575 double m_addr_token_bucket GUARDED_BY(m_addr_token_bucket_mutex){1.0};
577 std::chrono::microseconds
581 std::atomic<uint64_t> m_addr_rate_limited{0};
586 std::atomic<uint64_t> m_addr_processed{0};
587
594
596 Mutex m_getdata_requests_mutex;
598 std::deque<CInv> m_getdata_requests GUARDED_BY(m_getdata_requests_mutex);
599
603
605 Mutex m_headers_sync_mutex;
610 std::unique_ptr<HeadersSyncState>
611 m_headers_sync PT_GUARDED_BY(m_headers_sync_mutex)
612 GUARDED_BY(m_headers_sync_mutex){};
613
615 std::atomic<bool> m_sent_sendheaders{false};
616
620
622 std::chrono::microseconds m_headers_sync_timeout
624
630 false};
631
632 explicit Peer(NodeId id, ServiceFlags our_services, bool fRelayProofs)
633 : m_id(id), m_our_services{our_services},
634 m_proof_relay(fRelayProofs ? std::make_unique<ProofRelay>()
635 : nullptr) {}
636
637private:
638 mutable Mutex m_tx_relay_mutex;
639
641 std::unique_ptr<TxRelay> m_tx_relay GUARDED_BY(m_tx_relay_mutex);
642};
643
644using PeerRef = std::shared_ptr<Peer>;
645
652struct CNodeState {
654 const CBlockIndex *pindexBestKnownBlock{nullptr};
656 BlockHash hashLastUnknownBlock{};
658 const CBlockIndex *pindexLastCommonBlock{nullptr};
660 const CBlockIndex *pindexBestHeaderSent{nullptr};
662 bool fSyncStarted{false};
665 std::chrono::microseconds m_stalling_since{0us};
666 std::list<QueuedBlock> vBlocksInFlight;
669 std::chrono::microseconds m_downloading_since{0us};
671 bool fPreferredDownload{false};
676 bool m_requested_hb_cmpctblocks{false};
678 bool m_provides_cmpctblocks{false};
679
706 struct ChainSyncTimeoutState {
709 std::chrono::seconds m_timeout{0s};
711 const CBlockIndex *m_work_header{nullptr};
713 bool m_sent_getheaders{false};
716 bool m_protect{false};
717 };
718
719 ChainSyncTimeoutState m_chain_sync;
720
722 int64_t m_last_block_announcement{0};
723
725 const bool m_is_inbound;
726
727 CNodeState(bool is_inbound) : m_is_inbound(is_inbound) {}
728};
729
730class PeerManagerImpl final : public PeerManager {
731public:
732 PeerManagerImpl(CConnman &connman, AddrMan &addrman, BanMan *banman,
733 ChainstateManager &chainman, CTxMemPool &pool,
734 avalanche::Processor *const avalanche, Options opts);
735
737 void BlockConnected(const std::shared_ptr<const CBlock> &pblock,
738 const CBlockIndex *pindexConnected) override
739 EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
740 void BlockDisconnected(const std::shared_ptr<const CBlock> &block,
741 const CBlockIndex *pindex) override
742 EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
744 const CBlockIndex *pindexFork,
745 bool fInitialDownload) override
746 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
747 void BlockChecked(const CBlock &block,
748 const BlockValidationState &state) override
749 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
750 void NewPoWValidBlock(const CBlockIndex *pindex,
751 const std::shared_ptr<const CBlock> &pblock) override
752 EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex);
753
755 void InitializeNode(const Config &config, CNode &node,
756 ServiceFlags our_services) override
757 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
758 void FinalizeNode(const Config &config, const CNode &node) override
759 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !cs_proofrequest,
760 !m_headers_presync_mutex);
761 bool ProcessMessages(const Config &config, CNode *pfrom,
762 std::atomic<bool> &interrupt) override
763 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex,
764 !m_recent_confirmed_transactions_mutex,
765 !m_most_recent_block_mutex, !cs_proofrequest,
766 !m_headers_presync_mutex, g_msgproc_mutex);
767 bool SendMessages(const Config &config, CNode *pto) override
768 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex,
769 !m_recent_confirmed_transactions_mutex,
770 !m_most_recent_block_mutex, !cs_proofrequest,
771 g_msgproc_mutex);
772
774 void StartScheduledTasks(CScheduler &scheduler) override;
775 void CheckForStaleTipAndEvictPeers() override;
776 std::optional<std::string>
777 FetchBlock(const Config &config, NodeId peer_id,
778 const CBlockIndex &block_index) override;
779 bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) const override
780 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
781 bool IgnoresIncomingTxs() override { return m_opts.ignore_incoming_txs; }
782 void SendPings() override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
783 void RelayTransaction(const TxId &txid) override
784 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
785 void RelayProof(const avalanche::ProofId &proofid) override
786 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
787 void SetBestHeight(int height) override { m_best_height = height; };
788 void UnitTestMisbehaving(NodeId peer_id, const int howmuch) override
789 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex) {
791 }
792 void ProcessMessage(const Config &config, CNode &pfrom,
793 const std::string &msg_type, CDataStream &vRecv,
794 const std::chrono::microseconds time_received,
795 const std::atomic<bool> &interruptMsgProc) override
796 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex,
797 !m_recent_confirmed_transactions_mutex,
798 !m_most_recent_block_mutex, !cs_proofrequest,
799 !m_headers_presync_mutex, g_msgproc_mutex);
801 int64_t time_in_seconds) override;
802
803private:
808 void ConsiderEviction(CNode &pto, Peer &peer,
809 std::chrono::seconds time_in_seconds)
810 EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_msgproc_mutex);
811
816 void EvictExtraOutboundPeers(std::chrono::seconds now)
818
824 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
825
829 void UpdateAvalancheStatistics() const;
830
834 void AvalanchePeriodicNetworking(CScheduler &scheduler) const;
835
840 PeerRef GetPeerRef(NodeId id) const EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
841
847
853 void Misbehaving(Peer &peer, int howmuch, const std::string &message);
854
868 const BlockValidationState &state,
870 const std::string &message = "")
871 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
872
879 bool MaybePunishNodeForTx(NodeId nodeid, const TxValidationState &state,
880 const std::string &message = "")
881 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
882
892 bool MaybeDiscourageAndDisconnect(CNode &pnode, Peer &peer);
893
908 void ProcessInvalidTx(NodeId nodeid, const CTransactionRef &tx,
909 const TxValidationState &result,
911 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
912
913 struct PackageToValidate {
914 const Package m_txns;
915 const std::vector<NodeId> m_senders;
917 explicit PackageToValidate(const CTransactionRef &parent,
918 const CTransactionRef &child,
920 : m_txns{parent, child}, m_senders{parent_sender, child_sender} {}
921
922 std::string ToString() const {
923 Assume(m_txns.size() == 2);
924 return strprintf(
925 "parent %s (sender=%d) + child %s (sender=%d)",
926 m_txns.front()->GetId().ToString(), m_senders.front(),
927 m_txns.back()->GetId().ToString(), m_senders.back());
928 }
929 };
930
936 void ProcessPackageResult(const PackageToValidate &package_to_validate,
938 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
939
946 std::optional<PackageToValidate> Find1P1CPackage(const CTransactionRef &ptx,
947 NodeId nodeid)
948 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
949
955 void ProcessValidTx(NodeId nodeid, const CTransactionRef &tx)
956 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex, cs_main);
957
973 bool ProcessOrphanTx(const Config &config, Peer &peer)
974 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex);
975
986 void ProcessHeadersMessage(const Config &config, CNode &pfrom, Peer &peer,
987 std::vector<CBlockHeader> &&headers,
989 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !m_headers_presync_mutex,
990 g_msgproc_mutex);
991
992 // Various helpers for headers processing, invoked by
993 // ProcessHeadersMessage()
998 bool CheckHeadersPoW(const std::vector<CBlockHeader> &headers,
999 const Consensus::Params &consensusParams, Peer &peer);
1008 void HandleFewUnconnectingHeaders(CNode &pfrom, Peer &peer,
1009 const std::vector<CBlockHeader> &headers)
1010 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1012 bool
1013 CheckHeadersAreContinuous(const std::vector<CBlockHeader> &headers) const;
1034 std::vector<CBlockHeader> &headers)
1035 EXCLUSIVE_LOCKS_REQUIRED(peer.m_headers_sync_mutex,
1036 !m_headers_presync_mutex, g_msgproc_mutex);
1050 bool TryLowWorkHeadersSync(Peer &peer, CNode &pfrom,
1052 std::vector<CBlockHeader> &headers)
1053 EXCLUSIVE_LOCKS_REQUIRED(!peer.m_headers_sync_mutex, !m_peer_mutex,
1054 !m_headers_presync_mutex, g_msgproc_mutex);
1055
1060 bool IsAncestorOfBestHeaderOrTip(const CBlockIndex *header)
1061 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1062
1069 Peer &peer)
1070 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1074 void HeadersDirectFetchBlocks(const Config &config, CNode &pfrom,
1075 const CBlockIndex &last_header);
1078 const CBlockIndex &last_header,
1081 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1082
1083 void SendBlockTransactions(CNode &pfrom, Peer &peer, const CBlock &block,
1084 const BlockTransactionsRequest &req);
1085
1091 void AddTxAnnouncement(const CNode &node, const TxId &txid,
1092 std::chrono::microseconds current_time)
1093 EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
1094
1100 void
1101 AddProofAnnouncement(const CNode &node, const avalanche::ProofId &proofid,
1102 std::chrono::microseconds current_time, bool preferred)
1103 EXCLUSIVE_LOCKS_REQUIRED(cs_proofrequest);
1104
1106 void PushNodeVersion(const Config &config, CNode &pnode, const Peer &peer);
1107
1114 void MaybeSendPing(CNode &node_to, Peer &peer,
1115 std::chrono::microseconds now);
1116
1118 void MaybeSendAddr(CNode &node, Peer &peer,
1119 std::chrono::microseconds current_time)
1120 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1121
1126 void MaybeSendSendHeaders(CNode &node, Peer &peer)
1127 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1128
1130 void MaybeSendFeefilter(CNode &node, Peer &peer,
1131 std::chrono::microseconds current_time)
1132 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1133
1143 void RelayAddress(NodeId originator, const CAddress &addr, bool fReachable)
1144 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, g_msgproc_mutex);
1145
1147
1150
1151 const CChainParams &m_chainparams;
1152 CConnman &m_connman;
1153 AddrMan &m_addrman;
1158 BanMan *const m_banman;
1159 ChainstateManager &m_chainman;
1160 CTxMemPool &m_mempool;
1161 avalanche::Processor *const m_avalanche;
1163
1164 Mutex cs_proofrequest;
1166 m_proofrequest GUARDED_BY(cs_proofrequest);
1167
1169 std::atomic<int> m_best_height{-1};
1170
1172 std::chrono::seconds m_stale_tip_check_time{0s};
1173
1174 const Options m_opts;
1175
1176 bool RejectIncomingTxs(const CNode &peer) const;
1177
1182 bool m_initial_sync_finished{false};
1183
1188 mutable Mutex m_peer_mutex;
1195 std::map<NodeId, PeerRef> m_peer_map GUARDED_BY(m_peer_mutex);
1196
1198 std::map<NodeId, CNodeState> m_node_states GUARDED_BY(cs_main);
1199
1204 const CNodeState *State(NodeId pnode) const
1205 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1207 CNodeState *State(NodeId pnode) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1208
1209 std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
1210
1212 int nSyncStarted GUARDED_BY(cs_main) = 0;
1213
1215 BlockHash
1217
1224 std::map<BlockHash, std::pair<NodeId, bool>>
1225 mapBlockSource GUARDED_BY(cs_main);
1226
1229
1232
1234 std::atomic<std::chrono::seconds> m_block_stalling_timeout{
1236
1248 bool AlreadyHaveTx(const TxId &txid, bool include_reconsiderable)
1250 !m_recent_confirmed_transactions_mutex);
1251
1272 0.000'001};
1273
1280
1307 GUARDED_BY(::cs_main){120'000, 0.000'001};
1308
1314 mutable Mutex m_recent_confirmed_transactions_mutex;
1316 GUARDED_BY(m_recent_confirmed_transactions_mutex){24'000, 0.000'001};
1317
1325 std::chrono::microseconds
1326 NextInvToInbounds(std::chrono::microseconds now,
1327 std::chrono::seconds average_interval);
1328
1329 // All of the following cache a recent block, and are protected by
1330 // m_most_recent_block_mutex
1331 mutable Mutex m_most_recent_block_mutex;
1332 std::shared_ptr<const CBlock>
1333 m_most_recent_block GUARDED_BY(m_most_recent_block_mutex);
1334 std::shared_ptr<const CBlockHeaderAndShortTxIDs>
1335 m_most_recent_compact_block GUARDED_BY(m_most_recent_block_mutex);
1336 BlockHash m_most_recent_block_hash GUARDED_BY(m_most_recent_block_mutex);
1337
1338 // Data about the low-work headers synchronization, aggregated from all
1339 // peers' HeadersSyncStates.
1341 Mutex m_headers_presync_mutex;
1352 using HeadersPresyncStats =
1353 std::pair<arith_uint256, std::optional<std::pair<int64_t, uint32_t>>>;
1355 std::map<NodeId, HeadersPresyncStats>
1356 m_headers_presync_stats GUARDED_BY(m_headers_presync_mutex){};
1358 NodeId m_headers_presync_bestpeer GUARDED_BY(m_headers_presync_mutex){-1};
1360 std::atomic_bool m_headers_presync_should_signal{false};
1361
1365 int m_highest_fast_announce GUARDED_BY(::cs_main){0};
1366
1368 bool IsBlockRequested(const BlockHash &hash)
1369 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1370
1372 bool IsBlockRequestedFromOutbound(const BlockHash &hash)
1373 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1374
1383 void RemoveBlockRequest(const BlockHash &hash,
1384 std::optional<NodeId> from_peer)
1385 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1386
1393 bool BlockRequested(const Config &config, NodeId nodeid,
1394 const CBlockIndex &block,
1395 std::list<QueuedBlock>::iterator **pit = nullptr)
1396 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1397
1399
1404 void FindNextBlocksToDownload(NodeId nodeid, unsigned int count,
1405 std::vector<const CBlockIndex *> &vBlocks,
1407 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1408
1411 std::pair<NodeId, std::list<QueuedBlock>::iterator>>
1412 BlockDownloadMap;
1413 BlockDownloadMap mapBlocksInFlight GUARDED_BY(cs_main);
1414
1416 std::atomic<std::chrono::seconds> m_last_tip_update{0s};
1417
1422 CTransactionRef FindTxForGetData(const Peer &peer, const TxId &txid,
1423 const std::chrono::seconds mempool_req,
1424 const std::chrono::seconds now)
1425 LOCKS_EXCLUDED(cs_main)
1427
1428 void ProcessGetData(const Config &config, CNode &pfrom, Peer &peer,
1429 const std::atomic<bool> &interruptMsgProc)
1430 EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex,
1431 peer.m_getdata_requests_mutex,
1433 LOCKS_EXCLUDED(cs_main);
1434
1436 void ProcessBlock(const Config &config, CNode &node,
1437 const std::shared_ptr<const CBlock> &block,
1439
1441 typedef std::map<TxId, CTransactionRef> MapRelay;
1442 MapRelay mapRelay GUARDED_BY(cs_main);
1443
1448 std::deque<std::pair<std::chrono::microseconds, MapRelay::iterator>>
1450
1458 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1459
1461 std::list<NodeId> lNodesAnnouncingHeaderAndIDs GUARDED_BY(cs_main);
1462
1464 int m_peers_downloading_from GUARDED_BY(cs_main) = 0;
1465
1467 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1468
1476 std::vector<std::pair<TxHash, CTransactionRef>>
1477 vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);
1479 size_t vExtraTxnForCompactIt GUARDED_BY(g_msgproc_mutex) = 0;
1480
1484 void ProcessBlockAvailability(NodeId nodeid)
1485 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1489 void UpdateBlockAvailability(NodeId nodeid, const BlockHash &hash)
1490 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1492
1499 bool BlockRequestAllowed(const CBlockIndex *pindex)
1500 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1501 bool AlreadyHaveBlock(const BlockHash &block_hash)
1502 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1503 bool AlreadyHaveProof(const avalanche::ProofId &proofid);
1504 void ProcessGetBlockData(const Config &config, CNode &pfrom, Peer &peer,
1505 const CInv &inv)
1506 EXCLUSIVE_LOCKS_REQUIRED(!m_most_recent_block_mutex);
1507
1527 bool PrepareBlockFilterRequest(CNode &node, Peer &peer,
1530 const BlockHash &stop_hash,
1532 const CBlockIndex *&stop_index,
1533 BlockFilterIndex *&filter_index);
1534
1544 void ProcessGetCFilters(CNode &node, Peer &peer, CDataStream &vRecv);
1554 void ProcessGetCFHeaders(CNode &node, Peer &peer, CDataStream &vRecv);
1564 void ProcessGetCFCheckPt(CNode &node, Peer &peer, CDataStream &vRecv);
1565
1573 EXCLUSIVE_LOCKS_REQUIRED(cs_main);
1574
1581 uint32_t GetAvalancheVoteForTx(const TxId &id) const
1583 !m_recent_confirmed_transactions_mutex);
1584
1592 bool SetupAddressRelay(const CNode &node, Peer &peer)
1593 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1594
1595 void AddAddressKnown(Peer &peer, const CAddress &addr)
1596 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1597 void PushAddress(Peer &peer, const CAddress &addr)
1598 EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
1599
1605 bool ReceivedAvalancheProof(CNode &node, Peer &peer,
1606 const avalanche::ProofRef &proof)
1607 EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex, !cs_proofrequest);
1608
1609 avalanche::ProofRef FindProofForGetData(const Peer &peer,
1610 const avalanche::ProofId &proofid,
1611 const std::chrono::seconds now)
1613
1614 bool isPreferredDownloadPeer(const CNode &pfrom);
1615};
1616
1617const CNodeState *PeerManagerImpl::State(NodeId pnode) const
1618 EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
1619 std::map<NodeId, CNodeState>::const_iterator it = m_node_states.find(pnode);
1620 if (it == m_node_states.end()) {
1621 return nullptr;
1622 }
1623
1624 return &it->second;
1625}
1626
1627CNodeState *PeerManagerImpl::State(NodeId pnode)
1628 EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
1629 return const_cast<CNodeState *>(std::as_const(*this).State(pnode));
1630}
1631
1637static bool IsAddrCompatible(const Peer &peer, const CAddress &addr) {
1638 return peer.m_wants_addrv2 || addr.IsAddrV1Compatible();
1639}
1640
1641void PeerManagerImpl::AddAddressKnown(Peer &peer, const CAddress &addr) {
1642 assert(peer.m_addr_known);
1643 peer.m_addr_known->insert(addr.GetKey());
1644}
1645
1646void PeerManagerImpl::PushAddress(Peer &peer, const CAddress &addr) {
1647 // Known checking here is only to save space from duplicates.
1648 // Before sending, we'll filter it again for known addresses that were
1649 // added after addresses were pushed.
1650 assert(peer.m_addr_known);
1651 if (addr.IsValid() && !peer.m_addr_known->contains(addr.GetKey()) &&
1652 IsAddrCompatible(peer, addr)) {
1653 if (peer.m_addrs_to_send.size() >= m_opts.max_addr_to_send) {
1654 peer.m_addrs_to_send[m_rng.randrange(peer.m_addrs_to_send.size())] =
1655 addr;
1656 } else {
1657 peer.m_addrs_to_send.push_back(addr);
1658 }
1659 }
1660}
1661
1662static void AddKnownTx(Peer &peer, const TxId &txid) {
1663 auto tx_relay = peer.GetTxRelay();
1664 if (!tx_relay) {
1665 return;
1666 }
1667
1668 LOCK(tx_relay->m_tx_inventory_mutex);
1669 tx_relay->m_tx_inventory_known_filter.insert(txid);
1670}
1671
1672static void AddKnownProof(Peer &peer, const avalanche::ProofId &proofid) {
1673 if (peer.m_proof_relay != nullptr) {
1674 LOCK(peer.m_proof_relay->m_proof_inventory_mutex);
1675 peer.m_proof_relay->m_proof_inventory_known_filter.insert(proofid);
1676 }
1677}
1678
1679bool PeerManagerImpl::isPreferredDownloadPeer(const CNode &pfrom) {
1680 LOCK(cs_main);
1681 const CNodeState *state = State(pfrom.GetId());
1682 return state && state->fPreferredDownload;
1683}
1685static bool CanServeBlocks(const Peer &peer) {
1686 return peer.m_their_services & (NODE_NETWORK | NODE_NETWORK_LIMITED);
1687}
1688
1693static bool IsLimitedPeer(const Peer &peer) {
1694 return (!(peer.m_their_services & NODE_NETWORK) &&
1695 (peer.m_their_services & NODE_NETWORK_LIMITED));
1696}
1697
1698std::chrono::microseconds
1699PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
1700 std::chrono::seconds average_interval) {
1701 if (m_next_inv_to_inbounds.load() < now) {
1702 // If this function were called from multiple threads simultaneously
1703 // it would possible that both update the next send variable, and return
1704 // a different result to their caller. This is not possible in practice
1705 // as only the net processing thread invokes this function.
1706 m_next_inv_to_inbounds = GetExponentialRand(now, average_interval);
1707 }
1708 return m_next_inv_to_inbounds;
1709}
1710
1711bool PeerManagerImpl::IsBlockRequested(const BlockHash &hash) {
1712 return mapBlocksInFlight.count(hash);
1713}
1714
1715bool PeerManagerImpl::IsBlockRequestedFromOutbound(const BlockHash &hash) {
1716 for (auto range = mapBlocksInFlight.equal_range(hash);
1717 range.first != range.second; range.first++) {
1718 auto [nodeid, block_it] = range.first->second;
1719 CNodeState &nodestate = *Assert(State(nodeid));
1720 if (!nodestate.m_is_inbound) {
1721 return true;
1722 }
1723 }
1724
1725 return false;
1726}
1727
1728void PeerManagerImpl::RemoveBlockRequest(const BlockHash &hash,
1729 std::optional<NodeId> from_peer) {
1730 auto range = mapBlocksInFlight.equal_range(hash);
1731 if (range.first == range.second) {
1732 // Block was not requested from any peer
1733 return;
1734 }
1735
1736 // We should not have requested too many of this block
1738
1739 while (range.first != range.second) {
1740 auto [node_id, list_it] = range.first->second;
1741
1742 if (from_peer && *from_peer != node_id) {
1743 range.first++;
1744 continue;
1745 }
1746
1747 CNodeState &state = *Assert(State(node_id));
1748
1749 if (state.vBlocksInFlight.begin() == list_it) {
1750 // First block on the queue was received, update the start download
1751 // time for the next one
1752 state.m_downloading_since =
1753 std::max(state.m_downloading_since,
1755 }
1756 state.vBlocksInFlight.erase(list_it);
1757
1758 if (state.vBlocksInFlight.empty()) {
1759 // Last validated block on the queue for this peer was received.
1761 }
1762 state.m_stalling_since = 0us;
1763
1764 range.first = mapBlocksInFlight.erase(range.first);
1765 }
1766}
1767
1768bool PeerManagerImpl::BlockRequested(const Config &config, NodeId nodeid,
1769 const CBlockIndex &block,
1770 std::list<QueuedBlock>::iterator **pit) {
1771 const BlockHash &hash{block.GetBlockHash()};
1772
1773 CNodeState *state = State(nodeid);
1774 assert(state != nullptr);
1775
1777
1778 // Short-circuit most stuff in case it is from the same node
1779 for (auto range = mapBlocksInFlight.equal_range(hash);
1780 range.first != range.second; range.first++) {
1781 if (range.first->second.first == nodeid) {
1782 if (pit) {
1783 *pit = &range.first->second.second;
1784 }
1785 return false;
1786 }
1787 }
1788
1789 // Make sure it's not being fetched already from same peer.
1790 RemoveBlockRequest(hash, nodeid);
1791
1792 std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(
1793 state->vBlocksInFlight.end(),
1794 {&block, std::unique_ptr<PartiallyDownloadedBlock>(
1795 pit ? new PartiallyDownloadedBlock(config, &m_mempool)
1796 : nullptr)});
1797 if (state->vBlocksInFlight.size() == 1) {
1798 // We're starting a block download (batch) from this peer.
1799 state->m_downloading_since = GetTime<std::chrono::microseconds>();
1801 }
1802
1803 auto itInFlight = mapBlocksInFlight.insert(
1804 std::make_pair(hash, std::make_pair(nodeid, it)));
1805
1806 if (pit) {
1807 *pit = &itInFlight->second.second;
1808 }
1809
1810 return true;
1811}
1812
1813void PeerManagerImpl::MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid) {
1814 AssertLockHeld(cs_main);
1815
1816 // When in -blocksonly mode, never request high-bandwidth mode from peers.
1817 // Our mempool will not contain the transactions necessary to reconstruct
1818 // the compact block.
1819 if (m_opts.ignore_incoming_txs) {
1820 return;
1821 }
1822
1823 CNodeState *nodestate = State(nodeid);
1824 if (!nodestate) {
1825 LogPrint(BCLog::NET, "node state unavailable: peer=%d\n", nodeid);
1826 return;
1827 }
1828 if (!nodestate->m_provides_cmpctblocks) {
1829 return;
1830 }
1831 int num_outbound_hb_peers = 0;
1832 for (std::list<NodeId>::iterator it = lNodesAnnouncingHeaderAndIDs.begin();
1833 it != lNodesAnnouncingHeaderAndIDs.end(); it++) {
1834 if (*it == nodeid) {
1836 lNodesAnnouncingHeaderAndIDs.push_back(nodeid);
1837 return;
1838 }
1839 CNodeState *state = State(*it);
1840 if (state != nullptr && !state->m_is_inbound) {
1842 }
1843 }
1844 if (nodestate->m_is_inbound) {
1845 // If we're adding an inbound HB peer, make sure we're not removing
1846 // our last outbound HB peer in the process.
1847 if (lNodesAnnouncingHeaderAndIDs.size() >= 3 &&
1848 num_outbound_hb_peers == 1) {
1849 CNodeState *remove_node =
1850 State(lNodesAnnouncingHeaderAndIDs.front());
1851 if (remove_node != nullptr && !remove_node->m_is_inbound) {
1852 // Put the HB outbound peer in the second slot, so that it
1853 // doesn't get removed.
1854 std::swap(lNodesAnnouncingHeaderAndIDs.front(),
1855 *std::next(lNodesAnnouncingHeaderAndIDs.begin()));
1856 }
1857 }
1858 }
1859 m_connman.ForNode(nodeid, [this](CNode *pfrom) EXCLUSIVE_LOCKS_REQUIRED(
1860 ::cs_main) {
1861 AssertLockHeld(::cs_main);
1862 if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
1863 // As per BIP152, we only get 3 of our peers to announce
1864 // blocks using compact encodings.
1865 m_connman.ForNode(
1866 lNodesAnnouncingHeaderAndIDs.front(), [this](CNode *pnodeStop) {
1867 m_connman.PushMessage(
1868 pnodeStop, CNetMsgMaker(pnodeStop->GetCommonVersion())
1869 .Make(NetMsgType::SENDCMPCT,
1870 /*high_bandwidth=*/false,
1871 /*version=*/CMPCTBLOCKS_VERSION));
1872 // save BIP152 bandwidth state: we select peer to be
1873 // low-bandwidth
1874 pnodeStop->m_bip152_highbandwidth_to = false;
1875 return true;
1876 });
1877 lNodesAnnouncingHeaderAndIDs.pop_front();
1878 }
1879 m_connman.PushMessage(pfrom,
1880 CNetMsgMaker(pfrom->GetCommonVersion())
1882 /*high_bandwidth=*/true,
1883 /*version=*/CMPCTBLOCKS_VERSION));
1884 // save BIP152 bandwidth state: we select peer to be high-bandwidth
1885 pfrom->m_bip152_highbandwidth_to = true;
1886 lNodesAnnouncingHeaderAndIDs.push_back(pfrom->GetId());
1887 return true;
1888 });
1889}
1890
1891bool PeerManagerImpl::TipMayBeStale() {
1892 AssertLockHeld(cs_main);
1893 const Consensus::Params &consensusParams = m_chainparams.GetConsensus();
1894 if (m_last_tip_update.load() == 0s) {
1895 m_last_tip_update = GetTime<std::chrono::seconds>();
1896 }
1897 return m_last_tip_update.load() <
1899 std::chrono::seconds{consensusParams.nPowTargetSpacing *
1900 3} &&
1901 mapBlocksInFlight.empty();
1902}
1903
1904bool PeerManagerImpl::CanDirectFetch() {
1905 return m_chainman.ActiveChain().Tip()->Time() >
1906 GetAdjustedTime() -
1907 m_chainparams.GetConsensus().PowTargetSpacing() * 20;
1908}
1909
1910static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex)
1911 EXCLUSIVE_LOCKS_REQUIRED(cs_main) {
1912 if (state->pindexBestKnownBlock &&
1913 pindex == state->pindexBestKnownBlock->GetAncestor(pindex->nHeight)) {
1914 return true;
1915 }
1916 if (state->pindexBestHeaderSent &&
1917 pindex == state->pindexBestHeaderSent->GetAncestor(pindex->nHeight)) {
1918 return true;
1919 }
1920 return false;
1921}
1922
1923void PeerManagerImpl::ProcessBlockAvailability(NodeId nodeid) {
1924 CNodeState *state = State(nodeid);
1925 assert(state != nullptr);
1926
1927 if (!state->hashLastUnknownBlock.IsNull()) {
1928 const CBlockIndex *pindex =
1929 m_chainman.m_blockman.LookupBlockIndex(state->hashLastUnknownBlock);
1930 if (pindex && pindex->nChainWork > 0) {
1931 if (state->pindexBestKnownBlock == nullptr ||
1932 pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
1933 state->pindexBestKnownBlock = pindex;
1934 }
1935 state->hashLastUnknownBlock.SetNull();
1936 }
1937 }
1938}
1939
1940void PeerManagerImpl::UpdateBlockAvailability(NodeId nodeid,
1941 const BlockHash &hash) {
1942 CNodeState *state = State(nodeid);
1943 assert(state != nullptr);
1944
1946
1947 const CBlockIndex *pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
1948 if (pindex && pindex->nChainWork > 0) {
1949 // An actually better block was announced.
1950 if (state->pindexBestKnownBlock == nullptr ||
1951 pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork) {
1952 state->pindexBestKnownBlock = pindex;
1953 }
1954 } else {
1955 // An unknown block was announced; just assume that the latest one is
1956 // the best one.
1957 state->hashLastUnknownBlock = hash;
1958 }
1959}
1960
1961void PeerManagerImpl::FindNextBlocksToDownload(
1962 NodeId nodeid, unsigned int count,
1963 std::vector<const CBlockIndex *> &vBlocks, NodeId &nodeStaller) {
1964 if (count == 0) {
1965 return;
1966 }
1967
1968 vBlocks.reserve(vBlocks.size() + count);
1969 CNodeState *state = State(nodeid);
1970 assert(state != nullptr);
1971
1972 // Make sure pindexBestKnownBlock is up to date, we'll need it.
1974
1975 if (state->pindexBestKnownBlock == nullptr ||
1976 state->pindexBestKnownBlock->nChainWork <
1977 m_chainman.ActiveChain().Tip()->nChainWork ||
1978 state->pindexBestKnownBlock->nChainWork <
1979 m_chainman.MinimumChainWork()) {
1980 // This peer has nothing interesting.
1981 return;
1982 }
1983
1984 if (state->pindexLastCommonBlock == nullptr) {
1985 // Bootstrap quickly by guessing a parent of our best tip is the forking
1986 // point. Guessing wrong in either direction is not a problem.
1987 state->pindexLastCommonBlock =
1988 m_chainman
1989 .ActiveChain()[std::min(state->pindexBestKnownBlock->nHeight,
1990 m_chainman.ActiveChain().Height())];
1991 }
1992
1993 // If the peer reorganized, our previous pindexLastCommonBlock may not be an
1994 // ancestor of its current tip anymore. Go back enough to fix that.
1995 state->pindexLastCommonBlock = LastCommonAncestor(
1996 state->pindexLastCommonBlock, state->pindexBestKnownBlock);
1997 if (state->pindexLastCommonBlock == state->pindexBestKnownBlock) {
1998 return;
1999 }
2000
2001 std::vector<const CBlockIndex *> vToFetch;
2002 const CBlockIndex *pindexWalk = state->pindexLastCommonBlock;
2003 // Never fetch further than the best block we know the peer has, or more
2004 // than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last linked block we have in
2005 // common with this peer. The +1 is so we can detect stalling, namely if we
2006 // would be able to download that next block if the window were 1 larger.
2007 int nWindowEnd =
2008 state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
2009 int nMaxHeight =
2010 std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
2011 NodeId waitingfor = -1;
2012 while (pindexWalk->nHeight < nMaxHeight) {
2013 // Read up to 128 (or more, if more blocks than that are needed)
2014 // successors of pindexWalk (towards pindexBestKnownBlock) into
2015 // vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as
2016 // expensive as iterating over ~100 CBlockIndex* entries anyway.
2017 int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight,
2018 std::max<int>(count - vBlocks.size(), 128));
2019 vToFetch.resize(nToFetch);
2020 pindexWalk = state->pindexBestKnownBlock->GetAncestor(
2021 pindexWalk->nHeight + nToFetch);
2023 for (unsigned int i = nToFetch - 1; i > 0; i--) {
2024 vToFetch[i - 1] = vToFetch[i]->pprev;
2025 }
2026
2027 // Iterate over those blocks in vToFetch (in forward direction), adding
2028 // the ones that are not yet downloaded and not in flight to vBlocks. In
2029 // the meantime, update pindexLastCommonBlock as long as all ancestors
2030 // are already downloaded, or if it's already part of our chain (and
2031 // therefore don't need it even if pruned).
2032 for (const CBlockIndex *pindex : vToFetch) {
2033 if (!pindex->IsValid(BlockValidity::TREE)) {
2034 // We consider the chain that this peer is on invalid.
2035 return;
2036 }
2037 if (pindex->nStatus.hasData() ||
2038 m_chainman.ActiveChain().Contains(pindex)) {
2039 if (pindex->HaveTxsDownloaded()) {
2040 state->pindexLastCommonBlock = pindex;
2041 }
2042 } else if (!IsBlockRequested(pindex->GetBlockHash())) {
2043 // The block is not already downloaded, and not yet in flight.
2044 if (pindex->nHeight > nWindowEnd) {
2045 // We reached the end of the window.
2046 if (vBlocks.size() == 0 && waitingfor != nodeid) {
2047 // We aren't able to fetch anything, but we would be if
2048 // the download window was one larger.
2050 }
2051 return;
2052 }
2053 vBlocks.push_back(pindex);
2054 if (vBlocks.size() == count) {
2055 return;
2056 }
2057 } else if (waitingfor == -1) {
2058 // This is the first already-in-flight block.
2059 waitingfor =
2060 mapBlocksInFlight.lower_bound(pindex->GetBlockHash())
2061 ->second.first;
2062 }
2063 }
2064 }
2065}
2066
2067} // namespace
2068
2069template <class InvId>
2073 return !node.HasPermission(
2074 requestParams.bypass_request_limits_permissions) &&
2075 requestTracker.Count(node.GetId()) >=
2076 requestParams.max_peer_announcements;
2077}
2078
2086template <class InvId>
2087static std::chrono::microseconds
2091 std::chrono::microseconds current_time, bool preferred) {
2092 auto delay = std::chrono::microseconds{0};
2093
2094 if (!preferred) {
2095 delay += requestParams.nonpref_peer_delay;
2096 }
2097
2098 if (!node.HasPermission(requestParams.bypass_request_limits_permissions) &&
2099 requestTracker.CountInFlight(node.GetId()) >=
2100 requestParams.max_peer_request_in_flight) {
2101 delay += requestParams.overloaded_peer_delay;
2102 }
2103
2104 return current_time + delay;
2105}
2106
2107void PeerManagerImpl::PushNodeVersion(const Config &config, CNode &pnode,
2108 const Peer &peer) {
2109 uint64_t my_services{peer.m_our_services};
2111 uint64_t nonce = pnode.GetLocalNonce();
2112 const int nNodeStartingHeight{m_best_height};
2113 NodeId nodeid = pnode.GetId();
2114 CAddress addr = pnode.addr;
2115 uint64_t extraEntropy = pnode.GetLocalExtraEntropy();
2116
2118 addr.IsRoutable() && !IsProxy(addr) && addr.IsAddrV1Compatible()
2119 ? addr
2120 : CService();
2122
2123 const bool tx_relay{!RejectIncomingTxs(pnode)};
2124 m_connman.PushMessage(
2125 // your_services, addr_you: Together the pre-version-31402 serialization
2126 // of CAddress "addrYou" (without nTime)
2127 // my_services, CService(): Together the pre-version-31402 serialization
2128 // of CAddress "addrMe" (without nTime)
2132 CService(), nonce, userAgent(config),
2134
2135 if (fLogIPs) {
2137 "send version message: version %d, blocks=%d, them=%s, "
2138 "txrelay=%d, peer=%d\n",
2140 tx_relay, nodeid);
2141 } else {
2143 "send version message: version %d, blocks=%d, "
2144 "txrelay=%d, peer=%d\n",
2146 }
2147}
2148
2149void PeerManagerImpl::AddTxAnnouncement(
2150 const CNode &node, const TxId &txid,
2151 std::chrono::microseconds current_time) {
2152 // For m_txrequest and state
2154
2156 return;
2157 }
2158
2159 const bool preferred = isPreferredDownloadPeer(node);
2162
2163 m_txrequest.ReceivedInv(node.GetId(), txid, preferred, reqtime);
2164}
2165
2166void PeerManagerImpl::AddProofAnnouncement(
2167 const CNode &node, const avalanche::ProofId &proofid,
2168 std::chrono::microseconds current_time, bool preferred) {
2169 // For m_proofrequest
2170 AssertLockHeld(cs_proofrequest);
2171
2173 return;
2174 }
2175
2178
2179 m_proofrequest.ReceivedInv(node.GetId(), proofid, preferred, reqtime);
2180}
2181
2182void PeerManagerImpl::UpdateLastBlockAnnounceTime(NodeId node,
2184 LOCK(cs_main);
2185 CNodeState *state = State(node);
2186 if (state) {
2187 state->m_last_block_announcement = time_in_seconds;
2188 }
2189}
2190
2191void PeerManagerImpl::InitializeNode(const Config &config, CNode &node,
2193 NodeId nodeid = node.GetId();
2194 {
2195 LOCK(cs_main);
2196 m_node_states.emplace_hint(m_node_states.end(),
2197 std::piecewise_construct,
2198 std::forward_as_tuple(nodeid),
2199 std::forward_as_tuple(node.IsInboundConn()));
2200 assert(m_txrequest.Count(nodeid) == 0);
2201 }
2202
2203 if (NetPermissions::HasFlag(node.m_permission_flags,
2206 }
2207
2208 PeerRef peer = std::make_shared<Peer>(nodeid, our_services, !!m_avalanche);
2209 {
2210 LOCK(m_peer_mutex);
2211 m_peer_map.emplace_hint(m_peer_map.end(), nodeid, peer);
2212 }
2213 if (!node.IsInboundConn()) {
2214 PushNodeVersion(config, node, *peer);
2215 }
2216}
2217
2218void PeerManagerImpl::ReattemptInitialBroadcast(CScheduler &scheduler) {
2219 std::set<TxId> unbroadcast_txids = m_mempool.GetUnbroadcastTxs();
2220
2221 for (const TxId &txid : unbroadcast_txids) {
2222 // Sanity check: all unbroadcast txns should exist in the mempool
2223 if (m_mempool.exists(txid)) {
2224 RelayTransaction(txid);
2225 } else {
2226 m_mempool.RemoveUnbroadcastTx(txid, true);
2227 }
2228 }
2229
2230 if (m_avalanche) {
2231 // Get and sanitize the list of proofids to broadcast. The RelayProof
2232 // call is done in a second loop to avoid locking cs_vNodes while
2233 // cs_peerManager is locked which would cause a potential deadlock due
2234 // to reversed lock order.
2236 m_avalanche->withPeerManager([&](avalanche::PeerManager &pm) {
2237 auto unbroadcasted_proofids = pm.getUnbroadcastProofs();
2238
2239 auto it = unbroadcasted_proofids.begin();
2240 while (it != unbroadcasted_proofids.end()) {
2241 // Sanity check: all unbroadcast proofs should be bound to a
2242 // peer in the peermanager
2243 if (!pm.isBoundToPeer(*it)) {
2244 pm.removeUnbroadcastProof(*it);
2245 it = unbroadcasted_proofids.erase(it);
2246 continue;
2247 }
2248
2249 ++it;
2250 }
2251
2253 });
2254
2255 // Remaining proofids are the ones to broadcast
2256 for (const auto &proofid : unbroadcasted_proofids) {
2257 RelayProof(proofid);
2258 }
2259 }
2260
2261 // Schedule next run for 10-15 minutes in the future.
2262 // We add randomness on every cycle to avoid the possibility of P2P
2263 // fingerprinting.
2264 const auto reattemptBroadcastInterval = 10min + GetRandMillis(5min);
2265 scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); },
2267}
2268
2269void PeerManagerImpl::UpdateAvalancheStatistics() const {
2270 m_connman.ForEachNode([](CNode *pnode) {
2271 pnode->updateAvailabilityScore(AVALANCHE_STATISTICS_DECAY_FACTOR);
2272 });
2273
2274 if (!m_avalanche) {
2275 // Not enabled or not ready yet
2276 return;
2277 }
2278
2279 // Generate a peer availability score by computing an exponentially
2280 // weighted moving average of the average of node availability scores.
2281 // This ensures the peer score is bound to the lifetime of its proof which
2282 // incentivizes stable network activity.
2283 m_avalanche->withPeerManager([&](avalanche::PeerManager &pm) {
2284 pm.updateAvailabilityScores(
2285 AVALANCHE_STATISTICS_DECAY_FACTOR, [&](NodeId nodeid) -> double {
2286 double score{0.0};
2287 m_connman.ForNode(nodeid, [&](CNode *pavanode) {
2288 score = pavanode->getAvailabilityScore();
2289 return true;
2290 });
2291 return score;
2292 });
2293 });
2294}
2295
2296void PeerManagerImpl::AvalanchePeriodicNetworking(CScheduler &scheduler) const {
2297 const auto now = GetTime<std::chrono::seconds>();
2298 std::vector<NodeId> avanode_ids;
2299 bool fQuorumEstablished;
2301
2302 if (!m_avalanche) {
2303 // Not enabled or not ready yet, retry later
2304 goto scheduleLater;
2305 }
2306
2307 m_avalanche->sendDelayedAvahello();
2308
2309 fQuorumEstablished = m_avalanche->isQuorumEstablished();
2311 m_avalanche->withPeerManager([&](avalanche::PeerManager &pm) {
2312 return pm.shouldRequestMoreNodes();
2313 });
2314
2315 m_connman.ForEachNode([&](CNode *pnode) {
2316 // Build a list of the avalanche peers nodeids
2317 if (pnode->m_avalanche_enabled) {
2318 avanode_ids.push_back(pnode->GetId());
2319 }
2320
2321 PeerRef peer = GetPeerRef(pnode->GetId());
2322 if (peer == nullptr) {
2323 return;
2324 }
2325 // If a proof radix tree timed out, cleanup
2326 if (peer->m_proof_relay &&
2327 now > (peer->m_proof_relay->lastSharedProofsUpdate.load() +
2329 peer->m_proof_relay->sharedProofs = {};
2330 }
2331 });
2332
2333 if (avanode_ids.empty()) {
2334 // No node is available for messaging, retry later
2335 goto scheduleLater;
2336 }
2337
2339
2340 // Request avalanche addresses from our peers
2341 for (NodeId avanodeId : avanode_ids) {
2342 const bool sentGetavaaddr =
2343 m_connman.ForNode(avanodeId, [&](CNode *pavanode) {
2344 if (!fQuorumEstablished || !pavanode->IsInboundConn()) {
2345 m_connman.PushMessage(
2346 pavanode, CNetMsgMaker(pavanode->GetCommonVersion())
2347 .Make(NetMsgType::GETAVAADDR));
2348 PeerRef peer = GetPeerRef(avanodeId);
2349 WITH_LOCK(peer->m_addr_token_bucket_mutex,
2350 peer->m_addr_token_bucket +=
2351 m_opts.max_addr_to_send);
2352 return true;
2353 }
2354 return false;
2355 });
2356
2357 // If we have no reason to believe that we need more nodes, only request
2358 // addresses from one of our peers.
2360 break;
2361 }
2362 }
2363
2364 if (m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
2365 // Don't request proofs while in IBD. We're likely to orphan them
2366 // because we don't have the UTXOs.
2367 goto scheduleLater;
2368 }
2369
2370 // If we never had an avaproofs message yet, be kind and only request to a
2371 // subset of our peers as we expect a ton of avaproofs message in the
2372 // process.
2373 if (m_avalanche->getAvaproofsNodeCounter() == 0) {
2374 avanode_ids.resize(std::min<size_t>(avanode_ids.size(), 3));
2375 }
2376
2377 for (NodeId nodeid : avanode_ids) {
2378 // Send a getavaproofs to all of our peers
2379 m_connman.ForNode(nodeid, [&](CNode *pavanode) {
2380 PeerRef peer = GetPeerRef(nodeid);
2381 if (peer->m_proof_relay) {
2382 m_connman.PushMessage(pavanode,
2383 CNetMsgMaker(pavanode->GetCommonVersion())
2385
2386 peer->m_proof_relay->compactproofs_requested = true;
2387 }
2388 return true;
2389 });
2390 }
2391
2393 // Schedule next run for 2-5 minutes in the future.
2394 // We add randomness on every cycle to avoid the possibility of P2P
2395 // fingerprinting.
2396 const auto avalanchePeriodicNetworkingInterval = 2min + GetRandMillis(3min);
2397 scheduler.scheduleFromNow([&] { AvalanchePeriodicNetworking(scheduler); },
2399}
2400
2401void PeerManagerImpl::FinalizeNode(const Config &config, const CNode &node) {
2402 NodeId nodeid = node.GetId();
2403 int misbehavior{0};
2404 {
2405 LOCK(cs_main);
2406 {
2407 // We remove the PeerRef from g_peer_map here, but we don't always
2408 // destruct the Peer. Sometimes another thread is still holding a
2409 // PeerRef, so the refcount is >= 1. Be careful not to do any
2410 // processing here that assumes Peer won't be changed before it's
2411 // destructed.
2412 PeerRef peer = RemovePeer(nodeid);
2413 assert(peer != nullptr);
2414 misbehavior = WITH_LOCK(peer->m_misbehavior_mutex,
2415 return peer->m_misbehavior_score);
2416 LOCK(m_peer_mutex);
2417 m_peer_map.erase(nodeid);
2418 }
2419 CNodeState *state = State(nodeid);
2420 assert(state != nullptr);
2421
2422 if (state->fSyncStarted) {
2423 nSyncStarted--;
2424 }
2425
2426 for (const QueuedBlock &entry : state->vBlocksInFlight) {
2427 auto range =
2428 mapBlocksInFlight.equal_range(entry.pindex->GetBlockHash());
2429 while (range.first != range.second) {
2430 auto [node_id, list_it] = range.first->second;
2431 if (node_id != nodeid) {
2432 range.first++;
2433 } else {
2434 range.first = mapBlocksInFlight.erase(range.first);
2435 }
2436 }
2437 }
2438 m_mempool.withOrphanage([nodeid](TxOrphanage &orphanage) {
2439 orphanage.EraseForPeer(nodeid);
2440 });
2441 m_txrequest.DisconnectedPeer(nodeid);
2442 m_num_preferred_download_peers -= state->fPreferredDownload;
2443 m_peers_downloading_from -= (!state->vBlocksInFlight.empty());
2446 state->m_chain_sync.m_protect;
2448
2449 m_node_states.erase(nodeid);
2450
2451 if (m_node_states.empty()) {
2452 // Do a consistency check after the last peer is removed.
2453 assert(mapBlocksInFlight.empty());
2457 assert(m_txrequest.Size() == 0);
2458 assert(m_mempool.withOrphanage([](const TxOrphanage &orphanage) {
2459 return orphanage.Size();
2460 }) == 0);
2461 }
2462 }
2463
2464 if (node.fSuccessfullyConnected && misbehavior == 0 &&
2465 !node.IsBlockOnlyConn() && !node.IsInboundConn()) {
2466 // Only change visible addrman state for full outbound peers. We don't
2467 // call Connected() for feeler connections since they don't have
2468 // fSuccessfullyConnected set.
2469 m_addrman.Connected(node.addr);
2470 }
2471 {
2472 LOCK(m_headers_presync_mutex);
2473 m_headers_presync_stats.erase(nodeid);
2474 }
2475
2476 WITH_LOCK(cs_proofrequest, m_proofrequest.DisconnectedPeer(nodeid));
2477
2478 LogPrint(BCLog::NET, "Cleared nodestate for peer=%d\n", nodeid);
2479}
2480
2481PeerRef PeerManagerImpl::GetPeerRef(NodeId id) const {
2482 LOCK(m_peer_mutex);
2483 auto it = m_peer_map.find(id);
2484 return it != m_peer_map.end() ? it->second : nullptr;
2485}
2486
2487PeerRef PeerManagerImpl::RemovePeer(NodeId id) {
2488 PeerRef ret;
2489 LOCK(m_peer_mutex);
2490 auto it = m_peer_map.find(id);
2491 if (it != m_peer_map.end()) {
2492 ret = std::move(it->second);
2493 m_peer_map.erase(it);
2494 }
2495 return ret;
2496}
2497
2498bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid,
2499 CNodeStateStats &stats) const {
2500 {
2501 LOCK(cs_main);
2502 const CNodeState *state = State(nodeid);
2503 if (state == nullptr) {
2504 return false;
2505 }
2506 stats.nSyncHeight = state->pindexBestKnownBlock
2507 ? state->pindexBestKnownBlock->nHeight
2508 : -1;
2509 stats.nCommonHeight = state->pindexLastCommonBlock
2510 ? state->pindexLastCommonBlock->nHeight
2511 : -1;
2512 for (const QueuedBlock &queue : state->vBlocksInFlight) {
2513 if (queue.pindex) {
2514 stats.vHeightInFlight.push_back(queue.pindex->nHeight);
2515 }
2516 }
2517 }
2518
2519 PeerRef peer = GetPeerRef(nodeid);
2520 if (peer == nullptr) {
2521 return false;
2522 }
2523 stats.their_services = peer->m_their_services;
2524 stats.m_starting_height = peer->m_starting_height;
2525 // It is common for nodes with good ping times to suddenly become lagged,
2526 // due to a new block arriving or other large transfer.
2527 // Merely reporting pingtime might fool the caller into thinking the node
2528 // was still responsive, since pingtime does not update until the ping is
2529 // complete, which might take a while. So, if a ping is taking an unusually
2530 // long time in flight, the caller can immediately detect that this is
2531 // happening.
2532 auto ping_wait{0us};
2533 if ((0 != peer->m_ping_nonce_sent) &&
2534 (0 != peer->m_ping_start.load().count())) {
2535 ping_wait =
2536 GetTime<std::chrono::microseconds>() - peer->m_ping_start.load();
2537 }
2538
2539 if (auto tx_relay = peer->GetTxRelay()) {
2540 stats.m_relay_txs = WITH_LOCK(tx_relay->m_bloom_filter_mutex,
2541 return tx_relay->m_relay_txs);
2542 stats.m_fee_filter_received = tx_relay->m_fee_filter_received.load();
2543 } else {
2544 stats.m_relay_txs = false;
2546 }
2547
2548 stats.m_ping_wait = ping_wait;
2549 stats.m_addr_processed = peer->m_addr_processed.load();
2550 stats.m_addr_rate_limited = peer->m_addr_rate_limited.load();
2551 stats.m_addr_relay_enabled = peer->m_addr_relay_enabled.load();
2552 {
2553 LOCK(peer->m_headers_sync_mutex);
2554 if (peer->m_headers_sync) {
2555 stats.presync_height = peer->m_headers_sync->GetPresyncHeight();
2556 }
2557 }
2558
2559 return true;
2560}
2561
2562void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef &tx) {
2563 if (m_opts.max_extra_txs <= 0) {
2564 return;
2565 }
2566
2567 if (!vExtraTxnForCompact.size()) {
2568 vExtraTxnForCompact.resize(m_opts.max_extra_txs);
2569 }
2570
2572 std::make_pair(tx->GetHash(), tx);
2573 vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs;
2574}
2575
2576void PeerManagerImpl::Misbehaving(Peer &peer, int howmuch,
2577 const std::string &message) {
2578 assert(howmuch > 0);
2579
2580 LOCK(peer.m_misbehavior_mutex);
2581 const int score_before{peer.m_misbehavior_score};
2582 peer.m_misbehavior_score += howmuch;
2583 const int score_now{peer.m_misbehavior_score};
2584
2585 const std::string message_prefixed =
2586 message.empty() ? "" : (": " + message);
2587 std::string warning;
2588
2591 warning = " DISCOURAGE THRESHOLD EXCEEDED";
2592 peer.m_should_discourage = true;
2593 }
2594
2595 LogPrint(BCLog::NET, "Misbehaving: peer=%d (%d -> %d)%s%s\n", peer.m_id,
2597}
2598
2599bool PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid,
2600 const BlockValidationState &state,
2601 bool via_compact_block,
2602 const std::string &message) {
2603 PeerRef peer{GetPeerRef(nodeid)};
2604 switch (state.GetResult()) {
2606 break;
2608 // We didn't try to process the block because the header chain may
2609 // have too little work.
2610 break;
2611 // The node is providing invalid data:
2614 if (!via_compact_block) {
2615 if (peer) {
2616 Misbehaving(*peer, 100, message);
2617 }
2618 return true;
2619 }
2620 break;
2622 LOCK(cs_main);
2623 CNodeState *node_state = State(nodeid);
2624 if (node_state == nullptr) {
2625 break;
2626 }
2627
2628 // Ban outbound (but not inbound) peers if on an invalid chain.
2629 // Exempt HB compact block peers. Manual connections are always
2630 // protected from discouragement.
2631 if (!via_compact_block && !node_state->m_is_inbound) {
2632 if (peer) {
2633 Misbehaving(*peer, 100, message);
2634 }
2635 return true;
2636 }
2637 break;
2638 }
2642 if (peer) {
2643 Misbehaving(*peer, 100, message);
2644 }
2645 return true;
2646 // Conflicting (but not necessarily invalid) data or different policy:
2648 // TODO: Handle this much more gracefully (10 DoS points is super
2649 // arbitrary)
2650 if (peer) {
2651 Misbehaving(*peer, 10, message);
2652 }
2653 return true;
2655 break;
2656 }
2657 if (message != "") {
2658 LogPrint(BCLog::NET, "peer=%d: %s\n", nodeid, message);
2659 }
2660 return false;
2661}
2662
2663bool PeerManagerImpl::MaybePunishNodeForTx(NodeId nodeid,
2664 const TxValidationState &state,
2665 const std::string &message) {
2666 PeerRef peer{GetPeerRef(nodeid)};
2667 switch (state.GetResult()) {
2669 break;
2670 // The node is providing invalid data:
2672 if (peer) {
2673 Misbehaving(*peer, 100, message);
2674 }
2675 return true;
2676 // Conflicting (but not necessarily invalid) data or different policy:
2689 break;
2690 }
2691 if (message != "") {
2692 LogPrint(BCLog::NET, "peer=%d: %s\n", nodeid, message);
2693 }
2694 return false;
2695}
2696
2697bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex *pindex) {
2699 if (m_chainman.ActiveChain().Contains(pindex)) {
2700 return true;
2701 }
2702 return pindex->IsValid(BlockValidity::SCRIPTS) &&
2703 (m_chainman.m_best_header != nullptr) &&
2704 (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() <
2707 *m_chainman.m_best_header, *pindex, *m_chainman.m_best_header,
2708 m_chainparams.GetConsensus()) < STALE_RELAY_AGE_LIMIT);
2709}
2710
2711std::optional<std::string>
2712PeerManagerImpl::FetchBlock(const Config &config, NodeId peer_id,
2713 const CBlockIndex &block_index) {
2714 if (m_chainman.m_blockman.LoadingBlocks()) {
2715 return "Loading blocks ...";
2716 }
2717
2718 LOCK(cs_main);
2719
2720 // Ensure this peer exists and hasn't been disconnected
2721 CNodeState *state = State(peer_id);
2722 if (state == nullptr) {
2723 return "Peer does not exist";
2724 }
2725
2726 // Forget about all prior requests
2727 RemoveBlockRequest(block_index.GetBlockHash(), std::nullopt);
2728
2729 // Mark block as in-flight
2730 if (!BlockRequested(config, peer_id, block_index)) {
2731 return "Already requested from this peer";
2732 }
2733
2734 // Construct message to request the block
2735 const BlockHash &hash{block_index.GetBlockHash()};
2736 const std::vector<CInv> invs{CInv(MSG_BLOCK, hash)};
2737
2738 // Send block request message to the peer
2739 if (!m_connman.ForNode(peer_id, [this, &invs](CNode *node) {
2740 const CNetMsgMaker msgMaker(node->GetCommonVersion());
2741 this->m_connman.PushMessage(
2742 node, msgMaker.Make(NetMsgType::GETDATA, invs));
2743 return true;
2744 })) {
2745 return "Node not fully connected";
2746 }
2747
2748 LogPrint(BCLog::NET, "Requesting block %s from peer=%d\n", hash.ToString(),
2749 peer_id);
2750 return std::nullopt;
2751}
2752
2753std::unique_ptr<PeerManager>
2754PeerManager::make(CConnman &connman, AddrMan &addrman, BanMan *banman,
2755 ChainstateManager &chainman, CTxMemPool &pool,
2756 avalanche::Processor *const avalanche, Options opts) {
2757 return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman,
2758 pool, avalanche, opts);
2759}
2760
2761PeerManagerImpl::PeerManagerImpl(CConnman &connman, AddrMan &addrman,
2762 BanMan *banman, ChainstateManager &chainman,
2763 CTxMemPool &pool,
2765 Options opts)
2766 : m_rng{opts.deterministic_rng},
2768 m_chainparams(chainman.GetParams()), m_connman(connman),
2769 m_addrman(addrman), m_banman(banman), m_chainman(chainman),
2770 m_mempool(pool), m_avalanche(avalanche), m_opts{opts} {}
2771
2772void PeerManagerImpl::StartScheduledTasks(CScheduler &scheduler) {
2773 // Stale tip checking and peer eviction are on two different timers, but we
2774 // don't want them to get out of sync due to drift in the scheduler, so we
2775 // combine them in one function and schedule at the quicker (peer-eviction)
2776 // timer.
2777 static_assert(
2779 "peer eviction timer should be less than stale tip check timer");
2780 scheduler.scheduleEvery(
2781 [this]() {
2782 this->CheckForStaleTipAndEvictPeers();
2783 return true;
2784 },
2785 std::chrono::seconds{EXTRA_PEER_CHECK_INTERVAL});
2786
2787 // schedule next run for 10-15 minutes in the future
2788 const auto reattemptBroadcastInterval = 10min + GetRandMillis(5min);
2789 scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); },
2791
2792 // Update the avalanche statistics on a schedule
2793 scheduler.scheduleEvery(
2794 [this]() {
2796 return true;
2797 },
2799
2800 // schedule next run for 2-5 minutes in the future
2801 const auto avalanchePeriodicNetworkingInterval = 2min + GetRandMillis(3min);
2802 scheduler.scheduleFromNow([&] { AvalanchePeriodicNetworking(scheduler); },
2804}
2805
2812void PeerManagerImpl::BlockConnected(
2813 const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex) {
2814 m_mempool.withOrphanage([&pblock](TxOrphanage &orphanage) {
2815 orphanage.EraseForBlock(*pblock);
2816 });
2818 conflicting.EraseForBlock(*pblock);
2819 });
2820 m_last_tip_update = GetTime<std::chrono::seconds>();
2821
2822 {
2823 LOCK(m_recent_confirmed_transactions_mutex);
2824 for (const CTransactionRef &ptx : pblock->vtx) {
2825 m_recent_confirmed_transactions.insert(ptx->GetId());
2826 }
2827 }
2828 {
2829 LOCK(cs_main);
2830 for (const auto &ptx : pblock->vtx) {
2831 m_txrequest.ForgetInvId(ptx->GetId());
2832 }
2833 }
2834
2835 // In case the dynamic timeout was doubled once or more, reduce it slowly
2836 // back to its default value
2837 auto stalling_timeout = m_block_stalling_timeout.load();
2840 const auto new_timeout =
2841 std::max(std::chrono::duration_cast<std::chrono::seconds>(
2842 stalling_timeout * 0.85),
2844 if (m_block_stalling_timeout.compare_exchange_strong(stalling_timeout,
2845 new_timeout)) {
2846 LogPrint(BCLog::NET, "Decreased stalling timeout to %d seconds\n",
2848 }
2849 }
2850}
2851
2852void PeerManagerImpl::BlockDisconnected(
2853 const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {
2854 // To avoid relay problems with transactions that were previously
2855 // confirmed, clear our filter of recently confirmed transactions whenever
2856 // there's a reorg.
2857 // This means that in a 1-block reorg (where 1 block is disconnected and
2858 // then another block reconnected), our filter will drop to having only one
2859 // block's worth of transactions in it, but that should be fine, since
2860 // presumably the most common case of relaying a confirmed transaction
2861 // should be just after a new block containing it is found.
2862 LOCK(m_recent_confirmed_transactions_mutex);
2864}
2865
2870void PeerManagerImpl::NewPoWValidBlock(
2871 const CBlockIndex *pindex, const std::shared_ptr<const CBlock> &pblock) {
2872 std::shared_ptr<const CBlockHeaderAndShortTxIDs> pcmpctblock =
2873 std::make_shared<const CBlockHeaderAndShortTxIDs>(*pblock);
2875
2876 LOCK(cs_main);
2877
2878 if (pindex->nHeight <= m_highest_fast_announce) {
2879 return;
2880 }
2882
2883 BlockHash hashBlock(pblock->GetHash());
2884 const std::shared_future<CSerializedNetMsg> lazy_ser{
2885 std::async(std::launch::deferred, [&] {
2887 })};
2888
2889 {
2890 LOCK(m_most_recent_block_mutex);
2891 m_most_recent_block_hash = hashBlock;
2894 }
2895
2896 m_connman.ForEachNode(
2897 [this, pindex, &lazy_ser, &hashBlock](CNode *pnode)
2900
2901 if (pnode->GetCommonVersion() < INVALID_CB_NO_BAN_VERSION ||
2902 pnode->fDisconnect) {
2903 return;
2904 }
2906 CNodeState &state = *State(pnode->GetId());
2907 // If the peer has, or we announced to them the previous block
2908 // already, but we don't think they have this one, go ahead and
2909 // announce it.
2910 if (state.m_requested_hb_cmpctblocks &&
2911 !PeerHasHeader(&state, pindex) &&
2912 PeerHasHeader(&state, pindex->pprev)) {
2914 "%s sending header-and-ids %s to peer=%d\n",
2915 "PeerManager::NewPoWValidBlock",
2916 hashBlock.ToString(), pnode->GetId());
2917
2919 m_connman.PushMessage(pnode, ser_cmpctblock.Copy());
2920 state.pindexBestHeaderSent = pindex;
2921 }
2922 });
2923}
2924
2929void PeerManagerImpl::UpdatedBlockTip(const CBlockIndex *pindexNew,
2930 const CBlockIndex *pindexFork,
2931 bool fInitialDownload) {
2932 SetBestHeight(pindexNew->nHeight);
2934
2935 // Don't relay inventory during initial block download.
2936 if (fInitialDownload) {
2937 return;
2938 }
2939
2940 // Find the hashes of all blocks that weren't previously in the best chain.
2941 std::vector<BlockHash> vHashes;
2943 while (pindexToAnnounce != pindexFork) {
2944 vHashes.push_back(pindexToAnnounce->GetBlockHash());
2946 if (vHashes.size() == MAX_BLOCKS_TO_ANNOUNCE) {
2947 // Limit announcements in case of a huge reorganization. Rely on the
2948 // peer's synchronization mechanism in that case.
2949 break;
2950 }
2951 }
2952
2953 {
2954 LOCK(m_peer_mutex);
2955 for (auto &it : m_peer_map) {
2956 Peer &peer = *it.second;
2957 LOCK(peer.m_block_inv_mutex);
2958 for (const BlockHash &hash : reverse_iterate(vHashes)) {
2959 peer.m_blocks_for_headers_relay.push_back(hash);
2960 }
2961 }
2962 }
2963
2964 m_connman.WakeMessageHandler();
2965}
2966
2971void PeerManagerImpl::BlockChecked(const CBlock &block,
2972 const BlockValidationState &state) {
2973 LOCK(cs_main);
2974
2975 const BlockHash hash = block.GetHash();
2976 std::map<BlockHash, std::pair<NodeId, bool>>::iterator it =
2977 mapBlockSource.find(hash);
2978
2979 // If the block failed validation, we know where it came from and we're
2980 // still connected to that peer, maybe punish.
2981 if (state.IsInvalid() && it != mapBlockSource.end() &&
2982 State(it->second.first)) {
2983 MaybePunishNodeForBlock(/*nodeid=*/it->second.first, state,
2984 /*via_compact_block=*/!it->second.second);
2985 }
2986 // Check that:
2987 // 1. The block is valid
2988 // 2. We're not in initial block download
2989 // 3. This is currently the best block we're aware of. We haven't updated
2990 // the tip yet so we have no way to check this directly here. Instead we
2991 // just check that there are currently no other blocks in flight.
2992 else if (state.IsValid() &&
2993 !m_chainman.ActiveChainstate().IsInitialBlockDownload() &&
2994 mapBlocksInFlight.count(hash) == mapBlocksInFlight.size()) {
2995 if (it != mapBlockSource.end()) {
2996 MaybeSetPeerAsAnnouncingHeaderAndIDs(it->second.first);
2997 }
2998 }
2999
3000 if (it != mapBlockSource.end()) {
3001 mapBlockSource.erase(it);
3002 }
3003}
3004
3006//
3007// Messages
3008//
3009
3010bool PeerManagerImpl::AlreadyHaveTx(const TxId &txid,
3012 if (m_chainman.ActiveChain().Tip()->GetBlockHash() !=
3014 // If the chain tip has changed previously rejected transactions
3015 // might be now valid, e.g. due to a nLockTime'd tx becoming
3016 // valid, or a double-spend. Reset the rejects filter and give
3017 // those txs a second chance.
3019 m_chainman.ActiveChain().Tip()->GetBlockHash();
3020 m_recent_rejects.reset();
3022 }
3023
3024 if (m_mempool.withOrphanage([&txid](const TxOrphanage &orphanage) {
3025 return orphanage.HaveTx(txid);
3026 })) {
3027 return true;
3028 }
3029
3030 if (m_mempool.withConflicting([&txid](const TxConflicting &conflicting) {
3031 return conflicting.HaveTx(txid);
3032 })) {
3033 return true;
3034 }
3035
3038 return true;
3039 }
3040
3041 {
3042 LOCK(m_recent_confirmed_transactions_mutex);
3043 if (m_recent_confirmed_transactions.contains(txid)) {
3044 return true;
3045 }
3046 }
3047
3048 return m_recent_rejects.contains(txid) || m_mempool.exists(txid);
3049}
3050
3051bool PeerManagerImpl::AlreadyHaveBlock(const BlockHash &block_hash) {
3052 return m_chainman.m_blockman.LookupBlockIndex(block_hash) != nullptr;
3053}
3054
3055bool PeerManagerImpl::AlreadyHaveProof(const avalanche::ProofId &proofid) {
3056 if (!Assume(m_avalanche)) {
3057 return false;
3058 }
3059
3060 auto localProof = m_avalanche->getLocalProof();
3061 if (localProof && localProof->getId() == proofid) {
3062 return true;
3063 }
3064
3065 return m_avalanche->withPeerManager([&proofid](avalanche::PeerManager &pm) {
3066 return pm.exists(proofid) || pm.isInvalid(proofid);
3067 });
3068}
3069
3070void PeerManagerImpl::SendPings() {
3071 LOCK(m_peer_mutex);
3072 for (auto &it : m_peer_map) {
3073 it.second->m_ping_queued = true;
3074 }
3075}
3076
3077void PeerManagerImpl::RelayTransaction(const TxId &txid) {
3078 LOCK(m_peer_mutex);
3079 for (auto &it : m_peer_map) {
3080 Peer &peer = *it.second;
3081 auto tx_relay = peer.GetTxRelay();
3082 if (!tx_relay) {
3083 continue;
3084 }
3085 LOCK(tx_relay->m_tx_inventory_mutex);
3086 // Only queue transactions for announcement once the version handshake
3087 // is completed. The time of arrival for these transactions is
3088 // otherwise at risk of leaking to a spy, if the spy is able to
3089 // distinguish transactions received during the handshake from the rest
3090 // in the announcement.
3091 if (tx_relay->m_next_inv_send_time == 0s) {
3092 continue;
3093 }
3094
3095 if (!tx_relay->m_tx_inventory_known_filter.contains(txid)) {
3096 tx_relay->m_tx_inventory_to_send.insert(txid);
3097 }
3098 }
3099}
3100
3101void PeerManagerImpl::RelayProof(const avalanche::ProofId &proofid) {
3102 LOCK(m_peer_mutex);
3103 for (auto &it : m_peer_map) {
3104 Peer &peer = *it.second;
3105
3106 if (!peer.m_proof_relay) {
3107 continue;
3108 }
3109 LOCK(peer.m_proof_relay->m_proof_inventory_mutex);
3110 if (!peer.m_proof_relay->m_proof_inventory_known_filter.contains(
3111 proofid)) {
3112 peer.m_proof_relay->m_proof_inventory_to_send.insert(proofid);
3113 }
3114 }
3115}
3116
3117void PeerManagerImpl::RelayAddress(NodeId originator, const CAddress &addr,
3118 bool fReachable) {
3119 // We choose the same nodes within a given 24h window (if the list of
3120 // connected nodes does not change) and we don't relay to nodes that already
3121 // know an address. So within 24h we will likely relay a given address once.
3122 // This is to prevent a peer from unjustly giving their address better
3123 // propagation by sending it to us repeatedly.
3124
3125 if (!fReachable && !addr.IsRelayable()) {
3126 return;
3127 }
3128
3129 // Relay to a limited number of other nodes
3130 // Use deterministic randomness to send to the same nodes for 24 hours
3131 // at a time so the m_addr_knowns of the chosen nodes prevent repeats
3132 const uint64_t hash_addr{CServiceHash(0, 0)(addr)};
3134 // Adding address hash makes exact rotation time different per address,
3135 // while preserving periodicity.
3136 const uint64_t time_addr{
3137 (static_cast<uint64_t>(count_seconds(current_time)) + hash_addr) /
3139
3140 const CSipHasher hasher{
3143 .Write(time_addr)};
3144
3145 // Relay reachable addresses to 2 peers. Unreachable addresses are relayed
3146 // randomly to 1 or 2 peers.
3147 unsigned int nRelayNodes = (fReachable || (hasher.Finalize() & 1)) ? 2 : 1;
3148 std::array<std::pair<uint64_t, Peer *>, 2> best{
3149 {{0, nullptr}, {0, nullptr}}};
3150 assert(nRelayNodes <= best.size());
3151
3152 LOCK(m_peer_mutex);
3153
3154 for (auto &[id, peer] : m_peer_map) {
3155 if (peer->m_addr_relay_enabled && id != originator &&
3156 IsAddrCompatible(*peer, addr)) {
3157 uint64_t hashKey = CSipHasher(hasher).Write(id).Finalize();
3158 for (unsigned int i = 0; i < nRelayNodes; i++) {
3159 if (hashKey > best[i].first) {
3160 std::copy(best.begin() + i, best.begin() + nRelayNodes - 1,
3161 best.begin() + i + 1);
3162 best[i] = std::make_pair(hashKey, peer.get());
3163 break;
3164 }
3165 }
3166 }
3167 };
3168
3169 for (unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
3170 PushAddress(*best[i].second, addr);
3171 }
3172}
3173
3174void PeerManagerImpl::ProcessGetBlockData(const Config &config, CNode &pfrom,
3175 Peer &peer, const CInv &inv) {
3176 const BlockHash hash(inv.hash);
3177
3178 std::shared_ptr<const CBlock> a_recent_block;
3179 std::shared_ptr<const CBlockHeaderAndShortTxIDs> a_recent_compact_block;
3180 {
3181 LOCK(m_most_recent_block_mutex);
3184 }
3185
3186 bool need_activate_chain = false;
3187 {
3188 LOCK(cs_main);
3189 const CBlockIndex *pindex =
3190 m_chainman.m_blockman.LookupBlockIndex(hash);
3191 if (pindex) {
3192 if (pindex->HaveTxsDownloaded() &&
3193 !pindex->IsValid(BlockValidity::SCRIPTS) &&
3194 pindex->IsValid(BlockValidity::TREE)) {
3195 // If we have the block and all of its parents, but have not yet
3196 // validated it, we might be in the middle of connecting it (ie
3197 // in the unlock of cs_main before ActivateBestChain but after
3198 // AcceptBlock). In this case, we need to run ActivateBestChain
3199 // prior to checking the relay conditions below.
3200 need_activate_chain = true;
3201 }
3202 }
3203 } // release cs_main before calling ActivateBestChain
3204 if (need_activate_chain) {
3206 if (!m_chainman.ActiveChainstate().ActivateBestChain(
3207 state, a_recent_block, m_avalanche)) {
3208 LogPrint(BCLog::NET, "failed to activate chain (%s)\n",
3209 state.ToString());
3210 }
3211 }
3212
3213 LOCK(cs_main);
3214 const CBlockIndex *pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
3215 if (!pindex) {
3216 return;
3217 }
3218 if (!BlockRequestAllowed(pindex)) {
3220 "%s: ignoring request from peer=%i for old "
3221 "block that isn't in the main chain\n",
3222 __func__, pfrom.GetId());
3223 return;
3224 }
3225 const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
3226 // Disconnect node in case we have reached the outbound limit for serving
3227 // historical blocks.
3228 if (m_connman.OutboundTargetReached(true) &&
3229 (((m_chainman.m_best_header != nullptr) &&
3230 (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() >
3232 inv.IsMsgFilteredBlk()) &&
3233 // nodes with the download permission may exceed target
3234 !pfrom.HasPermission(NetPermissionFlags::Download)) {
3236 "historical block serving limit reached, disconnect peer=%d\n",
3237 pfrom.GetId());
3238 pfrom.fDisconnect = true;
3239 return;
3240 }
3241 // Avoid leaking prune-height by never sending blocks below the
3242 // NODE_NETWORK_LIMITED threshold.
3243 // Add two blocks buffer extension for possible races
3244 if (!pfrom.HasPermission(NetPermissionFlags::NoBan) &&
3245 ((((peer.m_our_services & NODE_NETWORK_LIMITED) ==
3247 ((peer.m_our_services & NODE_NETWORK) != NODE_NETWORK) &&
3248 (m_chainman.ActiveChain().Tip()->nHeight - pindex->nHeight >
3249 (int)NODE_NETWORK_LIMITED_MIN_BLOCKS + 2)))) {
3251 "Ignore block request below NODE_NETWORK_LIMITED "
3252 "threshold, disconnect peer=%d\n",
3253 pfrom.GetId());
3254
3255 // disconnect node and prevent it from stalling (would otherwise wait
3256 // for the missing block)
3257 pfrom.fDisconnect = true;
3258 return;
3259 }
3260 // Pruned nodes may have deleted the block, so check whether it's available
3261 // before trying to send.
3262 if (!pindex->nStatus.hasData()) {
3263 return;
3264 }
3265 std::shared_ptr<const CBlock> pblock;
3266 if (a_recent_block && a_recent_block->GetHash() == pindex->GetBlockHash()) {
3268 } else {
3269 // Send block from disk
3270 std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
3271 if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, *pindex)) {
3272 assert(!"cannot load block from disk");
3273 }
3275 }
3276 if (inv.IsMsgBlk()) {
3277 m_connman.PushMessage(&pfrom,
3279 } else if (inv.IsMsgFilteredBlk()) {
3280 bool sendMerkleBlock = false;
3282 if (auto tx_relay = peer.GetTxRelay()) {
3283 LOCK(tx_relay->m_bloom_filter_mutex);
3284 if (tx_relay->m_bloom_filter) {
3285 sendMerkleBlock = true;
3286 merkleBlock = CMerkleBlock(*pblock, *tx_relay->m_bloom_filter);
3287 }
3288 }
3289 if (sendMerkleBlock) {
3290 m_connman.PushMessage(
3292 // CMerkleBlock just contains hashes, so also push any
3293 // transactions in the block the client did not see. This avoids
3294 // hurting performance by pointlessly requiring a round-trip.
3295 // Note that there is currently no way for a node to request any
3296 // single transactions we didn't send here - they must either
3297 // disconnect and retry or request the full block. Thus, the
3298 // protocol spec specified allows for us to provide duplicate
3299 // txn here, however we MUST always provide at least what the
3300 // remote peer needs.
3301 typedef std::pair<size_t, uint256> PairType;
3302 for (PairType &pair : merkleBlock.vMatchedTxn) {
3303 m_connman.PushMessage(
3304 &pfrom,
3305 msgMaker.Make(NetMsgType::TX, *pblock->vtx[pair.first]));
3306 }
3307 }
3308 // else
3309 // no response
3310 } else if (inv.IsMsgCmpctBlk()) {
3311 // If a peer is asking for old blocks, we're almost guaranteed they
3312 // won't have a useful mempool to match against a compact block, and
3313 // we don't feel like constructing the object for them, so instead
3314 // we respond with the full, non-compact block.
3315 int nSendFlags = 0;
3316 if (CanDirectFetch() &&
3317 pindex->nHeight >=
3318 m_chainman.ActiveChain().Height() - MAX_CMPCTBLOCK_DEPTH) {
3320 a_recent_compact_block->header.GetHash() ==
3321 pindex->GetBlockHash()) {
3322 m_connman.PushMessage(&pfrom,
3325 } else {
3327 m_connman.PushMessage(
3329 cmpctblock));
3330 }
3331 } else {
3332 m_connman.PushMessage(
3334 }
3335 }
3336
3337 {
3338 LOCK(peer.m_block_inv_mutex);
3339 // Trigger the peer node to send a getblocks request for the next
3340 // batch of inventory.
3341 if (hash == peer.m_continuation_block) {
3342 // Send immediately. This must send even if redundant, and
3343 // we want it right after the last block so they don't wait for
3344 // other stuff first.
3345 std::vector<CInv> vInv;
3346 vInv.push_back(CInv(
3347 MSG_BLOCK, m_chainman.ActiveChain().Tip()->GetBlockHash()));
3348 m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::INV, vInv));
3349 peer.m_continuation_block = BlockHash();
3350 }
3351 }
3352}
3353
3355PeerManagerImpl::FindTxForGetData(const Peer &peer, const TxId &txid,
3356 const std::chrono::seconds mempool_req,
3357 const std::chrono::seconds now) {
3358 auto txinfo = m_mempool.info(txid);
3359 if (txinfo.tx) {
3360 // If a TX could have been INVed in reply to a MEMPOOL request,
3361 // or is older than UNCONDITIONAL_RELAY_DELAY, permit the request
3362 // unconditionally.
3363 if ((mempool_req.count() && txinfo.m_time <= mempool_req) ||
3364 txinfo.m_time <= now - UNCONDITIONAL_RELAY_DELAY) {
3365 return std::move(txinfo.tx);
3366 }
3367 }
3368
3369 {
3370 LOCK(cs_main);
3371
3372 // Otherwise, the transaction must have been announced recently.
3373 if (Assume(peer.GetTxRelay())
3374 ->m_recently_announced_invs.contains(txid)) {
3375 // If it was, it can be relayed from either the mempool...
3376 if (txinfo.tx) {
3377 return std::move(txinfo.tx);
3378 }
3379 // ... or the relay pool.
3380 auto mi = mapRelay.find(txid);
3381 if (mi != mapRelay.end()) {
3382 return mi->second;
3383 }
3384 }
3385 }
3386
3387 return {};
3388}
3389
3393PeerManagerImpl::FindProofForGetData(const Peer &peer,
3394 const avalanche::ProofId &proofid,
3395 const std::chrono::seconds now) {
3396 avalanche::ProofRef proof;
3397
3399 m_avalanche->withPeerManager([&](const avalanche::PeerManager &pm) {
3400 return pm.forPeer(proofid, [&](const avalanche::Peer &peer) {
3401 proof = peer.proof;
3402
3403 // If we know that proof for long enough, allow for requesting
3404 // it.
3405 return peer.registration_time <=
3407 });
3408 });
3409
3410 if (!proof) {
3411 // Always send our local proof if it gets requested, assuming it's
3412 // valid. This will make it easier to bind with peers upon startup where
3413 // the status of our proof is unknown pending for a block. Note that it
3414 // still needs to have been announced first (presumably via an avahello
3415 // message).
3416 proof = m_avalanche->getLocalProof();
3417 }
3418
3419 // We don't have this proof
3420 if (!proof) {
3421 return avalanche::ProofRef();
3422 }
3423
3425 return proof;
3426 }
3427
3428 // Otherwise, the proofs must have been announced recently.
3429 if (peer.m_proof_relay->m_recently_announced_proofs.contains(proofid)) {
3430 return proof;
3431 }
3432
3433 return avalanche::ProofRef();
3434}
3435
3436void PeerManagerImpl::ProcessGetData(
3437 const Config &config, CNode &pfrom, Peer &peer,
3438 const std::atomic<bool> &interruptMsgProc) {
3440
3441 auto tx_relay = peer.GetTxRelay();
3442
3443 std::deque<CInv>::iterator it = peer.m_getdata_requests.begin();
3444 std::vector<CInv> vNotFound;
3445 const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
3446
3447 const auto now{GetTime<std::chrono::seconds>()};
3448 // Get last mempool request time
3449 const auto mempool_req = tx_relay != nullptr
3450 ? tx_relay->m_last_mempool_req.load()
3451 : std::chrono::seconds::min();
3452
3453 // Process as many TX or AVA_PROOF items from the front of the getdata
3454 // queue as possible, since they're common and it's efficient to batch
3455 // process them.
3456 while (it != peer.m_getdata_requests.end()) {
3457 if (interruptMsgProc) {
3458 return;
3459 }
3460 // The send buffer provides backpressure. If there's no space in
3461 // the buffer, pause processing until the next call.
3462 if (pfrom.fPauseSend) {
3463 break;
3464 }
3465
3466 const CInv &inv = *it;
3467
3468 if (it->IsMsgProof()) {
3469 if (!m_avalanche) {
3470 vNotFound.push_back(inv);
3471 ++it;
3472 continue;
3473 }
3474 const avalanche::ProofId proofid(inv.hash);
3475 auto proof = FindProofForGetData(peer, proofid, now);
3476 if (proof) {
3477 m_connman.PushMessage(
3478 &pfrom, msgMaker.Make(NetMsgType::AVAPROOF, *proof));
3479 m_avalanche->withPeerManager([&](avalanche::PeerManager &pm) {
3480 pm.removeUnbroadcastProof(proofid);
3481 });
3482 } else {
3483 vNotFound.push_back(inv);
3484 }
3485
3486 ++it;
3487 continue;
3488 }
3489
3490 if (it->IsMsgTx()) {
3491 if (tx_relay == nullptr) {
3492 // Ignore GETDATA requests for transactions from
3493 // block-relay-only peers and peers that asked us not to
3494 // announce transactions.
3495 continue;
3496 }
3497
3498 const TxId txid(inv.hash);
3499 CTransactionRef tx = FindTxForGetData(peer, txid, mempool_req, now);
3500 if (tx) {
3501 int nSendFlags = 0;
3502 m_connman.PushMessage(
3503 &pfrom, msgMaker.Make(nSendFlags, NetMsgType::TX, *tx));
3504 m_mempool.RemoveUnbroadcastTx(txid);
3505 // As we're going to send tx, make sure its unconfirmed parents
3506 // are made requestable.
3507 std::vector<TxId> parent_ids_to_add;
3508 {
3509 LOCK(m_mempool.cs);
3510 auto txiter = m_mempool.GetIter(tx->GetId());
3511 if (txiter) {
3512 auto &pentry = *txiter;
3514 (*pentry)->GetMemPoolParentsConst();
3515 parent_ids_to_add.reserve(parents.size());
3516 for (const auto &parent : parents) {
3517 if (parent.get()->GetTime() >
3519 parent_ids_to_add.push_back(
3520 parent.get()->GetTx().GetId());
3521 }
3522 }
3523 }
3524 }
3525 for (const TxId &parent_txid : parent_ids_to_add) {
3526 // Relaying a transaction with a recent but unconfirmed
3527 // parent.
3528 if (WITH_LOCK(tx_relay->m_tx_inventory_mutex,
3529 return !tx_relay->m_tx_inventory_known_filter
3530 .contains(parent_txid))) {
3531 tx_relay->m_recently_announced_invs.insert(parent_txid);
3532 }
3533 }
3534 } else {
3535 vNotFound.push_back(inv);
3536 }
3537
3538 ++it;
3539 continue;
3540 }
3541
3542 // It's neither a proof nor a transaction
3543 break;
3544 }
3545
3546 // Only process one BLOCK item per call, since they're uncommon and can be
3547 // expensive to process.
3548 if (it != peer.m_getdata_requests.end() && !pfrom.fPauseSend) {
3549 const CInv &inv = *it++;
3550 if (inv.IsGenBlkMsg()) {
3551 ProcessGetBlockData(config, pfrom, peer, inv);
3552 }
3553 // else: If the first item on the queue is an unknown type, we erase it
3554 // and continue processing the queue on the next call.
3555 }
3556
3557 peer.m_getdata_requests.erase(peer.m_getdata_requests.begin(), it);
3558
3559 if (!vNotFound.empty()) {
3560 // Let the peer know that we didn't find what it asked for, so it
3561 // doesn't have to wait around forever. SPV clients care about this
3562 // message: it's needed when they are recursively walking the
3563 // dependencies of relevant unconfirmed transactions. SPV clients want
3564 // to do that because they want to know about (and store and rebroadcast
3565 // and risk analyze) the dependencies of transactions relevant to them,
3566 // without having to download the entire memory pool. Also, other nodes
3567 // can use these messages to automatically request a transaction from
3568 // some other peer that annnounced it, and stop waiting for us to
3569 // respond. In normal operation, we often send NOTFOUND messages for
3570 // parents of transactions that we relay; if a peer is missing a parent,
3571 // they may assume we have them and request the parents from us.
3572 m_connman.PushMessage(&pfrom,
3574 }
3575}
3576
3577void PeerManagerImpl::SendBlockTransactions(
3578 CNode &pfrom, Peer &peer, const CBlock &block,
3579 const BlockTransactionsRequest &req) {
3581 for (size_t i = 0; i < req.indices.size(); i++) {
3582 if (req.indices[i] >= block.vtx.size()) {
3583 Misbehaving(peer, 100, "getblocktxn with out-of-bounds tx indices");
3584 return;
3585 }
3586 resp.txn[i] = block.vtx[req.indices[i]];
3587 }
3588 LOCK(cs_main);
3589 const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
3590 int nSendFlags = 0;
3591 m_connman.PushMessage(
3593}
3594
3595bool PeerManagerImpl::CheckHeadersPoW(const std::vector<CBlockHeader> &headers,
3597 Peer &peer) {
3598 // Do these headers have proof-of-work matching what's claimed?
3600 Misbehaving(peer, 100, "header with invalid proof of work");
3601 return false;
3602 }
3603
3604 // Are these headers connected to each other?
3606 Misbehaving(peer, 20, "non-continuous headers sequence");
3607 return false;
3608 }
3609 return true;
3610}
3611
3612arith_uint256 PeerManagerImpl::GetAntiDoSWorkThreshold() {
3614 LOCK(cs_main);
3615 if (m_chainman.ActiveChain().Tip() != nullptr) {
3616 const CBlockIndex *tip = m_chainman.ActiveChain().Tip();
3617 // Use a 144 block buffer, so that we'll accept headers that fork from
3618 // near our tip.
3620 tip->nChainWork -
3621 std::min<arith_uint256>(144 * GetBlockProof(*tip), tip->nChainWork);
3622 }
3623 return std::max(near_chaintip_work, m_chainman.MinimumChainWork());
3624}
3625
3638void PeerManagerImpl::HandleFewUnconnectingHeaders(
3639 CNode &pfrom, Peer &peer, const std::vector<CBlockHeader> &headers) {
3640 const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
3641
3642 peer.m_num_unconnecting_headers_msgs++;
3643 // Try to fill in the missing headers.
3644 const CBlockIndex *best_header{
3645 WITH_LOCK(cs_main, return m_chainman.m_best_header)};
3647 LogPrint(
3648 BCLog::NET,
3649 "received header %s: missing prev block %s, sending getheaders "
3650 "(%d) to end (peer=%d, m_num_unconnecting_headers_msgs=%d)\n",
3651 headers[0].GetHash().ToString(),
3652 headers[0].hashPrevBlock.ToString(), best_header->nHeight,
3653 pfrom.GetId(), peer.m_num_unconnecting_headers_msgs);
3654 }
3655
3656 // Set hashLastUnknownBlock for this peer, so that if we
3657 // eventually get the headers - even from a different peer -
3658 // we can use this peer to download.
3660 UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
3661
3662 // The peer may just be broken, so periodically assign DoS points if this
3663 // condition persists.
3664 if (peer.m_num_unconnecting_headers_msgs %
3666 0) {
3667 Misbehaving(peer, 20,
3668 strprintf("%d non-connecting headers",
3669 peer.m_num_unconnecting_headers_msgs));
3670 }
3671}
3672
3673bool PeerManagerImpl::CheckHeadersAreContinuous(
3674 const std::vector<CBlockHeader> &headers) const {
3676 for (const CBlockHeader &header : headers) {
3677 if (!hashLastBlock.IsNull() && header.hashPrevBlock != hashLastBlock) {
3678 return false;
3679 }
3680 hashLastBlock = header.GetHash();
3681 }
3682 return true;
3683}
3684
3685bool PeerManagerImpl::IsContinuationOfLowWorkHeadersSync(
3686 Peer &peer, CNode &pfrom, std::vector<CBlockHeader> &headers) {
3687 if (peer.m_headers_sync) {
3688 auto result = peer.m_headers_sync->ProcessNextHeaders(
3690 if (result.request_more) {
3691 auto locator = peer.m_headers_sync->NextHeadersRequestLocator();
3692 // If we were instructed to ask for a locator, it should not be
3693 // empty.
3694 Assume(!locator.vHave.empty());
3695 if (!locator.vHave.empty()) {
3696 // It should be impossible for the getheaders request to fail,
3697 // because we should have cleared the last getheaders timestamp
3698 // when processing the headers that triggered this call. But
3699 // it may be possible to bypass this via compactblock
3700 // processing, so check the result before logging just to be
3701 // safe.
3702 bool sent_getheaders =
3704 if (sent_getheaders) {
3706 "more getheaders (from %s) to peer=%d\n",
3707 locator.vHave.front().ToString(), pfrom.GetId());
3708 } else {
3710 "error sending next getheaders (from %s) to "
3711 "continue sync with peer=%d\n",
3712 locator.vHave.front().ToString(), pfrom.GetId());
3713 }
3714 }
3715 }
3716
3717 if (peer.m_headers_sync->GetState() == HeadersSyncState::State::FINAL) {
3718 peer.m_headers_sync.reset(nullptr);
3719
3720 // Delete this peer's entry in m_headers_presync_stats.
3721 // If this is m_headers_presync_bestpeer, it will be replaced later
3722 // by the next peer that triggers the else{} branch below.
3723 LOCK(m_headers_presync_mutex);
3724 m_headers_presync_stats.erase(pfrom.GetId());
3725 } else {
3726 // Build statistics for this peer's sync.
3727 HeadersPresyncStats stats;
3728 stats.first = peer.m_headers_sync->GetPresyncWork();
3729 if (peer.m_headers_sync->GetState() ==
3731 stats.second = {peer.m_headers_sync->GetPresyncHeight(),
3732 peer.m_headers_sync->GetPresyncTime()};
3733 }
3734
3735 // Update statistics in stats.
3736 LOCK(m_headers_presync_mutex);
3737 m_headers_presync_stats[pfrom.GetId()] = stats;
3738 auto best_it =
3740 bool best_updated = false;
3741 if (best_it == m_headers_presync_stats.end()) {
3742 // If the cached best peer is outdated, iterate over all
3743 // remaining ones (including newly updated one) to find the best
3744 // one.
3745 NodeId peer_best{-1};
3746 const HeadersPresyncStats *stat_best{nullptr};
3747 for (const auto &[_peer, _stat] : m_headers_presync_stats) {
3748 if (!stat_best || _stat > *stat_best) {
3749 peer_best = _peer;
3750 stat_best = &_stat;
3751 }
3752 }
3754 best_updated = (peer_best == pfrom.GetId());
3755 } else if (best_it->first == pfrom.GetId() ||
3756 stats > best_it->second) {
3757 // pfrom was and remains the best peer, or pfrom just became
3758 // best.
3760 best_updated = true;
3761 }
3762 if (best_updated && stats.second.has_value()) {
3763 // If the best peer updated, and it is in its first phase,
3764 // signal.
3765 m_headers_presync_should_signal = true;
3766 }
3767 }
3768
3769 if (result.success) {
3770 // We only overwrite the headers passed in if processing was
3771 // successful.
3772 headers.swap(result.pow_validated_headers);
3773 }
3774
3775 return result.success;
3776 }
3777 // Either we didn't have a sync in progress, or something went wrong
3778 // processing these headers, or we are returning headers to the caller to
3779 // process.
3780 return false;
3781}
3782
3783bool PeerManagerImpl::TryLowWorkHeadersSync(
3784 Peer &peer, CNode &pfrom, const CBlockIndex *chain_start_header,
3785 std::vector<CBlockHeader> &headers) {
3786 // Calculate the total work on this chain.
3789
3790 // Our dynamic anti-DoS threshold (minimum work required on a headers chain
3791 // before we'll store it)
3792 arith_uint256 minimum_chain_work = GetAntiDoSWorkThreshold();
3793
3794 // Avoid DoS via low-difficulty-headers by only processing if the headers
3795 // are part of a chain with sufficient work.
3796 if (total_work < minimum_chain_work) {
3797 // Only try to sync with this peer if their headers message was full;
3798 // otherwise they don't have more headers after this so no point in
3799 // trying to sync their too-little-work chain.
3800 if (headers.size() == MAX_HEADERS_RESULTS) {
3801 // Note: we could advance to the last header in this set that is
3802 // known to us, rather than starting at the first header (which we
3803 // may already have); however this is unlikely to matter much since
3804 // ProcessHeadersMessage() already handles the case where all
3805 // headers in a received message are already known and are
3806 // ancestors of m_best_header or chainActive.Tip(), by skipping
3807 // this logic in that case. So even if the first header in this set
3808 // of headers is known, some header in this set must be new, so
3809 // advancing to the first unknown header would be a small effect.
3810 LOCK(peer.m_headers_sync_mutex);
3811 peer.m_headers_sync.reset(
3812 new HeadersSyncState(peer.m_id, m_chainparams.GetConsensus(),
3813 chain_start_header, minimum_chain_work));
3814
3815 // Now a HeadersSyncState object for tracking this synchronization
3816 // is created, process the headers using it as normal. Failures are
3817 // handled inside of IsContinuationOfLowWorkHeadersSync.
3819 } else {
3821 "Ignoring low-work chain (height=%u) from peer=%d\n",
3822 chain_start_header->nHeight + headers.size(),
3823 pfrom.GetId());
3824 }
3825 // The peer has not yet given us a chain that meets our work threshold,
3826 // so we want to prevent further processing of the headers in any case.
3827 headers = {};
3828 return true;
3829 }
3830
3831 return false;
3832}
3833
3834bool PeerManagerImpl::IsAncestorOfBestHeaderOrTip(const CBlockIndex *header) {
3835 return header != nullptr &&
3836 ((m_chainman.m_best_header != nullptr &&
3837 header ==
3838 m_chainman.m_best_header->GetAncestor(header->nHeight)) ||
3839 m_chainman.ActiveChain().Contains(header));
3840}
3841
3842bool PeerManagerImpl::MaybeSendGetHeaders(CNode &pfrom,
3843 const CBlockLocator &locator,
3844 Peer &peer) {
3845 const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
3846
3847 const auto current_time = NodeClock::now();
3848
3849 // Only allow a new getheaders message to go out if we don't have a recent
3850 // one already in-flight
3851 if (current_time - peer.m_last_getheaders_timestamp >
3853 m_connman.PushMessage(
3855 peer.m_last_getheaders_timestamp = current_time;
3856 return true;
3857 }
3858 return false;
3859}
3860
3867void PeerManagerImpl::HeadersDirectFetchBlocks(const Config &config,
3868 CNode &pfrom,
3869 const CBlockIndex &last_header) {
3870 const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
3871
3872 LOCK(cs_main);
3873 CNodeState *nodestate = State(pfrom.GetId());
3874
3876 m_chainman.ActiveChain().Tip()->nChainWork <= last_header.nChainWork) {
3877 std::vector<const CBlockIndex *> vToFetch;
3879 // Calculate all the blocks we'd need to switch to last_header, up to
3880 // a limit.
3881 while (pindexWalk && !m_chainman.ActiveChain().Contains(pindexWalk) &&
3883 if (!pindexWalk->nStatus.hasData() &&
3884 !IsBlockRequested(pindexWalk->GetBlockHash())) {
3885 // We don't have this block, and it's not yet in flight.
3886 vToFetch.push_back(pindexWalk);
3887 }
3889 }
3890 // If pindexWalk still isn't on our main chain, we're looking at a
3891 // very large reorg at a time we think we're close to caught up to
3892 // the main chain -- this shouldn't really happen. Bail out on the
3893 // direct fetch and rely on parallel download instead.
3894 if (!m_chainman.ActiveChain().Contains(pindexWalk)) {
3895 LogPrint(BCLog::NET, "Large reorg, won't direct fetch to %s (%d)\n",
3896 last_header.GetBlockHash().ToString(),
3897 last_header.nHeight);
3898 } else {
3899 std::vector<CInv> vGetData;
3900 // Download as much as possible, from earliest to latest.
3901 for (const CBlockIndex *pindex : reverse_iterate(vToFetch)) {
3902 if (nodestate->vBlocksInFlight.size() >=
3904 // Can't download any more from this peer
3905 break;
3906 }
3907 vGetData.push_back(CInv(MSG_BLOCK, pindex->GetBlockHash()));
3908 BlockRequested(config, pfrom.GetId(), *pindex);
3909 LogPrint(BCLog::NET, "Requesting block %s from peer=%d\n",
3910 pindex->GetBlockHash().ToString(), pfrom.GetId());
3911 }
3912 if (vGetData.size() > 1) {
3914 "Downloading blocks toward %s (%d) via headers "
3915 "direct fetch\n",
3916 last_header.GetBlockHash().ToString(),
3917 last_header.nHeight);
3918 }
3919 if (vGetData.size() > 0) {
3920 if (!m_opts.ignore_incoming_txs &&
3921 nodestate->m_provides_cmpctblocks && vGetData.size() == 1 &&
3922 mapBlocksInFlight.size() == 1 &&
3923 last_header.pprev->IsValid(BlockValidity::CHAIN)) {
3924 // In any case, we want to download using a compact
3925 // block, not a regular one.
3926 vGetData[0] = CInv(MSG_CMPCT_BLOCK, vGetData[0].hash);
3927 }
3928 m_connman.PushMessage(
3930 }
3931 }
3932 }
3933}
3934
3940void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(
3941 CNode &pfrom, Peer &peer, const CBlockIndex &last_header,
3943 if (peer.m_num_unconnecting_headers_msgs > 0) {
3944 LogPrint(
3945 BCLog::NET,
3946 "peer=%d: resetting m_num_unconnecting_headers_msgs (%d -> 0)\n",
3947 pfrom.GetId(), peer.m_num_unconnecting_headers_msgs);
3948 }
3949 peer.m_num_unconnecting_headers_msgs = 0;
3950
3951 LOCK(cs_main);
3952
3953 CNodeState *nodestate = State(pfrom.GetId());
3954
3955 UpdateBlockAvailability(pfrom.GetId(), last_header.GetBlockHash());
3956
3957 // From here, pindexBestKnownBlock should be guaranteed to be non-null,
3958 // because it is set in UpdateBlockAvailability. Some nullptr checks are
3959 // still present, however, as belt-and-suspenders.
3960
3961 if (received_new_header &&
3962 last_header.nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
3963 nodestate->m_last_block_announcement = GetTime();
3964 }
3965
3966 // If we're in IBD, we want outbound peers that will serve us a useful
3967 // chain. Disconnect peers that are on chains with insufficient work.
3968 if (m_chainman.ActiveChainstate().IsInitialBlockDownload() &&
3970 // When nCount < MAX_HEADERS_RESULTS, we know we have no more
3971 // headers to fetch from this peer.
3972 if (nodestate->pindexBestKnownBlock &&
3973 nodestate->pindexBestKnownBlock->nChainWork <
3974 m_chainman.MinimumChainWork()) {
3975 // This peer has too little work on their headers chain to help
3976 // us sync -- disconnect if it is an outbound disconnection
3977 // candidate.
3978 // Note: We compare their tip to the minimum chain work (rather than
3979 // m_chainman.ActiveChain().Tip()) because we won't start block
3980 // download until we have a headers chain that has at least
3981 // the minimum chain work, even if a peer has a chain past our tip,
3982 // as an anti-DoS measure.
3983 if (pfrom.IsOutboundOrBlockRelayConn()) {
3984 LogPrintf("Disconnecting outbound peer %d -- headers "
3985 "chain has insufficient work\n",
3986 pfrom.GetId());
3987 pfrom.fDisconnect = true;
3988 }
3989 }
3990 }
3991
3992 // If this is an outbound full-relay peer, check to see if we should
3993 // protect it from the bad/lagging chain logic.
3994 // Note that outbound block-relay peers are excluded from this
3995 // protection, and thus always subject to eviction under the bad/lagging
3996 // chain logic.
3997 // See ChainSyncTimeoutState.
3998 if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() &&
3999 nodestate->pindexBestKnownBlock != nullptr) {
4002 nodestate->pindexBestKnownBlock->nChainWork >=
4003 m_chainman.ActiveChain().Tip()->nChainWork &&
4004 !nodestate->m_chain_sync.m_protect) {
4005 LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n",
4006 pfrom.GetId());
4007 nodestate->m_chain_sync.m_protect = true;
4009 }
4010 }
4011}
4012
4013void PeerManagerImpl::ProcessHeadersMessage(const Config &config, CNode &pfrom,
4014 Peer &peer,
4015 std::vector<CBlockHeader> &&headers,
4016 bool via_compact_block) {
4017 size_t nCount = headers.size();
4018
4019 if (nCount == 0) {
4020 // Nothing interesting. Stop asking this peers for more headers.
4021 // If we were in the middle of headers sync, receiving an empty headers
4022 // message suggests that the peer suddenly has nothing to give us
4023 // (perhaps it reorged to our chain). Clear download state for this
4024 // peer.
4025 LOCK(peer.m_headers_sync_mutex);
4026 if (peer.m_headers_sync) {
4027 peer.m_headers_sync.reset(nullptr);
4028 LOCK(m_headers_presync_mutex);
4029 m_headers_presync_stats.erase(pfrom.GetId());
4030 }
4031 return;
4032 }
4033
4034 // Before we do any processing, make sure these pass basic sanity checks.
4035 // We'll rely on headers having valid proof-of-work further down, as an
4036 // anti-DoS criteria (note: this check is required before passing any
4037 // headers into HeadersSyncState).
4038 if (!CheckHeadersPoW(headers, m_chainparams.GetConsensus(), peer)) {
4039 // Misbehaving() calls are handled within CheckHeadersPoW(), so we can
4040 // just return. (Note that even if a header is announced via compact
4041 // block, the header itself should be valid, so this type of error can
4042 // always be punished.)
4043 return;
4044 }
4045
4046 const CBlockIndex *pindexLast = nullptr;
4047
4048 // We'll set already_validated_work to true if these headers are
4049 // successfully processed as part of a low-work headers sync in progress
4050 // (either in PRESYNC or REDOWNLOAD phase).
4051 // If true, this will mean that any headers returned to us (ie during
4052 // REDOWNLOAD) can be validated without further anti-DoS checks.
4053 bool already_validated_work = false;
4054
4055 // If we're in the middle of headers sync, let it do its magic.
4056 bool have_headers_sync = false;
4057 {
4058 LOCK(peer.m_headers_sync_mutex);
4059
4062
4063 // The headers we passed in may have been:
4064 // - untouched, perhaps if no headers-sync was in progress, or some
4065 // failure occurred
4066 // - erased, such as if the headers were successfully processed and no
4067 // additional headers processing needs to take place (such as if we
4068 // are still in PRESYNC)
4069 // - replaced with headers that are now ready for validation, such as
4070 // during the REDOWNLOAD phase of a low-work headers sync.
4071 // So just check whether we still have headers that we need to process,
4072 // or not.
4073 if (headers.empty()) {
4074 return;
4075 }
4076
4077 have_headers_sync = !!peer.m_headers_sync;
4078 }
4079
4080 // Do these headers connect to something in our block index?
4083 headers[0].hashPrevBlock))};
4085
4088 // If this looks like it could be a BIP 130 block announcement, use
4089 // special logic for handling headers that don't connect, as this
4090 // could be benign.
4092 } else {
4093 Misbehaving(peer, 10, "invalid header received");
4094 }
4095 return;
4096 }
4097
4098 // If the headers we received are already in memory and an ancestor of
4099 // m_best_header or our tip, skip anti-DoS checks. These headers will not
4100 // use any more memory (and we are not leaking information that could be
4101 // used to fingerprint us).
4102 const CBlockIndex *last_received_header{nullptr};
4103 {
4104 LOCK(cs_main);
4106 m_chainman.m_blockman.LookupBlockIndex(headers.back().GetHash());
4109 }
4110 }
4111
4112 // If our peer has NetPermissionFlags::NoBan privileges, then bypass our
4113 // anti-DoS logic (this saves bandwidth when we connect to a trusted peer
4114 // on startup).
4115 if (pfrom.HasPermission(NetPermissionFlags::NoBan)) {
4117 }
4118
4119 // At this point, the headers connect to something in our block index.
4120 // Do anti-DoS checks to determine if we should process or store for later
4121 // processing.
4124 // If we successfully started a low-work headers sync, then there
4125 // should be no headers to process any further.
4126 Assume(headers.empty());
4127 return;
4128 }
4129
4130 // At this point, we have a set of headers with sufficient work on them
4131 // which can be processed.
4132
4133 // If we don't have the last header, then this peer will have given us
4134 // something new (if these headers are valid).
4136
4137 // Now process all the headers.
4139 if (!m_chainman.ProcessNewBlockHeaders(headers, /*min_pow_checked=*/true,
4140 state, &pindexLast)) {
4141 if (state.IsInvalid()) {
4143 "invalid header received");
4144 return;
4145 }
4146 }
4148
4149 // Consider fetching more headers if we are not using our headers-sync
4150 // mechanism.
4152 // Headers message had its maximum size; the peer may have more headers.
4154 LogPrint(
4155 BCLog::NET,
4156 "more getheaders (%d) to end to peer=%d (startheight:%d)\n",
4157 pindexLast->nHeight, pfrom.GetId(), peer.m_starting_height);
4158 }
4159 }
4160
4164
4165 // Consider immediately downloading blocks.
4167}
4168
4169void PeerManagerImpl::ProcessInvalidTx(NodeId nodeid,
4170 const CTransactionRef &ptx,
4171 const TxValidationState &state,
4173 AssertLockNotHeld(m_peer_mutex);
4174 AssertLockHeld(g_msgproc_mutex);
4176
4177 const TxId &txid = ptx->GetId();
4178
4179 LogPrint(BCLog::MEMPOOLREJ, "%s from peer=%d was not accepted: %s\n",
4180 txid.ToString(), nodeid, state.ToString());
4181
4183 return;
4184 }
4185
4186 if (m_avalanche && m_avalanche->m_preConsensus &&
4188 return;
4189 }
4190
4192 // If the result is TX_PACKAGE_RECONSIDERABLE, add it to
4193 // m_recent_rejects_package_reconsiderable because we should not
4194 // download or submit this transaction by itself again, but may submit
4195 // it as part of a package later.
4197 } else {
4198 m_recent_rejects.insert(txid);
4199 }
4200 m_txrequest.ForgetInvId(txid);
4201
4204 }
4205
4206 MaybePunishNodeForTx(nodeid, state);
4207
4208 // If the tx failed in ProcessOrphanTx, it should be removed from the
4209 // orphanage unless the tx was still missing inputs. If the tx was not in
4210 // the orphanage, EraseTx does nothing and returns 0.
4211 if (m_mempool.withOrphanage([&txid](TxOrphanage &orphanage) {
4212 return orphanage.EraseTx(txid);
4213 }) > 0) {
4214 LogPrint(BCLog::TXPACKAGES, " removed orphan tx %s\n",
4215 txid.ToString());
4216 }
4217}
4218
4219void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef &tx) {
4220 AssertLockNotHeld(m_peer_mutex);
4221 AssertLockHeld(g_msgproc_mutex);
4223
4224 // As this version of the transaction was acceptable, we can forget about
4225 // any requests for it. No-op if the tx is not in txrequest.
4226 m_txrequest.ForgetInvId(tx->GetId());
4227
4228 m_mempool.withOrphanage([&tx](TxOrphanage &orphanage) {
4229 orphanage.AddChildrenToWorkSet(*tx);
4230 // If it came from the orphanage, remove it. No-op if the tx is not in
4231 // txorphanage.
4232 orphanage.EraseTx(tx->GetId());
4233 });
4234
4235 LogPrint(
4237 "AcceptToMemoryPool: peer=%d: accepted %s (poolsz %u txn, %u kB)\n",
4238 nodeid, tx->GetId().ToString(), m_mempool.size(),
4239 m_mempool.DynamicMemoryUsage() / 1000);
4240
4241 RelayTransaction(tx->GetId());
4242}
4243
4244void PeerManagerImpl::ProcessPackageResult(
4245 const PackageToValidate &package_to_validate,
4247 AssertLockNotHeld(m_peer_mutex);
4248 AssertLockHeld(g_msgproc_mutex);
4250
4251 const auto &package = package_to_validate.m_txns;
4252 const auto &senders = package_to_validate.m_senders;
4253
4254 if (package_result.m_state.IsInvalid()) {
4256 }
4257 // We currently only expect to process 1-parent-1-child packages. Remove if
4258 // this changes.
4259 if (!Assume(package.size() == 2)) {
4260 return;
4261 }
4262
4263 // Iterate backwards to erase in-package descendants from the orphanage
4264 // before they become relevant in AddChildrenToWorkSet.
4265 auto package_iter = package.rbegin();
4266 auto senders_iter = senders.rbegin();
4267 while (package_iter != package.rend()) {
4268 const auto &tx = *package_iter;
4269 const NodeId nodeid = *senders_iter;
4270 const auto it_result{package_result.m_tx_results.find(tx->GetId())};
4271
4272 // It is not guaranteed that a result exists for every transaction.
4273 if (it_result != package_result.m_tx_results.end()) {
4274 const auto &tx_result = it_result->second;
4275 switch (tx_result.m_result_type) {
4277 ProcessValidTx(nodeid, tx);
4278 break;
4279 }
4281 // Don't add to vExtraTxnForCompact, as these transactions
4282 // should have already been added there when added to the
4283 // orphanage or rejected for TX_PACKAGE_RECONSIDERABLE.
4284 // This should be updated if package submission is ever used
4285 // for transactions that haven't already been validated
4286 // before.
4287 ProcessInvalidTx(nodeid, tx, tx_result.m_state,
4288 /*maybe_add_extra_compact_tx=*/false);
4289 break;
4290 }
4292 // AlreadyHaveTx() should be catching transactions that are
4293 // already in mempool.
4294 Assume(false);
4295 break;
4296 }
4297 }
4298 }
4299 package_iter++;
4300 senders_iter++;
4301 }
4302}
4303
4304std::optional<PeerManagerImpl::PackageToValidate>
4305PeerManagerImpl::Find1P1CPackage(const CTransactionRef &ptx, NodeId nodeid) {
4306 AssertLockNotHeld(m_peer_mutex);
4307 AssertLockHeld(g_msgproc_mutex);
4309
4310 const auto &parent_txid{ptx->GetId()};
4311
4313
4314 // Prefer children from this peer. This helps prevent censorship attempts in
4315 // which an attacker sends lots of fake children for the parent, and we
4316 // (unluckily) keep selecting the fake children instead of the real one
4317 // provided by the honest peer.
4318 const auto cpfp_candidates_same_peer{
4319 m_mempool.withOrphanage([&ptx, nodeid](const TxOrphanage &orphanage) {
4320 return orphanage.GetChildrenFromSamePeer(ptx, nodeid);
4321 })};
4322
4323 // These children should be sorted from newest to oldest.
4324 for (const auto &child : cpfp_candidates_same_peer) {
4328 return PeerManagerImpl::PackageToValidate{ptx, child, nodeid,
4329 nodeid};
4330 }
4331 }
4332
4333 // If no suitable candidate from the same peer is found, also try children
4334 // that were provided by a different peer. This is useful because sometimes
4335 // multiple peers announce both transactions to us, and we happen to
4336 // download them from different peers (we wouldn't have known that these 2
4337 // transactions are related). We still want to find 1p1c packages then.
4338 //
4339 // If we start tracking all announcers of orphans, we can restrict this
4340 // logic to parent + child pairs in which both were provided by the same
4341 // peer, i.e. delete this step.
4343 m_mempool.withOrphanage([&ptx, nodeid](const TxOrphanage &orphanage) {
4344 return orphanage.GetChildrenFromDifferentPeer(ptx, nodeid);
4345 })};
4346
4347 // Find the first 1p1c that hasn't already been rejected. We randomize the
4348 // order to not create a bias that attackers can use to delay package
4349 // acceptance.
4350 //
4351 // Create a random permutation of the indices.
4352 std::vector<size_t> tx_indices(cpfp_candidates_different_peer.size());
4353 std::iota(tx_indices.begin(), tx_indices.end(), 0);
4354 Shuffle(tx_indices.begin(), tx_indices.end(), m_rng);
4355
4356 for (const auto index : tx_indices) {
4357 // If we already tried a package and failed for any reason, the combined
4358 // hash was cached in m_recent_rejects_package_reconsiderable.
4359 const auto [child_tx, child_sender] =
4364 return PeerManagerImpl::PackageToValidate{ptx, child_tx, nodeid,
4365 child_sender};
4366 }
4367 }
4368 return std::nullopt;
4369}
4370
4371bool PeerManagerImpl::ProcessOrphanTx(const Config &config, Peer &peer) {
4372 AssertLockHeld(g_msgproc_mutex);
4373 LOCK(cs_main);
4374
4375 while (CTransactionRef porphanTx =
4376 m_mempool.withOrphanage([&peer](TxOrphanage &orphanage) {
4377 return orphanage.GetTxToReconsider(peer.m_id);
4378 })) {
4379 const MempoolAcceptResult result =
4380 m_chainman.ProcessTransaction(porphanTx);
4381 const TxValidationState &state = result.m_state;
4382 const TxId &orphanTxId = porphanTx->GetId();
4383
4385 LogPrint(BCLog::TXPACKAGES, " accepted orphan tx %s\n",
4386 orphanTxId.ToString());
4387 ProcessValidTx(peer.m_id, porphanTx);
4388 return true;
4389 }
4390
4393 " invalid orphan tx %s from peer=%d. %s\n",
4394 orphanTxId.ToString(), peer.m_id, state.ToString());
4395
4396 if (Assume(state.IsInvalid() &&
4398 state.GetResult() !=
4400 ProcessInvalidTx(peer.m_id, porphanTx, state,
4401 /*maybe_add_extra_compact_tx=*/false);
4402 }
4403
4404 return true;
4405 }
4406 }
4407
4408 return false;
4409}
4410
4411bool PeerManagerImpl::PrepareBlockFilterRequest(
4414 const CBlockIndex *&stop_index, BlockFilterIndex *&filter_index) {
4415 const bool supported_filter_type =
4417 (peer.m_our_services & NODE_COMPACT_FILTERS));
4418 if (!supported_filter_type) {
4420 "peer %d requested unsupported block filter type: %d\n",
4421 node.GetId(), static_cast<uint8_t>(filter_type));
4422 node.fDisconnect = true;
4423 return false;
4424 }
4425
4426 {
4427 LOCK(cs_main);
4429
4430 // Check that the stop block exists and the peer would be allowed to
4431 // fetch it.
4433 LogPrint(BCLog::NET, "peer %d requested invalid block hash: %s\n",
4434 node.GetId(), stop_hash.ToString());
4435 node.fDisconnect = true;
4436 return false;
4437 }
4438 }
4439
4440 uint32_t stop_height = stop_index->nHeight;
4441 if (start_height > stop_height) {
4442 LogPrint(
4443 BCLog::NET,
4444 "peer %d sent invalid getcfilters/getcfheaders with " /* Continued
4445 */
4446 "start height %d and stop height %d\n",
4447 node.GetId(), start_height, stop_height);
4448 node.fDisconnect = true;
4449 return false;
4450 }
4453 "peer %d requested too many cfilters/cfheaders: %d / %d\n",
4455 node.fDisconnect = true;
4456 return false;
4457 }
4458
4459 filter_index = GetBlockFilterIndex(filter_type);
4460 if (!filter_index) {
4461 LogPrint(BCLog::NET, "Filter index for supported type %s not found\n",
4463 return false;
4464 }
4465
4466 return true;
4467}
4468
4469void PeerManagerImpl::ProcessGetCFilters(CNode &node, Peer &peer,
4470 CDataStream &vRecv) {
4474
4475 vRecv >> filter_type_ser >> start_height >> stop_hash;
4476
4478 static_cast<BlockFilterType>(filter_type_ser);
4479
4480 const CBlockIndex *stop_index;
4481 BlockFilterIndex *filter_index;
4484 filter_index)) {
4485 return;
4486 }
4487
4488 std::vector<BlockFilter> filters;
4489 if (!filter_index->LookupFilterRange(start_height, stop_index, filters)) {
4491 "Failed to find block filter in index: filter_type=%s, "
4492 "start_height=%d, stop_hash=%s\n",
4494 stop_hash.ToString());
4495 return;
4496 }
4497
4498 for (const auto &filter : filters) {
4499 CSerializedNetMsg msg = CNetMsgMaker(node.GetCommonVersion())
4500 .Make(NetMsgType::CFILTER, filter);
4501 m_connman.PushMessage(&node, std::move(msg));
4502 }
4503}
4504
4505void PeerManagerImpl::ProcessGetCFHeaders(CNode &node, Peer &peer,
4506 CDataStream &vRecv) {
4510
4511 vRecv >> filter_type_ser >> start_height >> stop_hash;
4512
4514 static_cast<BlockFilterType>(filter_type_ser);
4515
4516 const CBlockIndex *stop_index;
4517 BlockFilterIndex *filter_index;
4520 filter_index)) {
4521 return;
4522 }
4523
4525 if (start_height > 0) {
4526 const CBlockIndex *const prev_block =
4527 stop_index->GetAncestor(static_cast<int>(start_height - 1));
4528 if (!filter_index->LookupFilterHeader(prev_block, prev_header)) {
4530 "Failed to find block filter header in index: "
4531 "filter_type=%s, block_hash=%s\n",
4533 prev_block->GetBlockHash().ToString());
4534 return;
4535 }
4536 }
4537
4538 std::vector<uint256> filter_hashes;
4539 if (!filter_index->LookupFilterHashRange(start_height, stop_index,
4540 filter_hashes)) {
4542 "Failed to find block filter hashes in index: filter_type=%s, "
4543 "start_height=%d, stop_hash=%s\n",
4545 stop_hash.ToString());
4546 return;
4547 }
4548
4549 CSerializedNetMsg msg =
4550 CNetMsgMaker(node.GetCommonVersion())
4552 stop_index->GetBlockHash(), prev_header, filter_hashes);
4553 m_connman.PushMessage(&node, std::move(msg));
4554}
4555
4556void PeerManagerImpl::ProcessGetCFCheckPt(CNode &node, Peer &peer,
4557 CDataStream &vRecv) {
4560
4561 vRecv >> filter_type_ser >> stop_hash;
4562
4564 static_cast<BlockFilterType>(filter_type_ser);
4565
4566 const CBlockIndex *stop_index;
4567 BlockFilterIndex *filter_index;
4569 node, peer, filter_type, /*start_height=*/0, stop_hash,
4570 /*max_height_diff=*/std::numeric_limits<uint32_t>::max(),
4571 stop_index, filter_index)) {
4572 return;
4573 }
4574
4575 std::vector<uint256> headers(stop_index->nHeight / CFCHECKPT_INTERVAL);
4576
4577 // Populate headers.
4579 for (int i = headers.size() - 1; i >= 0; i--) {
4580 int height = (i + 1) * CFCHECKPT_INTERVAL;
4582
4583 if (!filter_index->LookupFilterHeader(block_index, headers[i])) {
4585 "Failed to find block filter header in index: "
4586 "filter_type=%s, block_hash=%s\n",
4588 block_index->GetBlockHash().ToString());
4589 return;
4590 }
4591 }
4592
4593 CSerializedNetMsg msg = CNetMsgMaker(node.GetCommonVersion())
4595 stop_index->GetBlockHash(), headers);
4596 m_connman.PushMessage(&node, std::move(msg));
4597}
4598
4609
4611PeerManagerImpl::GetAvalancheVoteForBlock(const BlockHash &hash) const {
4613
4614 const CBlockIndex *pindex = m_chainman.m_blockman.LookupBlockIndex(hash);
4615
4616 // Unknown block.
4617 if (!pindex) {
4618 return -1;
4619 }
4620
4621 // Invalid block
4622 if (pindex->nStatus.isInvalid()) {
4623 return 1;
4624 }
4625
4626 // Parked block
4627 if (pindex->nStatus.isOnParkedChain()) {
4628 return 2;
4629 }
4630
4631 const CBlockIndex *pindexTip = m_chainman.ActiveChain().Tip();
4633
4634 // Active block.
4635 if (pindex == pindexFork) {
4636 return 0;
4637 }
4638
4639 // Fork block.
4640 if (pindexFork != pindexTip) {
4641 return 3;
4642 }
4643
4644 // Missing block data.
4645 if (!pindex->nStatus.hasData()) {
4646 return -2;
4647 }
4648
4649 // This block is built on top of the tip, we have the data, it
4650 // is pending connection or rejection.
4651 return -3;
4652};
4653
4654uint32_t PeerManagerImpl::GetAvalancheVoteForTx(const TxId &id) const {
4655 // Accepted in mempool, or in a recent block
4656 if (m_mempool.exists(id) ||
4657 WITH_LOCK(m_recent_confirmed_transactions_mutex,
4658 return m_recent_confirmed_transactions.contains(id))) {
4659 return 0;
4660 }
4661
4662 // Conflicting tx
4663 if (m_mempool.withConflicting([&id](const TxConflicting &conflicting) {
4664 return conflicting.HaveTx(id);
4665 })) {
4666 return 2;
4667 }
4668
4669 // Invalid tx
4670 if (m_recent_rejects.contains(id)) {
4671 return 1;
4672 }
4673
4674 // Orphan tx
4675 if (m_mempool.withOrphanage([&id](const TxOrphanage &orphanage) {
4676 return orphanage.HaveTx(id);
4677 })) {
4678 return -2;
4679 }
4680
4681 // Unknown tx
4682 return -1;
4683};
4684
4692 const avalanche::ProofId &id) {
4693 return avalanche.withPeerManager([&id](avalanche::PeerManager &pm) {
4694 // Rejected proof
4695 if (pm.isInvalid(id)) {
4696 return 1;
4697 }
4698
4699 // The proof is actively bound to a peer
4700 if (pm.isBoundToPeer(id)) {
4701 return 0;
4702 }
4703
4704 // Unknown proof
4705 if (!pm.exists(id)) {
4706 return -1;
4707 }
4708
4709 // Immature proof
4710 if (pm.isImmature(id)) {
4711 return 2;
4712 }
4713
4714 // Not immature, but in conflict with an actively bound proof
4715 if (pm.isInConflictingPool(id)) {
4716 return 3;
4717 }
4718
4719 // The proof is known, not rejected, not immature, not a conflict, but
4720 // for some reason unbound. This should not happen if the above pools
4721 // are managed correctly, but added for robustness.
4722 return -2;
4723 });
4724};
4725
4726void PeerManagerImpl::ProcessBlock(const Config &config, CNode &node,
4727 const std::shared_ptr<const CBlock> &block,
4728 bool force_processing,
4729 bool min_pow_checked) {
4730 bool new_block{false};
4732 &new_block, m_avalanche);
4733 if (new_block) {
4734 node.m_last_block_time = GetTime<std::chrono::seconds>();
4735 // In case this block came from a different peer than we requested
4736 // from, we can erase the block request now anyway (as we just stored
4737 // this block to disk).
4738 LOCK(cs_main);
4739 RemoveBlockRequest(block->GetHash(), std::nullopt);
4740 } else {
4741 LOCK(cs_main);
4742 mapBlockSource.erase(block->GetHash());
4743 }
4744}
4745
4746void PeerManagerImpl::ProcessMessage(
4747 const Config &config, CNode &pfrom, const std::string &msg_type,
4748 CDataStream &vRecv, const std::chrono::microseconds time_received,
4749 const std::atomic<bool> &interruptMsgProc) {
4750 AssertLockHeld(g_msgproc_mutex);
4751
4752 LogPrint(BCLog::NETDEBUG, "received: %s (%u bytes) peer=%d\n",
4753 SanitizeString(msg_type), vRecv.size(), pfrom.GetId());
4754
4755 PeerRef peer = GetPeerRef(pfrom.GetId());
4756 if (peer == nullptr) {
4757 return;
4758 }
4759
4760 if (!m_avalanche && IsAvalancheMessageType(msg_type)) {
4762 "Avalanche is not initialized, ignoring %s message\n",
4763 msg_type);
4764 return;
4765 }
4766
4768 // Each connection can only send one version message
4769 if (pfrom.nVersion != 0) {
4770 Misbehaving(*peer, 1, "redundant version message");
4771 return;
4772 }
4773
4774 int64_t nTime;
4776 uint64_t nNonce = 1;
4777 ServiceFlags nServices;
4778 int nVersion;
4779 std::string cleanSubVer;
4780 int starting_height = -1;
4781 bool fRelay = true;
4783
4784 vRecv >> nVersion >> Using<CustomUintFormatter<8>>(nServices) >> nTime;
4785 if (nTime < 0) {
4786 nTime = 0;
4787 }
4788 // Ignore the addrMe service bits sent by the peer
4789 vRecv.ignore(8);
4790 vRecv >> addrMe;
4791 if (!pfrom.IsInboundConn()) {
4792 m_addrman.SetServices(pfrom.addr, nServices);
4793 }
4794 if (pfrom.ExpectServicesFromConn() &&
4795 !HasAllDesirableServiceFlags(nServices)) {
4797 "peer=%d does not offer the expected services "
4798 "(%08x offered, %08x expected); disconnecting\n",
4799 pfrom.GetId(), nServices,
4800 GetDesirableServiceFlags(nServices));
4801 pfrom.fDisconnect = true;
4802 return;
4803 }
4804
4805 if (pfrom.IsAvalancheOutboundConnection() &&
4806 !(nServices & NODE_AVALANCHE)) {
4807 LogPrint(
4809 "peer=%d does not offer the avalanche service; disconnecting\n",
4810 pfrom.GetId());
4811 pfrom.fDisconnect = true;
4812 return;
4813 }
4814
4815 if (nVersion < MIN_PEER_PROTO_VERSION) {
4816 // disconnect from peers older than this proto version
4818 "peer=%d using obsolete version %i; disconnecting\n",
4819 pfrom.GetId(), nVersion);
4820 pfrom.fDisconnect = true;
4821 return;
4822 }
4823
4824 if (!vRecv.empty()) {
4825 // The version message includes information about the sending node
4826 // which we don't use:
4827 // - 8 bytes (service bits)
4828 // - 16 bytes (ipv6 address)
4829 // - 2 bytes (port)
4830 vRecv.ignore(26);
4831 vRecv >> nNonce;
4832 }
4833 if (!vRecv.empty()) {
4834 std::string strSubVer;
4835 vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
4836 cleanSubVer = SanitizeString(strSubVer);
4837 }
4838 if (!vRecv.empty()) {
4839 vRecv >> starting_height;
4840 }
4841 if (!vRecv.empty()) {
4842 vRecv >> fRelay;
4843 }
4844 if (!vRecv.empty()) {
4845 vRecv >> nExtraEntropy;
4846 }
4847 // Disconnect if we connected to ourself
4848 if (pfrom.IsInboundConn() && !m_connman.CheckIncomingNonce(nNonce)) {
4849 LogPrintf("connected to self at %s, disconnecting\n",
4850 pfrom.addr.ToString());
4851 pfrom.fDisconnect = true;
4852 return;
4853 }
4854
4855 if (pfrom.IsInboundConn() && addrMe.IsRoutable()) {
4857 }
4858
4859 // Inbound peers send us their version message when they connect.
4860 // We send our version message in response.
4861 if (pfrom.IsInboundConn()) {
4862 PushNodeVersion(config, pfrom, *peer);
4863 }
4864
4865 // Change version
4866 const int greatest_common_version =
4867 std::min(nVersion, PROTOCOL_VERSION);
4868 pfrom.SetCommonVersion(greatest_common_version);
4869 pfrom.nVersion = nVersion;
4870
4872
4873 m_connman.PushMessage(&pfrom, msg_maker.Make(NetMsgType::VERACK));
4874
4875 // Signal ADDRv2 support (BIP155).
4877
4878 pfrom.m_has_all_wanted_services =
4879 HasAllDesirableServiceFlags(nServices);
4880 peer->m_their_services = nServices;
4881 pfrom.SetAddrLocal(addrMe);
4882 {
4883 LOCK(pfrom.m_subver_mutex);
4884 pfrom.cleanSubVer = cleanSubVer;
4885 }
4886 peer->m_starting_height = starting_height;
4887
4888 // Only initialize the m_tx_relay data structure if:
4889 // - this isn't an outbound block-relay-only connection; and
4890 // - this isn't an outbound feeler connection, and
4891 // - fRelay=true or we're offering NODE_BLOOM to this peer
4892 // (NODE_BLOOM means that the peer may turn on tx relay later)
4893 if (!pfrom.IsBlockOnlyConn() && !pfrom.IsFeelerConn() &&
4894 (fRelay || (peer->m_our_services & NODE_BLOOM))) {
4895 auto *const tx_relay = peer->SetTxRelay();
4896 {
4897 LOCK(tx_relay->m_bloom_filter_mutex);
4898 // set to true after we get the first filter* message
4899 tx_relay->m_relay_txs = fRelay;
4900 }
4901 if (fRelay) {
4902 pfrom.m_relays_txs = true;
4903 }
4904 }
4905
4906 pfrom.nRemoteHostNonce = nNonce;
4907 pfrom.nRemoteExtraEntropy = nExtraEntropy;
4908
4909 // Potentially mark this peer as a preferred download peer.
4910 {
4911 LOCK(cs_main);
4912 CNodeState *state = State(pfrom.GetId());
4913 state->fPreferredDownload =
4914 (!pfrom.IsInboundConn() ||
4915 pfrom.HasPermission(NetPermissionFlags::NoBan)) &&
4916 !pfrom.IsAddrFetchConn() && CanServeBlocks(*peer);
4917 m_num_preferred_download_peers += state->fPreferredDownload;
4918 }
4919
4920 // Attempt to initialize address relay for outbound peers and use result
4921 // to decide whether to send GETADDR, so that we don't send it to
4922 // inbound or outbound block-relay-only peers.
4923 bool send_getaddr{false};
4924 if (!pfrom.IsInboundConn()) {
4926 }
4927 if (send_getaddr) {
4928 // Do a one-time address fetch to help populate/update our addrman.
4929 // If we're starting up for the first time, our addrman may be
4930 // pretty empty, so this mechanism is important to help us connect
4931 // to the network.
4932 // We skip this for block-relay-only peers. We want to avoid
4933 // potentially leaking addr information and we do not want to
4934 // indicate to the peer that we will participate in addr relay.
4936 .Make(NetMsgType::GETADDR));
4937 peer->m_getaddr_sent = true;
4938 // When requesting a getaddr, accept an additional MAX_ADDR_TO_SEND
4939 // addresses in response (bypassing the
4940 // MAX_ADDR_PROCESSING_TOKEN_BUCKET limit).
4941 WITH_LOCK(peer->m_addr_token_bucket_mutex,
4942 peer->m_addr_token_bucket += m_opts.max_addr_to_send);
4943 }
4944
4945 if (!pfrom.IsInboundConn()) {
4946 // For non-inbound connections, we update the addrman to record
4947 // connection success so that addrman will have an up-to-date
4948 // notion of which peers are online and available.
4949 //
4950 // While we strive to not leak information about block-relay-only
4951 // connections via the addrman, not moving an address to the tried
4952 // table is also potentially detrimental because new-table entries
4953 // are subject to eviction in the event of addrman collisions. We
4954 // mitigate the information-leak by never calling
4955 // AddrMan::Connected() on block-relay-only peers; see
4956 // FinalizeNode().
4957 //
4958 // This moves an address from New to Tried table in Addrman,
4959 // resolves tried-table collisions, etc.
4960 m_addrman.Good(pfrom.addr);
4961 }
4962
4963 std::string remoteAddr;
4964 if (fLogIPs) {
4965 remoteAddr = ", peeraddr=" + pfrom.addr.ToString();
4966 }
4967
4969 "receive version message: [%s] %s: version %d, blocks=%d, "
4970 "us=%s, txrelay=%d, peer=%d%s\n",
4971 pfrom.addr.ToString(), cleanSubVer, pfrom.nVersion,
4972 peer->m_starting_height, addrMe.ToString(), fRelay,
4973 pfrom.GetId(), remoteAddr);
4974
4976 int64_t nTimeOffset = nTime - currentTime;
4977 pfrom.nTimeOffset = nTimeOffset;
4978 if (nTime < int64_t(m_chainparams.GenesisBlock().nTime)) {
4979 // Ignore time offsets that are improbable (before the Genesis
4980 // block) and may underflow our adjusted time.
4981 Misbehaving(*peer, 20,
4982 "Ignoring invalid timestamp in version message");
4983 } else if (!pfrom.IsInboundConn()) {
4984 // Don't use timedata samples from inbound peers to make it
4985 // harder for others to tamper with our adjusted time.
4986 AddTimeData(pfrom.addr, nTimeOffset);
4987 }
4988
4989 // Feeler connections exist only to verify if address is online.
4990 if (pfrom.IsFeelerConn()) {
4992 "feeler connection completed peer=%d; disconnecting\n",
4993 pfrom.GetId());
4994 pfrom.fDisconnect = true;
4995 }
4996 return;
4997 }
4998
4999 if (pfrom.nVersion == 0) {
5000 // Must have a version message before anything else
5001 Misbehaving(*peer, 10, "non-version message before version handshake");
5002 return;
5003 }
5004
5005 // At this point, the outgoing message serialization version can't change.
5006 const CNetMsgMaker msgMaker(pfrom.GetCommonVersion());
5007
5009 if (pfrom.fSuccessfullyConnected) {
5011 "ignoring redundant verack message from peer=%d\n",
5012 pfrom.GetId());
5013 return;
5014 }
5015
5016 if (!pfrom.IsInboundConn()) {
5017 LogPrintf(
5018 "New outbound peer connected: version: %d, blocks=%d, "
5019 "peer=%d%s (%s)\n",
5020 pfrom.nVersion.load(), peer->m_starting_height, pfrom.GetId(),
5021 (fLogIPs ? strprintf(", peeraddr=%s", pfrom.addr.ToString())
5022 : ""),
5024 }
5025
5026 if (pfrom.GetCommonVersion() >= SHORT_IDS_BLOCKS_VERSION) {
5027 // Tell our peer we are willing to provide version 1
5028 // cmpctblocks. However, we do not request new block announcements
5029 // using cmpctblock messages. We send this to non-NODE NETWORK peers
5030 // as well, because they may wish to request compact blocks from us.
5031 m_connman.PushMessage(
5032 &pfrom,
5033 msgMaker.Make(NetMsgType::SENDCMPCT, /*high_bandwidth=*/false,
5034 /*version=*/CMPCTBLOCKS_VERSION));
5035 }
5036
5037 if (m_avalanche) {
5038 if (m_avalanche->sendHello(&pfrom)) {
5039 auto localProof = m_avalanche->getLocalProof();
5040
5041 if (localProof) {
5042 AddKnownProof(*peer, localProof->getId());
5043 // Add our proof id to the list or the recently announced
5044 // proof INVs to this peer. This is used for filtering which
5045 // INV can be requested for download.
5046 peer->m_proof_relay->m_recently_announced_proofs.insert(
5047 localProof->getId());
5048 }
5049 }
5050 }
5051
5052 if (auto tx_relay = peer->GetTxRelay()) {
5053 // `TxRelay::m_tx_inventory_to_send` must be empty before the
5054 // version handshake is completed as
5055 // `TxRelay::m_next_inv_send_time` is first initialised in
5056 // `SendMessages` after the verack is received. Any transactions
5057 // received during the version handshake would otherwise
5058 // immediately be advertised without random delay, potentially
5059 // leaking the time of arrival to a spy.
5060 Assume(WITH_LOCK(tx_relay->m_tx_inventory_mutex,
5061 return tx_relay->m_tx_inventory_to_send.empty() &&
5062 tx_relay->m_next_inv_send_time == 0s));
5063 }
5064
5065 pfrom.fSuccessfullyConnected = true;
5066 return;
5067 }
5068
5069 if (!pfrom.fSuccessfullyConnected) {
5070 // Must have a verack message before anything else
5071 Misbehaving(*peer, 10, "non-verack message before version handshake");
5072 return;
5073 }
5074
5076 int stream_version = vRecv.GetVersion();
5078 // Add ADDRV2_FORMAT to the version so that the CNetAddr and
5079 // CAddress unserialize methods know that an address in v2 format is
5080 // coming.
5082 }
5083
5085 std::vector<CAddress> vAddr;
5086
5087 s >> vAddr;
5088
5089 if (!SetupAddressRelay(pfrom, *peer)) {
5090 LogPrint(BCLog::NET, "ignoring %s message from %s peer=%d\n",
5091 msg_type, pfrom.ConnectionTypeAsString(), pfrom.GetId());
5092 return;
5093 }
5094
5095 if (vAddr.size() > m_opts.max_addr_to_send) {
5097 *peer, 20,
5098 strprintf("%s message size = %u", msg_type, vAddr.size()));
5099 return;
5100 }
5101
5102 // Store the new addresses
5103 std::vector<CAddress> vAddrOk;
5104 const auto current_a_time{Now<NodeSeconds>()};
5105
5106 // Update/increment addr rate limiting bucket.
5108 {
5109 LOCK(peer->m_addr_token_bucket_mutex);
5110 if (peer->m_addr_token_bucket < MAX_ADDR_PROCESSING_TOKEN_BUCKET) {
5111 // Don't increment bucket if it's already full
5112 const auto time_diff =
5113 std::max(current_time - peer->m_addr_token_timestamp, 0us);
5114 const double increment =
5116 peer->m_addr_token_bucket =
5117 std::min<double>(peer->m_addr_token_bucket + increment,
5119 }
5120 }
5121 peer->m_addr_token_timestamp = current_time;
5122
5123 const bool rate_limited =
5124 !pfrom.HasPermission(NetPermissionFlags::Addr);
5125 uint64_t num_proc = 0;
5127 Shuffle(vAddr.begin(), vAddr.end(), m_rng);
5128 for (CAddress &addr : vAddr) {
5129 if (interruptMsgProc) {
5130 return;
5131 }
5132
5133 {
5134 LOCK(peer->m_addr_token_bucket_mutex);
5135 // Apply rate limiting.
5136 if (peer->m_addr_token_bucket < 1.0) {
5137 if (rate_limited) {
5139 continue;
5140 }
5141 } else {
5142 peer->m_addr_token_bucket -= 1.0;
5143 }
5144 }
5145
5146 // We only bother storing full nodes, though this may include things
5147 // which we would not make an outbound connection to, in part
5148 // because we may make feeler connections to them.
5149 if (!MayHaveUsefulAddressDB(addr.nServices) &&
5151 continue;
5152 }
5153
5154 if (addr.nTime <= NodeSeconds{100000000s} ||
5155 addr.nTime > current_a_time + 10min) {
5156 addr.nTime = current_a_time - 5 * 24h;
5157 }
5158 AddAddressKnown(*peer, addr);
5159 if (m_banman &&
5160 (m_banman->IsDiscouraged(addr) || m_banman->IsBanned(addr))) {
5161 // Do not process banned/discouraged addresses beyond
5162 // remembering we received them
5163 continue;
5164 }
5165 ++num_proc;
5166 bool fReachable = IsReachable(addr);
5167 if (addr.nTime > current_a_time - 10min && !peer->m_getaddr_sent &&
5168 vAddr.size() <= 10 && addr.IsRoutable()) {
5169 // Relay to a limited number of other nodes
5170 RelayAddress(pfrom.GetId(), addr, fReachable);
5171 }
5172 // Do not store addresses outside our network
5173 if (fReachable) {
5174 vAddrOk.push_back(addr);
5175 }
5176 }
5177 peer->m_addr_processed += num_proc;
5178 peer->m_addr_rate_limited += num_rate_limit;
5180 "Received addr: %u addresses (%u processed, %u rate-limited) "
5181 "from peer=%d\n",
5182 vAddr.size(), num_proc, num_rate_limit, pfrom.GetId());
5183
5184 m_addrman.Add(vAddrOk, pfrom.addr, 2h);
5185 if (vAddr.size() < 1000) {
5186 peer->m_getaddr_sent = false;
5187 }
5188
5189 // AddrFetch: Require multiple addresses to avoid disconnecting on
5190 // self-announcements
5191 if (pfrom.IsAddrFetchConn() && vAddr.size() > 1) {
5193 "addrfetch connection completed peer=%d; disconnecting\n",
5194 pfrom.GetId());
5195 pfrom.fDisconnect = true;
5196 }
5197 return;
5198 }
5199
5201 peer->m_wants_addrv2 = true;
5202 return;
5203 }
5204
5206 peer->m_prefers_headers = true;
5207 return;
5208 }
5209
5211 bool sendcmpct_hb{false};
5213 vRecv >> sendcmpct_hb >> sendcmpct_version;
5214
5216 return;
5217 }
5218
5219 LOCK(cs_main);
5220 CNodeState *nodestate = State(pfrom.GetId());
5221 nodestate->m_provides_cmpctblocks = true;
5222 nodestate->m_requested_hb_cmpctblocks = sendcmpct_hb;
5223 // save whether peer selects us as BIP152 high-bandwidth peer
5224 // (receiving sendcmpct(1) signals high-bandwidth,
5225 // sendcmpct(0) low-bandwidth)
5226 pfrom.m_bip152_highbandwidth_from = sendcmpct_hb;
5227 return;
5228 }
5229
5230 if (msg_type == NetMsgType::INV) {
5231 std::vector<CInv> vInv;
5232 vRecv >> vInv;
5233 if (vInv.size() > MAX_INV_SZ) {
5234 Misbehaving(*peer, 20,
5235 strprintf("inv message size = %u", vInv.size()));
5236 return;
5237 }
5238
5240
5242 std::optional<BlockHash> best_block;
5243
5244 auto logInv = [&](const CInv &inv, bool fAlreadyHave) {
5245 LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(),
5246 fAlreadyHave ? "have" : "new", pfrom.GetId());
5247 };
5248
5249 for (CInv &inv : vInv) {
5250 if (interruptMsgProc) {
5251 return;
5252 }
5253
5254 if (inv.IsMsgStakeContender()) {
5255 // Ignore invs with stake contenders. This type is only used for
5256 // polling.
5257 continue;
5258 }
5259
5260 if (inv.IsMsgBlk()) {
5261 LOCK(cs_main);
5262 const bool fAlreadyHave = AlreadyHaveBlock(BlockHash(inv.hash));
5264
5265 BlockHash hash{inv.hash};
5266 UpdateBlockAvailability(pfrom.GetId(), hash);
5267 if (!fAlreadyHave && !m_chainman.m_blockman.LoadingBlocks() &&
5268 !IsBlockRequested(hash)) {
5269 // Headers-first is the primary method of announcement on
5270 // the network. If a node fell back to sending blocks by
5271 // inv, it may be for a re-org, or because we haven't
5272 // completed initial headers sync. The final block hash
5273 // provided should be the highest, so send a getheaders and
5274 // then fetch the blocks we need to catch up.
5275 best_block = std::move(hash);
5276 }
5277
5278 continue;
5279 }
5280
5281 if (inv.IsMsgProof()) {
5282 if (!m_avalanche) {
5283 continue;
5284 }
5285 const avalanche::ProofId proofid(inv.hash);
5286 const bool fAlreadyHave = AlreadyHaveProof(proofid);
5288 AddKnownProof(*peer, proofid);
5289
5290 if (!fAlreadyHave && m_avalanche &&
5291 !m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
5292 const bool preferred = isPreferredDownloadPeer(pfrom);
5293
5294 LOCK(cs_proofrequest);
5295 AddProofAnnouncement(pfrom, proofid, current_time,
5296 preferred);
5297 }
5298 continue;
5299 }
5300
5301 if (inv.IsMsgTx()) {
5302 LOCK(cs_main);
5303 const TxId txid(inv.hash);
5304 const bool fAlreadyHave =
5305 AlreadyHaveTx(txid, /*include_reconsiderable=*/true);
5307
5308 AddKnownTx(*peer, txid);
5309 if (reject_tx_invs) {
5311 "transaction (%s) inv sent in violation of "
5312 "protocol, disconnecting peer=%d\n",
5313 txid.ToString(), pfrom.GetId());
5314 pfrom.fDisconnect = true;
5315 return;
5316 } else if (!fAlreadyHave && !m_chainman.ActiveChainstate()
5317 .IsInitialBlockDownload()) {
5319 }
5320
5321 continue;
5322 }
5323
5325 "Unknown inv type \"%s\" received from peer=%d\n",
5326 inv.ToString(), pfrom.GetId());
5327 }
5328
5329 if (best_block) {
5330 // If we haven't started initial headers-sync with this peer, then
5331 // consider sending a getheaders now. On initial startup, there's a
5332 // reliability vs bandwidth tradeoff, where we are only trying to do
5333 // initial headers sync with one peer at a time, with a long
5334 // timeout (at which point, if the sync hasn't completed, we will
5335 // disconnect the peer and then choose another). In the meantime,
5336 // as new blocks are found, we are willing to add one new peer per
5337 // block to sync with as well, to sync quicker in the case where
5338 // our initial peer is unresponsive (but less bandwidth than we'd
5339 // use if we turned on sync with all peers).
5340 LOCK(::cs_main);
5341 CNodeState &state{*Assert(State(pfrom.GetId()))};
5342 if (state.fSyncStarted ||
5343 (!peer->m_inv_triggered_getheaders_before_sync &&
5346 pfrom, GetLocator(m_chainman.m_best_header), *peer)) {
5347 LogPrint(BCLog::NET, "getheaders (%d) %s to peer=%d\n",
5348 m_chainman.m_best_header->nHeight,
5349 best_block->ToString(), pfrom.GetId());
5350 }
5351 if (!state.fSyncStarted) {
5352 peer->m_inv_triggered_getheaders_before_sync = true;
5353 // Update the last block hash that triggered a new headers
5354 // sync, so that we don't turn on headers sync with more
5355 // than 1 new peer every new block.
5357 }
5358 }
5359 }
5360
5361 return;
5362 }
5363
5365 std::vector<CInv> vInv;
5366 vRecv >> vInv;
5367 if (vInv.size() > MAX_INV_SZ) {
5368 Misbehaving(*peer, 20,
5369 strprintf("getdata message size = %u", vInv.size()));
5370 return;
5371 }
5372
5373 LogPrint(BCLog::NET, "received getdata (%u invsz) peer=%d\n",
5374 vInv.size(), pfrom.GetId());
5375
5376 if (vInv.size() > 0) {
5377 LogPrint(BCLog::NET, "received getdata for: %s peer=%d\n",
5378 vInv[0].ToString(), pfrom.GetId());
5379 }
5380
5381 {
5382 LOCK(peer->m_getdata_requests_mutex);
5383 peer->m_getdata_requests.insert(peer->m_getdata_requests.end(),
5384 vInv.begin(), vInv.end());
5385 ProcessGetData(config, pfrom, *peer, interruptMsgProc);
5386 }
5387
5388 return;
5389 }
5390
5394 vRecv >> locator >> hashStop;
5395
5396 if (locator.vHave.size() > MAX_LOCATOR_SZ) {
5398 "getblocks locator size %lld > %d, disconnect peer=%d\n",
5399 locator.vHave.size(), MAX_LOCATOR_SZ, pfrom.GetId());
5400 pfrom.fDisconnect = true;
5401 return;
5402 }
5403
5404 // We might have announced the currently-being-connected tip using a
5405 // compact block, which resulted in the peer sending a getblocks
5406 // request, which we would otherwise respond to without the new block.
5407 // To avoid this situation we simply verify that we are on our best
5408 // known chain now. This is super overkill, but we handle it better
5409 // for getheaders requests, and there are no known nodes which support
5410 // compact blocks but still use getblocks to request blocks.
5411 {
5412 std::shared_ptr<const CBlock> a_recent_block;
5413 {
5414 LOCK(m_most_recent_block_mutex);
5416 }
5418 if (!m_chainman.ActiveChainstate().ActivateBestChain(
5419 state, a_recent_block, m_avalanche)) {
5420 LogPrint(BCLog::NET, "failed to activate chain (%s)\n",
5421 state.ToString());
5422 }
5423 }
5424
5425 LOCK(cs_main);
5426
5427 // Find the last block the caller has in the main chain
5428 const CBlockIndex *pindex =
5429 m_chainman.ActiveChainstate().FindForkInGlobalIndex(locator);
5430
5431 // Send the rest of the chain
5432 if (pindex) {
5433 pindex = m_chainman.ActiveChain().Next(pindex);
5434 }
5435 int nLimit = 500;
5436 LogPrint(BCLog::NET, "getblocks %d to %s limit %d from peer=%d\n",
5437 (pindex ? pindex->nHeight : -1),
5438 hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit,
5439 pfrom.GetId());
5440 for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex)) {
5441 if (pindex->GetBlockHash() == hashStop) {
5442 LogPrint(BCLog::NET, " getblocks stopping at %d %s\n",
5443 pindex->nHeight, pindex->GetBlockHash().ToString());
5444 break;
5445 }
5446 // If pruning, don't inv blocks unless we have on disk and are
5447 // likely to still have for some reasonable time window (1 hour)
5448 // that block relay might require.
5449 const int nPrunedBlocksLikelyToHave =
5451 3600 / m_chainparams.GetConsensus().nPowTargetSpacing;
5452 if (m_chainman.m_blockman.IsPruneMode() &&
5453 (!pindex->nStatus.hasData() ||
5454 pindex->nHeight <= m_chainman.ActiveChain().Tip()->nHeight -
5456 LogPrint(
5457 BCLog::NET,
5458 " getblocks stopping, pruned or too old block at %d %s\n",
5459 pindex->nHeight, pindex->GetBlockHash().ToString());
5460 break;
5461 }
5462 WITH_LOCK(
5463 peer->m_block_inv_mutex,
5464 peer->m_blocks_for_inv_relay.push_back(pindex->GetBlockHash()));
5465 if (--nLimit <= 0) {
5466 // When this block is requested, we'll send an inv that'll
5467 // trigger the peer to getblocks the next batch of inventory.
5468 LogPrint(BCLog::NET, " getblocks stopping at limit %d %s\n",
5469 pindex->nHeight, pindex->GetBlockHash().ToString());
5470 WITH_LOCK(peer->m_block_inv_mutex, {
5471 peer->m_continuation_block = pindex->GetBlockHash();
5472 });
5473 break;
5474 }
5475 }
5476 return;
5477 }
5478
5481 vRecv >> req;
5482
5483 std::shared_ptr<const CBlock> recent_block;
5484 {
5485 LOCK(m_most_recent_block_mutex);
5488 }
5489 // Unlock m_most_recent_block_mutex to avoid cs_main lock inversion
5490 }
5491 if (recent_block) {
5493 return;
5494 }
5495
5496 {
5497 LOCK(cs_main);
5498
5499 const CBlockIndex *pindex =
5500 m_chainman.m_blockman.LookupBlockIndex(req.blockhash);
5501 if (!pindex || !pindex->nStatus.hasData()) {
5502 LogPrint(
5503 BCLog::NET,
5504 "Peer %d sent us a getblocktxn for a block we don't have\n",
5505 pfrom.GetId());
5506 return;
5507 }
5508
5509 if (pindex->nHeight >=
5510 m_chainman.ActiveChain().Height() - MAX_BLOCKTXN_DEPTH) {
5511 CBlock block;
5512 const bool ret{
5513 m_chainman.m_blockman.ReadBlockFromDisk(block, *pindex)};
5514 assert(ret);
5515
5516 SendBlockTransactions(pfrom, *peer, block, req);
5517 return;
5518 }
5519 }
5520
5521 // If an older block is requested (should never happen in practice,
5522 // but can happen in tests) send a block response instead of a
5523 // blocktxn response. Sending a full block response instead of a
5524 // small blocktxn response is preferable in the case where a peer
5525 // might maliciously send lots of getblocktxn requests to trigger
5526 // expensive disk reads, because it will require the peer to
5527 // actually receive all the data read from disk over the network.
5529 "Peer %d sent us a getblocktxn for a block > %i deep\n",
5530 pfrom.GetId(), MAX_BLOCKTXN_DEPTH);
5531 CInv inv;
5532 inv.type = MSG_BLOCK;
5533 inv.hash = req.blockhash;
5534 WITH_LOCK(peer->m_getdata_requests_mutex,
5535 peer->m_getdata_requests.push_back(inv));
5536 // The message processing loop will go around again (without pausing)
5537 // and we'll respond then (without cs_main)
5538 return;
5539 }
5540
5544 vRecv >> locator >> hashStop;
5545
5546 if (locator.vHave.size() > MAX_LOCATOR_SZ) {
5548 "getheaders locator size %lld > %d, disconnect peer=%d\n",
5549 locator.vHave.size(), MAX_LOCATOR_SZ, pfrom.GetId());
5550 pfrom.fDisconnect = true;
5551 return;
5552 }
5553
5554 if (m_chainman.m_blockman.LoadingBlocks()) {
5555 LogPrint(
5556 BCLog::NET,
5557 "Ignoring getheaders from peer=%d while importing/reindexing\n",
5558 pfrom.GetId());
5559 return;
5560 }
5561
5562 LOCK(cs_main);
5563
5564 // Note that if we were to be on a chain that forks from the
5565 // checkpointed chain, then serving those headers to a peer that has
5566 // seen the checkpointed chain would cause that peer to disconnect us.
5567 // Requiring that our chainwork exceed the minimum chainwork is a
5568 // protection against being fed a bogus chain when we started up for
5569 // the first time and getting partitioned off the honest network for
5570 // serving that chain to others.
5571 if (m_chainman.ActiveTip() == nullptr ||
5572 (m_chainman.ActiveTip()->nChainWork <
5573 m_chainman.MinimumChainWork() &&
5574 !pfrom.HasPermission(NetPermissionFlags::Download))) {
5576 "Ignoring getheaders from peer=%d because active chain "
5577 "has too little work; sending empty response\n",
5578 pfrom.GetId());
5579 // Just respond with an empty headers message, to tell the peer to
5580 // go away but not treat us as unresponsive.
5582 std::vector<CBlock>()));
5583 return;
5584 }
5585
5586 CNodeState *nodestate = State(pfrom.GetId());
5587 const CBlockIndex *pindex = nullptr;
5588 if (locator.IsNull()) {
5589 // If locator is null, return the hashStop block
5590 pindex = m_chainman.m_blockman.LookupBlockIndex(hashStop);
5591 if (!pindex) {
5592 return;
5593 }
5594
5595 if (!BlockRequestAllowed(pindex)) {
5597 "%s: ignoring request from peer=%i for old block "
5598 "header that isn't in the main chain\n",
5599 __func__, pfrom.GetId());
5600 return;
5601 }
5602 } else {
5603 // Find the last block the caller has in the main chain
5604 pindex =
5605 m_chainman.ActiveChainstate().FindForkInGlobalIndex(locator);
5606 if (pindex) {
5607 pindex = m_chainman.ActiveChain().Next(pindex);
5608 }
5609 }
5610
5611 // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx
5612 // count at the end
5613 std::vector<CBlock> vHeaders;
5615 LogPrint(BCLog::NET, "getheaders %d to %s from peer=%d\n",
5616 (pindex ? pindex->nHeight : -1),
5617 hashStop.IsNull() ? "end" : hashStop.ToString(),
5618 pfrom.GetId());
5619 for (; pindex; pindex = m_chainman.ActiveChain().Next(pindex)) {
5620 vHeaders.push_back(pindex->GetBlockHeader());
5621 if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop) {
5622 break;
5623 }
5624 }
5625 // pindex can be nullptr either if we sent
5626 // m_chainman.ActiveChain().Tip() OR if our peer has
5627 // m_chainman.ActiveChain().Tip() (and thus we are sending an empty
5628 // headers message). In both cases it's safe to update
5629 // pindexBestHeaderSent to be our tip.
5630 //
5631 // It is important that we simply reset the BestHeaderSent value here,
5632 // and not max(BestHeaderSent, newHeaderSent). We might have announced
5633 // the currently-being-connected tip using a compact block, which
5634 // resulted in the peer sending a headers request, which we respond to
5635 // without the new block. By resetting the BestHeaderSent, we ensure we
5636 // will re-announce the new block via headers (or compact blocks again)
5637 // in the SendMessages logic.
5638 nodestate->pindexBestHeaderSent =
5639 pindex ? pindex : m_chainman.ActiveChain().Tip();
5640 m_connman.PushMessage(&pfrom,
5642 return;
5643 }
5644
5645 if (msg_type == NetMsgType::TX) {
5646 if (RejectIncomingTxs(pfrom)) {
5648 "transaction sent in violation of protocol peer=%d\n",
5649 pfrom.GetId());
5650 pfrom.fDisconnect = true;
5651 return;
5652 }
5653
5654 // Stop processing the transaction early if we are still in IBD since we
5655 // don't have enough information to validate it yet. Sending unsolicited
5656 // transactions is not considered a protocol violation, so don't punish
5657 // the peer.
5658 if (m_chainman.ActiveChainstate().IsInitialBlockDownload()) {
5659 return;
5660 }
5661
5663 vRecv >> ptx;
5664 const CTransaction &tx = *ptx;
5665 const TxId &txid = tx.GetId();
5666 AddKnownTx(*peer, txid);
5667
5668 bool shouldReconcileTx{false};
5669 {
5670 LOCK(cs_main);
5671
5672 m_txrequest.ReceivedResponse(pfrom.GetId(), txid);
5673
5674 if (AlreadyHaveTx(txid, /*include_reconsiderable=*/true)) {
5675 if (pfrom.HasPermission(NetPermissionFlags::ForceRelay)) {
5676 // Always relay transactions received from peers with
5677 // forcerelay permission, even if they were already in the
5678 // mempool, allowing the node to function as a gateway for
5679 // nodes hidden behind it.
5680 if (!m_mempool.exists(tx.GetId())) {
5681 LogPrintf(
5682 "Not relaying non-mempool transaction %s from "
5683 "forcerelay peer=%d\n",
5684 tx.GetId().ToString(), pfrom.GetId());
5685 } else {
5686 LogPrintf("Force relaying tx %s from peer=%d\n",
5687 tx.GetId().ToString(), pfrom.GetId());
5688 RelayTransaction(tx.