aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Newbery <john@johnnewbery.com>2021-12-14 10:35:37 +0000
committerMartin Zumsande <mzumsande@gmail.com>2022-01-13 15:55:01 +0100
commitea99f5d01e56ab0192d211da1034ffb299876937 (patch)
treeac2d9ad1df5486eb188ff69c4665477c3b46ff1b /src
parentbb060746df22c956b8f44e5b8cd1ae4ed73faddc (diff)
downloadbitcoin-ea99f5d01e56ab0192d211da1034ffb299876937.tar.xz
[net processing] Move PoissonNextSendInbound to PeerManager
Diffstat (limited to 'src')
-rw-r--r--src/net.cpp11
-rw-r--r--src/net.h8
-rw-r--r--src/net_processing.cpp25
-rw-r--r--src/test/fuzz/connman.cpp6
4 files changed, 24 insertions, 26 deletions
diff --git a/src/net.cpp b/src/net.cpp
index 3ce0b8ee81..a3ff6670b8 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -3058,17 +3058,6 @@ bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
return found != nullptr && NodeFullyConnected(found) && func(found);
}
-std::chrono::microseconds CConnman::PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval)
-{
- if (m_next_send_inv_to_incoming.load() < now) {
- // If this function were called from multiple threads simultaneously
- // it would possible that both update the next send variable, and return a different result to their caller.
- // This is not possible in practice as only the net processing thread invokes this function.
- m_next_send_inv_to_incoming = GetExponentialRand(now, average_interval);
- }
- return m_next_send_inv_to_incoming;
-}
-
CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const
{
return CSipHasher(nSeed0, nSeed1).Write(id);
diff --git a/src/net.h b/src/net.h
index b0162bb949..ea929b0d0e 100644
--- a/src/net.h
+++ b/src/net.h
@@ -936,12 +936,6 @@ public:
void WakeMessageHandler();
- /** Attempts to obfuscate tx time through exponentially distributed emitting.
- Works assuming that a single interval is used.
- Variable intervals will result in privacy decrease.
- */
- std::chrono::microseconds PoissonNextSendInbound(std::chrono::microseconds now, std::chrono::seconds average_interval);
-
/** Return true if we should disconnect the peer for failing an inactivity check. */
bool ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const;
@@ -1221,8 +1215,6 @@ private:
*/
std::atomic_bool m_start_extra_block_relay_peers{false};
- std::atomic<std::chrono::microseconds> m_next_send_inv_to_incoming{0us};
-
/**
* A vector of -bind=<address>:<port>=onion arguments each of which is
* an address and port that are designated for incoming Tor connections.
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index b24f94bd6d..8a7dc9e1f7 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -444,6 +444,8 @@ private:
*/
std::map<NodeId, PeerRef> m_peer_map GUARDED_BY(m_peer_mutex);
+ std::atomic<std::chrono::microseconds> m_next_send_inv_to_incoming{0us};
+
/** Number of nodes with fSyncStarted. */
int nSyncStarted GUARDED_BY(cs_main) = 0;
@@ -518,6 +520,15 @@ private:
Mutex m_recent_confirmed_transactions_mutex;
CRollingBloomFilter m_recent_confirmed_transactions GUARDED_BY(m_recent_confirmed_transactions_mutex){48'000, 0.000'001};
+ /**
+ * For sending `inv`s to inbound peers, we use a single (exponentially
+ * distributed) timer for all peers. If we used a separate timer for each
+ * peer, a spy node could make multiple inbound connections to us to
+ * accurately determine when we received the transaction (and potentially
+ * determine the transaction's origin). */
+ std::chrono::microseconds PoissonNextSendInbound(std::chrono::microseconds now,
+ std::chrono::seconds average_interval);
+
/** Have we requested this block from a peer */
bool IsBlockRequested(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
@@ -819,6 +830,18 @@ static void UpdatePreferredDownload(const CNode& node, CNodeState* state) EXCLUS
nPreferredDownload += state->fPreferredDownload;
}
+std::chrono::microseconds PeerManagerImpl::PoissonNextSendInbound(std::chrono::microseconds now,
+ std::chrono::seconds average_interval)
+{
+ if (m_next_send_inv_to_incoming.load() < now) {
+ // If this function were called from multiple threads simultaneously
+ // it would possible that both update the next send variable, and return a different result to their caller.
+ // This is not possible in practice as only the net processing thread invokes this function.
+ m_next_send_inv_to_incoming = GetExponentialRand(now, average_interval);
+ }
+ return m_next_send_inv_to_incoming;
+}
+
bool PeerManagerImpl::IsBlockRequested(const uint256& hash)
{
return mapBlocksInFlight.find(hash) != mapBlocksInFlight.end();
@@ -4786,7 +4809,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
if (pto->m_tx_relay->nNextInvSend < current_time) {
fSendTrickle = true;
if (pto->IsInboundConn()) {
- pto->m_tx_relay->nNextInvSend = m_connman.PoissonNextSendInbound(current_time, INBOUND_INVENTORY_BROADCAST_INTERVAL);
+ pto->m_tx_relay->nNextInvSend = PoissonNextSendInbound(current_time, INBOUND_INVENTORY_BROADCAST_INTERVAL);
} else {
pto->m_tx_relay->nNextInvSend = GetExponentialRand(current_time, OUTBOUND_INVENTORY_BROADCAST_INTERVAL);
}
diff --git a/src/test/fuzz/connman.cpp b/src/test/fuzz/connman.cpp
index f87b6f1503..b615462001 100644
--- a/src/test/fuzz/connman.cpp
+++ b/src/test/fuzz/connman.cpp
@@ -90,12 +90,6 @@ FUZZ_TARGET_INIT(connman, initialize_connman)
(void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
},
[&] {
- // Limit now to int32_t to avoid signed integer overflow
- (void)connman.PoissonNextSendInbound(
- std::chrono::microseconds{fuzzed_data_provider.ConsumeIntegral<int32_t>()},
- std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<int>()});
- },
- [&] {
CSerializedNetMsg serialized_net_msg;
serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE);
serialized_net_msg.data = ConsumeRandomLengthByteVector(fuzzed_data_provider);