Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 3: [PATCH 03/68] feat(policy): preserve Roots relay and network controls on Core 30.3

src/net_processing.cpp

Before: src/net_processing.cpp · After: src/net_processing.cpp

File metadata
index 9287a67a04eaffee5838a1a9198414d950a28c89..b1dcbf122e0ab69b292923fca2123116abe2a758 100644

Download original patch · Release notes

Diff rows 1–400 of 407. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

src/net_processing.cpp CHANGED
@@ -13,6 +13,7 @@
13
13
  #include <chain.h>
14
14
  #include <chainparams.h>
15
15
  #include <common/bloom.h>
16
+ #include <common/args.h>
16
17
  #include <consensus/amount.h>
17
18
  #include <consensus/params.h>
18
19
  #include <consensus/validation.h>
@@ -530,7 +531,7 @@ public:
530
531
  /** Implement PeerManager */
531
532
  void StartScheduledTasks(CScheduler& scheduler) override;
532
533
  void CheckForStaleTipAndEvictPeers() override;
533
- std::optional<std::string> FetchBlock(NodeId peer_id, const CBlockIndex& block_index) override
534
+ std::optional<std::string> FetchBlock(NodeId peer_id, const uint256& hash, const CBlockIndex* block_index) override
534
535
  EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
535
536
  bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override EXCLUSIVE_LOCKS_REQUIRED(!m_peer_mutex);
536
537
  std::vector<node::TxOrphanage::OrphanInfo> GetOrphanTransactions() override EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
@@ -807,7 +808,7 @@ private:
807
808
 
808
809
  uint32_t GetFetchFlags(const Peer& peer) const;
809
810
 
810
- std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
811
+ std::map<uint64_t, std::chrono::microseconds> m_next_inv_to_inbounds_per_network_key GUARDED_BY(g_msgproc_mutex);
811
812
 
812
813
  /** Number of nodes with fSyncStarted. */
813
814
  int nSyncStarted GUARDED_BY(cs_main) = 0;
@@ -837,12 +838,14 @@ private:
837
838
 
838
839
  /**
839
840
  * For sending `inv`s to inbound peers, we use a single (exponentially
840
- * distributed) timer for all peers. If we used a separate timer for each
841
+ * distributed) timer for all peers with the same network key. If we used a separate timer for each
841
842
  * peer, a spy node could make multiple inbound connections to us to
842
- * accurately determine when we received the transaction (and potentially
843
- * determine the transaction's origin). */
843
+ * accurately determine when we received a transaction (and potentially
844
+ * determine the transaction's origin). Each network key has its own timer
845
+ * to make fingerprinting harder. */
844
846
  std::chrono::microseconds NextInvToInbounds(std::chrono::microseconds now,
845
- std::chrono::seconds average_interval) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
847
+ std::chrono::seconds average_interval,
848
+ uint64_t network_key) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
846
849
 
847
850
 
848
851
  // All of the following cache a recent block, and are protected by m_most_recent_block_mutex
@@ -879,6 +882,9 @@ private:
879
882
  /** Have we requested this block from an outbound peer */
880
883
  bool IsBlockRequestedFromOutbound(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main, !m_peer_mutex);
881
884
 
885
+ /** Have we requested this block from a specific peer */
886
+ bool IsBlockRequestedFromPeer(const uint256& hash, NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
887
+
882
888
  /** Remove this block from our tracked requested blocks. Called if:
883
889
  * - the block has been received from a peer
884
890
  * - the request for the block has timed out
@@ -969,7 +975,7 @@ private:
969
975
  /** Number of peers from which we're downloading blocks. */
970
976
  int m_peers_downloading_from GUARDED_BY(cs_main) = 0;
971
977
 
972
- void AddToCompactExtraTransactions(const CTransactionRef& tx) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
978
+ void AddToCompactExtraTransactions(const CTransactionRef& tx, size_t tx_dynamic_usage) EXCLUSIVE_LOCKS_REQUIRED(g_msgproc_mutex);
973
979
 
974
980
  /** Orphan/conflicted/etc transactions that are kept for compact block reconstruction.
975
981
  * The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN of
@@ -977,6 +983,7 @@ private:
977
983
  std::vector<std::pair<Wtxid, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_msgproc_mutex);
978
984
  /** Offset into vExtraTxnForCompact to insert the next tx */
979
985
  size_t vExtraTxnForCompactIt GUARDED_BY(g_msgproc_mutex) = 0;
986
+ size_t blockreconstructionextratxn_memusage{0};
980
987
 
981
988
  /** Check whether the last unknown block a peer advertised is not yet known. */
982
989
  void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
@@ -1143,15 +1150,15 @@ static bool CanServeWitnesses(const Peer& peer)
1143
1150
  }
