Skip to content

Commit d45b344

Browse files
committed
Bucket for inbound when scheduling invs to hide tx time
1 parent 287e4ed commit d45b344

File tree

4 files changed

+45
-19
lines changed

4 files changed

+45
-19
lines changed

src/net.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,8 +2864,20 @@ bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
28642864
return found != nullptr && NodeFullyConnected(found) && func(found);
28652865
}
28662866

2867-
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
2868-
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
2867+
int64_t CConnman::PoissonNextSendInbound(int64_t now, int average_interval_seconds)
2868+
{
2869+
if (m_next_send_inv_to_incoming < now) {
2870+
// If this function were called from multiple threads simultaneously
2871+
// it would possible that both update the next send variable, and return a different result to their caller.
2872+
// This is not possible in practice as only the net processing thread invokes this function.
2873+
m_next_send_inv_to_incoming = PoissonNextSend(now, average_interval_seconds);
2874+
}
2875+
return m_next_send_inv_to_incoming;
2876+
}
2877+
2878+
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
2879+
{
2880+
return now + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
28692881
}
28702882

28712883
CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const

src/net.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ class CConnman
310310
unsigned int GetReceiveFloodSize() const;
311311

312312
void WakeMessageHandler();
313+
314+
/** Attempts to obfuscate tx time through exponentially distributed emitting.
315+
Works assuming that a single interval is used.
316+
Variable intervals will result in privacy decrease.
317+
*/
318+
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds);
319+
313320
private:
314321
struct ListenSocket {
315322
SOCKET socket;
@@ -434,6 +441,8 @@ class CConnman
434441
* This takes the place of a feeler connection */
435442
std::atomic_bool m_try_another_outbound_peer;
436443

444+
std::atomic<int64_t> m_next_send_inv_to_incoming;
445+
437446
friend struct CConnmanTest;
438447
};
439448
extern std::unique_ptr<CConnman> g_connman;
@@ -863,6 +872,6 @@ class CNode
863872

864873

865874
/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
866-
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
875+
int64_t PoissonNextSend(int64_t now, int average_interval_seconds);
867876

868877
#endif // BITCOIN_NET_H

src/net_processing.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,21 @@ static const int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60;
7171
/// limiting block relay. Set to one week, denominated in seconds.
7272
static const int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60;
7373

74+
/** Average delay between local address broadcasts in seconds. */
75+
static constexpr unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 60 * 60;
76+
/** Average delay between peer address broadcasts in seconds. */
77+
static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30;
78+
/** Average delay between trickled inventory transmissions in seconds.
79+
* Blocks and whitelisted receivers bypass this, outbound peers get half this delay. */
80+
static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
81+
/** Maximum number of inventory items to send per transmission.
82+
* Limits the impact of low-fee transaction floods. */
83+
static constexpr unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL;
84+
/** Average delay between feefilter broadcasts in seconds. */
85+
static constexpr unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60;
86+
/** Maximum feefilter broadcast delay after significant change. */
87+
static constexpr unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60;
88+
7489
// Internal stuff
7590
namespace {
7691
/** Number of nodes with fSyncStarted. */
@@ -3496,8 +3511,12 @@ bool PeerLogicValidation::SendMessages(CNode* pto, std::atomic<bool>& interruptM
34963511
bool fSendTrickle = pto->fWhitelisted;
34973512
if (pto->nNextInvSend < nNow) {
34983513
fSendTrickle = true;
3499-
// Use half the delay for outbound peers, as there is less privacy concern for them.
3500-
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
3514+
if (pto->fInbound) {
3515+
pto->nNextInvSend = connman->PoissonNextSendInbound(nNow, INVENTORY_BROADCAST_INTERVAL);
3516+
} else {
3517+
// Use half the delay for outbound peers, as there is less privacy concern for them.
3518+
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> 1);
3519+
}
35013520
}
35023521

35033522
// Time to send but the peer has requested we not relay transactions.

src/validation.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -104,20 +104,6 @@ static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60;
104104
static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60;
105105
/** Maximum length of reject messages. */
106106
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
107-
/** Average delay between local address broadcasts in seconds. */
108-
static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 60 * 60;
109-
/** Average delay between peer address broadcasts in seconds. */
110-
static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30;
111-
/** Average delay between trickled inventory transmissions in seconds.
112-
* Blocks and whitelisted receivers bypass this, outbound peers get half this delay. */
113-
static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
114-
/** Maximum number of inventory items to send per transmission.
115-
* Limits the impact of low-fee transaction floods. */
116-
static const unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL;
117-
/** Average delay between feefilter broadcasts in seconds. */
118-
static const unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60;
119-
/** Maximum feefilter broadcast delay after significant change. */
120-
static const unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60;
121107
/** Block download timeout base, expressed in millionths of the block interval (i.e. 10 min) */
122108
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 1000000;
123109
/** Additional block download timeout per parallel downloading peer (i.e. 5 min) */

0 commit comments

Comments
 (0)