Skip to content

Commit 9bbf08b

Browse files
committed
Merge #20721: Net: Move ping data to net_processing
a5e15ae scripted-diff: rename ping members (John Newbery) 45dcf22 [net processing] Move ping data fields to net processing (John Newbery) dd2646d [net processing] Move ping timeout logic to net processing (John Newbery) 0b43b81 [net processing] Move send ping message logic into function (John Newbery) 1a07600 [net] Add RunInactivityChecks() (John Newbery) f8b3058 [net processing] Add Peer& arg to MaybeDiscourageAndDisconnect() (John Newbery) Pull request description: This continues the work of moving application layer data into net_processing, by moving all ping data into the new Peer object added in #19607. For motivation, see #19398. ACKs for top commit: glozow: reACK bitcoin/bitcoin@a5e15ae MarcoFalke: review ACK a5e15ae 🥉 amitiuttarwar: ACK a5e15ae Tree-SHA512: fb84241613d6a6e1f2832fa5378030b5877a02e8308188f57ab545a6eaf2ab731a93abb7dcd3a7f7285bb66700f938096378a8e90cd6a3e6f3309f81d85a344e
2 parents b55dc3a + a5e15ae commit 9bbf08b

File tree

7 files changed

+136
-105
lines changed

7 files changed

+136
-105
lines changed

src/net.cpp

Lines changed: 10 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -601,21 +601,8 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
601601
stats.minFeeFilter = 0;
602602
}
603603

604-
// It is common for nodes with good ping times to suddenly become lagged,
605-
// due to a new block arriving or other large transfer.
606-
// Merely reporting pingtime might fool the caller into thinking the node was still responsive,
607-
// since pingtime does not update until the ping is complete, which might take a while.
608-
// So, if a ping is taking an unusually long time in flight,
609-
// the caller can immediately detect that this is happening.
610-
std::chrono::microseconds ping_wait{0};
611-
if ((0 != nPingNonceSent) && (0 != m_ping_start.load().count())) {
612-
ping_wait = GetTime<std::chrono::microseconds>() - m_ping_start.load();
613-
}
614-
615-
// Raw ping time is in microseconds, but show it to user as whole seconds (Bitcoin users should be well used to small numbers with many decimal places by now :)
616-
stats.m_ping_usec = nPingUsecTime;
617-
stats.m_min_ping_usec = nMinPingUsecTime;
618-
stats.m_ping_wait_usec = count_microseconds(ping_wait);
604+
stats.m_ping_usec = m_last_ping_time;
605+
stats.m_min_ping_usec = m_min_ping_time;
619606

620607
// Leave string empty if addrLocal invalid (not filled in yet)
621608
CService addrLocalUnlocked = GetAddrLocal();
@@ -837,7 +824,7 @@ size_t CConnman::SocketSendData(CNode& node) const
837824

838825
static bool ReverseCompareNodeMinPingTime(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
839826
{
840-
return a.nMinPingUsecTime > b.nMinPingUsecTime;
827+
return a.m_min_ping_time > b.m_min_ping_time;
841828
}
842829

843830
static bool ReverseCompareNodeTimeConnected(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b)
@@ -992,7 +979,7 @@ bool CConnman::AttemptToEvictConnection()
992979
peer_relay_txes = node->m_tx_relay->fRelayTxes;
993980
peer_filter_not_null = node->m_tx_relay->pfilter != nullptr;
994981
}
995-
NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
982+
NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->m_min_ping_time,
996983
node->nLastBlockTime, node->nLastTXTime,
997984
HasAllDesirableServiceFlags(node->nServices),
998985
peer_relay_txes, peer_filter_not_null, node->nKeyedNetGroup,
@@ -1221,18 +1208,17 @@ void CConnman::NotifyNumConnectionsChanged()
12211208
}
12221209
}
12231210