1144
1151
 
1145
1152
  std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
1146
- std::chrono::seconds average_interval)
1153
+ std::chrono::seconds average_interval,
1154
+ uint64_t network_key)
1147
1155
  {
1148
- if (m_next_inv_to_inbounds.load() < now) {
1149
- // If this function were called from multiple threads simultaneously
1150
- // it would possible that both update the next send variable, and return a different result to their caller.
1151
- // This is not possible in practice as only the net processing thread invokes this function.
1152
- m_next_inv_to_inbounds = now + m_rng.rand_exp_duration(average_interval);
1156
+ auto [it, inserted] = m_next_inv_to_inbounds_per_network_key.try_emplace(network_key, 0us);
1157
+ auto& timer{it->second};
1158
+ if (timer < now) {
1159
+ timer = now + m_rng.rand_exp_duration(average_interval);
1153
1160
  }
1154
- return m_next_inv_to_inbounds;
1161
+ return timer;
1155
1162
  }
1156
1163
 
1157
1164
  bool PeerManagerImpl::IsBlockRequested(const uint256& hash)
@@ -1170,6 +1177,16 @@ bool PeerManagerImpl::IsBlockRequestedFromOutbound(const uint256& hash)
1170
1177
  return false;
1171
1178
  }
1172
1179
 
1180
+ bool PeerManagerImpl::IsBlockRequestedFromPeer(const uint256& hash, NodeId peer)
1181
+ {
1182
+ for (auto range = mapBlocksInFlight.equal_range(hash); range.first != range.second; range.first++) {
1183
+ auto [nodeid, block_it] = range.first->second;
1184
+ if (nodeid == peer) return true;
1185
+ }
1186
+
1187
+ return false;
1188
+ }
1189
+
1173
1190
  void PeerManagerImpl::RemoveBlockRequest(const uint256& hash, std::optional<NodeId> from_peer)
1174
1191
  {
1175
1192
  auto range = mapBlocksInFlight.equal_range(hash);
@@ -1561,6 +1578,9 @@ void PeerManagerImpl::InitializeNode(const CNode& node, ServiceFlags our_service
1561
1578
  if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BloomFilter)) {
1562
1579
  our_services = static_cast<ServiceFlags>(our_services | NODE_BLOOM);
1563
1580
  }
1581
+ if (NetPermissions::HasFlag(node.m_permission_flags, NetPermissionFlags::BlockFilters)) {
1582
+ our_services = static_cast<ServiceFlags>(our_services | NODE_COMPACT_FILTERS);
1583
+ }
1564
1584
 
1565
1585
  PeerRef peer = std::make_shared<Peer>(nodeid, our_services, node.IsInboundConn());
1566
1586
  {
@@ -1708,6 +1728,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c
1708
1728
  if (queue.pindex)
1709
1729
  stats.vHeightInFlight.push_back(queue.pindex->nHeight);
1710
1730
  }
1731
+ stats.m_last_block_announcement = NodeSeconds{std::chrono::seconds{state->m_last_block_announcement}};
1711
1732
  }
1712
1733
 
1713
1734
  PeerRef peer = GetPeerRef(nodeid);
@@ -1744,6 +1765,7 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c
1744
1765
  }
1745
1766
  }
1746
1767
  stats.time_offset = peer->m_time_offset;
