aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPieter Wuille <pieter@wuille.net>2020-09-23 17:00:46 -0700
committerPieter Wuille <pieter@wuille.net>2020-10-12 12:14:53 -0700
commitde11b0a4eff20da3e3ca52dc90948b5253d329c5 (patch)
tree62ffc21d451eab444a4635a110581d645902639b /src
parent242d16477df1a024c7126bad23dde39cad217eca (diff)
Reduce MAX_PEER_TX_ANNOUNCEMENTS for non-PF_RELAY peers
Maintaining up to 100000 INVs per peer is excessive, as that is far more than fits in a typical mempool. Also disable the "overload" penalty for PF_RELAY peers.
Diffstat (limited to 'src')
-rw-r--r--src/net_permissions.cpp2
-rw-r--r--src/net_permissions.h1
-rw-r--r--src/net_processing.cpp14
3 files changed, 11 insertions, 6 deletions
diff --git a/src/net_permissions.cpp b/src/net_permissions.cpp
index 53648deb40..d40fdfb113 100644
--- a/src/net_permissions.cpp
+++ b/src/net_permissions.cpp
@@ -12,7 +12,7 @@ const std::vector<std::string> NET_PERMISSIONS_DOC{
"bloomfilter (allow requesting BIP37 filtered blocks and transactions)",
"noban (do not ban for misbehavior; implies download)",
"forcerelay (relay transactions that are already in the mempool; implies relay)",
- "relay (relay even in -blocksonly mode)",
+ "relay (relay even in -blocksonly mode, and unlimited transaction announcements)",
"mempool (allow requesting BIP35 mempool contents)",
"download (allow getheaders during IBD, no disconnect after maxuploadtarget limit)",
"addr (responses to GETADDR avoid hitting the cache and contain random records with the most up-to-date info)"
diff --git a/src/net_permissions.h b/src/net_permissions.h
index 5b68f635a7..bba0ea1695 100644
--- a/src/net_permissions.h
+++ b/src/net_permissions.h
@@ -19,6 +19,7 @@ enum NetPermissionFlags {
// Can query bloomfilter even if -peerbloomfilters is false
PF_BLOOMFILTER = (1U << 1),
// Relay and accept transactions from this peer, even if -blocksonly is true
+ // This peer is also not subject to limits on how many transaction INVs are tracked
PF_RELAY = (1U << 3),
// Always relay transactions from this peer, even if already in mempool
// Keep parameter interaction: forcerelay implies relay
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 163c9c1f72..ee50bc1805 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -75,8 +75,11 @@ static const unsigned int MAX_INV_SZ = 50000;
/** Maximum number of in-flight transaction requests from a peer. It is not a hard limit, but the threshold at which
* point the OVERLOADED_PEER_TX_DELAY kicks in. */
static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT = 100;
-/** Maximum number of announced transactions from a peer */
-static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 2 * MAX_INV_SZ;
+/** Maximum number of transactions to consider for requesting, per peer. It provides a reasonable DoS limit to
+ * per-peer memory usage spent on announcements, while covering peers continuously sending INVs at the maximum
+ * rate (by our own policy, see INVENTORY_BROADCAST_PER_SECOND) for several minutes, while not receiving
+ * the actual transaction (from any peer) in response to requests for them. */
+static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 5000;
/** How long to delay requesting transactions via txids, if we have wtxid-relaying peers */
static constexpr auto TXID_RELAY_DELAY = std::chrono::seconds{2};
/** How long to delay requesting transactions from non-preferred peers */
@@ -754,7 +757,7 @@ void PeerManager::AddTxAnnouncement(const CNode& node, const GenTxid& gtxid, std
{
AssertLockHeld(::cs_main); // For m_txrequest
NodeId nodeid = node.GetId();
- if (m_txrequest.Count(nodeid) >= MAX_PEER_TX_ANNOUNCEMENTS) {
+ if (!node.HasPermission(PF_RELAY) && m_txrequest.Count(nodeid) >= MAX_PEER_TX_ANNOUNCEMENTS) {
// Too many queued announcements from this peer
return;
}
@@ -766,12 +769,13 @@ void PeerManager::AddTxAnnouncement(const CNode& node, const GenTxid& gtxid, std
// - NONPREF_PEER_TX_DELAY for announcements from non-preferred connections
// - TXID_RELAY_DELAY for announcements from txid peers while wtxid peers are available
// - OVERLOADED_PEER_TX_DELAY for announcements from peers which have at least
- // MAX_PEER_TX_REQUEST_IN_FLIGHT requests in flight.
+ // MAX_PEER_TX_REQUEST_IN_FLIGHT requests in flight (and don't have PF_RELAY).
auto delay = std::chrono::microseconds{0};
const bool preferred = state->fPreferredDownload;
if (!preferred) delay += NONPREF_PEER_TX_DELAY;
if (!state->m_wtxid_relay && g_wtxid_relay_peers > 0) delay += TXID_RELAY_DELAY;
- const bool overloaded = m_txrequest.CountInFlight(nodeid) >= MAX_PEER_TX_REQUEST_IN_FLIGHT;
+ const bool overloaded = !node.HasPermission(PF_RELAY) &&
+ m_txrequest.CountInFlight(nodeid) >= MAX_PEER_TX_REQUEST_IN_FLIGHT;
if (overloaded) delay += OVERLOADED_PEER_TX_DELAY;
m_txrequest.ReceivedInv(nodeid, gtxid, preferred, current_time + delay);
}