Bucket for inbound when scheduling invs to hide tx time
This commit is contained in:
parent
287e4edc2f
commit
d45b344ffd
4 changed files with 45 additions and 19 deletions
16
src/net.cpp
16
src/net.cpp
|
@ -2864,8 +2864,20 @@ bool CConnman::ForNode(NodeId id, std::function<bool(CNode* pnode)> func)
|
||||||
return found != nullptr && NodeFullyConnected(found) && func(found);
|
return found != nullptr && NodeFullyConnected(found) && func(found);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds) {
|
int64_t CConnman::PoissonNextSendInbound(int64_t now, int average_interval_seconds)
|
||||||
return nNow + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
|
{
|
||||||
|
if (m_next_send_inv_to_incoming < 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 = PoissonNextSend(now, average_interval_seconds);
|
||||||
|
}
|
||||||
|
return m_next_send_inv_to_incoming;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t PoissonNextSend(int64_t now, int average_interval_seconds)
|
||||||
|
{
|
||||||
|
return now + (int64_t)(log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */) * average_interval_seconds * -1000000.0 + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const
|
CSipHasher CConnman::GetDeterministicRandomizer(uint64_t id) const
|
||||||
|
|
11
src/net.h
11
src/net.h
|
@ -310,6 +310,13 @@ public:
|
||||||
unsigned int GetReceiveFloodSize() const;
|
unsigned int GetReceiveFloodSize() const;
|
||||||
|
|
||||||
void WakeMessageHandler();
|
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.
|
||||||
|
*/
|
||||||
|
int64_t PoissonNextSendInbound(int64_t now, int average_interval_seconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ListenSocket {
|
struct ListenSocket {
|
||||||
SOCKET socket;
|
SOCKET socket;
|
||||||
|
@ -434,6 +441,8 @@ private:
|
||||||
* This takes the place of a feeler connection */
|
* This takes the place of a feeler connection */
|
||||||
std::atomic_bool m_try_another_outbound_peer;
|
std::atomic_bool m_try_another_outbound_peer;
|
||||||
|
|
||||||
|
std::atomic<int64_t> m_next_send_inv_to_incoming;
|
||||||
|
|
||||||
friend struct CConnmanTest;
|
friend struct CConnmanTest;
|
||||||
};
|
};
|
||||||
extern std::unique_ptr<CConnman> g_connman;
|
extern std::unique_ptr<CConnman> g_connman;
|
||||||
|
@ -863,6 +872,6 @@ public:
|
||||||
|
|
||||||
|
|
||||||
/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
|
/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
|
||||||
int64_t PoissonNextSend(int64_t nNow, int average_interval_seconds);
|
int64_t PoissonNextSend(int64_t now, int average_interval_seconds);
|
||||||
|
|
||||||
#endif // BITCOIN_NET_H
|
#endif // BITCOIN_NET_H
|
||||||
|
|
|
@ -71,6 +71,21 @@ static const int STALE_RELAY_AGE_LIMIT = 30 * 24 * 60 * 60;
|
||||||
/// limiting block relay. Set to one week, denominated in seconds.
|
/// limiting block relay. Set to one week, denominated in seconds.
|
||||||
static const int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60;
|
static const int HISTORICAL_BLOCK_AGE = 7 * 24 * 60 * 60;
|
||||||
|
|
||||||
|
/** Average delay between local address broadcasts in seconds. */
|
||||||
|
static constexpr unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 60 * 60;
|
||||||
|
/** Average delay between peer address broadcasts in seconds. */
|
||||||
|
static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30;
|
||||||
|
/** Average delay between trickled inventory transmissions in seconds.
|
||||||
|
* Blocks and whitelisted receivers bypass this, outbound peers get half this delay. */
|
||||||
|
static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
|
||||||
|
/** Maximum number of inventory items to send per transmission.
|
||||||
|
* Limits the impact of low-fee transaction floods. */
|
||||||
|
static constexpr unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL;
|
||||||
|
/** Average delay between feefilter broadcasts in seconds. */
|
||||||
|
static constexpr unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60;
|
||||||
|
/** Maximum feefilter broadcast delay after significant change. */
|
||||||
|
static constexpr unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60;
|
||||||
|
|
||||||
// Internal stuff
|
// Internal stuff
|
||||||
namespace {
|
namespace {
|
||||||
/** Number of nodes with fSyncStarted. */
|
/** Number of nodes with fSyncStarted. */
|
||||||
|
@ -3496,8 +3511,12 @@ bool PeerLogicValidation::SendMessages(CNode* pto, std::atomic<bool>& interruptM
|
||||||
bool fSendTrickle = pto->fWhitelisted;
|
bool fSendTrickle = pto->fWhitelisted;
|
||||||
if (pto->nNextInvSend < nNow) {
|
if (pto->nNextInvSend < nNow) {
|
||||||
fSendTrickle = true;
|
fSendTrickle = true;
|
||||||
// Use half the delay for outbound peers, as there is less privacy concern for them.
|
if (pto->fInbound) {
|
||||||
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> !pto->fInbound);
|
pto->nNextInvSend = connman->PoissonNextSendInbound(nNow, INVENTORY_BROADCAST_INTERVAL);
|
||||||
|
} else {
|
||||||
|
// Use half the delay for outbound peers, as there is less privacy concern for them.
|
||||||
|
pto->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time to send but the peer has requested we not relay transactions.
|
// Time to send but the peer has requested we not relay transactions.
|
||||||
|
|
|
@ -104,20 +104,6 @@ static const unsigned int DATABASE_WRITE_INTERVAL = 60 * 60;
|
||||||
static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60;
|
static const unsigned int DATABASE_FLUSH_INTERVAL = 24 * 60 * 60;
|
||||||
/** Maximum length of reject messages. */
|
/** Maximum length of reject messages. */
|
||||||
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
|
static const unsigned int MAX_REJECT_MESSAGE_LENGTH = 111;
|
||||||
/** Average delay between local address broadcasts in seconds. */
|
|
||||||
static const unsigned int AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL = 24 * 60 * 60;
|
|
||||||
/** Average delay between peer address broadcasts in seconds. */
|
|
||||||
static const unsigned int AVG_ADDRESS_BROADCAST_INTERVAL = 30;
|
|
||||||
/** Average delay between trickled inventory transmissions in seconds.
|
|
||||||
* Blocks and whitelisted receivers bypass this, outbound peers get half this delay. */
|
|
||||||
static const unsigned int INVENTORY_BROADCAST_INTERVAL = 5;
|
|
||||||
/** Maximum number of inventory items to send per transmission.
|
|
||||||
* Limits the impact of low-fee transaction floods. */
|
|
||||||
static const unsigned int INVENTORY_BROADCAST_MAX = 7 * INVENTORY_BROADCAST_INTERVAL;
|
|
||||||
/** Average delay between feefilter broadcasts in seconds. */
|
|
||||||
static const unsigned int AVG_FEEFILTER_BROADCAST_INTERVAL = 10 * 60;
|
|
||||||
/** Maximum feefilter broadcast delay after significant change. */
|
|
||||||
static const unsigned int MAX_FEEFILTER_CHANGE_DELAY = 5 * 60;
|
|
||||||
/** Block download timeout base, expressed in millionths of the block interval (i.e. 10 min) */
|
/** Block download timeout base, expressed in millionths of the block interval (i.e. 10 min) */
|
||||||
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 1000000;
|
static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 1000000;
|
||||||
/** Additional block download timeout per parallel downloading peer (i.e. 5 min) */
|
/** Additional block download timeout per parallel downloading peer (i.e. 5 min) */
|
||||||
|
|
Loading…
Reference in a new issue