1768
+ stats.m_misbehavior_score = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_should_discourage) ? 100 : 0;
1747
1769
 
1748
1770
  return true;
1749
1771
  }
@@ -1762,14 +1784,26 @@ PeerManagerInfo PeerManagerImpl::GetInfo() const
1762
1784
  };
1763
1785
  }
1764
1786
 
1765
- void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx)
1787
+ void PeerManagerImpl::AddToCompactExtraTransactions(const CTransactionRef& tx, const size_t tx_dynamic_usage)
1766
1788
  {
1767
1789
  if (m_opts.max_extra_txs <= 0)
1768
1790
  return;
1769
1791
  if (!vExtraTxnForCompact.size())
1770
1792
  vExtraTxnForCompact.resize(m_opts.max_extra_txs);
1771
- vExtraTxnForCompact[vExtraTxnForCompactIt] = std::make_pair(tx->GetWitnessHash(), tx);
1793
+ {
1794
+ auto& entry = vExtraTxnForCompact[vExtraTxnForCompactIt];
1795
+ if (entry.second) blockreconstructionextratxn_memusage -= RecursiveDynamicUsage(*entry.second);
1796
+ entry = std::make_pair(tx->GetWitnessHash(), tx);
1797
+ blockreconstructionextratxn_memusage += tx_dynamic_usage;
1798
+ }
1772
1799
  vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs;
1800
+
1801
+ while (blockreconstructionextratxn_memusage > m_opts.max_extra_txs_size) {
1802
+ auto& entry = vExtraTxnForCompact[vExtraTxnForCompactIt];
1803
+ if (entry.second) blockreconstructionextratxn_memusage -= RecursiveDynamicUsage(*entry.second);
1804
+ entry = {};
1805
+ vExtraTxnForCompactIt = (vExtraTxnForCompactIt + 1) % m_opts.max_extra_txs;
1806
+ }
1773
1807
  }
1774
1808
 
1775
1809
  void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
@@ -1785,10 +1819,23 @@ void PeerManagerImpl::Misbehaving(Peer& peer, const std::string& message)
1785
1819
  );
1786
1820
  }
1787
1821
 
1822
+ static void HandleDoSPunishment(CConnman& connman, NodeId node_id, const int nDoS, const char * const what_is_it) {
1823
+ // We never actually DoS ban for invalid blocks, merely disconnect nodes if we're relying on them as a primary node
1824
+ const std::string msg = strprintf("peer=%d got DoS score %d on invalid %s", node_id, nDoS, what_is_it);
1825
+ connman.ForNode(node_id, [msg](CNode* node) {
1826
+ if (node->PunishInvalidBlocks()) {
1827
+ LogDebug(BCLog::NET, "%s; simply disconnecting\n", msg);
1828
+ node->fDisconnect = true;
1829
+ } else {
1830
+ LogDebug(BCLog::NET, "%s; tolerating\n", msg);
1831
+ }
1832
+ return true;
1833
+ });
1834
+ }
1835
+
1788
1836
  void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidationState& state,
1789
1837
  bool via_compact_block, const std::string& message)
