Skip to content

Commit

Permalink
policy: reduce MAX_PEER_TX_ANNOUNCEMENTS
Browse files Browse the repository at this point in the history
Maintaining up to 100000 INVs per peer is excessive. A Dogecoin
Core node will never send more than 7 invs per second.

Backported from: de11b0a
Original Author: Pieter Wuille <[email protected]>
  • Loading branch information
patricklodder committed Jul 15, 2024
1 parent 3a700cd commit 8eb5214
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 2 deletions.
25 changes: 25 additions & 0 deletions qa/rpc-tests/p2p-tx-download.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
INBOUND_PEER_TX_DELAY = 2 # seconds
TXID_RELAY_DELAY = 2 # seconds
MAX_GETDATA_IN_FLIGHT = 100
MAX_PEER_TX_ANNOUNCEMENTS = 5000

class TxDownloadTestNode(SingleNodeConnCB):
def __init__(self):
Expand Down Expand Up @@ -51,6 +52,11 @@ def is_closed():
return self.connection.state == "closed"
return wait_until(is_closed, timeout=30)

def wait_until_numgetdata(self, num):
def has_num():
return len(self.tx_getdata_received) == num
return wait_until(has_num, timeout=60)

def disconnect(self):
self.connection.disconnect_node()
return self.wait_for_disconnect()
Expand Down Expand Up @@ -80,6 +86,7 @@ def run_test(self):
self.test_invblock_resolution()
self.test_disconnect_fallback()
self.test_notfound_fallback()
self.test_max_announcements()

def setup_network(self):
# set up full nodes
Expand Down Expand Up @@ -261,5 +268,23 @@ def test_disconnect_fallback(self):
# the losing peer is now the fallback and received a getdata message
assert self.wait_for_getdata([txid], [loser])

def test_max_announcements(self):
# create a test node
peer = self.create_testnode()
peer.wait_for_verack()

hashes = []
for _ in range(MAX_PEER_TX_ANNOUNCEMENTS):
hashes.append(self.next_fake_txid())

peer.send_tx_inv(hashes)
peer.wait_until_numgetdata(MAX_PEER_TX_ANNOUNCEMENTS)
peer.sync_with_ping()

# send one more - this should never come back.
extratx = self.next_fake_txid()
peer.send_tx_inv([extratx])
assert not self.any_received_getdata(extratx, [peer])

if __name__ == '__main__':
TxDownloadTest().main()
11 changes: 9 additions & 2 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,15 @@ struct IteratorComparator

/** Maximum number of in-flight transactions from a peer */
static constexpr int32_t MAX_PEER_TX_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 for several minutes (see INVENTORY_BROADCAST_MAX), 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 many microseconds to delay requesting transactions from inbound peers */
static constexpr int64_t NONPREF_PEER_TX_DELAY = 2 * 1000000; // 2 seconds
/** How many microseconds to delay requesting transactions from overloaded peers */
Expand Down

0 comments on commit 8eb5214

Please sign in to comment.