mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
merge bitcoin#24021: Rename and move PoissonNextSend functions
This commit is contained in:
parent
6d690ede82
commit
112c4e0a16
27
src/net.cpp
27
src/net.cpp
@ -2497,8 +2497,8 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
|||||||
auto start = GetTime<std::chrono::microseconds>();
|
auto start = GetTime<std::chrono::microseconds>();
|
||||||
|
|
||||||
// Minimum time before next feeler connection (in microseconds).
|
// Minimum time before next feeler connection (in microseconds).
|
||||||
auto next_feeler = PoissonNextSend(start, FEELER_INTERVAL);
|
auto next_feeler = GetExponentialRand(start, FEELER_INTERVAL);
|
||||||
auto next_extra_block_relay = PoissonNextSend(start, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
|
auto next_extra_block_relay = GetExponentialRand(start, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
|
||||||
const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED);
|
const bool dnsseed = gArgs.GetBoolArg("-dnsseed", DEFAULT_DNSSEED);
|
||||||
bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS);
|
bool add_fixed_seeds = gArgs.GetBoolArg("-fixedseeds", DEFAULT_FIXEDSEEDS);
|
||||||
|
|
||||||
@ -2632,7 +2632,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
|||||||
//
|
//
|
||||||
// This is similar to the logic for trying extra outbound (full-relay)
|
// This is similar to the logic for trying extra outbound (full-relay)
|
||||||
// peers, except:
|
// peers, except:
|
||||||
// - we do this all the time on a poisson timer, rather than just when
|
// - we do this all the time on an exponential timer, rather than just when
|
||||||
// our tip is stale
|
// our tip is stale
|
||||||
// - we potentially disconnect our next-youngest block-relay-only peer, if our
|
// - we potentially disconnect our next-youngest block-relay-only peer, if our
|
||||||
// newest block-relay-only peer delivers a block more recently.
|
// newest block-relay-only peer delivers a block more recently.
|
||||||
@ -2641,10 +2641,10 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect, CDe
|
|||||||
// Because we can promote these connections to block-relay-only
|
// Because we can promote these connections to block-relay-only
|
||||||
// connections, they do not get their own ConnectionType enum
|
// connections, they do not get their own ConnectionType enum
|
||||||
// (similar to how we deal with extra outbound peers).
|
// (similar to how we deal with extra outbound peers).
|
||||||
next_extra_block_relay = PoissonNextSend(now, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
|
next_extra_block_relay = GetExponentialRand(now, EXTRA_BLOCK_RELAY_ONLY_PEER_INTERVAL);
|
||||||
conn_type = ConnectionType::BLOCK_RELAY;
|
conn_type = ConnectionType::BLOCK_RELAY;
|
||||||
} else if (now > next_feeler) {
|
} else if (now > next_feeler) {
|
||||||
next_feeler = PoissonNextSend(now, FEELER_INTERVAL);
|
next_feeler = GetExponentialRand(now, FEELER_INTERVAL);
|
||||||
conn_type = ConnectionType::FEELER;
|
conn_type = ConnectionType::FEELER;
|
||||||
fFeeler = true;
|
fFeeler = true;
|
||||||
} else if (nOutboundOnionRelay < m_max_outbound_onion && IsReachable(Network::NET_ONION)) {
|
} else if (nOutboundOnionRelay < m_max_outbound_onion && IsReachable(Network::NET_ONION)) {
|
||||||
@ -4234,23 +4234,6 @@ bool CConnman::IsMasternodeOrDisconnectRequested(const CService& addr) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = PoissonNextSend(now, average_interval);
|
|
||||||
}
|
|
||||||
return m_next_send_inv_to_incoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
|
|
||||||
{
|
|
||||||
double unscaled = -log1p(GetRand(1ULL << 48) * -0.0000000000000035527136788 /* -1/2^48 */);
|
|
||||||
return now + std::chrono::duration_cast<std::chrono::microseconds>(unscaled * average_interval + 0.5us);
|
|
||||||
}
|
|
||||||
|
|
||||||
CConnman::NodesSnapshot::NodesSnapshot(const CConnman& connman, std::function<bool(const CNode* pnode)> filter,
|
CConnman::NodesSnapshot::NodesSnapshot(const CConnman& connman, std::function<bool(const CNode* pnode)> filter,
|
||||||
bool shuffle)
|
bool shuffle)
|
||||||
{
|
{
|
||||||
|
11
src/net.h
11
src/net.h
@ -1205,12 +1205,6 @@ public:
|
|||||||
|
|
||||||
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
|
void WakeMessageHandler() EXCLUSIVE_LOCKS_REQUIRED(!mutexMsgProc);
|
||||||
|
|
||||||
/** 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. */
|
/** Return true if we should disconnect the peer for failing an inactivity check. */
|
||||||
bool ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const;
|
bool ShouldRunInactivityChecks(const CNode& node, std::chrono::seconds now) const;
|
||||||
|
|
||||||
@ -1584,8 +1578,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
std::atomic_bool m_start_extra_block_relay_peers{false};
|
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
|
* A vector of -bind=<address>:<port>=onion arguments each of which is
|
||||||
* an address and port that are designated for incoming Tor connections.
|
* an address and port that are designated for incoming Tor connections.
|
||||||
@ -1616,9 +1608,6 @@ private:
|
|||||||
friend struct ConnmanTestMsg;
|
friend struct ConnmanTestMsg;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Return a timestamp in the future (in microseconds) for exponentially distributed events. */
|
|
||||||
std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval);
|
|
||||||
|
|
||||||
/** Dump binary message to file, with timestamp */
|
/** Dump binary message to file, with timestamp */
|
||||||
void CaptureMessageToFile(const CAddress& addr,
|
void CaptureMessageToFile(const CAddress& addr,
|
||||||
const std::string& msg_type,
|
const std::string& msg_type,
|
||||||
|
@ -565,6 +565,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
std::map<NodeId, PeerRef> m_peer_map GUARDED_BY(m_peer_mutex);
|
std::map<NodeId, PeerRef> m_peer_map GUARDED_BY(m_peer_mutex);
|
||||||
|
|
||||||
|
std::atomic<std::chrono::microseconds> m_next_inv_to_inbounds{0us};
|
||||||
|
|
||||||
/** Check whether the last unknown block a peer advertised is not yet known. */
|
/** Check whether the last unknown block a peer advertised is not yet known. */
|
||||||
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
void ProcessBlockAvailability(NodeId nodeid) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
/** Update tracking information about which blocks a peer is assumed to have. */
|
/** Update tracking information about which blocks a peer is assumed to have. */
|
||||||
@ -703,6 +705,15 @@ private:
|
|||||||
Mutex m_recent_confirmed_transactions_mutex;
|
Mutex m_recent_confirmed_transactions_mutex;
|
||||||
CRollingBloomFilter m_recent_confirmed_transactions GUARDED_BY(m_recent_confirmed_transactions_mutex){48'000, 0.000'001};
|
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 NextInvToInbounds(std::chrono::microseconds now,
|
||||||
|
std::chrono::seconds average_interval);
|
||||||
|
|
||||||
/* Returns a bool indicating whether we requested this block.
|
/* Returns a bool indicating whether we requested this block.
|
||||||
* Also used if a block was /not/ received and timed out or started with another peer
|
* Also used if a block was /not/ received and timed out or started with another peer
|
||||||
*/
|
*/
|
||||||
@ -1032,6 +1043,18 @@ static void UpdatePreferredDownload(const CNode& node, const Peer& peer, CNodeSt
|
|||||||
nPreferredDownload += state->fPreferredDownload;
|
nPreferredDownload += state->fPreferredDownload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::chrono::microseconds PeerManagerImpl::NextInvToInbounds(std::chrono::microseconds now,
|
||||||
|
std::chrono::seconds average_interval)
|
||||||
|
{
|
||||||
|
if (m_next_inv_to_inbounds.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_inv_to_inbounds = GetExponentialRand(now, average_interval);
|
||||||
|
}
|
||||||
|
return m_next_inv_to_inbounds;
|
||||||
|
}
|
||||||
|
|
||||||
bool PeerManagerImpl::MarkBlockAsReceived(const uint256& hash)
|
bool PeerManagerImpl::MarkBlockAsReceived(const uint256& hash)
|
||||||
{
|
{
|
||||||
std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
|
std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
|
||||||
@ -5279,13 +5302,13 @@ void PeerManagerImpl::MaybeSendAddr(CNode& node, Peer& peer, std::chrono::micros
|
|||||||
FastRandomContext insecure_rand;
|
FastRandomContext insecure_rand;
|
||||||
PushAddress(peer, local_addr, insecure_rand);
|
PushAddress(peer, local_addr, insecure_rand);
|
||||||
}
|
}
|
||||||
peer.m_next_local_addr_send = PoissonNextSend(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
|
peer.m_next_local_addr_send = GetExponentialRand(current_time, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We sent an `addr` message to this peer recently. Nothing more to do.
|
// We sent an `addr` message to this peer recently. Nothing more to do.
|
||||||
if (current_time <= peer.m_next_addr_send) return;
|
if (current_time <= peer.m_next_addr_send) return;
|
||||||
|
|
||||||
peer.m_next_addr_send = PoissonNextSend(current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
|
peer.m_next_addr_send = GetExponentialRand(current_time, AVG_ADDRESS_BROADCAST_INTERVAL);
|
||||||
|
|
||||||
if (!Assume(peer.m_addrs_to_send.size() <= MAX_ADDR_TO_SEND)) {
|
if (!Assume(peer.m_addrs_to_send.size() <= MAX_ADDR_TO_SEND)) {
|
||||||
// Should be impossible since we always check size before adding to
|
// Should be impossible since we always check size before adding to
|
||||||
@ -5660,12 +5683,12 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
if (peer->m_tx_relay->m_next_inv_send_time < current_time) {
|
if (peer->m_tx_relay->m_next_inv_send_time < current_time) {
|
||||||
fSendTrickle = true;
|
fSendTrickle = true;
|
||||||
if (pto->IsInboundConn()) {
|
if (pto->IsInboundConn()) {
|
||||||
peer->m_tx_relay->m_next_inv_send_time = m_connman.PoissonNextSendInbound(current_time, INBOUND_INVENTORY_BROADCAST_INTERVAL);
|
peer->m_tx_relay->m_next_inv_send_time = NextInvToInbounds(current_time, INBOUND_INVENTORY_BROADCAST_INTERVAL);
|
||||||
} else {
|
} else {
|
||||||
// Use half the delay for Masternode outbound peers, as there is less privacy concern for them.
|
// Use half the delay for Masternode outbound peers, as there is less privacy concern for them.
|
||||||
peer->m_tx_relay->m_next_inv_send_time = pto->GetVerifiedProRegTxHash().IsNull() ?
|
peer->m_tx_relay->m_next_inv_send_time = pto->GetVerifiedProRegTxHash().IsNull() ?
|
||||||
PoissonNextSend(current_time, OUTBOUND_INVENTORY_BROADCAST_INTERVAL) :
|
GetExponentialRand(current_time, OUTBOUND_INVENTORY_BROADCAST_INTERVAL) :
|
||||||
PoissonNextSend(current_time, OUTBOUND_INVENTORY_BROADCAST_INTERVAL / 2);
|
GetExponentialRand(current_time, OUTBOUND_INVENTORY_BROADCAST_INTERVAL / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <util/time.h> // for GetTimeMicros()
|
#include <util/time.h> // for GetTimeMicros()
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cmath>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@ -724,3 +725,9 @@ void RandomInit()
|
|||||||
|
|
||||||
ReportHardwareRand();
|
ReportHardwareRand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval)
|
||||||
|
{
|
||||||
|
double unscaled = -std::log1p(GetRand(uint64_t{1} << 48) * -0.0000000000000035527136788 /* -1/2^48 */);
|
||||||
|
return now + std::chrono::duration_cast<std::chrono::microseconds>(unscaled * average_interval + 0.5us);
|
||||||
|
}
|
||||||
|
12
src/random.h
12
src/random.h
@ -85,6 +85,18 @@ D GetRandomDuration(typename std::common_type<D>::type max) noexcept
|
|||||||
};
|
};
|
||||||
constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
|
constexpr auto GetRandMicros = GetRandomDuration<std::chrono::microseconds>;
|
||||||
constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
|
constexpr auto GetRandMillis = GetRandomDuration<std::chrono::milliseconds>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a timestamp in the future sampled from an exponential distribution
|
||||||
|
* (https://en.wikipedia.org/wiki/Exponential_distribution). This distribution
|
||||||
|
* is memoryless and should be used for repeated network events (e.g. sending a
|
||||||
|
* certain type of message) to minimize leaking information to observers.
|
||||||
|
*
|
||||||
|
* The probability of an event occuring before time x is 1 - e^-(x/a) where a
|
||||||
|
* is the average interval between events.
|
||||||
|
* */
|
||||||
|
std::chrono::microseconds GetExponentialRand(std::chrono::microseconds now, std::chrono::seconds average_interval);
|
||||||
|
|
||||||
int GetRandInt(int nMax) noexcept;
|
int GetRandInt(int nMax) noexcept;
|
||||||
uint256 GetRandHash() noexcept;
|
uint256 GetRandHash() noexcept;
|
||||||
|
|
||||||
|
@ -91,12 +91,6 @@ FUZZ_TARGET_INIT(connman, initialize_connman)
|
|||||||
[&] {
|
[&] {
|
||||||
(void)connman.OutboundTargetReached(fuzzed_data_provider.ConsumeBool());
|
(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;
|
CSerializedNetMsg serialized_net_msg;
|
||||||
serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE);
|
serialized_net_msg.m_type = fuzzed_data_provider.ConsumeRandomLengthString(CMessageHeader::COMMAND_SIZE);
|
||||||
|
Loading…
Reference in New Issue
Block a user