1790
1838
  {
1791
- PeerRef peer{GetPeerRef(nodeid)};
1792
1839
  switch (state.GetResult()) {
1793
1840
  case BlockValidationResult::BLOCK_RESULT_UNSET:
1794
1841
  break;
@@ -1800,7 +1847,7 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
1800
1847
  case BlockValidationResult::BLOCK_CONSENSUS:
1801
1848
  case BlockValidationResult::BLOCK_MUTATED:
1802
1849
  if (!via_compact_block) {
1803
- if (peer) Misbehaving(*peer, message);
1850
+ HandleDoSPunishment(m_connman, nodeid, 100, "block");
1804
1851
  return;
1805
1852
  }
1806
1853
  break;
@@ -1808,19 +1855,19 @@ void PeerManagerImpl::MaybePunishNodeForBlock(NodeId nodeid, const BlockValidati
1808
1855
  {
1809
1856
  // Discourage outbound (but not inbound) peers if on an invalid chain.
1810
1857
  // Exempt HB compact block peers. Manual connections are always protected from discouragement.
1811
- if (peer && !via_compact_block && !peer->m_is_inbound) {
1812
- if (peer) Misbehaving(*peer, message);
1858
+ if (!via_compact_block) {
1859
+ HandleDoSPunishment(m_connman, nodeid, 100, "block");
1813
1860
  return;
1814
1861
  }
1815
1862
  break;
1816
1863
  }
1817
1864
  case BlockValidationResult::BLOCK_INVALID_HEADER:
1818
1865
  case BlockValidationResult::BLOCK_INVALID_PREV:
1819
- if (peer) Misbehaving(*peer, message);
1866
+ HandleDoSPunishment(m_connman, nodeid, 100, "block header");
1820
1867
  return;
1821
1868
  // Conflicting (but not necessarily invalid) data or different policy:
1822
1869
  case BlockValidationResult::BLOCK_MISSING_PREV:
1823
- if (peer) Misbehaving(*peer, message);
1870
+ HandleDoSPunishment(m_connman, nodeid, 100, "block header");
1824
1871
  return;
1825
1872
  case BlockValidationResult::BLOCK_TIME_FUTURE:
1826
1873
  break;
@@ -1839,7 +1886,7 @@ bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex)
1839
1886
  (GetBlockProofEquivalentTime(*m_chainman.m_best_header, *pindex, *m_chainman.m_best_header, m_chainparams.GetConsensus()) < STALE_RELAY_AGE_LIMIT);
1840
1887
  }
1841
1888
 
1842
- std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBlockIndex& block_index)
1889
+ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const uint256& hash, const CBlockIndex* block_index)
1843
1890
  {
1844
1891
  if (m_chainman.m_blockman.LoadingBlocks()) return "Loading blocks ...";
1845
1892
 
@@ -1852,14 +1899,18 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
1852
1899
 
1853
1900
  LOCK(cs_main);
1854
1901
 
1855
- // Forget about all prior requests
1856
- RemoveBlockRequest(block_index.GetBlockHash(), std::nullopt);
1902
+ if (IsBlockRequestedFromPeer(hash, peer_id)) return "Already requested from this peer";
1857
1903
 
1858
- // Mark block as in-flight
1859
- if (!BlockRequested(peer_id, block_index)) return "Already requested from this peer";
1904
+ // Mark block as in-flight unless we don't have the header.
1905
+ if (block_index != nullptr) {
1906
+ // Forget about all prior requests
1907
+ RemoveBlockRequest(hash, std::nullopt);
1908
+
1909
+ // Mark block as in-flight
1910
+ Assume(BlockRequested(peer_id, *block_index));
1911
+ }
1860
1912
 
1861
1913
  // Construct message to request the block
1862
- const uint256& hash{block_index.GetBlockHash()};
1863
1914
  std::vector<CInv> invs{CInv(MSG_BLOCK | MSG_WITNESS_FLAG, hash)};
1864
1915
 
1865
1916
  // Send block request message to the peer
@@ -1875,6 +1926,12 @@ std::optional<std::string> PeerManagerImpl::FetchBlock(NodeId peer_id, const CBl
1875
1926
  return std::nullopt;
1876
1927
  }
1877
1928
 
1929
+ std::optional<std::string> PeerManager::FetchBlock(NodeId peer_id, const CBlockIndex& block_index)
1930
+ {
1931
+ const uint256& hash{block_index.GetBlockHash()};
1932
+ return FetchBlock(peer_id, hash, &block_index);
1933
+ }
1934
+
1878
1935
  std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrman,
1879
1936
  BanMan* banman, ChainstateManager& chainman,
1880
1937
  CTxMemPool& pool, node::Warnings& warnings, Options opts)
@@ -1882,11 +1939,12 @@ std::unique_ptr<PeerManager> PeerManager::make(CConnman& connman, AddrMan& addrm
1882
1939
  return std::make_unique<PeerManagerImpl>(connman, addrman, banman, chainman, pool, warnings, opts);
1883
1940
  }
