Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | |||||
static const unsigned int MAX_INV_SZ = 50000; | static const unsigned int MAX_INV_SZ = 50000; | ||||
static_assert(MAX_PROTOCOL_MESSAGE_LENGTH > MAX_INV_SZ * sizeof(CInv), | static_assert(MAX_PROTOCOL_MESSAGE_LENGTH > MAX_INV_SZ * sizeof(CInv), | ||||
"Max protocol message length must be greater than largest " | "Max protocol message length must be greater than largest " | ||||
"possible INV message"); | "possible INV message"); | ||||
/** Maximum number of in-flight transaction requests from a peer. It is not a | /** 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 | * hard limit, but the threshold at which point the OVERLOADED_PEER_TX_DELAY | ||||
* kicks in. */ | * kicks in. */ | ||||
static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT = 100; | static constexpr int32_t MAX_PEER_TX_REQUEST_IN_FLIGHT = 100; | ||||
/** Maximum number of announced transactions from a peer */ | /** Maximum number of transactions to consider for requesting, per peer. It | ||||
static constexpr int32_t MAX_PEER_TX_ANNOUNCEMENTS = 2 * MAX_INV_SZ; | * 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 from non-preferred peers */ | /** How long to delay requesting transactions from non-preferred peers */ | ||||
static constexpr auto NONPREF_PEER_TX_DELAY = std::chrono::seconds{2}; | static constexpr auto NONPREF_PEER_TX_DELAY = std::chrono::seconds{2}; | ||||
/** How long to delay requesting transactions from overloaded peers (see | /** How long to delay requesting transactions from overloaded peers (see | ||||
* MAX_PEER_TX_REQUEST_IN_FLIGHT). */ | * MAX_PEER_TX_REQUEST_IN_FLIGHT). */ | ||||
static constexpr auto OVERLOADED_PEER_TX_DELAY = std::chrono::seconds{2}; | static constexpr auto OVERLOADED_PEER_TX_DELAY = std::chrono::seconds{2}; | ||||
/** | /** | ||||
* How long to wait (in microseconds) before downloading a transaction from an | * How long to wait (in microseconds) before downloading a transaction from an | ||||
* additional peer. | * additional peer. | ||||
▲ Show 20 Lines • Show All 791 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
} // namespace | } // namespace | ||||
void PeerManager::AddTxAnnouncement(const CNode &node, const TxId >xid, | void PeerManager::AddTxAnnouncement(const CNode &node, const TxId >xid, | ||||
std::chrono::microseconds current_time) { | std::chrono::microseconds current_time) { | ||||
AssertLockHeld(::cs_main); // For m_txrequest | AssertLockHeld(::cs_main); // For m_txrequest | ||||
NodeId nodeid = node.GetId(); | 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 | // Too many queued announcements from this peer | ||||
return; | return; | ||||
} | } | ||||
const CNodeState *state = State(nodeid); | const CNodeState *state = State(nodeid); | ||||
// Decide the TxRequestTracker parameters for this announcement: | // Decide the TxRequestTracker parameters for this announcement: | ||||
// - "preferred": if fPreferredDownload is set (= outbound, or PF_NOBAN | // - "preferred": if fPreferredDownload is set (= outbound, or PF_NOBAN | ||||
// permission) | // permission) | ||||
// - "reqtime": current time plus delays for: | // - "reqtime": current time plus delays for: | ||||
// - NONPREF_PEER_TX_DELAY for announcements from non-preferred | // - NONPREF_PEER_TX_DELAY for announcements from non-preferred | ||||
// connections | // connections | ||||
// - TXID_RELAY_DELAY for announcements from txid peers while wtxid peers | // - TXID_RELAY_DELAY for announcements from txid peers while wtxid peers | ||||
// are available | // are available | ||||
// - OVERLOADED_PEER_TX_DELAY for announcements from peers which have at | // - OVERLOADED_PEER_TX_DELAY for announcements from peers which have at | ||||
// least | // 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}; | auto delay = std::chrono::microseconds{0}; | ||||
const bool preferred = state->fPreferredDownload; | const bool preferred = state->fPreferredDownload; | ||||
if (!preferred) { | if (!preferred) { | ||||
delay += NONPREF_PEER_TX_DELAY; | delay += NONPREF_PEER_TX_DELAY; | ||||
} | } | ||||
const bool overloaded = | const bool overloaded = | ||||
!node.HasPermission(PF_RELAY) && | |||||
m_txrequest.CountInFlight(nodeid) >= MAX_PEER_TX_REQUEST_IN_FLIGHT; | m_txrequest.CountInFlight(nodeid) >= MAX_PEER_TX_REQUEST_IN_FLIGHT; | ||||
if (overloaded) { | if (overloaded) { | ||||
delay += OVERLOADED_PEER_TX_DELAY; | delay += OVERLOADED_PEER_TX_DELAY; | ||||
} | } | ||||
m_txrequest.ReceivedInv(nodeid, gtxid, preferred, current_time + delay); | m_txrequest.ReceivedInv(nodeid, gtxid, preferred, current_time + delay); | ||||
} | } | ||||
// This function is used for testing the stale tip eviction logic, see | // This function is used for testing the stale tip eviction logic, see | ||||
▲ Show 20 Lines • Show All 4,496 Lines • Show Last 20 Lines |