mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
Merge #17243: p2p: add PoissonNextSend method that returns mockable time
1a8f0d5a74
[tools] update nNextInvSend to use mockable time (Amiti Uttarwar)4de630354f
[tools] add PoissonNextSend method that returns mockable time (Amiti Uttarwar) Pull request description: Introduce a Poisson helper method that wraps the existing method to return `std::chrono::duration` type, which is mockable. Needed for https://github.com/bitcoin/bitcoin/pull/16698. ACKs for top commit: ajtowns: ACK1a8f0d5a74
MarcoFalke: re-ACK1a8f0d5a74
naumenkogs: ACK1a8f0d5
, and let's merge it and come back to it later. Tree-SHA512: 7e2325d7c55fc0b4357cb86b83e0c218ba269f678c1786342d8bc380bfd9696373bc24ff124b9ff17a6e761c62b2b44ff5247c3911e2afdc7cc5c20417e8290b
This commit is contained in:
commit
c7e6b3b343
3 changed files with 27 additions and 9 deletions
12
src/net.h
12
src/net.h
|
@ -808,7 +808,7 @@ public:
|
||||||
bool fSendMempool GUARDED_BY(cs_tx_inventory){false};
|
bool fSendMempool GUARDED_BY(cs_tx_inventory){false};
|
||||||
// Last time a "MEMPOOL" request was serviced.
|
// Last time a "MEMPOOL" request was serviced.
|
||||||
std::atomic<std::chrono::seconds> m_last_mempool_req{std::chrono::seconds{0}};
|
std::atomic<std::chrono::seconds> m_last_mempool_req{std::chrono::seconds{0}};
|
||||||
int64_t nNextInvSend{0};
|
std::chrono::microseconds nNextInvSend{0};
|
||||||
|
|
||||||
CCriticalSection cs_feeFilter;
|
CCriticalSection cs_feeFilter;
|
||||||
// Minimum fee rate with which to filter inv's to this node
|
// Minimum fee rate with which to filter inv's to this node
|
||||||
|
@ -991,11 +991,13 @@ public:
|
||||||
void MaybeSetAddrName(const std::string& addrNameIn);
|
void MaybeSetAddrName(const std::string& addrNameIn);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** 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 now, int average_interval_seconds);
|
int64_t PoissonNextSend(int64_t now, int average_interval_seconds);
|
||||||
|
|
||||||
|
/** Wrapper to return mockable type */
|
||||||
|
inline std::chrono::microseconds PoissonNextSend(std::chrono::microseconds now, std::chrono::seconds average_interval)
|
||||||
|
{
|
||||||
|
return std::chrono::microseconds{PoissonNextSend(now.count(), average_interval.count())};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BITCOIN_NET_H
|
#endif // BITCOIN_NET_H
|
||||||
|
|
|
@ -3575,6 +3575,8 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
||||||
|
|
||||||
// Address refresh broadcast
|
// Address refresh broadcast
|
||||||
int64_t nNow = GetTimeMicros();
|
int64_t nNow = GetTimeMicros();
|
||||||
|
auto current_time = GetTime<std::chrono::microseconds>();
|
||||||
|
|
||||||
if (pto->IsAddrRelayPeer() && !::ChainstateActive().IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
|
if (pto->IsAddrRelayPeer() && !::ChainstateActive().IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) {
|
||||||
AdvertiseLocal(pto);
|
AdvertiseLocal(pto);
|
||||||
pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
|
pto->nNextLocalAddrSend = PoissonNextSend(nNow, AVG_LOCAL_ADDRESS_BROADCAST_INTERVAL);
|
||||||
|
@ -3796,13 +3798,13 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
||||||
LOCK(pto->m_tx_relay->cs_tx_inventory);
|
LOCK(pto->m_tx_relay->cs_tx_inventory);
|
||||||
// Check whether periodic sends should happen
|
// Check whether periodic sends should happen
|
||||||
bool fSendTrickle = pto->HasPermission(PF_NOBAN);
|
bool fSendTrickle = pto->HasPermission(PF_NOBAN);
|
||||||
if (pto->m_tx_relay->nNextInvSend < nNow) {
|
if (pto->m_tx_relay->nNextInvSend < current_time) {
|
||||||
fSendTrickle = true;
|
fSendTrickle = true;
|
||||||
if (pto->fInbound) {
|
if (pto->fInbound) {
|
||||||
pto->m_tx_relay->nNextInvSend = connman->PoissonNextSendInbound(nNow, INVENTORY_BROADCAST_INTERVAL);
|
pto->m_tx_relay->nNextInvSend = std::chrono::microseconds{connman->PoissonNextSendInbound(nNow, INVENTORY_BROADCAST_INTERVAL)};
|
||||||
} else {
|
} else {
|
||||||
// Use half the delay for outbound peers, as there is less privacy concern for them.
|
// Use half the delay for outbound peers, as there is less privacy concern for them.
|
||||||
pto->m_tx_relay->nNextInvSend = PoissonNextSend(nNow, INVENTORY_BROADCAST_INTERVAL >> 1);
|
pto->m_tx_relay->nNextInvSend = PoissonNextSend(current_time, std::chrono::seconds{INVENTORY_BROADCAST_INTERVAL >> 1});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3917,7 +3919,7 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
|
||||||
connman->PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
|
connman->PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv));
|
||||||
|
|
||||||
// Detect whether we're stalling
|
// Detect whether we're stalling
|
||||||
const auto current_time = GetTime<std::chrono::microseconds>();
|
current_time = GetTime<std::chrono::microseconds>();
|
||||||
// nNow is the current system time (GetTimeMicros is not mockable) and
|
// nNow is the current system time (GetTimeMicros is not mockable) and
|
||||||
// should be replaced by the mockable current_time eventually
|
// should be replaced by the mockable current_time eventually
|
||||||
nNow = GetTimeMicros();
|
nNow = GetTimeMicros();
|
||||||
|
|
|
@ -301,5 +301,19 @@ BOOST_AUTO_TEST_CASE(LocalAddress_BasicLifecycle)
|
||||||
BOOST_CHECK_EQUAL(IsLocal(addr), false);
|
BOOST_CHECK_EQUAL(IsLocal(addr), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(PoissonNextSend)
|
||||||
|
{
|
||||||
|
g_mock_deterministic_tests = true;
|
||||||
|
|
||||||
|
int64_t now = 5000;
|
||||||
|
int average_interval_seconds = 600;
|
||||||
|
|
||||||
|
auto poisson = ::PoissonNextSend(now, average_interval_seconds);
|
||||||
|
std::chrono::microseconds poisson_chrono = ::PoissonNextSend(std::chrono::microseconds{now}, std::chrono::seconds{average_interval_seconds});
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL(poisson, poisson_chrono.count());
|
||||||
|
|
||||||
|
g_mock_deterministic_tests = false;
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Add table
Reference in a new issue