1884
1941
 
1942
+ static_assert(CORE_INCREMENTAL_RELAY_FEE < DEFAULT_INCREMENTAL_RELAY_FEE, "Trinary logic for m_fee_filter_rounder is based on assumption that CORE_INCREMENTAL_RELAY_FEE is less than DEFAULT_INCREMENTAL_RELAY_FEE");
1885
1943
  PeerManagerImpl::PeerManagerImpl(CConnman& connman, AddrMan& addrman,
1886
1944
  BanMan* banman, ChainstateManager& chainman,
1887
1945
  CTxMemPool& pool, node::Warnings& warnings, Options opts)
1888
1946
  : m_rng{opts.deterministic_rng},
1889
- m_fee_filter_rounder{CFeeRate{DEFAULT_MIN_RELAY_TX_FEE}, m_rng},
1947
+ m_fee_filter_rounder{CFeeRate{pool.m_opts.incremental_relay_feerate.GetFeePerK() < DEFAULT_INCREMENTAL_RELAY_FEE ? CORE_INCREMENTAL_RELAY_FEE : DEFAULT_INCREMENTAL_RELAY_FEE}, m_rng},
1890
1948
  m_chainparams(chainman.GetParams()),
1891
1949
  m_connman(connman),
1892
1950
  m_addrman(addrman),
@@ -2239,7 +2297,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
2239
2297
  }
2240
2298
  // disconnect node in case we have reached the outbound limit for serving historical blocks
