Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2016 The Bitcoin Core developers
3 : // Copyright (c) 2014-2021 The Dash Core developers
4 : // Copyright (c) 2015-2022 The PIVX Core developers
5 : // Distributed under the MIT software license, see the accompanying
6 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 :
8 : #include "net_processing.h"
9 :
10 : #include "budget/budgetmanager.h"
11 : #include "chain.h"
12 : #include "evo/deterministicmns.h"
13 : #include "evo/mnauth.h"
14 : #include "llmq/quorums_blockprocessor.h"
15 : #include "llmq/quorums_chainlocks.h"
16 : #include "llmq/quorums_dkgsessionmgr.h"
17 : #include "llmq/quorums_signing.h"
18 : #include "masternode-payments.h"
19 : #include "masternode-sync.h"
20 : #include "masternodeman.h"
21 : #include "merkleblock.h"
22 : #include "netbase.h"
23 : #include "netmessagemaker.h"
24 : #include "primitives/block.h"
25 : #include "primitives/transaction.h"
26 : #include "spork.h"
27 : #include "sporkdb.h"
28 : #include "streams.h"
29 : #include "tiertwo/tiertwo_sync_state.h"
30 : #include "util/validation.h"
31 : #include "validation.h"
32 :
33 : #include <chrono>
34 :
35 : using namespace std::chrono_literals;
36 :
37 :
38 : static const uint64_t RANDOMIZER_ID_ADDRESS_RELAY = 0x3cac0035b5866b90ULL; // SHA256("main address relay")[0:8]
39 :
40 : /** the maximum percentage of addresses from our addrman to return in response to a getaddr message. */
41 : static constexpr size_t MAX_PCT_ADDR_TO_SEND = 23;
42 :
43 : struct IteratorComparator
44 : {
45 : template<typename I>
46 182 : bool operator()(const I& a, const I& b) const
47 : {
48 182 : return &(*a) < &(*b);
49 : }
50 : };
51 :
52 364 : struct COrphanTx {
53 : // When modifying, adapt the copy of this definition in tests/DoS_tests.
54 : CTransactionRef tx;
55 : NodeId fromPeer;
56 : int64_t nTimeExpire;
57 : size_t list_pos;
58 : };
59 : RecursiveMutex g_cs_orphans;
60 : std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans);
61 : std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans);
62 : std::vector<std::map<uint256, COrphanTx>::iterator> g_orphan_list GUARDED_BY(g_cs_orphans); //! For random eviction
63 :
64 : void EraseOrphansFor(NodeId peer);
65 :
66 : // Internal stuff
67 : namespace {
68 :
69 : /** Number of nodes with fSyncStarted. */
70 : int nSyncStarted = 0;
71 :
72 : /**
73 : * Sources of received blocks, to be able to send them reject messages or ban
74 : * them, if processing happens afterwards. Protected by cs_main.
75 : */
76 : std::map<uint256, NodeId> mapBlockSource;
77 :
78 : /**
79 : * Filter for transactions that were recently rejected by
80 : * AcceptToMemoryPool. These are not rerequested until the chain tip
81 : * changes, at which point the entire filter is reset. Protected by
82 : * cs_main.
83 : *
84 : * Without this filter we'd be re-requesting txs from each of our peers,
85 : * increasing bandwidth consumption considerably. For instance, with 100
86 : * peers, half of which relay a tx we don't accept, that might be a 50x
87 : * bandwidth increase. A flooding attacker attempting to roll-over the
88 : * filter using minimum-sized, 60byte, transactions might manage to send
89 : * 1000/sec if we have fast peers, so we pick 120,000 to give our peers a
90 : * two minute window to send invs to us.
91 : *
92 : * Decreasing the false positive rate is fairly cheap, so we pick one in a
93 : * million to make it highly unlikely for users to have issues with this
94 : * filter.
95 : *
96 : * Memory used: 1.3MB
97 : */
98 : std::unique_ptr<CRollingBloomFilter> recentRejects;
99 : uint256 hashRecentRejectsChainTip;
100 :
101 : /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */
102 : struct QueuedBlock {
103 : uint256 hash;
104 : const CBlockIndex* pindex; //! Optional.
105 : int64_t nTime; //! Time of "getdata" request in microseconds.
106 : int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested.
107 : bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
108 : };
109 : std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> > mapBlocksInFlight;
110 :
111 : /** Number of blocks in flight with validated headers. */
112 : int nQueuedValidatedHeaders = 0;
113 :
114 : /** Number of preferable block download peers. */
115 : int nPreferredDownload = 0;
116 :
117 : } // anon namespace
118 :
119 : namespace
120 : {
121 :
122 : class CNodeBlocks
123 : {
124 : public:
125 1460 : CNodeBlocks():
126 : maxSize(0),
127 1460 : maxAvg(0)
128 : {
129 1460 : maxSize = gArgs.GetArg("-blockspamfiltermaxsize", DEFAULT_BLOCK_SPAM_FILTER_MAX_SIZE);
130 1460 : maxAvg = gArgs.GetArg("-blockspamfiltermaxavg", DEFAULT_BLOCK_SPAM_FILTER_MAX_AVG);
131 1460 : }
132 :
133 23 : bool onBlockReceived(int nHeight) {
134 23 : if(nHeight > 0 && maxSize && maxAvg) {
135 23 : addPoint(nHeight);
136 23 : return true;
137 : }
138 : return false;
139 : }
140 :
141 23 : bool updateState(CValidationState& state, bool ret)
142 : {
143 : // No Blocks
144 23 : size_t size = points.size();
145 23 : if(size == 0)
146 : return ret;
147 :
148 : // Compute the number of the received blocks
149 23 : size_t nBlocks = 0;
150 49 : for (auto point : points) {
151 26 : nBlocks += point.second;
152 : }
153 :
154 : // Compute the average value per height
155 23 : double nAvgValue = (double)nBlocks / size;
156 :
157 : // Ban the node if try to spam
158 46 : bool banNode = (nAvgValue >= 1.5 * maxAvg && size >= maxAvg) ||
159 23 : (nAvgValue >= maxAvg && nBlocks >= maxSize) ||
160 23 : (nBlocks >= maxSize * 3);
161 : if (banNode) {
162 : // Clear the points and ban the node
163 0 : points.clear();
164 0 : return state.DoS(100, error("block-spam ban node for sending spam"));
165 : }
166 :
167 : return ret;
168 : }
169 :
170 : private:
171 23 : void addPoint(int height)
172 : {
173 : // Remove the last element in the list
174 23 : if(points.size() == maxSize)
175 : {
176 0 : points.erase(points.begin());
177 : }
178 :
179 : // Add the point to the list
180 23 : int occurrence = 0;
181 23 : auto mi = points.find(height);
182 23 : if (mi != points.end())
183 1 : occurrence = (*mi).second;
184 23 : occurrence++;
185 23 : points[height] = occurrence;
186 23 : }
187 :
188 : private:
189 : std::map<int,int> points;
190 : size_t maxSize;
191 : size_t maxAvg;
192 : };
193 :
194 :
195 :
196 : /**
197 : * Maintain validation-specific state about nodes, protected by cs_main, instead
198 : * by CNode's own locks. This simplifies asynchronous operation, where
199 : * processing of incoming data is done after the ProcessMessage call returns,
200 : * and we're no longer holding the node's locks.
201 : */
202 : struct CNodeState {
203 : //! The peer's address
204 : const CService address;
205 : //! Whether we have a fully established connection.
206 : bool fCurrentlyConnected;
207 : //! Accumulated misbehaviour score for this peer.
208 : int nMisbehavior;
209 : //! Whether this peer should be disconnected and banned (unless whitelisted).
210 : bool fShouldBan;
211 : //! String name of this peer (debugging/logging purposes).
212 : const std::string name;
213 : //! The best known block we know this peer has announced.
214 : const CBlockIndex* pindexBestKnownBlock;
215 : //! The hash of the last unknown block this peer has announced.
216 : uint256 hashLastUnknownBlock;
217 : //! The last full block we both have.
218 : const CBlockIndex* pindexLastCommonBlock;
219 : //! Whether we've started headers synchronization with this peer.
220 : bool fSyncStarted;
221 : //! Since when we're stalling block download progress (in microseconds), or 0.
222 : int64_t nStallingSince;
223 : std::list<QueuedBlock> vBlocksInFlight;
224 : int nBlocksInFlight;
225 : //! Whether we consider this a preferred download peer.
226 : bool fPreferredDownload;
227 : //! Addresses processed
228 : uint64_t amt_addr_processed = 0;
229 : //! Addresses rate limited
230 : uint64_t amt_addr_rate_limited = 0;
231 :
232 : CNodeBlocks nodeBlocks;
233 :
234 4380 : CNodeState(CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) {
235 1460 : fCurrentlyConnected = false;
236 1460 : nMisbehavior = 0;
237 1460 : fShouldBan = false;
238 1460 : pindexBestKnownBlock = nullptr;
239 1460 : hashLastUnknownBlock.SetNull();
240 1460 : pindexLastCommonBlock = nullptr;
241 1460 : fSyncStarted = false;
242 1460 : nStallingSince = 0;
243 1460 : nBlocksInFlight = 0;
244 1460 : fPreferredDownload = false;
245 1460 : }
246 : };
247 :
248 : /** Map maintaining per-node state. Requires cs_main. */
249 : std::map<NodeId, CNodeState> mapNodeState;
250 :
251 : // Requires cs_main.
252 6954623 : CNodeState* State(NodeId pnode)
253 : {
254 6954623 : std::map<NodeId, CNodeState>::iterator it = mapNodeState.find(pnode);
255 6954623 : if (it == mapNodeState.end())
256 : return nullptr;
257 6954543 : return &it->second;
258 : }
259 :
260 1362 : void UpdatePreferredDownload(CNode* node, CNodeState* state)
261 : {
262 1362 : nPreferredDownload -= state->fPreferredDownload;
263 :
264 : // Whether this node should be marked as a preferred download node.
265 1362 : state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient;
266 :
267 1362 : nPreferredDownload += state->fPreferredDownload;
268 1362 : }
269 :
270 1407 : void PushNodeVersion(CNode* pnode, CConnman* connman, int64_t nTime)
271 : {
272 1407 : ServiceFlags nLocalNodeServices = pnode->GetLocalServices();
273 1407 : uint64_t nonce = pnode->GetLocalNonce();
274 1407 : int nNodeStartingHeight = pnode->GetMyStartingHeight();
275 1407 : NodeId nodeid = pnode->GetId();
276 1407 : CAddress addr = pnode->addr;
277 :
278 2825 : CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService(), addr.nServices));
279 4221 : CAddress addrMe = CAddress(CService(), nLocalNodeServices);
280 :
281 : // Create the version message
282 1407 : auto version_msg = CNetMsgMaker(INIT_PROTO_VERSION).Make(NetMsgType::VERSION, PROTOCOL_VERSION, (uint64_t)nLocalNodeServices, nTime, addrYou, addrMe,
283 2814 : nonce, strSubVersion, nNodeStartingHeight, true);
284 :
285 : // DMN-to-DMN, set auth connection type and create challenge.
286 1407 : if (pnode->m_masternode_connection) {
287 236 : uint256 mnauthChallenge;
288 236 : GetRandBytes(mnauthChallenge.begin(), (int) mnauthChallenge.size());
289 472 : WITH_LOCK(pnode->cs_mnauth, pnode->sentMNAuthChallenge = mnauthChallenge);
290 236 : CVectorWriter{SER_NETWORK, 0 | INIT_PROTO_VERSION, version_msg.data, version_msg.data.size(), pnode->sentMNAuthChallenge};
291 : }
292 :
293 1407 : connman->PushMessage(pnode, std::move(version_msg));
294 :
295 1407 : if (fLogIPs)
296 0 : LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, them=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.ToString(), addrYou.ToString(), nodeid);
297 : else
298 2790 : LogPrint(BCLog::NET, "send version message: version %d, blocks=%d, us=%s, peer=%d\n", PROTOCOL_VERSION, nNodeStartingHeight, addrMe.ToString(), nodeid);
299 1407 : }
300 :
301 : // Requires cs_main.
302 25750 : void MarkBlockAsReceived(const uint256& hash)
303 : {
304 25750 : std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
305 25750 : if (itInFlight != mapBlocksInFlight.end()) {
306 0 : CNodeState* state = State(itInFlight->second.first);
307 0 : assert(state != nullptr);
308 0 : nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
309 0 : state->vBlocksInFlight.erase(itInFlight->second.second);
310 0 : state->nBlocksInFlight--;
311 0 : state->nStallingSince = 0;
312 0 : mapBlocksInFlight.erase(itInFlight);
313 : }
314 25750 : }
315 :
316 : // Requires cs_main.
317 0 : void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, const CBlockIndex* pindex = nullptr)
318 : {
319 0 : CNodeState* state = State(nodeid);
320 0 : assert(state != nullptr);
321 :
322 : // Make sure it's not listed somewhere already.
323 0 : MarkBlockAsReceived(hash);
324 :
325 0 : QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != nullptr};
326 0 : nQueuedValidatedHeaders += newentry.fValidatedHeaders;
327 0 : std::list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
328 0 : state->nBlocksInFlight++;
329 0 : mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
330 0 : }
331 :
332 : /** Check whether the last unknown block a peer advertised is not yet known. */
333 1312383 : static void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
334 : {
335 1312383 : AssertLockHeld(cs_main);
336 :
337 1312383 : CNodeState* state = State(nodeid);
338 1312383 : assert(state != nullptr);
339 :
340 39495799 : if (!state->hashLastUnknownBlock.IsNull()) {
341 123004 : CBlockIndex* pindex = LookupBlockIndex(state->hashLastUnknownBlock);
342 139489 : if (pindex && pindex->nChainWork > 0) {
343 16485 : if (!state->pindexBestKnownBlock || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork)
344 16484 : state->pindexBestKnownBlock = pindex;
345 16485 : state->hashLastUnknownBlock.SetNull();
346 : }
347 : }
348 1312383 : }
349 :
350 : /** Update tracking information about which blocks a peer is assumed to have. */
351 187483 : static void UpdateBlockAvailability(NodeId nodeid, const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
352 : {
353 187483 : AssertLockHeld(cs_main);
354 :
355 187483 : CNodeState* state = State(nodeid);
356 187483 : assert(state != nullptr);
357 :
358 187483 : ProcessBlockAvailability(nodeid);
359 :
360 187483 : CBlockIndex* pindex = LookupBlockIndex(hash);
361 324814 : if (pindex && pindex->nChainWork > 0) {
362 : // An actually better block was announced.
363 137331 : if (!state->pindexBestKnownBlock || pindex->nChainWork >= state->pindexBestKnownBlock->nChainWork)
364 136148 : state->pindexBestKnownBlock = pindex;
365 : } else {
366 : // An unknown block was announced; just assume that the latest one is the best one.
367 50152 : state->hashLastUnknownBlock = hash;
368 : }
369 187483 : }
370 :
371 : /** Update pindexLastCommonBlock and add not-in-flight missing successors to vBlocks, until it has
372 : * at most count entries. */
373 1124903 : static void FindNextBlocksToDownload(NodeId nodeid, unsigned int count, std::vector<const CBlockIndex*>& vBlocks, NodeId& nodeStaller) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
374 : {
375 1124903 : AssertLockHeld(cs_main);
376 :
377 1124903 : if (count == 0)
378 1094183 : return;
379 :
380 1124903 : vBlocks.reserve(vBlocks.size() + count);
381 1124903 : CNodeState* state = State(nodeid);
382 1124903 : assert(state != nullptr);
383 :
384 : // Make sure pindexBestKnownBlock is up to date, we'll need it.
385 1124903 : ProcessBlockAvailability(nodeid);
386 :
387 2097543 : if (!state->pindexBestKnownBlock || state->pindexBestKnownBlock->nChainWork < chainActive.Tip()->nChainWork) {
388 : // This peer has nothing interesting.
389 421826 : return;
390 : }
391 :
392 703074 : if (!state->pindexLastCommonBlock) {
393 : // Bootstrap quickly by guessing a parent of our best tip is the forking point.
394 : // Guessing wrong in either direction is not a problem.
395 1370 : state->pindexLastCommonBlock = chainActive[std::min(state->pindexBestKnownBlock->nHeight, chainActive.Height())];
396 : }
397 :
398 : // If the peer reorganized, our previous pindexLastCommonBlock may not be an ancestor
399 : // of their current tip anymore. Go back enough to fix that.
400 703074 : state->pindexLastCommonBlock = LastCommonAncestor(state->pindexLastCommonBlock, state->pindexBestKnownBlock);
401 703074 : if (state->pindexLastCommonBlock == state->pindexBestKnownBlock)
402 : return;
403 :
404 61428 : std::vector<const CBlockIndex*> vToFetch;
405 30714 : const CBlockIndex* pindexWalk = state->pindexLastCommonBlock;
406 : // Never fetch further than the best block we know the peer has, or more than BLOCK_DOWNLOAD_WINDOW + 1 beyond the last
407 : // linked block we have in common with this peer. The +1 is so we can detect stalling, namely if we would be able to
408 : // download that next block if the window were 1 larger.
409 30714 : int nWindowEnd = state->pindexLastCommonBlock->nHeight + BLOCK_DOWNLOAD_WINDOW;
410 30714 : int nMaxHeight = std::min<int>(state->pindexBestKnownBlock->nHeight, nWindowEnd + 1);
411 30714 : NodeId waitingfor = -1;
412 61445 : while (pindexWalk->nHeight < nMaxHeight) {
413 : // Read up to 128 (or more, if more blocks than that are needed) successors of pindexWalk (towards
414 : // pindexBestKnownBlock) into vToFetch. We fetch 128, because CBlockIndex::GetAncestor may be as expensive
415 : // as iterating over ~100 CBlockIndex* entries anyway.
416 61462 : int nToFetch = std::min(nMaxHeight - pindexWalk->nHeight, std::max<int>(count - vBlocks.size(), 128));
417 30731 : vToFetch.resize(nToFetch);
418 30731 : pindexWalk = state->pindexBestKnownBlock->GetAncestor(pindexWalk->nHeight + nToFetch);
419 30731 : vToFetch[nToFetch - 1] = pindexWalk;
420 96113 : for (unsigned int i = nToFetch - 1; i > 0; i--) {
421 65382 : vToFetch[i - 1] = vToFetch[i]->pprev;
422 : }
423 :
424 : // Iterate over those blocks in vToFetch (in forward direction), adding the ones that
425 : // are not yet downloaded and not in flight to vBlocks. In the mean time, update
426 : // pindexLastCommonBlock as long as all ancestors are already downloaded.
427 126844 : for (const CBlockIndex* pindex : vToFetch) {
428 96113 : if (!pindex->IsValid(BLOCK_VALID_TREE)) {
429 : // We consider the chain that this peer is on invalid.
430 0 : return;
431 : }
432 96113 : if (pindex->nStatus & BLOCK_HAVE_DATA) {
433 96113 : if (pindex->nChainTx)
434 96113 : state->pindexLastCommonBlock = pindex;
435 0 : } else if (mapBlocksInFlight.count(pindex->GetBlockHash()) == 0) {
436 : // The block is not already downloaded, and not yet in flight.
437 0 : if (pindex->nHeight > nWindowEnd) {
438 : // We reached the end of the window.
439 0 : if (vBlocks.size() == 0 && waitingfor != nodeid) {
440 : // We aren't able to fetch anything, but we would be if the download window was one larger.
441 0 : nodeStaller = waitingfor;
442 : }
443 0 : return;
444 : }
445 0 : vBlocks.push_back(pindex);
446 0 : if (vBlocks.size() == count) {
447 : return;
448 : }
449 0 : } else if (waitingfor == -1) {
450 : // This is the first already-in-flight block.
451 0 : waitingfor = mapBlocksInFlight[pindex->GetBlockHash()].first;
452 : }
453 : }
454 : }
455 : }
456 :
457 : } // anon namespace
458 :
459 1460 : void PeerLogicValidation::InitializeNode(CNode *pnode) {
460 1460 : CAddress addr = pnode->addr;
461 2920 : std::string addrName = pnode->GetAddrName();
462 1460 : NodeId nodeid = pnode->GetId();
463 1460 : {
464 1460 : LOCK(cs_main);
465 1460 : mapNodeState.emplace_hint(mapNodeState.end(), std::piecewise_construct, std::forward_as_tuple(nodeid), std::forward_as_tuple(addr, std::move(addrName)));
466 : }
467 1460 : if(!pnode->fInbound)
468 693 : PushNodeVersion(pnode, connman, GetTime());
469 1460 : }
470 :
471 1456 : void PeerLogicValidation::FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTime)
472 : {
473 1456 : fUpdateConnectionTime = false;
474 1456 : LOCK(cs_main);
475 1456 : CNodeState* state = State(nodeid);
476 :
477 1456 : if (state->fSyncStarted)
478 1226 : nSyncStarted--;
479 :
480 1456 : if (state->nMisbehavior == 0 && state->fCurrentlyConnected) {
481 642 : fUpdateConnectionTime = true;
482 : }
483 :
484 1456 : for (const QueuedBlock& entry : state->vBlocksInFlight)
485 0 : mapBlocksInFlight.erase(entry.hash);
486 1456 : EraseOrphansFor(nodeid);
487 1456 : nPreferredDownload -= state->fPreferredDownload;
488 :
489 1456 : mapNodeState.erase(nodeid);
490 1456 : }
491 :
492 61373 : bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats)
493 : {
494 122746 : LOCK(cs_main);
495 61373 : CNodeState* state = State(nodeid);
496 61373 : if (!state)
497 : return false;
498 61373 : stats.nMisbehavior = state->nMisbehavior;
499 61373 : stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
500 61373 : stats.nCommonHeight = state->pindexLastCommonBlock ? state->pindexLastCommonBlock->nHeight : -1;
501 61373 : for (const QueuedBlock& queue : state->vBlocksInFlight) {
502 0 : if (queue.pindex)
503 0 : stats.vHeightInFlight.push_back(queue.pindex->nHeight);
504 : }
505 :
506 61373 : stats.m_addr_processed = state->amt_addr_processed;
507 61373 : stats.m_addr_rate_limited = state->amt_addr_rate_limited;
508 61373 : return true;
509 : }
510 :
511 : //////////////////////////////////////////////////////////////////////////////
512 : //
513 : // mapOrphanTransactions
514 : //
515 :
516 215 : bool AddOrphanTx(const CTransactionRef& tx, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
517 : {
518 215 : const uint256& hash = tx->GetHash();
519 215 : if (mapOrphanTransactions.count(hash))
520 23 : return false;
521 :
522 : // Ignore big transactions, to avoid a
523 : // send-big-orphans memory exhaustion attack. If a peer has a legitimate
524 : // large transaction with a missing parent then we assume
525 : // it will rebroadcast it later, after the parent transaction(s)
526 : // have been mined or received.
527 : // 25 orphans, each of which is at most 400,000 bytes big is
528 : // at most 10 megabytes of orphans and somewhat more byprev index (in the worst case):
529 192 : unsigned int sz = tx->GetTotalSize();
530 192 : unsigned int nMaxSize = tx->IsShieldedTx() ? MAX_TX_SIZE_AFTER_SAPLING : MAX_STANDARD_TX_SIZE;
531 192 : if (sz >= nMaxSize) {
532 10 : LogPrint(BCLog::MEMPOOL, "ignoring large orphan tx (size: %u, hash: %s)\n", sz, hash.ToString());
533 10 : return false;
534 : }
535 :
536 182 : auto ret = mapOrphanTransactions.emplace(hash, COrphanTx{tx, peer, GetTime() + ORPHAN_TX_EXPIRE_TIME, g_orphan_list.size()});
537 182 : assert(ret.second);
538 182 : g_orphan_list.emplace_back(ret.first);
539 364 : for (const CTxIn& txin : tx->vin) {
540 182 : mapOrphanTransactionsByPrev[txin.prevout].insert(ret.first);
541 : }
542 :
543 287 : LogPrint(BCLog::MEMPOOL, "stored orphan tx %s (mapsz %u outsz %u)\n", hash.ToString(),
544 : mapOrphanTransactions.size(), mapOrphanTransactionsByPrev.size());
545 : return true;
546 : }
547 :
548 182 : int static EraseOrphanTx(uint256 hash) EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans)
549 : {
550 182 : std::map<uint256, COrphanTx>::iterator it = mapOrphanTransactions.find(hash);
551 182 : if (it == mapOrphanTransactions.end())
552 : return 0;
553 364 : for (const CTxIn& txin : it->second.tx->vin) {
554 182 : auto itPrev = mapOrphanTransactionsByPrev.find(txin.prevout);
555 182 : if (itPrev == mapOrphanTransactionsByPrev.end())
556 0 : continue;
557 182 : itPrev->second.erase(it);
558 182 : if (itPrev->second.empty())
559 182 : mapOrphanTransactionsByPrev.erase(itPrev);
560 : }
561 :
562 182 : size_t old_pos = it->second.list_pos;
563 182 : assert(g_orphan_list[old_pos] == it);
564 182 : if (old_pos + 1 != g_orphan_list.size()) {
565 : // Unless we're deleting the last entry in g_orphan_list, move the last
566 : // entry to the position we're deleting.
567 163 : auto it_last = g_orphan_list.back();
568 163 : g_orphan_list[old_pos] = it_last;
569 163 : it_last->second.list_pos = old_pos;
570 : }
571 182 : g_orphan_list.pop_back();
572 :
573 182 : mapOrphanTransactions.erase(it);
574 182 : return 1;
575 : }
576 :
577 1459 : void EraseOrphansFor(NodeId peer)
578 : {
579 1459 : LOCK(g_cs_orphans);
580 1459 : int nErased = 0;
581 1459 : std::map<uint256, COrphanTx>::iterator iter = mapOrphanTransactions.begin();
582 1709 : while (iter != mapOrphanTransactions.end()) {
583 250 : std::map<uint256, COrphanTx>::iterator maybeErase = iter++; // increment to avoid iterator becoming invalid
584 250 : if (maybeErase->second.fromPeer == peer) {
585 30 : nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
586 : }
587 : }
588 1459 : if (nErased > 0) LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx from peer %d\n", nErased, peer);
589 1459 : }
590 :
591 :
592 108 : unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
593 : {
594 108 : LOCK(g_cs_orphans);
595 :
596 108 : unsigned int nEvicted = 0;
597 108 : static int64_t nNextSweep;
598 108 : int64_t nNow = GetTime();
599 108 : if (nNextSweep <= nNow) {
600 : // Sweep out expired orphan pool entries:
601 2 : int nErased = 0;
602 2 : int64_t nMinExpTime = nNow + ORPHAN_TX_EXPIRE_TIME - ORPHAN_TX_EXPIRE_INTERVAL;
603 2 : auto iter = mapOrphanTransactions.begin();
604 75 : while (iter != mapOrphanTransactions.end()) {
605 73 : auto maybeErase = iter++;
606 73 : if (maybeErase->second.nTimeExpire <= nNow) {
607 0 : nErased += EraseOrphanTx(maybeErase->second.tx->GetHash());
608 : } else {
609 146 : nMinExpTime = std::min(maybeErase->second.nTimeExpire, nMinExpTime);
610 : }
611 : }
612 : // Sweep again 5 minutes after the next entry that expires in order to batch the linear scan.
613 2 : nNextSweep = nMinExpTime + ORPHAN_TX_EXPIRE_INTERVAL;
614 2 : if (nErased > 0) LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx due to expiration\n", nErased);
615 : }
616 108 : FastRandomContext rng;
617 256 : while (mapOrphanTransactions.size() > nMaxOrphans) {
618 : // Evict a random orphan:
619 148 : size_t randompos = rng.randrange(g_orphan_list.size());
620 148 : EraseOrphanTx(g_orphan_list[randompos]->first);
621 148 : ++nEvicted;
622 : }
623 216 : return nEvicted;
624 : }
625 :
626 : // Requires cs_main.
627 96 : void Misbehaving(NodeId pnode, int howmuch, const std::string& message) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
628 : {
629 96 : if (howmuch == 0)
630 1 : return;
631 :
632 96 : CNodeState* state = State(pnode);
633 96 : if (state == nullptr)
634 : return;
635 :
636 95 : state->nMisbehavior += howmuch;
637 95 : int banscore = gArgs.GetArg("-banscore", DEFAULT_BANSCORE_THRESHOLD);
638 190 : std::string message_prefixed = message.empty() ? "" : (": " + message);
639 95 : if (state->nMisbehavior >= banscore && state->nMisbehavior - howmuch < banscore) {
640 44 : LogPrint(BCLog::NET, "%s: %s peer=%d (%d -> %d) BAN THRESHOLD EXCEEDED%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed);
641 44 : state->fShouldBan = true;
642 : } else {
643 51 : LogPrint(BCLog::NET, "%s: %s peer=%d (%d -> %d)%s\n", __func__, state->name, pnode, state->nMisbehavior-howmuch, state->nMisbehavior, message_prefixed);
644 : }
645 : }
646 :
647 : // Requires cs_main.
648 26011 : bool IsBanned(NodeId pnode)
649 : {
650 26011 : CNodeState* state = State(pnode);
651 26011 : if (state == nullptr)
652 : return false;
653 25926 : if (state->fShouldBan) {
654 0 : return true;
655 : }
656 : return false;
657 : }
658 :
659 60 : static void CheckBlockSpam(NodeId nodeId, const uint256& hashBlock)
660 : {
661 : // Block spam filtering
662 120 : if (!gArgs.GetBoolArg("-blockspamfilter", DEFAULT_BLOCK_SPAM_FILTER)) {
663 37 : return;
664 : }
665 :
666 60 : CNodeState* nodestate = nullptr;
667 60 : int blockReceivedHeight = 0;
668 60 : {
669 60 : LOCK(cs_main);
670 60 : nodestate = State(nodeId);
671 97 : if (!nodestate) { return; }
672 :
673 60 : CBlockIndex* pindex = LookupBlockIndex(hashBlock);
674 60 : if (!pindex) { return; }
675 23 : blockReceivedHeight = pindex->nHeight;
676 : }
677 :
678 23 : nodestate->nodeBlocks.onBlockReceived(blockReceivedHeight);
679 23 : bool nodeStatus = true;
680 : // UpdateState will return false if the node is attacking us or update the score and return true.
681 46 : CValidationState state;
682 23 : nodeStatus = nodestate->nodeBlocks.updateState(state, nodeStatus);
683 23 : int nDoS = 0;
684 23 : if (state.IsInvalid(nDoS)) {
685 0 : if (nDoS > 0) {
686 0 : LOCK(cs_main);
687 0 : Misbehaving(nodeId, nDoS);
688 : }
689 : nodeStatus = false;
690 : }
691 :
692 23 : if (!nodeStatus) {
693 0 : LogPrintf("Block spam protection: %s\n", hashBlock.ToString());
694 : }
695 : }
696 :
697 :
698 : //////////////////////////////////////////////////////////////////////////////
699 : //
700 : // blockchain -> download logic notification
701 : //
702 :
703 484 : PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn) :
704 484 : connman(connmanIn)
705 : {
706 : // Initialize global variables that cannot be constructed at startup.
707 484 : recentRejects.reset(new CRollingBloomFilter(120000, 0.000001));
708 484 : }
709 :
710 38884 : void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
711 : {
712 38884 : LOCK(g_cs_orphans);
713 :
714 77768 : std::vector<uint256> vOrphanErase;
715 :
716 336640 : for (const CTransactionRef& ptx : pblock->vtx) {
717 297756 : const CTransaction& tx = *ptx;
718 :
719 : // Which orphan pool entries must we evict?
720 803630 : for (size_t j = 0; j < tx.vin.size(); j++) {
721 505874 : auto itByPrev = mapOrphanTransactionsByPrev.find(tx.vin[j].prevout);
722 505874 : if (itByPrev == mapOrphanTransactionsByPrev.end()) continue;
723 0 : for (auto mi = itByPrev->second.begin(); mi != itByPrev->second.end(); ++mi) {
724 0 : const CTransaction& orphanTx = *(*mi)->second.tx;
725 0 : const uint256& orphanHash = orphanTx.GetHash();
726 0 : vOrphanErase.emplace_back(orphanHash);
727 : }
728 : }
729 : }
730 :
731 : // Erase orphan transactions include or precluded by this block
732 38884 : if (!vOrphanErase.empty()) {
733 0 : int nErased = 0;
734 0 : for (uint256& orphanHash : vOrphanErase) {
735 0 : nErased += EraseOrphanTx(orphanHash);
736 : }
737 0 : LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx included or conflicted by block\n", nErased);
738 : }
739 38884 : }
740 :
741 38794 : void PeerLogicValidation::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload)
742 : {
743 38794 : const int nNewHeight = pindexNew->nHeight;
744 38794 : connman->SetBestHeight(nNewHeight);
745 :
746 38794 : if (!fInitialDownload) {
747 38235 : const uint256& hashNewTip = pindexNew->GetBlockHash();
748 : // Relay inventory, but don't relay old inventory during initial block download.
749 38235 : connman->ForEachNode([nNewHeight, hashNewTip](CNode* pnode) {
750 : // Don't sync from MN only connections.
751 184125 : if (!pnode->CanRelay()) {
752 : return;
753 : }
754 184082 : if (nNewHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : 0)) {
755 184082 : pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
756 : }
757 : });
758 : }
759 38794 : }
760 :
761 38956 : void PeerLogicValidation::BlockChecked(const CBlock& block, const CValidationState& state)
762 : {
763 38956 : LOCK(cs_main);
764 :
765 38956 : const uint256& hash = block.GetHash();
766 38956 : std::map<uint256, NodeId>::iterator it = mapBlockSource.find(hash);
767 :
768 38956 : int nDoS = 0;
769 38956 : if (state.IsInvalid(nDoS)) {
770 69 : if (it != mapBlockSource.end() && State(it->second)) {
771 60 : assert (state.GetRejectCode() < REJECT_INTERNAL); // Blocks are never rejected with internal reject codes
772 60 : if (nDoS > 0) {
773 116 : Misbehaving(it->second, nDoS);
774 : }
775 :
776 : // Spam filter
777 60 : CheckBlockSpam(it->second, block.GetHash());
778 : }
779 : }
780 :
781 38956 : if (it != mapBlockSource.end())
782 25708 : mapBlockSource.erase(it);
783 38956 : }
784 :
785 : //////////////////////////////////////////////////////////////////////////////
786 : //
787 : // Messages
788 : //
789 :
790 356161 : bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
791 : {
792 356161 : switch (inv.type) {
793 23509 : case MSG_TX: {
794 23509 : assert(recentRejects);
795 47018 : if (chainActive.Tip()->GetBlockHash() != hashRecentRejectsChainTip) {
796 : // If the chain tip has changed previously rejected transactions
797 : // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
798 : // or a double-spend. Reset the rejects filter and give those
799 : // txs a second chance.
800 1360 : hashRecentRejectsChainTip = chainActive.Tip()->GetBlockHash();
801 680 : recentRejects->reset();
802 : }
803 :
804 23509 : {
805 23509 : LOCK(g_cs_orphans);
806 47021 : if (mapOrphanTransactions.count(inv.hash)) return true;
807 : }
808 :
809 47012 : return recentRejects->contains(inv.hash) ||
810 42864 : mempool.exists(inv.hash) ||
811 62075 : pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
812 42717 : pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 1));
813 : }
814 :
815 187483 : case MSG_BLOCK:
816 187483 : return LookupBlockIndex(inv.hash) != nullptr;
817 : case MSG_TXLOCK_REQUEST:
818 : // deprecated
819 : return true;
820 : case MSG_TXLOCK_VOTE:
821 : // deprecated
822 : return true;
823 2307 : case MSG_SPORK:
824 4614 : return mapSporks.count(inv.hash);
825 4083 : case MSG_MASTERNODE_WINNER:
826 6306 : if (masternodePayments.mapMasternodePayeeVotes.count(inv.hash)) {
827 1860 : g_tiertwo_sync_state.AddedMasternodeWinner(inv.hash);
828 1860 : return true;
829 : }
830 : return false;
831 474 : case MSG_BUDGET_VOTE:
832 474 : if (g_budgetman.HaveSeenProposalVote(inv.hash)) {
833 377 : g_tiertwo_sync_state.AddedBudgetItem(inv.hash);
834 377 : return true;
835 : }
836 : return false;
837 5662 : case MSG_BUDGET_PROPOSAL:
838 5662 : if (g_budgetman.HaveProposal(inv.hash)) {
839 5249 : g_tiertwo_sync_state.AddedBudgetItem(inv.hash);
840 5249 : return true;
841 : }
842 : return false;
843 452 : case MSG_BUDGET_FINALIZED_VOTE:
844 452 : if (g_budgetman.HaveSeenFinalizedBudgetVote(inv.hash)) {
845 367 : g_tiertwo_sync_state.AddedBudgetItem(inv.hash);
846 367 : return true;
847 : }
848 : return false;
849 357 : case MSG_BUDGET_FINALIZED:
850 357 : if (g_budgetman.HaveFinalizedBudget(inv.hash)) {
851 324 : g_tiertwo_sync_state.AddedBudgetItem(inv.hash);
852 324 : return true;
853 : }
854 : return false;
855 330 : case MSG_MASTERNODE_ANNOUNCE:
856 504 : if (mnodeman.mapSeenMasternodeBroadcast.count(inv.hash)) {
857 156 : g_tiertwo_sync_state.AddedMasternodeList(inv.hash);
858 156 : return true;
859 : }
860 : return false;
861 109977 : case MSG_MASTERNODE_PING:
862 219954 : return mnodeman.mapSeenMasternodePing.count(inv.hash);
863 1686 : case MSG_QUORUM_FINAL_COMMITMENT:
864 1686 : return llmq::quorumBlockProcessor->HasMinableCommitment(inv.hash);
865 1038 : case MSG_QUORUM_CONTRIB:
866 1038 : case MSG_QUORUM_COMPLAINT:
867 1038 : case MSG_QUORUM_JUSTIFICATION:
868 1038 : case MSG_QUORUM_PREMATURE_COMMITMENT:
869 1038 : return llmq::quorumDKGSessionManager->AlreadyHave(inv);
870 8960 : case MSG_QUORUM_RECOVERED_SIG:
871 8960 : return llmq::quorumSigningManager->AlreadyHave(inv);
872 9843 : case MSG_CLSIG:
873 9843 : return llmq::chainLocksHandler->AlreadyHave(inv);
874 : }
875 :
876 : // Don't know what it is, just say we already got one
877 : return true;
878 : }
879 :
880 9370 : static void RelayTransaction(const CTransaction& tx, CConnman* connman)
881 : {
882 9370 : CInv inv(MSG_TX, tx.GetHash());
883 9370 : connman->RelayInv(inv);
884 9370 : }
885 :
886 21 : static void RelayAddress(const CAddress& addr, bool fReachable, CConnman* connman)
887 : {
888 21 : if (!fReachable && !addr.IsRelayable()) return;
889 21 : unsigned int nRelayNodes = fReachable ? 2 : 1; // limited relaying of addresses outside our network(s)
890 :
891 : // Relay to a limited number of other nodes
892 : // Use deterministic randomness to send to the same nodes for 24 hours
893 : // at a time so the addrKnowns of the chosen nodes prevent repeats
894 21 : uint64_t hashAddr = addr.GetHash();
895 21 : const CSipHasher hasher = connman->GetDeterministicRandomizer(RANDOMIZER_ID_ADDRESS_RELAY).Write(hashAddr << 32).Write((GetTime() + hashAddr) / (24*60*60));
896 21 : FastRandomContext insecure_rand;
897 :
898 21 : std::array<std::pair<uint64_t, CNode*>,2> best{{{0, nullptr}, {0, nullptr}}};
899 :
900 41 : auto sortfunc = [&best, &hasher, nRelayNodes](CNode* pnode) {
901 41 : uint64_t hashKey = CSipHasher(hasher).Write(pnode->GetId()).Finalize();
902 53 : for (unsigned int i = 0; i < nRelayNodes; i++) {
903 53 : if (hashKey > best[i].first) {
904 41 : std::copy(best.begin() + i, best.begin() + nRelayNodes - 1, best.begin() + i + 1);
905 41 : best[i] = std::make_pair(hashKey, pnode);
906 41 : break;
907 : }
908 : }
909 41 : };
910 :
911 187 : auto pushfunc = [&addr, &best, nRelayNodes, &insecure_rand] {
912 62 : for (unsigned int i = 0; i < nRelayNodes && best[i].first != 0; i++) {
913 41 : best[i].second->PushAddress(addr, insecure_rand);
914 : }
915 42 : };
916 :
917 21 : connman->ForEachNodeThen(std::move(sortfunc), std::move(pushfunc));
918 : }
919 :
920 6400 : bool static PushTierTwoGetDataRequest(const CInv& inv,
921 : CNode* pfrom,
922 : CConnman* connman,
923 : CNetMsgMaker& msgMaker)
924 : {
925 6400 : if (inv.type == MSG_SPORK) {
926 184 : if (mapSporks.count(inv.hash)) {
927 368 : CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
928 184 : ss.reserve(1000);
929 184 : ss << mapSporks[inv.hash];
930 184 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::SPORK, ss));
931 184 : return true;
932 : }
933 : }
934 :
935 6216 : if (inv.type == MSG_QUORUM_FINAL_COMMITMENT) {
936 : // Only respond if v6.0.0 is enforced and SPORK 22 is not active
937 96 : if (!deterministicMNManager->IsDIP3Enforced()) return false;
938 96 : if (sporkManager.IsSporkActive(SPORK_22_LLMQ_DKG_MAINTENANCE)) return false;
939 96 : llmq::CFinalCommitment o;
940 96 : if (llmq::quorumBlockProcessor->GetMinableCommitmentByHash(inv.hash, o)) {
941 96 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QFCOMMITMENT, o));
942 192 : return true;
943 : }
944 : }
945 :
946 6120 : if (inv.type == MSG_QUORUM_CONTRIB) {
947 : // Only respond if v6.0.0 is enforced.
948 247 : if (!deterministicMNManager->IsDIP3Enforced()) return false;
949 131 : llmq::CDKGContribution o;
950 126 : if (llmq::quorumDKGSessionManager->GetContribution(inv.hash, o)) {
951 121 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCONTRIB, o));
952 121 : return true;
953 : }
954 : }
955 :
956 5999 : if (inv.type == MSG_QUORUM_COMPLAINT) {
957 : // Only respond if v6.0.0 is enforced.
958 33 : if (!deterministicMNManager->IsDIP3Enforced()) return false;
959 40 : llmq::CDKGComplaint o;
960 33 : if (llmq::quorumDKGSessionManager->GetComplaint(inv.hash, o)) {
961 26 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QCOMPLAINT, o));
962 52 : return true;
963 : }
964 : }
965 :
966 5973 : if (inv.type == MSG_QUORUM_JUSTIFICATION) {
967 : // Only respond if v6.0.0 is enforced.
968 8 : if (!deterministicMNManager->IsDIP3Enforced()) return false;
969 8 : llmq::CDKGJustification o;
970 8 : if (llmq::quorumDKGSessionManager->GetJustification(inv.hash, o)) {
971 8 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QJUSTIFICATION, o));
972 8 : return true;
973 : }
974 : }
975 :
976 5965 : if (inv.type == MSG_QUORUM_PREMATURE_COMMITMENT) {
977 : // Only respond if v6.0.0 is enforced.
978 104 : if (!deterministicMNManager->IsDIP3Enforced()) return false;
979 104 : llmq::CDKGPrematureCommitment o;
980 104 : if (llmq::quorumDKGSessionManager->GetPrematureCommitment(inv.hash, o)) {
981 104 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QPCOMMITMENT, o));
982 208 : return true;
983 : }
984 : }
985 :
986 : // !TODO: remove when transition to DMN is complete
987 5861 : if (inv.type == MSG_MASTERNODE_WINNER && !deterministicMNManager->LegacyMNObsolete()) {
988 933 : if (masternodePayments.mapMasternodePayeeVotes.count(inv.hash)) {
989 1866 : CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
990 933 : ss.reserve(1000);
991 933 : ss << masternodePayments.mapMasternodePayeeVotes[inv.hash];
992 933 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::MNWINNER, ss));
993 933 : return true;
994 : }
995 : }
996 :
997 4928 : if (inv.type == MSG_BUDGET_VOTE) {
998 38 : if (g_budgetman.HaveSeenProposalVote(inv.hash)) {
999 38 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::BUDGETVOTE, g_budgetman.GetProposalVoteSerialized(inv.hash)));
1000 38 : return true;
1001 : }
1002 : }
1003 :
1004 4890 : if (inv.type == MSG_BUDGET_PROPOSAL) {
1005 163 : if (g_budgetman.HaveProposal(inv.hash)) {
1006 163 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::BUDGETPROPOSAL, g_budgetman.GetProposalSerialized(inv.hash)));
1007 163 : return true;
1008 : }
1009 : }
1010 :
1011 4727 : if (inv.type == MSG_BUDGET_FINALIZED_VOTE) {
1012 31 : if (g_budgetman.HaveSeenFinalizedBudgetVote(inv.hash)) {
1013 31 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::FINALBUDGETVOTE, g_budgetman.GetFinalizedBudgetVoteSerialized(inv.hash)));
1014 31 : return true;
1015 : }
1016 : }
1017 :
1018 4696 : if (inv.type == MSG_BUDGET_FINALIZED) {
1019 13 : if (g_budgetman.HaveFinalizedBudget(inv.hash)) {
1020 13 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::FINALBUDGET, g_budgetman.GetFinalizedBudgetSerialized(inv.hash)));
1021 13 : return true;
1022 : }
1023 : }
1024 :
1025 : // !TODO: remove when transition to DMN is complete
1026 4683 : if (inv.type == MSG_MASTERNODE_ANNOUNCE && !deterministicMNManager->LegacyMNObsolete()) {
1027 68 : auto it = mnodeman.mapSeenMasternodeBroadcast.find(inv.hash);
1028 68 : if (it != mnodeman.mapSeenMasternodeBroadcast.end()) {
1029 68 : const auto& mnb = it->second;
1030 :
1031 68 : int version = !mnb.addr.IsAddrV1Compatible() ? PROTOCOL_VERSION | ADDRV2_FORMAT : PROTOCOL_VERSION;
1032 136 : CDataStream ss(SER_NETWORK, version);
1033 68 : ss.reserve(1000);
1034 68 : ss << mnb;
1035 136 : std::string msgType = !mnb.addr.IsAddrV1Compatible() ? NetMsgType::MNBROADCAST2 : NetMsgType::MNBROADCAST;
1036 136 : connman->PushMessage(pfrom, msgMaker.Make(msgType, ss));
1037 68 : return true;
1038 : }
1039 : }
1040 :
1041 : // !TODO: remove when transition to DMN is complete
1042 4615 : if (inv.type == MSG_MASTERNODE_PING && !deterministicMNManager->LegacyMNObsolete()) {
1043 2135 : if (mnodeman.mapSeenMasternodePing.count(inv.hash)) {
1044 4250 : CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1045 2125 : ss.reserve(1000);
1046 2125 : ss << mnodeman.mapSeenMasternodePing[inv.hash];
1047 2125 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::MNPING, ss));
1048 2125 : return true;
1049 : }
1050 : }
1051 2490 : if (inv.type == MSG_QUORUM_RECOVERED_SIG) {
1052 1721 : if (!deterministicMNManager->IsDIP3Enforced()) return false;
1053 1721 : llmq::CRecoveredSig o;
1054 1721 : if (llmq::quorumSigningManager->GetRecoveredSigForGetData(inv.hash, o)) {
1055 1721 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::QSIGREC, o));
1056 3442 : return true;
1057 : }
1058 : }
1059 769 : if (inv.type == MSG_CLSIG) {
1060 727 : llmq::CChainLockSig o;
1061 727 : if (llmq::chainLocksHandler->GetChainLockByHash(inv.hash, o)) {
1062 727 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::CLSIG, o));
1063 : }
1064 : }
1065 : // nothing was pushed.
1066 : return false;
1067 : }
1068 :
1069 50384 : void static ProcessGetBlockData(CNode* pfrom, const CInv& inv, CConnman* connman, const std::atomic<bool>& interruptMsgProc)
1070 : {
1071 50384 : LOCK(cs_main);
1072 50384 : CNetMsgMaker msgMaker(pfrom->GetSendVersion());
1073 :
1074 50384 : bool send = false;
1075 50384 : CBlockIndex* pindex = LookupBlockIndex(inv.hash);
1076 50384 : if (pindex) {
1077 100768 : if (chainActive.Contains(pindex)) {
1078 : send = true;
1079 : } else {
1080 : // To prevent fingerprinting attacks, only send blocks outside of the active
1081 : // chain if they are valid, and no more than a max reorg depth than the best header
1082 : // chain we know about.
1083 0 : send = pindex->IsValid(BLOCK_VALID_SCRIPTS) && pindexBestHeader &&
1084 0 : (chainActive.Height() - pindex->nHeight < gArgs.GetArg("-maxreorg", DEFAULT_MAX_REORG_DEPTH));
1085 0 : if (!send) {
1086 0 : LogPrint(BCLog::NET, "ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
1087 : }
1088 : }
1089 : }
1090 : // Don't send not-validated blocks
1091 50384 : if (send && (pindex->nStatus & BLOCK_HAVE_DATA)) {
1092 : // Send block from disk
1093 100768 : CBlock block;
1094 50384 : if (!ReadBlockFromDisk(block, pindex))
1095 0 : assert(!"cannot load block from disk");
1096 50384 : if (inv.type == MSG_BLOCK)
1097 50384 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::BLOCK, block));
1098 : else // MSG_FILTERED_BLOCK)
1099 : {
1100 0 : bool send_ = false;
1101 0 : CMerkleBlock merkleBlock;
1102 0 : {
1103 0 : LOCK(pfrom->cs_filter);
1104 0 : if (pfrom->pfilter) {
1105 0 : send_ = true;
1106 0 : merkleBlock = CMerkleBlock(block, *pfrom->pfilter);
1107 : }
1108 : }
1109 0 : if (send_) {
1110 0 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::MERKLEBLOCK, merkleBlock));
1111 : // CMerkleBlock just contains hashes, so also push any transactions in the block the client did not see
1112 : // This avoids hurting performance by pointlessly requiring a round-trip
1113 : // Note that there is currently no way for a node to request any single transactions we didn't send here -
1114 : // they must either disconnect and retry or request the full block.
1115 : // Thus, the protocol spec specified allows for us to provide duplicate txn here,
1116 : // however we MUST always provide at least what the remote peer needs
1117 0 : for (std::pair<unsigned int, uint256>& pair : merkleBlock.vMatchedTxn)
1118 0 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::TX, *block.vtx[pair.first]));
1119 : }
1120 : // else
1121 : // no response
1122 : }
1123 :
1124 : // Trigger them to send a getblocks request for the next batch of inventory
1125 50384 : if (inv.hash == pfrom->hashContinue) {
1126 : // Bypass PushInventory, this must send even if redundant,
1127 : // and we want it right after the last block so they don't
1128 : // wait for other stuff first.
1129 0 : std::vector<CInv> vInv;
1130 0 : vInv.emplace_back(MSG_BLOCK, chainActive.Tip()->GetBlockHash());
1131 0 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::INV, vInv));
1132 0 : pfrom->hashContinue.SetNull();
1133 : }
1134 : }
1135 50384 : }
1136 :
1137 : // Only return true if the inv type can be answered, not supported types return false.
1138 56759 : bool static IsTierTwoInventoryTypeKnown(int type)
1139 : {
1140 56759 : return type == MSG_SPORK ||
1141 56759 : type == MSG_MASTERNODE_WINNER ||
1142 56759 : type == MSG_BUDGET_VOTE ||
1143 55604 : type == MSG_BUDGET_PROPOSAL ||
1144 : type == MSG_BUDGET_FINALIZED ||
1145 55428 : type == MSG_BUDGET_FINALIZED_VOTE ||
1146 55428 : type == MSG_MASTERNODE_ANNOUNCE ||
1147 55329 : type == MSG_MASTERNODE_PING ||
1148 55329 : type == MSG_QUORUM_FINAL_COMMITMENT ||
1149 53103 : type == MSG_QUORUM_CONTRIB ||
1150 : type == MSG_QUORUM_COMPLAINT ||
1151 52944 : type == MSG_QUORUM_JUSTIFICATION ||
1152 : type == MSG_QUORUM_PREMATURE_COMMITMENT ||
1153 109591 : type == MSG_QUORUM_RECOVERED_SIG ||
1154 56759 : type == MSG_CLSIG;
1155 : }
1156 :
1157 56438 : void static ProcessGetData(CNode* pfrom, CConnman* connman, const std::atomic<bool>& interruptMsgProc)
1158 : {
1159 56438 : AssertLockNotHeld(cs_main);
1160 :
1161 56438 : std::deque<CInv>::iterator it = pfrom->vRecvGetData.begin();
1162 112876 : std::vector<CInv> vNotFound;
1163 56438 : CNetMsgMaker msgMaker(pfrom->GetSendVersion());
1164 56438 : {
1165 56438 : LOCK(cs_main);
1166 :
1167 72207 : while (it != pfrom->vRecvGetData.end() && (it->type == MSG_TX || IsTierTwoInventoryTypeKnown(it->type))) {
1168 15769 : if (interruptMsgProc)
1169 0 : return;
1170 : // Don't bother if send buffer is too full to respond anyway
1171 15769 : if (pfrom->fPauseSend)
1172 : break;
1173 :
1174 15769 : const CInv &inv = *it;
1175 15769 : it++;
1176 :
1177 : // Send stream from relay memory
1178 15769 : bool pushed = false;
1179 15769 : if (inv.type == MSG_TX) {
1180 9394 : auto txinfo = mempool.info(inv.hash);
1181 9394 : if (txinfo.tx) { // future: add timeLastMempoolReq check
1182 18738 : CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
1183 9369 : ss.reserve(1000);
1184 9369 : ss << *txinfo.tx;
1185 9369 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::TX, ss));
1186 9369 : pushed = true;
1187 : }
1188 : }
1189 :
1190 9394 : if (!pushed) {
1191 : // Now check if it's a tier two data request and push it.
1192 6400 : pushed = PushTierTwoGetDataRequest(inv, pfrom, connman, msgMaker);
1193 : }
1194 :
1195 15769 : if (!pushed) {
1196 769 : vNotFound.push_back(inv);
1197 : }
1198 :
1199 : // todo: inventory signal
1200 : }
1201 : } // release cs_main
1202 :
1203 56438 : if (it != pfrom->vRecvGetData.end() && !pfrom->fPauseSend) {
1204 50384 : const CInv &inv = *it;
1205 50384 : if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) {
1206 50384 : it++;
1207 50384 : ProcessGetBlockData(pfrom, inv, connman, interruptMsgProc);
1208 : }
1209 : }
1210 :
1211 56438 : pfrom->vRecvGetData.erase(pfrom->vRecvGetData.begin(), it);
1212 :
1213 56438 : if (!vNotFound.empty()) {
1214 : // Let the peer know that we didn't find what it asked for, so it doesn't
1215 : // have to wait around forever. Currently only SPV clients actually care
1216 : // about this message: it's needed when they are recursively walking the
1217 : // dependencies of relevant unconfirmed transactions. SPV clients want to
1218 : // do that because they want to know about (and store and rebroadcast and
1219 : // risk analyze) the dependencies of transactions relevant to them, without
1220 : // having to download the entire memory pool.
1221 755 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::NOTFOUND, vNotFound));
1222 : }
1223 : }
1224 :
1225 : bool fRequestedSporksIDB = false;
1226 378827 : bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vRecv, int64_t nTimeReceived, CConnman* connman, std::atomic<bool>& interruptMsgProc)
1227 : {
1228 751851 : LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->GetId());
1229 757654 : if (gArgs.IsArgSet("-dropmessagestest") && GetRand(gArgs.GetArg("-dropmessagestest", 0)) == 0) {
1230 0 : LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
1231 0 : return true;
1232 : }
1233 :
1234 378827 : if (strCommand == NetMsgType::VERSION) {
1235 : // Each connection can only send one version message
1236 1364 : if (pfrom->nVersion != 0) {
1237 0 : LOCK(cs_main);
1238 0 : Misbehaving(pfrom->GetId(), 1);
1239 0 : return false;
1240 : }
1241 :
1242 1364 : int64_t nTime;
1243 2728 : CAddress addrMe;
1244 2728 : CAddress addrFrom;
1245 1364 : uint64_t nNonce = 1;
1246 1364 : uint64_t nServiceInt;
1247 1364 : ServiceFlags nServices;
1248 1364 : int nVersion;
1249 1364 : int nSendVersion;
1250 2728 : std::string strSubVer;
1251 1364 : std::string cleanSubVer;
1252 1364 : int nStartingHeight = -1;
1253 1364 : bool fRelay = true;
1254 1364 : vRecv >> nVersion >> nServiceInt >> nTime >> addrMe;
1255 1364 : nSendVersion = std::min(nVersion, PROTOCOL_VERSION);
1256 1364 : nServices = ServiceFlags(nServiceInt);
1257 1364 : if (!pfrom->fInbound) {
1258 648 : connman->SetServices(pfrom->addr, nServices);
1259 : }
1260 1364 : if (pfrom->nServicesExpected & ~nServices) {
1261 0 : LogPrint(BCLog::NET, "peer=%d does not offer the expected services (%08x offered, %08x expected); disconnecting\n", pfrom->GetId(), nServices, pfrom->nServicesExpected);
1262 0 : pfrom->fDisconnect = true;
1263 0 : return false;
1264 : }
1265 :
1266 1364 : if (pfrom->DisconnectOldProtocol(nVersion, ActiveProtocol())) {
1267 : return false;
1268 : }
1269 :
1270 1363 : if (nVersion == 10300)
1271 0 : nVersion = 300;
1272 1363 : if (!vRecv.empty())
1273 1363 : vRecv >> addrFrom >> nNonce;
1274 1363 : if (!vRecv.empty()) {
1275 1363 : vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
1276 1363 : cleanSubVer = SanitizeString(strSubVer);
1277 : }
1278 1363 : if (!vRecv.empty()) {
1279 1363 : vRecv >> nStartingHeight;
1280 : }
1281 1363 : if (!vRecv.empty()) {
1282 1363 : vRecv >> fRelay;
1283 : }
1284 : // Check if this is a quorum connection
1285 1363 : if (!vRecv.empty()) {
1286 627 : WITH_LOCK(pfrom->cs_mnauth, vRecv >> pfrom->receivedMNAuthChallenge;);
1287 209 : bool fOtherMasternode = !pfrom->receivedMNAuthChallenge.IsNull();
1288 209 : if (pfrom->fInbound) {
1289 105 : pfrom->m_masternode_connection = fOtherMasternode;
1290 105 : if (fOtherMasternode) {
1291 105 : LogPrint(BCLog::NET, "peer=%d is an inbound masternode connection, not relaying anything to it\n", pfrom->GetId());
1292 105 : if (!fMasterNode) { // global MN flag
1293 1 : LogPrint(BCLog::NET, "but we're not a masternode, disconnecting\n");
1294 1 : pfrom->fDisconnect = true;
1295 1 : return true;
1296 : }
1297 : }
1298 : }
1299 : }
1300 :
1301 : // Disconnect if we connected to ourself
1302 1362 : if (pfrom->fInbound && !connman->CheckIncomingNonce(nNonce)) {
1303 0 : LogPrintf("connected to self at %s, disconnecting\n", pfrom->addr.ToString());
1304 0 : pfrom->fDisconnect = true;
1305 0 : return true;
1306 : }
1307 :
1308 1362 : if (pfrom->fInbound && addrMe.IsRoutable()) {
1309 0 : SeenLocal(addrMe);
1310 : }
1311 :
1312 : // Be shy and don't send version until we hear
1313 1362 : if (pfrom->fInbound)
1314 714 : PushNodeVersion(pfrom, connman, GetAdjustedTime());
1315 :
1316 1362 : CNetMsgMaker msg_maker(INIT_PROTO_VERSION);
1317 :
1318 1362 : if (nVersion >= 70923) {
1319 : // BIP155 defines addrv2 and sendaddrv2 for all protocol versions, but some
1320 : // implementations reject messages they don't know. As a courtesy, don't send
1321 : // it to nodes with a version before 70923 (v5.2.99), as no software is known to support
1322 : // BIP155 that doesn't announce at least that protocol version number.
1323 :
1324 1362 : connman->PushMessage(pfrom, msg_maker.Make(NetMsgType::SENDADDRV2));
1325 : }
1326 :
1327 1362 : connman->PushMessage(pfrom, msg_maker.Make(NetMsgType::VERACK));
1328 :
1329 1362 : pfrom->nServices = nServices;
1330 1362 : pfrom->SetAddrLocal(addrMe);
1331 1362 : {
1332 1362 : LOCK(pfrom->cs_SubVer);
1333 1362 : pfrom->strSubVer = strSubVer;
1334 1362 : pfrom->cleanSubVer = cleanSubVer;
1335 : }
1336 1362 : pfrom->nStartingHeight = nStartingHeight;
1337 1362 : pfrom->fClient = !(nServices & NODE_NETWORK);
1338 :
1339 1362 : {
1340 1362 : LOCK(pfrom->cs_filter);
1341 1362 : pfrom->fRelayTxes = fRelay; // set to true after we get the first filter* message
1342 : }
1343 :
1344 : // Change version
1345 1362 : pfrom->SetSendVersion(nSendVersion);
1346 1362 : pfrom->nVersion = nVersion;
1347 :
1348 1362 : {
1349 1362 : LOCK(cs_main);
1350 : // Potentially mark this peer as a preferred download peer.
1351 1362 : UpdatePreferredDownload(pfrom, State(pfrom->GetId()));
1352 : }
1353 :
1354 1362 : if (!pfrom->fInbound) {
1355 : // Advertise our address
1356 648 : if (fListen && !IsInitialBlockDownload()) {
1357 436 : CAddress addr = GetLocalAddress(&pfrom->addr, pfrom->GetLocalServices());
1358 218 : FastRandomContext insecure_rand;
1359 218 : if (addr.IsRoutable()) {
1360 0 : LogPrintf("ProcessMessages: advertising address %s\n", addr.ToString());
1361 0 : pfrom->PushAddress(addr, insecure_rand);
1362 218 : } else if (IsPeerAddrLocalGood(pfrom)) {
1363 0 : addr.SetIP(addrMe);
1364 0 : LogPrintf("ProcessMessages: advertising address %s\n", addr.ToString());
1365 0 : pfrom->PushAddress(addr, insecure_rand);
1366 : }
1367 : }
1368 :
1369 : // Get recent addresses
1370 648 : connman->PushMessage(pfrom, CNetMsgMaker(nSendVersion).Make(NetMsgType::GETADDR));
1371 648 : pfrom->fGetAddr = true;
1372 : // When requesting a getaddr, accept an additional MAX_ADDR_TO_SEND addresses in response
1373 : // (bypassing the MAX_ADDR_PROCESSING_TOKEN_BUCKET limit).
1374 648 : pfrom->m_addr_token_bucket += MAX_ADDR_TO_SEND;
1375 648 : connman->MarkAddressGood(pfrom->addr);
1376 : }
1377 :
1378 2726 : std::string remoteAddr;
1379 1362 : if (fLogIPs)
1380 0 : remoteAddr = ", peeraddr=" + pfrom->addr.ToString();
1381 :
1382 2700 : LogPrint(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, peer=%d%s\n",
1383 : cleanSubVer, pfrom->nVersion,
1384 : pfrom->nStartingHeight, addrMe.ToString(), pfrom->GetId(),
1385 : remoteAddr);
1386 :
1387 1362 : int64_t nTimeOffset = nTime - GetTime();
1388 1362 : pfrom->nTimeOffset = nTimeOffset;
1389 1362 : const int nTimeSlotLength = Params().GetConsensus().nTimeSlotLength;
1390 1362 : if (abs64(nTimeOffset) < 2 * nTimeSlotLength) {
1391 1360 : AddTimeData(pfrom->addr, nTimeOffset, nTimeSlotLength);
1392 : } else {
1393 4 : LogPrintf("timeOffset (%d seconds) too large. Disconnecting node %s\n",
1394 2 : nTimeOffset, pfrom->addr.ToString().c_str());
1395 2 : pfrom->fDisconnect = true;
1396 2 : CheckOffsetDisconnectedPeers(pfrom->addr);
1397 : }
1398 :
1399 : // Feeler connections exist only to verify if address is online.
1400 1362 : if (pfrom->fFeeler) {
1401 0 : assert(pfrom->fInbound == false);
1402 0 : pfrom->fDisconnect = true;
1403 : }
1404 :
1405 : // PIVX: We use certain sporks during IBD, so check to see if they are
1406 : // available. If not, ask the first peer connected for them.
1407 : // TODO: Move this to an instant broadcast of the sporks.
1408 1362 : bool fMissingSporks = !pSporkDB->SporkExists(SPORK_14_NEW_PROTOCOL_ENFORCEMENT) ||
1409 0 : !pSporkDB->SporkExists(SPORK_15_NEW_PROTOCOL_ENFORCEMENT_2) ||
1410 1362 : !pSporkDB->SporkExists(SPORK_19_COLDSTAKING_MAINTENANCE) ||
1411 0 : !pSporkDB->SporkExists(SPORK_20_SAPLING_MAINTENANCE);
1412 :
1413 0 : if (fMissingSporks || !fRequestedSporksIDB){
1414 1362 : LogPrintf("asking peer for sporks\n");
1415 1362 : connman->PushMessage(pfrom, CNetMsgMaker(nSendVersion).Make(NetMsgType::GETSPORKS));
1416 1362 : fRequestedSporksIDB = true;
1417 : }
1418 :
1419 1362 : return true;
1420 : }
1421 :
1422 :
1423 377463 : else if (pfrom->nVersion == 0) {
1424 : // Must have a version message before anything else
1425 24 : LOCK(cs_main);
1426 12 : Misbehaving(pfrom->GetId(), 1);
1427 12 : return false;
1428 : }
1429 :
1430 : // At this point, the outgoing message serialization version can't change.
1431 377451 : CNetMsgMaker msgMaker(pfrom->GetSendVersion());
1432 :
1433 377451 : if (strCommand == NetMsgType::VERACK) {
1434 1358 : pfrom->SetRecvVersion(std::min(pfrom->nVersion.load(), PROTOCOL_VERSION));
1435 :
1436 1358 : if (!pfrom->fInbound) {
1437 : // Mark this node as currently connected, so we update its timestamp later.
1438 1296 : LOCK(cs_main);
1439 648 : State(pfrom->GetId())->fCurrentlyConnected = true;
1440 : }
1441 :
1442 1358 : if (pfrom->nVersion >= MNAUTH_NODE_VER_VERSION && !pfrom->m_masternode_probe_connection) {
1443 : // Only relayed if this is a mn connection
1444 1309 : CMNAuth::PushMNAUTH(pfrom, *connman);
1445 : }
1446 :
1447 1358 : pfrom->fSuccessfullyConnected = true;
1448 1358 : LogPrintf("New outbound peer connected: version: %d, blocks=%d, peer=%d%s\n",
1449 1358 : pfrom->nVersion.load(), pfrom->nStartingHeight, pfrom->GetId(),
1450 2716 : (fLogIPs ? strprintf(", peeraddr=%s", pfrom->addr.ToString()) : ""));
1451 1358 : return true;
1452 : }
1453 :
1454 376093 : else if (strCommand == NetMsgType::SENDADDRV2) {
1455 1297 : pfrom->m_wants_addrv2 = true;
1456 1297 : return true;
1457 : }
1458 :
1459 374796 : else if (!pfrom->fSuccessfullyConnected)
1460 : {
1461 : // Must have a verack message before anything else
1462 8 : LOCK(cs_main);
1463 4 : Misbehaving(pfrom->GetId(), 1);
1464 4 : return false;
1465 : }
1466 :
1467 374792 : else if (strCommand == NetMsgType::QSENDRECSIGS) {
1468 108 : bool b;
1469 108 : vRecv >> b;
1470 108 : if (pfrom->m_wants_recsigs == b) return true;
1471 : // Only accept recsigs messages every 20 min to prevent spam.
1472 108 : int64_t nNow = GetAdjustedTime();
1473 108 : if (pfrom->m_last_wants_recsigs_recv > 0 &&
1474 0 : nNow - pfrom->m_last_wants_recsigs_recv < 20 * 60) {
1475 0 : LOCK(cs_main);
1476 0 : Misbehaving(pfrom->GetId(), 20, "sendrecssigs msg is only accepted every 20 minutes");
1477 0 : return false;
1478 : }
1479 108 : pfrom->m_wants_recsigs = b;
1480 108 : pfrom->m_last_wants_recsigs_recv = nNow;
1481 : // Check if this is a iqr connection, and update the value
1482 : // if we haven't updated the connection during:
1483 : // (1) the relay quorum set function call, and (2) the verack receive.
1484 108 : connman->UpdateQuorumRelayMemberIfNeeded(pfrom);
1485 108 : return true;
1486 : }
1487 :
1488 374684 : if (strCommand != NetMsgType::GETSPORKS &&
1489 374684 : strCommand != NetMsgType::SPORK &&
1490 371102 : !pfrom->fFirstMessageReceived.exchange(true)) {
1491 : // First message after VERSION/VERACK (without counting the GETSPORKS/SPORK messages)
1492 1358 : pfrom->fFirstMessageReceived = true;
1493 1358 : pfrom->fFirstMessageIsMNAUTH = strCommand == NetMsgType::MNAUTH;
1494 1358 : if (pfrom->m_masternode_probe_connection && !pfrom->fFirstMessageIsMNAUTH) {
1495 0 : LogPrint(BCLog::NET, "masternode probe connection first received message is not a MNAUTH, disconnecting peer=%d\n", pfrom->GetId());
1496 0 : pfrom->fDisconnect = true;
1497 0 : return false;
1498 : }
1499 : }
1500 :
1501 374684 : if (strCommand == NetMsgType::ADDR || strCommand == NetMsgType::ADDRV2) {
1502 13 : int stream_version = vRecv.GetVersion();
1503 13 : if (strCommand == NetMsgType::ADDRV2) {
1504 : // Add ADDRV2_FORMAT to the version so that the CNetAddr and CAddress
1505 : // unserialize methods know that an address in v2 format is coming.
1506 6 : stream_version |= ADDRV2_FORMAT;
1507 : }
1508 :
1509 13 : OverrideStream<CDataStream> s(&vRecv, vRecv.GetType(), stream_version);
1510 22 : std::vector<CAddress> vAddr;
1511 13 : s >> vAddr;
1512 :
1513 11 : if (vAddr.size() > MAX_ADDR_TO_SEND) {
1514 4 : LOCK(cs_main);
1515 2 : Misbehaving(pfrom->GetId(), 20, strprintf("%s message size = %u", strCommand, vAddr.size()));
1516 2 : return false;
1517 : }
1518 :
1519 : // Store the new addresses
1520 9 : std::vector<CAddress> vAddrOk;
1521 9 : int64_t nNow = GetAdjustedTime();
1522 9 : int64_t nSince = nNow - 10 * 60;
1523 :
1524 : // Update/increment addr rate limiting bucket.
1525 : // TODO: Slight time improvement calculation, continue backporting
1526 9 : const auto current_time = GetTime<std::chrono::microseconds>();
1527 9 : if (pfrom->m_addr_token_bucket < MAX_ADDR_PROCESSING_TOKEN_BUCKET) {
1528 : // Don't increment bucket if it's already full
1529 9 : const auto time_diff = std::max(current_time - pfrom->m_addr_token_timestamp, 0us);
1530 9 : const double increment = CountSecondsDouble(time_diff) * MAX_ADDR_RATE_PER_SECOND;
1531 9 : pfrom->m_addr_token_bucket = std::min<double>(pfrom->m_addr_token_bucket + increment, MAX_ADDR_PROCESSING_TOKEN_BUCKET);
1532 : }
1533 9 : pfrom->m_addr_token_timestamp = current_time;
1534 :
1535 9 : uint64_t num_proc = 0;
1536 9 : uint64_t num_rate_limit = 0;
1537 9 : Shuffle(vAddr.begin(), vAddr.end(), FastRandomContext());
1538 :
1539 1441 : for (CAddress& addr : vAddr) {
1540 1432 : if (interruptMsgProc)
1541 0 : return true;
1542 :
1543 : // Apply rate limiting.
1544 1432 : if (pfrom->m_addr_token_bucket < 1.0) {
1545 1290 : ++num_rate_limit;
1546 1290 : continue;
1547 : } else {
1548 142 : pfrom->m_addr_token_bucket -= 1.0;
1549 : }
1550 :
1551 142 : if ((addr.nServices & REQUIRED_SERVICES) != REQUIRED_SERVICES)
1552 0 : continue;
1553 :
1554 142 : if (addr.nTime <= 100000000 || addr.nTime > nNow + 10 * 60)
1555 20 : addr.nTime = nNow - 5 * 24 * 60 * 60;
1556 142 : pfrom->AddAddressKnown(addr);
1557 142 : if (connman->IsBanned(addr)) continue; // Do not process banned addresses beyond remembering we received them
1558 142 : ++num_proc;
1559 142 : bool fReachable = IsReachable(addr);
1560 142 : if (addr.nTime > nSince && !pfrom->fGetAddr && vAddr.size() <= 10 && addr.IsRoutable()) {
1561 : // Relay to a limited number of other nodes
1562 21 : RelayAddress(addr, fReachable, connman);
1563 : }
1564 : // Do not store addresses outside our network
1565 142 : if (fReachable)
1566 142 : vAddrOk.push_back(addr);
1567 : }
1568 9 : CNodeState* state = State(pfrom->GetId());
1569 9 : state->amt_addr_processed += num_proc;
1570 9 : state->amt_addr_rate_limited += num_rate_limit;
1571 9 : LogPrint(BCLog::NET, "Received addr: %u addresses (%u processed, %u rate-limited) from peer=%d\n",
1572 : vAddr.size(), num_proc, num_rate_limit, pfrom->GetId());
1573 9 : connman->AddNewAddresses(vAddrOk, pfrom->addr, 2 * 60 * 60);
1574 9 : if (vAddr.size() < 1000)
1575 9 : pfrom->fGetAddr = false;
1576 9 : if (pfrom->fOneShot)
1577 9 : pfrom->fDisconnect = true;
1578 : }
1579 :
1580 374671 : else if (strCommand == NetMsgType::INV) {
1581 363121 : std::vector<CInv> vInv;
1582 181561 : vRecv >> vInv;
1583 181561 : if (vInv.size() > MAX_INV_SZ) {
1584 2 : LOCK(cs_main);
1585 1 : Misbehaving(pfrom->GetId(), 20, strprintf("message inv size() = %u", vInv.size()));
1586 1 : return false;
1587 : }
1588 :
1589 363120 : LOCK(cs_main);
1590 :
1591 363120 : std::vector<CInv> vToFetch;
1592 :
1593 471563 : for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) {
1594 290003 : const CInv& inv = vInv[nInv];
1595 :
1596 290003 : if (interruptMsgProc)
1597 0 : return true;
1598 :
1599 : // Reject deprecated messages
1600 290003 : if (inv.type == MSG_TXLOCK_REQUEST || inv.type == MSG_TXLOCK_VOTE) {
1601 0 : Misbehaving(pfrom->GetId(), 100, strprintf("message inv deprecated %d", (int)inv.type));
1602 0 : return false;
1603 : }
1604 :
1605 290003 : pfrom->AddInventoryKnown(inv);
1606 :
1607 290003 : bool fAlreadyHave = AlreadyHave(inv);
1608 695007 : LogPrint(BCLog::NET, "got inv: %s %s peer=%d\n", inv.ToString(), fAlreadyHave ? "have" : "new", pfrom->GetId());
1609 :
1610 290003 : if (inv.type == MSG_BLOCK) {
1611 187483 : UpdateBlockAvailability(pfrom->GetId(), inv.hash);
1612 187483 : if (!fAlreadyHave && !fImporting && !fReindex && !mapBlocksInFlight.count(inv.hash)) {
1613 : // Add this to the list of blocks to request
1614 50152 : vToFetch.push_back(inv);
1615 98847 : LogPrint(BCLog::NET, "getblocks (%d) %s to peer=%d\n", pindexBestHeader->nHeight, inv.hash.ToString(), pfrom->GetId());
1616 : }
1617 : } else {
1618 : // Allowed inv request types while we are in IBD
1619 102520 : static std::set<int> allowWhileInIBDObjs = {
1620 : MSG_SPORK
1621 102520 : };
1622 :
1623 : // Can be safely removed post v6.0.0 enforcement
1624 : // Disallowed inv request
1625 102520 : static std::set<int> disallowedRequestsUntilV6 = {
1626 : MSG_QUORUM_FINAL_COMMITMENT
1627 102520 : };
1628 205040 : if (disallowedRequestsUntilV6.count(inv.type) &&
1629 1584 : !deterministicMNManager->IsDIP3Enforced()) {
1630 0 : continue; // Move to next inv
1631 : }
1632 :
1633 : // If we don't have it, check if we should ask for it now or
1634 : // wait until we are sync
1635 102520 : if (!fAlreadyHave) {
1636 71161 : bool allowWhileInIBD = allowWhileInIBDObjs.count(inv.type);
1637 71161 : if (allowWhileInIBD || !IsInitialBlockDownload()) {
1638 71161 : int64_t doubleRequestDelay = 2 * 60 * 1000000;
1639 : // some messages need to be re-requested faster when the first announcing peer did not answer to GETDATA
1640 71161 : switch (inv.type) {
1641 2580 : case MSG_QUORUM_RECOVERED_SIG:
1642 2580 : doubleRequestDelay = 5 * 1000000;
1643 2580 : break;
1644 2888 : case MSG_CLSIG:
1645 2888 : doubleRequestDelay = 5 * 1000000;
1646 2888 : break;
1647 : }
1648 71161 : pfrom->AskFor(inv, doubleRequestDelay);
1649 : }
1650 : }
1651 : }
1652 :
1653 : }
1654 :
1655 181560 : if (!vToFetch.empty())
1656 33188 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETDATA, vToFetch));
1657 : }
1658 :
1659 :
1660 193110 : else if (strCommand == NetMsgType::GETDATA) {
1661 78733 : std::vector<CInv> vInv;
1662 39367 : vRecv >> vInv;
1663 39367 : if (vInv.size() > MAX_INV_SZ) {
1664 2 : LOCK(cs_main);
1665 1 : Misbehaving(pfrom->GetId(), 20, strprintf("message getdata size() = %u", vInv.size()));
1666 1 : return false;
1667 : }
1668 :
1669 39366 : if (vInv.size() != 1)
1670 6366 : LogPrint(BCLog::NET, "received getdata (%u invsz) peer=%d\n", vInv.size(), pfrom->GetId());
1671 :
1672 39366 : if (vInv.size() > 0)
1673 78233 : LogPrint(BCLog::NET, "received getdata for: %s peer=%d\n", vInv[0].ToString(), pfrom->GetId());
1674 :
1675 39366 : pfrom->vRecvGetData.insert(pfrom->vRecvGetData.end(), vInv.begin(), vInv.end());
1676 39366 : ProcessGetData(pfrom, connman, interruptMsgProc);
1677 : }
1678 :
1679 :
1680 153743 : else if (strCommand == NetMsgType::GETBLOCKS || strCommand == NetMsgType::GETHEADERS) {
1681 :
1682 : // Don't relay blocks inv to masternode-only connections
1683 1184 : if (!pfrom->CanRelay()) {
1684 4 : LogPrint(BCLog::NET, "getblocks, don't relay blocks inv to masternode connection. peer=%d\n", pfrom->GetId());
1685 4 : return true;
1686 : }
1687 :
1688 2360 : CBlockLocator locator;
1689 1180 : uint256 hashStop;
1690 1180 : vRecv >> locator >> hashStop;
1691 :
1692 1180 : if (locator.vHave.size() > MAX_LOCATOR_SZ) {
1693 0 : LogPrint(BCLog::NET, "getblocks locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
1694 0 : pfrom->fDisconnect = true;
1695 4 : return true;
1696 : }
1697 :
1698 2360 : LOCK(cs_main);
1699 :
1700 : // Find the last block the caller has in the main chain
1701 1180 : CBlockIndex* pindex = FindForkInGlobalIndex(chainActive, locator);
1702 :
1703 : // Send the rest of the chain
1704 1180 : if (pindex)
1705 1180 : pindex = chainActive.Next(pindex);
1706 1180 : int nLimit = 500;
1707 2354 : LogPrint(BCLog::NET, "getblocks %d to %s limit %d from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.IsNull() ? "end" : hashStop.ToString(), nLimit, pfrom->GetId());
1708 5143 : for (; pindex; pindex = chainActive.Next(pindex)) {
1709 3981 : if (pindex->GetBlockHash() == hashStop) {
1710 36 : LogPrint(BCLog::NET, " getblocks stopping at %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
1711 : break;
1712 : }
1713 3963 : pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
1714 3963 : if (--nLimit <= 0) {
1715 : // When this block is requested, we'll send an inv that'll make them
1716 : // getblocks the next batch of inventory.
1717 0 : LogPrint(BCLog::NET, " getblocks stopping at limit %d %s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
1718 0 : pfrom->hashContinue = pindex->GetBlockHash();
1719 0 : break;
1720 : }
1721 : }
1722 : }
1723 :
1724 :
1725 152559 : else if (strCommand == NetMsgType::HEADERS && Params().HeadersFirstSyncingActive()) {
1726 : CBlockLocator locator;
1727 : uint256 hashStop;
1728 : vRecv >> locator >> hashStop;
1729 :
1730 : if (locator.vHave.size() > MAX_LOCATOR_SZ) {
1731 : LogPrint(BCLog::NET, "getblocks locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
1732 : pfrom->fDisconnect = true;
1733 : return true;
1734 : }
1735 :
1736 : LOCK(cs_main);
1737 :
1738 : if (IsInitialBlockDownload())
1739 : return true;
1740 :
1741 : CBlockIndex* pindex = nullptr;
1742 : if (locator.IsNull()) {
1743 : // If locator is null, return the hashStop block
1744 : CBlockIndex* pindex = LookupBlockIndex(hashStop);
1745 : if (!pindex)
1746 : return true;
1747 : } else {
1748 : // Find the last block the caller has in the main chain
1749 : pindex = FindForkInGlobalIndex(chainActive, locator);
1750 : if (pindex)
1751 : pindex = chainActive.Next(pindex);
1752 : }
1753 :
1754 : // we must use CBlocks, as CBlockHeaders won't include the 0x00 nTx count at the end
1755 : std::vector<CBlock> vHeaders;
1756 : int nLimit = MAX_HEADERS_RESULTS;
1757 : LogPrintf("getheaders %d to %s from peer=%d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString(), pfrom->GetId());
1758 : for (; pindex; pindex = chainActive.Next(pindex)) {
1759 : vHeaders.push_back(pindex->GetBlockHeader());
1760 : if (--nLimit <= 0 || pindex->GetBlockHash() == hashStop)
1761 : break;
1762 : }
1763 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::HEADERS, vHeaders));
1764 : }
1765 :
1766 :
1767 152559 : else if (strCommand == NetMsgType::TX) {
1768 18954 : std::deque<COutPoint> vWorkQueue;
1769 18954 : std::vector<uint256> vEraseQueue;
1770 18954 : CTransaction tx(deserialize, vRecv);
1771 18954 : CTransactionRef ptx = MakeTransactionRef(tx);
1772 :
1773 9477 : CInv inv(MSG_TX, tx.GetHash());
1774 9477 : pfrom->AddInventoryKnown(inv);
1775 :
1776 28431 : LOCK2(cs_main, g_cs_orphans);
1777 :
1778 9477 : bool ignoreFees = false;
1779 9477 : bool fMissingInputs = false;
1780 18954 : CValidationState state;
1781 :
1782 9477 : pfrom->setAskFor.erase(inv.hash);
1783 9477 : mapAlreadyAskedFor.erase(inv);
1784 :
1785 9477 : if (ptx->ContainsZerocoins()) {
1786 : // Don't even try to check zerocoins at all.
1787 0 : Misbehaving(pfrom->GetId(), 100, strprintf("received a zc transaction"));
1788 0 : return false;
1789 : }
1790 :
1791 9477 : if (AcceptToMemoryPool(mempool, state, ptx, true, &fMissingInputs, false, ignoreFees)) {
1792 9368 : mempool.check(pcoinsTip.get());
1793 9368 : RelayTransaction(tx, connman);
1794 26733 : for (unsigned int i = 0; i < tx.vout.size(); i++) {
1795 17365 : vWorkQueue.emplace_back(inv.hash, i);
1796 : }
1797 :
1798 18736 : LogPrint(BCLog::MEMPOOL, "%s : peer=%d %s : accepted %s (poolsz %u txn, %u kB)\n",
1799 : __func__, pfrom->GetId(), pfrom->cleanSubVer, tx.GetHash().ToString(),
1800 : mempool.size(), mempool.DynamicMemoryUsage() / 1000);
1801 :
1802 : // Recursively process any orphan transactions that depended on this one
1803 18736 : std::set<NodeId> setMisbehaving;
1804 26737 : while (!vWorkQueue.empty()) {
1805 17369 : auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front());
1806 17369 : vWorkQueue.pop_front();
1807 17369 : if(itByPrev == mapOrphanTransactionsByPrev.end())
1808 17365 : continue;
1809 8 : for (auto mi = itByPrev->second.begin();
1810 8 : mi != itByPrev->second.end();
1811 8 : ++mi) {
1812 4 : const CTransactionRef& orphanTx = (*mi)->second.tx;
1813 4 : const uint256& orphanHash = orphanTx->GetHash();
1814 4 : NodeId fromPeer = (*mi)->second.fromPeer;
1815 4 : bool fMissingInputs2 = false;
1816 : // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
1817 : // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
1818 : // anyone relaying LegitTxX banned)
1819 8 : CValidationState stateDummy;
1820 :
1821 :
1822 4 : if (setMisbehaving.count(fromPeer))
1823 0 : continue;
1824 4 : if (AcceptToMemoryPool(mempool, stateDummy, orphanTx, true, &fMissingInputs2)) {
1825 4 : LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
1826 2 : RelayTransaction(*orphanTx, connman);
1827 6 : for (unsigned int i = 0; i < orphanTx->vout.size(); i++) {
1828 4 : vWorkQueue.emplace_back(orphanHash, i);
1829 : }
1830 2 : vEraseQueue.push_back(orphanHash);
1831 2 : } else if (!fMissingInputs2) {
1832 2 : int nDos = 0;
1833 2 : if(stateDummy.IsInvalid(nDos) && nDos > 0) {
1834 : // Punish peer that gave us an invalid orphan tx
1835 0 : Misbehaving(fromPeer, nDos);
1836 0 : setMisbehaving.insert(fromPeer);
1837 0 : LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s\n", orphanHash.ToString());
1838 : }
1839 : // Has inputs but not accepted to mempool
1840 : // Probably non-standard or insufficient fee
1841 4 : LogPrint(BCLog::MEMPOOL, " removed orphan tx %s\n", orphanHash.ToString());
1842 2 : vEraseQueue.push_back(orphanHash);
1843 2 : assert(recentRejects);
1844 2 : recentRejects->insert(orphanHash);
1845 : }
1846 4 : mempool.check(pcoinsTip.get());
1847 : }
1848 : }
1849 :
1850 9372 : for (uint256& hash : vEraseQueue) EraseOrphanTx(hash);
1851 :
1852 109 : } else if (fMissingInputs) {
1853 106 : bool fRejectedParents = false; // It may be the case that the orphans parents have all been rejected
1854 :
1855 : // Deduplicate parent txids, so that we don't have to loop over
1856 : // the same parent txid more than once down below.
1857 212 : std::vector<uint256> unique_parents;
1858 106 : unique_parents.reserve(tx.vin.size());
1859 212 : for (const CTxIn& txin : ptx->vin) {
1860 : // We start with all parents, and then remove duplicates below.
1861 106 : unique_parents.emplace_back(txin.prevout.hash);
1862 : }
1863 106 : std::sort(unique_parents.begin(), unique_parents.end());
1864 106 : unique_parents.erase(std::unique(unique_parents.begin(), unique_parents.end()), unique_parents.end());
1865 211 : for (const uint256& parent_txid : unique_parents) {
1866 106 : if (recentRejects->contains(parent_txid)) {
1867 : fRejectedParents = true;
1868 : break;
1869 : }
1870 : }
1871 106 : if (!fRejectedParents) {
1872 210 : for (const uint256& parent_txid : unique_parents) {
1873 105 : CInv _inv(MSG_TX, parent_txid);
1874 105 : pfrom->AddInventoryKnown(_inv);
1875 105 : if (!AlreadyHave(_inv)) pfrom->AskFor(_inv);
1876 : }
1877 105 : AddOrphanTx(ptx, pfrom->GetId());
1878 :
1879 : // DoS prevention: do not allow mapOrphanTransactions to grow unbounded
1880 210 : unsigned int nMaxOrphanTx = (unsigned int)std::max((int64_t)0, gArgs.GetArg("-maxorphantx", DEFAULT_MAX_ORPHAN_TRANSACTIONS));
1881 105 : unsigned int nEvicted = LimitOrphanTxSize(nMaxOrphanTx);
1882 105 : if (nEvicted > 0)
1883 76 : LogPrint(BCLog::MEMPOOL, "mapOrphan overflow, removed %u tx\n", nEvicted);
1884 : } else {
1885 2 : LogPrint(BCLog::MEMPOOL, "not keeping orphan with rejected parents %s\n",tx.GetHash().ToString());
1886 : }
1887 : } else {
1888 : // AcceptToMemoryPool() returned false, possibly because the tx is
1889 : // already in the mempool; if the tx isn't in the mempool that
1890 : // means it was rejected and we shouldn't ask for it again.
1891 3 : if (!mempool.exists(tx.GetHash())) {
1892 3 : assert(recentRejects);
1893 3 : recentRejects->insert(tx.GetHash());
1894 : }
1895 3 : if (pfrom->fWhitelisted) {
1896 : // Always relay transactions received from whitelisted peers, even
1897 : // if they were rejected from the mempool, allowing the node to
1898 : // function as a gateway for nodes hidden behind it.
1899 : //
1900 : // FIXME: This includes invalid transactions, which means a
1901 : // whitelisted peer could get us banned! We may want to change
1902 : // that.
1903 0 : RelayTransaction(tx, connman);
1904 : }
1905 : }
1906 :
1907 9477 : int nDoS = 0;
1908 9480 : if (state.IsInvalid(nDoS)) {
1909 9 : LogPrint(BCLog::MEMPOOLREJ, "%s from peer=%d %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(),
1910 : pfrom->GetId(), pfrom->cleanSubVer,
1911 : FormatStateMessage(state));
1912 3 : if (nDoS > 0) {
1913 2 : Misbehaving(pfrom->GetId(), nDoS);
1914 : }
1915 : }
1916 : }
1917 :
1918 143082 : else if (strCommand == NetMsgType::HEADERS && Params().HeadersFirstSyncingActive() && !fImporting && !fReindex) // Ignore headers received while importing
1919 : {
1920 : std::vector<CBlockHeader> headers;
1921 :
1922 : // Bypass the normal CBlock deserialization, as we don't want to risk deserializing 2000 full blocks.
1923 : unsigned int nCount = ReadCompactSize(vRecv);
1924 : if (nCount > MAX_HEADERS_RESULTS) {
1925 : LOCK(cs_main);
1926 : Misbehaving(pfrom->GetId(), 20, strprintf("headers message size = %u", nCount));
1927 : return false;
1928 : }
1929 : headers.resize(nCount);
1930 : for (unsigned int n = 0; n < nCount; n++) {
1931 : vRecv >> headers[n];
1932 : ReadCompactSize(vRecv); // ignore tx count; assume it is 0.
1933 : }
1934 :
1935 : LOCK(cs_main);
1936 :
1937 : if (nCount == 0) {
1938 : // Nothing interesting. Stop asking this peers for more headers.
1939 : return true;
1940 : }
1941 : CBlockIndex* pindexLast = nullptr;
1942 : for (const CBlockHeader& header : headers) {
1943 : CValidationState state;
1944 : if (pindexLast && header.hashPrevBlock != pindexLast->GetBlockHash()) {
1945 : Misbehaving(pfrom->GetId(), 20, "non-continuous headers sequence");
1946 : return false;
1947 : }
1948 :
1949 : /*TODO: this has a CBlock cast on it so that it will compile. There should be a solution for this
1950 : * before headers are reimplemented on mainnet
1951 : */
1952 : if (!AcceptBlockHeader((CBlock)header, state, &pindexLast)) {
1953 : int nDoS;
1954 : if (state.IsInvalid(nDoS)) {
1955 : if (nDoS > 0) {
1956 : Misbehaving(pfrom->GetId(), nDoS, "invalid header received");
1957 : } else {
1958 : LogPrint(BCLog::NET, "peer=%d: invalid header received\n", pfrom->GetId());
1959 : }
1960 : return false;
1961 : }
1962 : }
1963 : }
1964 :
1965 : if (pindexLast)
1966 : UpdateBlockAvailability(pfrom->GetId(), pindexLast->GetBlockHash());
1967 :
1968 : if (nCount == MAX_HEADERS_RESULTS && pindexLast) {
1969 : // Headers message had its maximum size; the peer may have more headers.
1970 : // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
1971 : // from there instead.
1972 : LogPrintf("more getheaders (%d) to end to peer=%d (startheight:%d)\n", pindexLast->nHeight, pfrom->GetId(), pfrom->nStartingHeight);
1973 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexLast), UINT256_ZERO));
1974 : }
1975 : }
1976 :
1977 143082 : else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
1978 : {
1979 100710 : std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
1980 50355 : vRecv >> *pblock;
1981 50355 : const uint256& hashBlock = pblock->GetHash();
1982 50355 : CInv inv(MSG_BLOCK, hashBlock);
1983 99253 : LogPrint(BCLog::NET, "received block %s peer=%d\n", inv.hash.ToString(), pfrom->GetId());
1984 :
1985 : // sometimes we will be sent their most recent block and its not the one we want, in that case tell where we are
1986 50355 : if (!mapBlockIndex.count(pblock->hashPrevBlock)) {
1987 112 : CBlockLocator locator = WITH_LOCK(cs_main, return chainActive.GetLocator(););
1988 28 : if (find(pfrom->vBlockRequested.begin(), pfrom->vBlockRequested.end(), hashBlock) != pfrom->vBlockRequested.end()) {
1989 : // we already asked for this block, so lets work backwards and ask for the previous block
1990 13 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETBLOCKS, locator, pblock->hashPrevBlock));
1991 13 : pfrom->vBlockRequested.emplace_back(pblock->hashPrevBlock);
1992 : } else {
1993 : // ask to sync to this block
1994 15 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETBLOCKS, locator, hashBlock));
1995 15 : pfrom->vBlockRequested.emplace_back(hashBlock);
1996 : }
1997 : } else {
1998 50327 : pfrom->AddInventoryKnown(inv);
1999 50327 : if (!mapBlockIndex.count(hashBlock)) {
2000 25750 : {
2001 25750 : LOCK(cs_main);
2002 25750 : MarkBlockAsReceived(hashBlock);
2003 25750 : mapBlockSource.emplace(hashBlock, pfrom->GetId());
2004 : }
2005 25750 : ProcessNewBlock(pblock, nullptr);
2006 :
2007 : // Disconnect node if its running an old protocol version,
2008 : // used during upgrades, when the node is already connected.
2009 25750 : pfrom->DisconnectOldProtocol(pfrom->nVersion, ActiveProtocol());
2010 : } else {
2011 48297 : LogPrint(BCLog::NET, "%s : Already processed block %s, skipping ProcessNewBlock()\n", __func__, pblock->GetHash().GetHex());
2012 : }
2013 : }
2014 : }
2015 :
2016 : // This asymmetric behavior for inbound and outbound connections was introduced
2017 : // to prevent a fingerprinting attack: an attacker can send specific fake addresses
2018 : // to users' AddrMan and later request them by sending getaddr messages.
2019 : // Making users (which are behind NAT and can only make outgoing connections) ignore
2020 : // getaddr message mitigates the attack.
2021 92727 : else if ((strCommand == NetMsgType::GETADDR) && (pfrom->fInbound)) {
2022 648 : pfrom->vAddrToSend.clear();
2023 1296 : std::vector<CAddress> vAddr = connman->GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND, /* network */ nullopt);
2024 648 : FastRandomContext insecure_rand;
2025 648 : for (const CAddress& addr : vAddr) {
2026 0 : if (!connman->IsBanned(addr)) {
2027 0 : pfrom->PushAddress(addr, insecure_rand);
2028 : }
2029 : }
2030 : }
2031 :
2032 :
2033 92079 : else if (strCommand == NetMsgType::MEMPOOL) {
2034 :
2035 1 : if (!(pfrom->GetLocalServices() & NODE_BLOOM) && !pfrom->fWhitelisted) {
2036 1 : LogPrint(BCLog::NET, "mempool request with bloom filters disabled, disconnect peer=%d\n", pfrom->GetId());
2037 1 : pfrom->fDisconnect = true;
2038 1 : return true;
2039 : }
2040 :
2041 : // todo: limit mempool request with a bandwidth limit
2042 0 : LOCK(pfrom->cs_inventory);
2043 0 : pfrom->fSendMempool = true;
2044 : }
2045 :
2046 :
2047 92078 : else if (strCommand == NetMsgType::PING) {
2048 1669 : uint64_t nonce = 0;
2049 1669 : vRecv >> nonce;
2050 : // Echo the message back with the nonce. This allows for two useful features:
2051 : //
2052 : // 1) A remote node can quickly check if the connection is operational
2053 : // 2) Remote nodes can measure the latency of the network thread. If this node
2054 : // is overloaded it won't respond to pings quickly and the remote node can
2055 : // avoid sending us more work, like chain download requests.
2056 : //
2057 : // The nonce stops the remote getting confused between different pings: without
2058 : // it, if the remote node sends a ping once per second and this node takes 5
2059 : // seconds to respond to each, the 5th ping the remote sends would appear to
2060 : // return very quickly.
2061 1669 : connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::PONG, nonce));
2062 : }
2063 :
2064 :
2065 90409 : else if (strCommand == NetMsgType::PONG) {
2066 1550 : int64_t pingUsecEnd = nTimeReceived;
2067 1550 : uint64_t nonce = 0;
2068 1550 : size_t nAvail = vRecv.in_avail();
2069 1550 : bool bPingFinished = false;
2070 3100 : std::string sProblem;
2071 :
2072 1550 : if (nAvail >= sizeof(nonce)) {
2073 1550 : vRecv >> nonce;
2074 :
2075 : // Only process pong message if there is an outstanding ping (old ping without nonce should never pong)
2076 1550 : if (pfrom->nPingNonceSent != 0) {
2077 1550 : if (nonce == pfrom->nPingNonceSent) {
2078 : // Matching pong received, this ping is no longer outstanding
2079 1550 : bPingFinished = true;
2080 1550 : int64_t pingUsecTime = pingUsecEnd - pfrom->nPingUsecStart;
2081 1550 : if (pingUsecTime > 0) {
2082 : // Successful ping time measurement, replace previous
2083 1550 : pfrom->nPingUsecTime = pingUsecTime;
2084 3015 : pfrom->nMinPingUsecTime = std::min(pfrom->nMinPingUsecTime.load(), pingUsecTime);
2085 : } else {
2086 : // This should never happen
2087 1550 : sProblem = "Timing mishap";
2088 : }
2089 : } else {
2090 : // Nonce mismatches are normal when pings are overlapping
2091 0 : sProblem = "Nonce mismatch";
2092 0 : if (nonce == 0) {
2093 : // This is most likely a bug in another implementation somewhere, cancel this ping
2094 0 : bPingFinished = true;
2095 0 : sProblem = "Nonce zero";
2096 : }
2097 : }
2098 : } else {
2099 0 : sProblem = "Unsolicited pong without ping";
2100 : }
2101 : } else {
2102 : // This is most likely a bug in another implementation somewhere, cancel this ping
2103 0 : bPingFinished = true;
2104 0 : sProblem = "Short payload";
2105 : }
2106 :
2107 1550 : if (!(sProblem.empty())) {
2108 0 : LogPrint(BCLog::NET, "pong peer=%d %s: %s, %x expected, %x received, %u bytes\n",
2109 : pfrom->GetId(),
2110 : pfrom->cleanSubVer,
2111 : sProblem,
2112 : pfrom->nPingNonceSent,
2113 : nonce,
2114 : nAvail);
2115 : }
2116 1550 : if (bPingFinished) {
2117 1550 : pfrom->nPingNonceSent = 0;
2118 : }
2119 : }
2120 :
2121 88859 : else if (!(pfrom->GetLocalServices() & NODE_BLOOM) &&
2122 0 : (strCommand == NetMsgType::FILTERLOAD ||
2123 0 : strCommand == NetMsgType::FILTERADD ||
2124 0 : strCommand == NetMsgType::FILTERCLEAR)) {
2125 0 : LOCK(cs_main);
2126 0 : Misbehaving(pfrom->GetId(), 100, "banning, filter received.");
2127 0 : return false;
2128 : }
2129 :
2130 88859 : else if (strCommand == NetMsgType::FILTERLOAD) {
2131 0 : CBloomFilter filter;
2132 0 : vRecv >> filter;
2133 :
2134 0 : LOCK(pfrom->cs_filter);
2135 :
2136 0 : if (!filter.IsWithinSizeConstraints()) {
2137 : // There is no excuse for sending a too-large filter
2138 0 : LOCK(cs_main);
2139 0 : Misbehaving(pfrom->GetId(), 100);
2140 : } else {
2141 0 : pfrom->pfilter.reset(new CBloomFilter(filter));
2142 0 : pfrom->pfilter->UpdateEmptyFull();
2143 0 : pfrom->fRelayTxes = true;
2144 : }
2145 : }
2146 :
2147 :
2148 88859 : else if (strCommand == NetMsgType::FILTERADD) {
2149 0 : std::vector<unsigned char> vData;
2150 0 : vRecv >> vData;
2151 :
2152 : // Nodes must NEVER send a data item > 520 bytes (the max size for a script data object,
2153 : // and thus, the maximum size any matched object can have) in a filteradd message
2154 0 : bool bad = false;
2155 0 : if (vData.size() > MAX_SCRIPT_ELEMENT_SIZE) {
2156 : bad = true;
2157 : } else {
2158 0 : LOCK(pfrom->cs_filter);
2159 0 : if (pfrom->pfilter) {
2160 0 : pfrom->pfilter->insert(vData);
2161 : } else {
2162 : bad = true;
2163 : }
2164 : }
2165 0 : if (bad) {
2166 0 : LOCK(cs_main);
2167 0 : Misbehaving(pfrom->GetId(), 100);
2168 : }
2169 : }
2170 :
2171 :
2172 88859 : else if (strCommand == NetMsgType::FILTERCLEAR) {
2173 0 : LOCK(pfrom->cs_filter);
2174 0 : pfrom->pfilter.reset(new CBloomFilter());
2175 0 : pfrom->fRelayTxes = true;
2176 : }
2177 :
2178 88859 : else if (strCommand == NetMsgType::NOTFOUND) {
2179 : // We do not care about the NOTFOUND message (for now), but logging an Unknown Command
2180 : // message is undesirable as we transmit it ourselves.
2181 : return true;
2182 : }
2183 :
2184 : else {
2185 : // Tier two msg type search
2186 88106 : const std::vector<std::string>& allMessages = getTierTwoNetMessageTypes();
2187 88106 : if (std::find(allMessages.begin(), allMessages.end(), strCommand) != allMessages.end()) {
2188 : // Check if the dispatcher can process this message first. If not, try going with the old flow.
2189 88026 : if (!masternodeSync.MessageDispatcher(pfrom, strCommand, vRecv)) {
2190 : // Probably one the extensions, future: encapsulate all of this inside tiertwo_networksync.
2191 55750 : int dosScore{0};
2192 55750 : if (!mnodeman.ProcessMessage(pfrom, strCommand, vRecv, dosScore)) {
2193 24 : WITH_LOCK(cs_main, Misbehaving(pfrom->GetId(), dosScore));
2194 16 : return false;
2195 : }
2196 55744 : if (!g_budgetman.ProcessMessage(pfrom, strCommand, vRecv, dosScore)) {
2197 0 : WITH_LOCK(cs_main, Misbehaving(pfrom->GetId(), dosScore));
2198 0 : return false;
2199 : }
2200 111478 : CValidationState state_payments;
2201 55744 : if (!masternodePayments.ProcessMessageMasternodePayments(pfrom, strCommand, vRecv, state_payments)) {
2202 10 : if (state_payments.IsInvalid(dosScore)) {
2203 12 : WITH_LOCK(cs_main, Misbehaving(pfrom->GetId(), dosScore));
2204 : }
2205 10 : return false;
2206 : }
2207 55734 : if (!sporkManager.ProcessSpork(pfrom, strCommand, vRecv, dosScore)) {
2208 0 : WITH_LOCK(cs_main, Misbehaving(pfrom->GetId(), dosScore));
2209 0 : return false;
2210 : }
2211 :
2212 55734 : CValidationState mnauthState;
2213 55734 : if (!CMNAuth::ProcessMessage(pfrom, strCommand, vRecv, *connman, mnauthState)) {
2214 0 : int dosScore{0};
2215 55734 : if (mnauthState.IsInvalid(dosScore) && dosScore > 0) {
2216 0 : LOCK(cs_main);
2217 0 : Misbehaving(pfrom->GetId(), dosScore, mnauthState.GetRejectReason());
2218 : }
2219 : }
2220 : }
2221 : } else {
2222 : // Ignore unknown commands for extensibility
2223 160 : LogPrint(BCLog::NET, "Unknown command \"%s\" from peer=%d\n", SanitizeString(strCommand), pfrom->GetId());
2224 : }
2225 : }
2226 :
2227 : return true;
2228 : }
2229 :
2230 2308807 : static bool DisconnectIfBanned(CNode* pnode, CConnman* connman)
2231 : {
2232 2308807 : AssertLockHeld(cs_main);
2233 2308807 : CNodeState &state = *State(pnode->GetId());
2234 :
2235 2308807 : if (state.fShouldBan) {
2236 44 : state.fShouldBan = false;
2237 44 : if (pnode->fWhitelisted) {
2238 2 : LogPrintf("Warning: not punishing whitelisted peer %s!\n", pnode->addr.ToString());
2239 43 : } else if (pnode->fAddnode) {
2240 0 : LogPrintf("Warning: not punishing addnoded peer %s!\n", pnode->addr.ToString());
2241 : } else {
2242 43 : pnode->fDisconnect = true;
2243 43 : if (pnode->addr.IsLocal()) {
2244 78 : LogPrintf("Warning: not banning local peer %s!\n", pnode->addr.ToString());
2245 : } else {
2246 4 : connman->Ban(pnode->addr, BanReasonNodeMisbehaving);
2247 : }
2248 : }
2249 44 : return true;
2250 : }
2251 : return false;
2252 : }
2253 :
2254 2037610 : bool PeerLogicValidation::ProcessMessages(CNode* pfrom, std::atomic<bool>& interruptMsgProc)
2255 : {
2256 : // Message format
2257 : // (4) message start
2258 : // (12) command
2259 : // (4) size
2260 : // (4) checksum
2261 : // (x) data
2262 : //
2263 2037610 : bool fMoreWork = false;
2264 :
2265 2037610 : if (!pfrom->vRecvGetData.empty())
2266 17072 : ProcessGetData(pfrom, connman, interruptMsgProc);
2267 :
2268 2037610 : if (pfrom->fDisconnect)
2269 : return false;
2270 :
2271 : // this maintains the order of responses
2272 2037610 : if (!pfrom->vRecvGetData.empty()) return true;
2273 :
2274 : // Don't bother if send buffer is too full to respond anyway
2275 2025720 : if (pfrom->fPauseSend)
2276 : return false;
2277 :
2278 4063330 : std::list<CNetMessage> msgs;
2279 2025720 : {
2280 2025720 : LOCK(pfrom->cs_vProcessMsg);
2281 2025720 : if (pfrom->vProcessMsg.empty())
2282 3293770 : return false;
2283 : // Just take one message
2284 378830 : msgs.splice(msgs.begin(), pfrom->vProcessMsg, pfrom->vProcessMsg.begin());
2285 378830 : pfrom->nProcessQueueSize -= msgs.front().vRecv.size() + CMessageHeader::HEADER_SIZE;
2286 378830 : pfrom->fPauseRecv = pfrom->nProcessQueueSize > connman->GetReceiveFloodSize();
2287 378830 : fMoreWork = !pfrom->vProcessMsg.empty();
2288 : }
2289 378830 : CNetMessage& msg(msgs.front());
2290 :
2291 378830 : msg.SetVersion(pfrom->GetRecvVersion());
2292 : // Scan for message start
2293 378830 : if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), CMessageHeader::MESSAGE_START_SIZE) != 0) {
2294 2 : LogPrint(BCLog::NET, "PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->GetId());
2295 1 : pfrom->fDisconnect = true;
2296 1 : return false;
2297 : }
2298 :
2299 : // Read header
2300 378829 : CMessageHeader& hdr = msg.hdr;
2301 378829 : if (!hdr.IsValid(Params().MessageStart())) {
2302 2 : LogPrint(BCLog::NET, "PROCESSMESSAGE: ERRORS IN HEADER '%s' peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->GetId());
2303 1 : return fMoreWork;
2304 : }
2305 2404540 : std::string strCommand = hdr.GetCommand();
2306 :
2307 : // Message size
2308 378828 : unsigned int nMessageSize = hdr.nMessageSize;
2309 :
2310 : // Checksum
2311 378828 : CDataStream& vRecv = msg.vRecv;
2312 378828 : uint256 hash = msg.GetMessageHash();
2313 378828 : if (memcmp(hash.begin(), hdr.pchChecksum, CMessageHeader::CHECKSUM_SIZE) != 0)
2314 : {
2315 2 : LogPrint(BCLog::NET, "%s(%s, %u bytes): CHECKSUM ERROR expected %s was %s\n", __func__,
2316 : SanitizeString(strCommand), nMessageSize,
2317 : HexStr(Span<uint8_t>(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE)),
2318 : HexStr(hdr.pchChecksum));
2319 1 : return fMoreWork;
2320 : }
2321 :
2322 : // Process message
2323 378827 : bool fRet = false;
2324 378827 : try {
2325 757656 : fRet = ProcessMessage(pfrom, strCommand, vRecv, msg.nTime, connman, interruptMsgProc);
2326 378825 : if (interruptMsgProc)
2327 : return false;
2328 378825 : if (!pfrom->vRecvGetData.empty())
2329 5178 : fMoreWork = true;
2330 4 : } catch (const std::ios_base::failure& e) {
2331 2 : if (strstr(e.what(), "end of data")) {
2332 : // Allow exceptions from under-length message on vRecv
2333 2 : LogPrint(BCLog::NET, "ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
2334 1 : } else if (strstr(e.what(), "size too large")) {
2335 : // Allow exceptions from over-long size
2336 0 : LogPrint(BCLog::NET, "ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
2337 : } else {
2338 1 : PrintExceptionContinue(&e, "ProcessMessages()");
2339 : }
2340 0 : } catch (const std::exception& e) {
2341 0 : PrintExceptionContinue(&e, "ProcessMessages()");
2342 0 : } catch (...) {
2343 0 : PrintExceptionContinue(nullptr, "ProcessMessages()");
2344 : }
2345 :
2346 378827 : if (!fRet) {
2347 78 : LogPrint(BCLog::NET, "ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize,
2348 : pfrom->GetId());
2349 : }
2350 :
2351 757655 : LOCK(cs_main);
2352 378827 : DisconnectIfBanned(pfrom, connman);
2353 :
2354 378827 : return fMoreWork;
2355 : }
2356 :
2357 : class CompareInvMempoolOrder
2358 : {
2359 : CTxMemPool *mp;
2360 : public:
2361 247535 : explicit CompareInvMempoolOrder(CTxMemPool *_mempool)
2362 247535 : {
2363 247535 : mp = _mempool;
2364 : }
2365 :
2366 117409 : bool operator()(std::set<uint256>::iterator a, std::set<uint256>::iterator b)
2367 : {
2368 : /* As std::make_heap produces a max-heap, we want the entries with the
2369 : * fewest ancestors/highest fee to sort later. */
2370 117409 : return mp->CompareDepthAndScore(*b, *a);
2371 : }
2372 : };
2373 :
2374 1955907 : bool PeerLogicValidation::SendMessages(CNode* pto, std::atomic<bool>& interruptMsgProc)
2375 : {
2376 1955907 : {
2377 : // Don't send anything until the version handshake is complete
2378 1955907 : if (!pto->fSuccessfullyConnected || pto->fDisconnect)
2379 4479 : return true;
2380 :
2381 : // If we get here, the outgoing message serialization version is set and can't change.
2382 1951427 : CNetMsgMaker msgMaker(pto->GetSendVersion());
2383 :
2384 : //
2385 : // Message: ping
2386 : //
2387 1951427 : bool pingSend = false;
2388 1951427 : if (pto->fPingQueued) {
2389 : // RPC ping request by user
2390 2 : pingSend = true;
2391 : }
2392 1951427 : if (pto->nPingNonceSent == 0 && pto->nPingUsecStart + PING_INTERVAL * 1000000 < GetTimeMicros()) {
2393 : // Ping automatically sent as a latency probe & keepalive.
2394 : pingSend = true;
2395 : }
2396 1949833 : if (pingSend) {
2397 1588 : uint64_t nonce = 0;
2398 3176 : while (nonce == 0) {
2399 1588 : GetRandBytes((unsigned char*)&nonce, sizeof(nonce));
2400 : }
2401 1588 : pto->fPingQueued = false;
2402 1588 : pto->nPingUsecStart = GetTimeMicros();
2403 1588 : pto->nPingNonceSent = nonce;
2404 1588 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::PING, nonce));
2405 : }
2406 :
2407 1951427 : TRY_LOCK(cs_main, lockMain); // Acquire cs_main for IsInitialBlockDownload() and CNodeState()
2408 1951427 : if (!lockMain)
2409 25924 : return true;
2410 :
2411 1929987 : if (DisconnectIfBanned(pto, connman)) {
2412 : return true;
2413 : }
2414 :
2415 1929983 : CNodeState& state = *State(pto->GetId());
2416 :
2417 : // Address refresh broadcast
2418 1929983 : int64_t nNow = GetTimeMicros();
2419 1929983 : auto current_time = GetTime<std::chrono::microseconds>();
2420 :
2421 1929983 : if (!IsInitialBlockDownload() && pto->m_next_local_addr_send < current_time) {
2422 1239 : AdvertiseLocal(pto);
2423 1239 : pto->m_next_local_addr_send = PoissonNextSend(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
2424 : }
2425 :
2426 : //
2427 : // Message: addr
2428 : //
2429 1929983 : if (pto->m_next_addr_send < current_time) {
2430 14858 : pto->m_next_addr_send = PoissonNextSend(current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
2431 29716 : std::vector<CAddress> vAddr;
2432 14858 : vAddr.reserve(pto->vAddrToSend.size());
2433 :
2434 14858 : const char* msg_type;
2435 14858 : int make_flags;
2436 14858 : if (pto->m_wants_addrv2) {
2437 14777 : msg_type = NetMsgType::ADDRV2;
2438 14777 : make_flags = ADDRV2_FORMAT;
2439 : } else {
2440 81 : msg_type = NetMsgType::ADDR;
2441 81 : make_flags = 0;
2442 : }
2443 :
2444 14878 : for (const CAddress& addr : pto->vAddrToSend) {
2445 40 : if (!pto->addrKnown.contains(addr.GetKey())) {
2446 20 : pto->addrKnown.insert(addr.GetKey());
2447 20 : vAddr.push_back(addr);
2448 : // receiver rejects addr messages larger than 1000
2449 20 : if (vAddr.size() >= 1000) {
2450 0 : connman->PushMessage(pto, msgMaker.Make(make_flags, msg_type, vAddr));
2451 20 : vAddr.clear();
2452 : }
2453 : }
2454 : }
2455 14858 : pto->vAddrToSend.clear();
2456 14858 : if (!vAddr.empty())
2457 2 : connman->PushMessage(pto, msgMaker.Make(make_flags, msg_type, vAddr));
2458 : }
2459 :
2460 : // Start block sync
2461 1929983 : if (!pindexBestHeader)
2462 0 : pindexBestHeader = chainActive.Tip();
2463 1929983 : bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do.
2464 1929983 : if (!state.fSyncStarted && !pto->fClient && !fImporting && !fReindex && pto->CanRelay()) {
2465 : // Only actively request headers from a single peer, unless we're close to end of initial download.
2466 119817 : if ((nSyncStarted == 0 && fFetch) || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 6 * 60 * 60) { // NOTE: was "close to today" and 24h in Bitcoin
2467 1227 : state.fSyncStarted = true;
2468 1227 : nSyncStarted++;
2469 : //CBlockIndex *pindexStart = pindexBestHeader->pprev ? pindexBestHeader->pprev : pindexBestHeader;
2470 : //LogPrint(BCLog::NET, "initial getheaders (%d) to peer=%d (startheight:%d)\n", pindexStart->nHeight, pto->GetId(), pto->nStartingHeight);
2471 : //pto->PushMessage(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexStart), UINT256_ZERO);
2472 3681 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::GETBLOCKS, chainActive.GetLocator(chainActive.Tip()), UINT256_ZERO));
2473 : }
2474 : }
2475 :
2476 : // Resend wallet transactions that haven't gotten in a block yet
2477 : // Except during reindex, importing and IBD, when old wallet
2478 : // transactions become unconfirmed and spams other nodes.
2479 1929983 : if (!fReindex && !fImporting && !IsInitialBlockDownload()) {
2480 1789460 : GetMainSignals().Broadcast(connman);
2481 : }
2482 :
2483 : //
2484 : // Message: inventory
2485 : //
2486 3859956 : std::vector<CInv> vInv;
2487 1929983 : std::vector<CInv> vInvWait;
2488 1929983 : {
2489 3859956 : LOCK2(mempool.cs, pto->cs_inventory);
2490 3859896 : vInv.reserve(std::max<size_t>(pto->vInventoryBlockToSend.size() + pto->vInventoryTierTwoToSend.size(), INVENTORY_BROADCAST_MAX));
2491 :
2492 : // Add blocks
2493 2117903 : for (const uint256& hash : pto->vInventoryBlockToSend) {
2494 187921 : vInv.emplace_back(CInv(MSG_BLOCK, hash));
2495 187921 : if (vInv.size() == MAX_INV_SZ) {
2496 0 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2497 187921 : vInv.clear();
2498 : }
2499 : }
2500 1929983 : pto->vInventoryBlockToSend.clear();
2501 :
2502 : // Add tier two INVs
2503 1968723 : for (const CInv& tInv : pto->vInventoryTierTwoToSend) {
2504 38750 : vInv.emplace_back(tInv);
2505 38750 : if (vInv.size() == MAX_INV_SZ) {
2506 0 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2507 38750 : vInv.clear();
2508 : }
2509 : }
2510 1929983 : pto->vInventoryTierTwoToSend.clear();
2511 :
2512 : // Check whether periodic send should happen
2513 1929983 : bool fSendTrickle = pto->fWhitelisted;
2514 1929983 : if (pto->nNextInvSend < current_time) {
2515 40541 : fSendTrickle = true;
2516 : // Use half the delay for outbound peers, as there is less privacy concern for them.
2517 40541 : pto->nNextInvSend = PoissonNextSend(current_time, std::chrono::seconds{INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound});
2518 : }
2519 :
2520 : // Time to send but the peer has requested we not relay transactions.
2521 1929983 : if (fSendTrickle) {
2522 495070 : LOCK(pto->cs_filter);
2523 247537 : if (!pto->fRelayTxes) pto->setInventoryTxToSend.clear();
2524 : }
2525 :
2526 : // Respond to BIP35 mempool requests
2527 1929983 : if (fSendTrickle && pto->fSendMempool) {
2528 0 : auto vtxinfo = mempool.infoAll();
2529 0 : pto->fSendMempool = false;
2530 : // future: back port fee filter rate
2531 0 : LOCK(pto->cs_filter);
2532 :
2533 0 : for (const auto& txinfo : vtxinfo) {
2534 0 : const uint256& hash = txinfo.tx->GetHash();
2535 0 : CInv inv(MSG_TX, hash);
2536 0 : pto->setInventoryTxToSend.erase(hash);
2537 : // future: add fee filter check here..
2538 0 : if (pto->pfilter) {
2539 0 : if (!pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue;
2540 : }
2541 0 : pto->filterInventoryKnown.insert(hash);
2542 0 : vInv.emplace_back(inv);
2543 0 : if (vInv.size() == MAX_INV_SZ) {
2544 0 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2545 0 : vInv.clear();
2546 : }
2547 : }
2548 0 : pto->timeLastMempoolReq = GetTime();
2549 : }
2550 :
2551 : // Determine transactions to relay
2552 1929983 : if (fSendTrickle) {
2553 : // Produce a vector with all candidates for sending
2554 495070 : std::vector<std::set<uint256>::iterator> vInvTx;
2555 247535 : vInvTx.reserve(pto->setInventoryTxToSend.size());
2556 275905 : for (std::set<uint256>::iterator it = pto->setInventoryTxToSend.begin(); it != pto->setInventoryTxToSend.end(); it++) {
2557 28370 : vInvTx.push_back(it);
2558 : }
2559 : // Topologically and fee-rate sort the inventory we send for privacy and priority reasons.
2560 : // A heap is used so that not all items need sorting if only a few are being sent.
2561 247535 : CompareInvMempoolOrder compareInvMempoolOrder(&mempool);
2562 247535 : std::make_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
2563 : // No reason to drain out at many times the network's capacity,
2564 : // especially since we have many peers and some will draw much shorter delays.
2565 247535 : unsigned int nRelayedTransactions = 0;
2566 495070 : LOCK(pto->cs_filter);
2567 268831 : while (!vInvTx.empty() && nRelayedTransactions < INVENTORY_BROADCAST_MAX) {
2568 : // Fetch the top element from the heap
2569 21296 : std::pop_heap(vInvTx.begin(), vInvTx.end(), compareInvMempoolOrder);
2570 21296 : std::set<uint256>::iterator it = vInvTx.back();
2571 21296 : vInvTx.pop_back();
2572 21296 : uint256 hash = *it;
2573 : // Remove it from the to-be-sent set
2574 21296 : pto->setInventoryTxToSend.erase(it);
2575 : // Check if not in the filter already
2576 21296 : if (pto->filterInventoryKnown.contains(hash)) {
2577 4034 : continue;
2578 : }
2579 : // Not in the mempool anymore? don't bother sending it.
2580 31037 : auto txinfo = mempool.info(hash);
2581 17262 : if (!txinfo.tx) {
2582 11008 : continue;
2583 : }
2584 : // todo: back port feerate filter.
2585 13775 : if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(*txinfo.tx)) continue;
2586 : // Send
2587 13775 : vInv.emplace_back(CInv(MSG_TX, hash));
2588 13775 : nRelayedTransactions++;
2589 13775 : if (vInv.size() == MAX_INV_SZ) {
2590 0 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2591 0 : vInv.clear();
2592 : }
2593 13775 : pto->filterInventoryKnown.insert(hash);
2594 : }
2595 : }
2596 : }
2597 1929983 : if (!vInv.empty())
2598 181791 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
2599 :
2600 : // Detect whether we're stalling
2601 1929983 : current_time = GetTime<std::chrono::microseconds>();
2602 1929983 : nNow = GetTimeMicros();
2603 1929983 : if (state.nStallingSince && state.nStallingSince < nNow - 1000000 * BLOCK_STALLING_TIMEOUT) {
2604 : // Stalling only triggers when the block download window cannot move. During normal steady state,
2605 : // the download window should be much larger than the to-be-downloaded set of blocks, so disconnection
2606 : // should only happen during initial block download.
2607 0 : LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->GetId());
2608 0 : pto->fDisconnect = true;
2609 0 : return true;
2610 : }
2611 : // In case there is a block that has been in flight from this peer for (2 + 0.5 * N) times the block interval
2612 : // (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
2613 : // timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
2614 : // being saturated. We only count validated in-flight blocks so peers can't advertise nonexisting block hashes
2615 : // to unreasonably increase our timeout.
2616 1929983 : if (state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().GetConsensus().nTargetSpacing * (4 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
2617 0 : LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->GetId());
2618 0 : pto->fDisconnect = true;
2619 0 : return true;
2620 : }
2621 :
2622 : //
2623 : // Message: getdata (blocks)
2624 : //
2625 3859956 : std::vector<CInv> vGetData;
2626 1929983 : if (!pto->fClient && pto->CanRelay() && fFetch && state.nBlocksInFlight < MAX_BLOCKS_IN_TRANSIT_PER_PEER) {
2627 2249796 : std::vector<const CBlockIndex*> vToDownload;
2628 1124903 : NodeId staller = -1;
2629 1124903 : FindNextBlocksToDownload(pto->GetId(), MAX_BLOCKS_IN_TRANSIT_PER_PEER - state.nBlocksInFlight, vToDownload, staller);
2630 1124903 : for (const CBlockIndex* pindex : vToDownload) {
2631 0 : vGetData.emplace_back(MSG_BLOCK, pindex->GetBlockHash());
2632 0 : MarkBlockAsInFlight(pto->GetId(), pindex->GetBlockHash(), pindex);
2633 0 : LogPrintf("Requesting block %s (%d) peer=%d\n", pindex->GetBlockHash().ToString(),
2634 0 : pindex->nHeight, pto->GetId());
2635 : }
2636 1124903 : if (state.nBlocksInFlight == 0 && staller != -1) {
2637 0 : if (State(staller)->nStallingSince == 0) {
2638 0 : State(staller)->nStallingSince = nNow;
2639 0 : LogPrint(BCLog::NET, "Stall started peer=%d\n", staller);
2640 : }
2641 : }
2642 : }
2643 :
2644 : //
2645 : // Message: getdata (non-blocks)
2646 : //
2647 1996033 : while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) {
2648 66053 : const CInv& inv = (*pto->mapAskFor.begin()).second;
2649 66053 : if (!AlreadyHave(inv)) {
2650 131744 : LogPrint(BCLog::NET, "Requesting %s peer=%d\n", inv.ToString(), pto->GetId());
2651 65872 : vGetData.push_back(inv);
2652 65872 : if (vGetData.size() >= 1000) {
2653 50 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::GETDATA, vGetData));
2654 50 : vGetData.clear();
2655 : }
2656 : } else {
2657 : //If we're not going to ask, don't expect a response.
2658 181 : pto->setAskFor.erase(inv.hash);
2659 : }
2660 66053 : pto->mapAskFor.erase(pto->mapAskFor.begin());
2661 : }
2662 1929983 : if (!vGetData.empty())
2663 6157 : connman->PushMessage(pto, msgMaker.Make(NetMsgType::GETDATA, vGetData));
2664 : }
2665 1929983 : return true;
2666 : }
2667 :
2668 : class CNetProcessingCleanup
2669 : {
2670 : public:
2671 : CNetProcessingCleanup() {}
2672 479 : ~CNetProcessingCleanup() {
2673 : // orphan transactions
2674 479 : mapOrphanTransactions.clear();
2675 479 : mapOrphanTransactionsByPrev.clear();
2676 479 : }
2677 : } instance_of_cnetprocessingcleanup;
|