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