2241
2299
  if (m_connman.OutboundTargetReached(true) &&
2242
- (((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk()) &&
2300
+ (((m_chainman.m_best_header != nullptr) && (m_chainman.m_best_header->GetBlockTime() - pindex->GetBlockTime() > HISTORICAL_BLOCK_AGE)) || inv.IsMsgFilteredBlk() || inv.IsMsgFilteredWitnessBlk()) &&
2243
2301
  !pfrom.HasPermission(NetPermissionFlags::Download) // nodes with the download permission may exceed target
2244
2302
  ) {
2245
2303
  LogDebug(BCLog::NET, "historical block serving limit reached, %s\n", pfrom.DisconnectMsg(fLogIPs));
@@ -2302,7 +2360,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
2302
2360
  MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_NO_WITNESS(*pblock));
2303
2361
  } else if (inv.IsMsgWitnessBlk()) {
2304
2362
  MakeAndPushMessage(pfrom, NetMsgType::BLOCK, TX_WITH_WITNESS(*pblock));
2305
- } else if (inv.IsMsgFilteredBlk()) {
2363
+ } else if (inv.IsMsgFilteredBlk() || inv.IsMsgFilteredWitnessBlk()) {
2306
2364
  bool sendMerkleBlock = false;
2307
2365
  CMerkleBlock merkleBlock;
2308
2366
  if (auto tx_relay = peer.GetTxRelay(); tx_relay != nullptr) {
@@ -2320,8 +2378,9 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
2320
2378
  // they must either disconnect and retry or request the full block.
2321
2379
  // Thus, the protocol spec specified allows for us to provide duplicate txn here,
2322
2380
  // however we MUST always provide at least what the remote peer needs
2381
+ const auto maybe_with_witness = (inv.IsMsgFilteredWitnessBlk() ? TX_WITH_WITNESS : TX_NO_WITNESS);
2323
2382
  for (const auto& [tx_idx, _] : merkleBlock.vMatchedTxn)
2324
- MakeAndPushMessage(pfrom, NetMsgType::TX, TX_NO_WITNESS(*pblock->vtx[tx_idx]));
2383
+ MakeAndPushMessage(pfrom, NetMsgType::TX, maybe_with_witness(*pblock->vtx[tx_idx]));
2325
2384
  }
2326
2385
  // else
2327
2386
  // no response
@@ -2531,6 +2590,10 @@ void PeerManagerImpl::HandleUnconnectingHeaders(CNode& pfrom, Peer& peer,
2531
2590
  // eventually get the headers - even from a different peer -
2532
2591
  // we can use this peer to download.
2533
2592
  WITH_LOCK(cs_main, UpdateBlockAvailability(pfrom.GetId(), headers.back().GetHash()));
2593
+
2594
+ if (pfrom.PunishInvalidBlocks()) {
2595
+ pfrom.fDisconnect = true;
2596
+ }
2534
2597
  }
2535
2598
 
2536
2599
  bool PeerManagerImpl::CheckHeadersAreContinuous(const std::vector<CBlockHeader>& headers) const
@@ -2994,8 +3057,9 @@ std::optional<node::PackageToValidate> PeerManagerImpl::ProcessInvalidTx(NodeId
2994
3057
 
2995
3058
  const auto& [add_extra_compact_tx, unique_parents, package_to_validate] = m_txdownloadman.MempoolRejectedTx(ptx, state, nodeid, first_time_failure);
2996
3059
 
2997
- if (add_extra_compact_tx && RecursiveDynamicUsage(*ptx) < 100000) {
2998
- AddToCompactExtraTransactions(ptx);
3060
+ const size_t tx_dynamic_usage{RecursiveDynamicUsage(*ptx)};
3061
+ if (add_extra_compact_tx && tx_dynamic_usage < BLOCK_RECONSTRUCTION_EXTRA_TXN_PER_TXN_SIZE_LIMIT) {
3062
+ AddToCompactExtraTransactions(ptx, tx_dynamic_usage);
2999
3063
  }
3000
3064
  for (const Txid& parent_txid : unique_parents) {
3001
3065
  if (peer) AddKnownTx(*peer, parent_txid.ToUint256());
@@ -3021,7 +3085,8 @@ void PeerManagerImpl::ProcessValidTx(NodeId nodeid, const CTransactionRef& tx, c
3021
3085
  RelayTransaction(tx->GetHash(), tx->GetWitnessHash());
3022
3086
 
3023
3087
  for (const CTransactionRef& removedTx : replaced_transactions) {
3024
- AddToCompactExtraTransactions(removedTx);
3088
+ const size_t tx_dynamic_usage{RecursiveDynamicUsage(*removedTx)};
3089
+ AddToCompactExtraTransactions(removedTx, tx_dynamic_usage);
3025
3090
  }
3026
3091
  }
3027
3092
 
@@ -3479,7 +3544,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3479
3544
  if (!vRecv.empty()) {
3480
3545
  std::string strSubVer;
3481
3546
  vRecv >> LIMITED_STRING(strSubVer, MAX_SUBVERSION_LENGTH);
3482
- cleanSubVer = SanitizeString(strSubVer);
3547
+ cleanSubVer = SanitizeString(strSubVer, SAFE_CHARS_PRINTABLE);
3483
3548
  }
3484
3549
  if (!vRecv.empty()) {
3485
3550
  vRecv >> starting_height;
@@ -3508,6 +3573,10 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3508
3573
  // Change version
3509
3574
  const int greatest_common_version = std::min(nVersion, PROTOCOL_VERSION);
3510
3575
  pfrom.SetCommonVersion(greatest_common_version);
3576
+ {
3577
+ LOCK(pfrom.m_subver_mutex);
3578
+ pfrom.cleanSubVer = cleanSubVer;
3579
+ }
3511
3580
  pfrom.nVersion = nVersion;
3512
3581
 
3513
3582
  if (greatest_common_version >= WTXID_RELAY_VERSION) {
@@ -3526,10 +3595,6 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3526
3595
  pfrom.m_has_all_wanted_services = HasAllDesirableServiceFlags(nServices);
3527
3596
  peer->m_their_services = nServices;
3528
3597
  pfrom.SetAddrLocal(addrMe);
3529
- {
3530
- LOCK(pfrom.m_subver_mutex);
3531
- pfrom.cleanSubVer = cleanSubVer;
3532
- }
3533
3598
  peer->m_starting_height = starting_height;
3534
3599
 
3535
3600
  // Only initialize the Peer::TxRelay m_relay_txs data structure if:
@@ -3615,10 +3680,11 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3615
3680
  }
3616
3681
 
3617
3682
  const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
3618
- LogDebug(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s\n",
3619
- cleanSubVer, pfrom.nVersion,
3683
+ LogDebug(BCLog::NET, "receive version message: %s: version %d, blocks=%d, us=%s, txrelay=%d, peer=%d%s%s%s\n",
3684
+ SanitizeString(cleanSubVer, SAFE_CHARS_DEFAULT, true), pfrom.nVersion,
3620
3685
  peer->m_starting_height, addrMe.ToStringAddrPort(), fRelay, pfrom.GetId(),
3621
- pfrom.LogIP(fLogIPs), (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
3686
+ fLogIPs ? "," : "", pfrom.LogIP(fLogIPs),
3687
+ (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
3622
3688
 
3623
3689
  peer->m_time_offset = NodeSeconds{std::chrono::seconds{nTime}} - Now<NodeSeconds>();
3624
3690
  if (!pfrom.IsInboundConn()) {
@@ -3658,11 +3724,12 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3658
3724
  // can be triggered by an attacker at high rate.
3659
3725
  if (!pfrom.IsInboundConn() || LogAcceptCategory(BCLog::NET, BCLog::Level::Debug)) {
3660
3726
  const auto mapped_as{m_connman.GetMappedAS(pfrom.addr)};
3661
- LogPrintf("New %s %s peer connected: version: %d, blocks=%d, peer=%d%s%s\n",
3727
+ LogPrintf("New %s %s peer connected: version: %d, blocks=%d, peer=%d%s%s%s\n",
3662
3728
  pfrom.ConnectionTypeAsString(),
3663
3729
  TransportTypeAsString(pfrom.m_transport->GetInfo().transport_type),
3664
3730
  pfrom.nVersion.load(), peer->m_starting_height,
3665
- pfrom.GetId(), pfrom.LogIP(fLogIPs),
3731
+ pfrom.GetId(),
3732
+ fLogIPs ? "," : "", pfrom.LogIP(fLogIPs),
3666
3733
  (mapped_as ? strprintf(", mapped_as=%d", mapped_as) : ""));
3667
3734
  }
3668
3735
 
@@ -4939,13 +5006,13 @@ bool PeerManagerImpl::MaybeDiscourageAndDisconnect(CNode& pnode, Peer& peer)
4939
5006
 
4940
5007
  if (pnode.HasPermission(NetPermissionFlags::NoBan)) {
4941
5008
  // We never disconnect or discourage peers for bad behavior if they have NetPermissionFlags::NoBan permission
4942
- LogPrintf("Warning: not punishing noban peer %d!\n", peer.m_id);
5009
+ LogWarning("Not punishing noban peer %d!", peer.m_id);
4943
5010
  return false;
4944
5011
  }
4945
5012
 
4946
5013
  if (pnode.IsManualConn()) {
4947
5014
  // We never disconnect or discourage manual peers for bad behavior
4948
- LogPrintf("Warning: not punishing manually connected peer %d!\n", peer.m_id);
5015
+ LogWarning("Not punishing manually connected peer %d!", peer.m_id);
4949
5016
  return false;
4950
5017
  }
4951
5018
 
@@ -5371,6 +5438,7 @@ void PeerManagerImpl::MaybeSendFeefilter(CNode& pto, Peer& peer, std::chrono::mi
5371
5438
  {
5372
5439
  if (m_opts.ignore_incoming_txs) return;
5373
5440
  if (pto.GetCommonVersion() < FEEFILTER_VERSION) return;
5441
+ if (!gArgs.GetBoolArg("-feefilter", DEFAULT_FEEFILTER)) return;
5374
5442
  // peers with the forcerelay permission should not filter txs to us
5375
5443
  if (pto.HasPermission(NetPermissionFlags::ForceRelay)) return;
5376
5444
  // Don't send feefilter messages to outbound block-relay-only peers since they should never announce
@@ -5711,7 +5779,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
5711
5779
  if (tx_relay->m_next_inv_send_time < current_time) {