1211+
bool CConnman::RunInactivityChecks(const CNode& node) const
1212+
{
1213+
return GetSystemTimeInSeconds() > node.nTimeConnected + m_peer_connect_timeout;
1214+
}
1215+
12241216
bool CConnman::InactivityCheck(const CNode& node) const
12251217
{
12261218
// Use non-mockable system time (otherwise these timers will pop when we
12271219
// use setmocktime in the tests).
12281220
int64_t now = GetSystemTimeInSeconds();
12291221

1230-
if (now <= node.nTimeConnected + m_peer_connect_timeout) {
1231-
// Only run inactivity checks if the peer has been connected longer
1232-
// than m_peer_connect_timeout.
1233-
return false;
1234-
}
1235-
12361222
if (node.nLastRecv == 0 || node.nLastSend == 0) {
12371223
LogPrint(BCLog::NET, "socket no message in first %i seconds, %d %d peer=%d\n", m_peer_connect_timeout, node.nLastRecv != 0, node.nLastSend != 0, node.GetId());
12381224
return true;
@@ -1248,14 +1234,6 @@ bool CConnman::InactivityCheck(const CNode& node) const
12481234
return true;
12491235
}
12501236

1251-
if (node.nPingNonceSent && node.m_ping_start.load() + std::chrono::seconds{TIMEOUT_INTERVAL} < GetTime<std::chrono::microseconds>()) {
1252-
// We use mockable time for ping timeouts. This means that setmocktime
1253-
// may cause pings to time out for peers that have been connected for
1254-
// longer than m_peer_connect_timeout.
1255-
LogPrint(BCLog::NET, "ping timeout: %fs peer=%d\n", 0.000001 * count_microseconds(GetTime<std::chrono::microseconds>() - node.m_ping_start.load()), node.GetId());
1256-
return true;
1257-
}
1258-
12591237
if (!node.fSuccessfullyConnected) {
12601238
LogPrint(BCLog::NET, "version handshake timeout peer=%d\n", node.GetId());
12611239
return true;
@@ -1537,7 +1515,7 @@ void CConnman::SocketHandler()
15371515
if (bytes_sent) RecordBytesSent(bytes_sent);
15381516
}
15391517

1540-
if (InactivityCheck(*pnode)) pnode->fDisconnect = true;
1518+
if (RunInactivityChecks(*pnode) && InactivityCheck(*pnode)) pnode->fDisconnect = true;
15411519
}
15421520
{
15431521
LOCK(cs_vNodes);

src/net.h

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,6 @@ class CNodeStats
260260
mapMsgCmdSize mapRecvBytesPerMsgCmd;
261261
NetPermissionFlags m_permissionFlags;
262262
int64_t m_ping_usec;
263-
int64_t m_ping_wait_usec;
264263
int64_t m_min_ping_usec;
265264
CAmount minFeeFilter;
266265
// Our address, as reported by the peer
@@ -591,17 +590,12 @@ class CNode
591590
* in CConnman::AttemptToEvictConnection. */
592591
std::atomic<int64_t> nLastTXTime{0};
593592

594-
// Ping time measurement:
595-
// The pong reply we're expecting, or 0 if no pong expected.
596-
std::atomic<uint64_t> nPingNonceSent{0};
597-
/** When the last ping was sent, or 0 if no ping was ever sent */
598-
std::atomic<std::chrono::microseconds> m_ping_start{0us};
599-
// Last measured round-trip time.
600-
std::atomic<int64_t> nPingUsecTime{0};
601-
// Best measured round-trip time.
602-
std::atomic<int64_t> nMinPingUsecTime{std::numeric_limits<int64_t>::max()};
603-
// Whether a ping is requested.
604-
std::atomic<bool> fPingQueued{false};
593+
/** Last measured round-trip time. Used only for RPC/GUI stats/debugging.*/
594+
std::atomic<int64_t> m_last_ping_time{0};
595+
596+
/** Lowest measured round-trip time. Used as an inbound peer eviction
597+
* criterium in CConnman::AttemptToEvictConnection. */
598+
std::atomic<int64_t> m_min_ping_time{std::numeric_limits<int64_t>::max()};
605599

606600
CNode(NodeId id, ServiceFlags nLocalServicesIn, SOCKET hSocketIn, const CAddress& addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress& addrBindIn, const std::string& addrNameIn, ConnectionType conn_type_in, bool inbound_onion);
607601
~CNode();
@@ -721,6 +715,12 @@ class CNode
721715

722716
std::string ConnectionTypeAsString() const { return ::ConnectionTypeAsString(m_conn_type); }
723717

718+
/** A ping-pong round trip has completed successfully. Update latest and minimum ping times. */
719+
void PongReceived(std::chrono::microseconds ping_time) {
720+
m_last_ping_time = count_microseconds(ping_time);
721+
m_min_ping_time = std::min(m_min_ping_time.load(), count_microseconds(ping_time));
722+
}
723+
724724
private:
725725
const NodeId id;
726726
const uint64_t nLocalHostNonce;
@@ -1022,6 +1022,9 @@ class CConnman
10221022

10231023
void SetAsmap(std::vector<bool> asmap) { addrman.m_asmap = std::move(asmap); }
10241024

1025+
/** Return true if the peer has been connected for long enough to do inactivity checks. */
1026+
bool RunInactivityChecks(const CNode& node) const;
1027+
10251028
private:
10261029
struct ListenSocket {
10271030
public:
@@ -1250,7 +1253,7 @@ struct NodeEvictionCandidate
12501253
{
12511254
NodeId id;
12521255
int64_t nTimeConnected;
1253-
int64_t nMinPingUsecTime;
1256+
int64_t m_min_ping_time;
12541257
int64_t nLastBlockTime;
12551258
int64_t nLastTXTime;
12561259
bool fRelevantServices;

0 commit comments

Comments
 (0)