aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/net_processing.cpp26
1 files changed, 23 insertions, 3 deletions
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index ca94a1db11..bc09e94094 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -75,6 +75,8 @@ static const unsigned int MAX_INV_SZ = 50000;
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;
+/** How many microseconds to delay requesting transactions via txids, if we have wtxid-relaying peers */
+static constexpr std::chrono::microseconds TXID_RELAY_DELAY{std::chrono::seconds{2}};
/** How many microseconds to delay requesting transactions from inbound peers */
static constexpr std::chrono::microseconds INBOUND_PEER_TX_DELAY{std::chrono::seconds{2}};
/** How long to wait (in microseconds) before downloading a transaction from an additional peer */
@@ -219,6 +221,9 @@ namespace {
/** Number of peers from which we're downloading blocks. */
int nPeersWithValidatedDownloads GUARDED_BY(cs_main) = 0;
+ /** Number of peers with wtxid relay. */
+ int g_wtxid_relay_peers GUARDED_BY(cs_main) = 0;
+
/** Number of outbound peers with m_chain_sync.m_protect. */
int g_outbound_peers_with_protect_from_disconnect GUARDED_BY(cs_main) = 0;
@@ -764,7 +769,7 @@ void UpdateTxRequestTime(const uint256& txid, std::chrono::microseconds request_
}
}
-std::chrono::microseconds CalculateTxGetDataTime(const uint256& txid, std::chrono::microseconds current_time, bool use_inbound_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
+std::chrono::microseconds CalculateTxGetDataTime(const uint256& txid, std::chrono::microseconds current_time, bool use_inbound_delay, bool use_txid_delay) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
{
std::chrono::microseconds process_time;
const auto last_request_time = GetTxRequestTime(txid);
@@ -780,6 +785,9 @@ std::chrono::microseconds CalculateTxGetDataTime(const uint256& txid, std::chron
// We delay processing announcements from inbound peers
if (use_inbound_delay) process_time += INBOUND_PEER_TX_DELAY;
+ // We delay processing announcements from peers that use txid-relay (instead of wtxid)
+ if (use_txid_delay) process_time += TXID_RELAY_DELAY;
+
return process_time;
}
@@ -797,7 +805,7 @@ void RequestTx(CNodeState* state, const uint256& txid, std::chrono::microseconds
// Calculate the time to try requesting this transaction. Use
// fPreferredDownload as a proxy for outbound peers.
- const auto process_time = CalculateTxGetDataTime(txid, current_time, !state->fPreferredDownload);
+ const auto process_time = CalculateTxGetDataTime(txid, current_time, !state->fPreferredDownload, !state->m_wtxid_relay && g_wtxid_relay_peers > 0);
peer_download_state.m_tx_process_time.emplace(process_time, txid);
}
@@ -874,6 +882,8 @@ void PeerLogicValidation::FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTim
assert(nPeersWithValidatedDownloads >= 0);
g_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect;
assert(g_outbound_peers_with_protect_from_disconnect >= 0);
+ g_wtxid_relay_peers -= state->m_wtxid_relay;
+ assert(g_wtxid_relay_peers >= 0);
mapNodeState.erase(nodeid);
@@ -883,6 +893,7 @@ void PeerLogicValidation::FinalizeNode(NodeId nodeid, bool& fUpdateConnectionTim
assert(nPreferredDownload == 0);
assert(nPeersWithValidatedDownloads == 0);
assert(g_outbound_peers_with_protect_from_disconnect == 0);
+ assert(g_wtxid_relay_peers == 0);
}
LogPrint(BCLog::NET, "Cleared nodestate for peer=%d\n", nodeid);
}
@@ -2489,6 +2500,7 @@ void ProcessMessage(
LOCK(cs_main);
if (!State(pfrom.GetId())->m_wtxid_relay) {
State(pfrom.GetId())->m_wtxid_relay = true;
+ g_wtxid_relay_peers++;
}
}
return;
@@ -4490,7 +4502,15 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
// up processing to happen after the download times out
// (with a slight delay for inbound peers, to prefer
// requests to outbound peers).
- const auto next_process_time = CalculateTxGetDataTime(txid, current_time, !state.fPreferredDownload);
+ // Don't apply the txid-delay to re-requests of a
+ // transaction; the heuristic of delaying requests to
+ // txid-relay peers is to save bandwidth on initial
+ // announcement of a transaction, and doesn't make sense
+ // for a followup request if our first peer times out (and
+ // would open us up to an attacker using inbound
+ // wtxid-relay to prevent us from requesting transactions
+ // from outbound txid-relay peers).
+ const auto next_process_time = CalculateTxGetDataTime(txid, current_time, !state.fPreferredDownload, false);
tx_process_time.emplace(next_process_time, txid);
}
} else {