Skip to content

Commit 99464bc

Browse files
committed
net: Consistently use GetTimeMicros() for inactivity checks
The use of mocktime in test logic means that comparisons between GetTime() and GetTimeMicros()/1000000 are unreliable since the former can use mocktime values while the latter always gets the system clock; this changes the networking code's inactivity checks to consistently use the system clock for inactivity comparisons. Also remove some hacks from setmocktime() that are no longer needed, now that we're using the system clock for nLastSend and nLastRecv.
1 parent 054d664 commit 99464bc

File tree

5 files changed

+28
-18
lines changed

5 files changed

+28
-18
lines changed

src/net.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
391391
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
392392
CNode* pnode = new CNode(id, nLocalServices, GetBestHeight(), hSocket, addrConnect, CalculateKeyedNetGroup(addrConnect), nonce, pszDest ? pszDest : "", false);
393393
pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
394-
pnode->nTimeConnected = GetTime();
394+
pnode->nTimeConnected = GetSystemTimeInSeconds();
395395
pnode->AddRef();
396396
GetNodeSignals().InitializeNode(pnode, *this);
397397
{
@@ -771,7 +771,7 @@ size_t CConnman::SocketSendData(CNode *pnode)
771771
assert(data.size() > pnode->nSendOffset);
772772
int nBytes = send(pnode->hSocket, reinterpret_cast<const char*>(data.data()) + pnode->nSendOffset, data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
773773
if (nBytes > 0) {
774-
pnode->nLastSend = GetTime();
774+
pnode->nLastSend = GetSystemTimeInSeconds();
775775
pnode->nSendBytes += nBytes;
776776
pnode->nSendOffset += nBytes;
777777
nSentSize += nBytes;
@@ -1284,7 +1284,7 @@ void CConnman::ThreadSocketHandler()
12841284
//
12851285
// Inactivity checking
12861286
//
1287-
int64_t nTime = GetTime();
1287+
int64_t nTime = GetSystemTimeInSeconds();
12881288
if (nTime - pnode->nTimeConnected > 60)
12891289
{
12901290
if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
@@ -2570,7 +2570,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
25702570
nLastRecv = 0;
25712571
nSendBytes = 0;
25722572
nRecvBytes = 0;
2573-
nTimeConnected = GetTime();
2573+
nTimeConnected = GetSystemTimeInSeconds();
25742574
nTimeOffset = 0;
25752575
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
25762576
nVersion = 0;

src/qt/rpcconsole.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,11 +1023,11 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
10231023
peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
10241024
ui->peerHeading->setText(peerAddrDetails);
10251025
ui->peerServices->setText(GUIUtil::formatServicesStr(stats->nodeStats.nServices));
1026-
ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastSend) : tr("never"));
1027-
ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastRecv) : tr("never"));
1026+
ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastSend) : tr("never"));
1027+
ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastRecv) : tr("never"));
10281028
ui->peerBytesSent->setText(FormatBytes(stats->nodeStats.nSendBytes));
10291029
ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
1030-
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected));
1030+
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nTimeConnected));
10311031
ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime));
10321032
ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingWait));
10331033
ui->peerMinPing->setText(GUIUtil::formatPingTime(stats->nodeStats.dMinPing));

src/rpc/misc.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -431,22 +431,16 @@ UniValue setmocktime(const JSONRPCRequest& request)
431431
if (!Params().MineBlocksOnDemand())
432432
throw runtime_error("setmocktime for regression testing (-regtest mode) only");
433433

434-
// cs_vNodes is locked and node send/receive times are updated
435-
// atomically with the time change to prevent peers from being
436-
// disconnected because we think we haven't communicated with them
437-
// in a long time.
434+
// For now, don't change mocktime if we're in the middle of validation, as
435+
// this could have an effect on mempool time-based eviction, as well as
436+
// IsCurrentForFeeEstimation() and IsInitialBlockDownload().
437+
// TODO: figure out the right way to synchronize around mocktime, and
438+
// ensure all callsites of GetTime() are accessing this safely.
438439
LOCK(cs_main);
439440

440441
RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM));
441442
SetMockTime(request.params[0].get_int64());
442443

443-
uint64_t t = GetTime();
444-
if(g_connman) {
445-
g_connman->ForEachNode([t](CNode* pnode) {
446-
pnode->nLastSend = pnode->nLastRecv = t;
447-
});
448-
}
449-
450444
return NullUniValue;
451445
}
452446

src/utiltime.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ int64_t GetTimeMicros()
4646
return now;
4747
}
4848

49+
int64_t GetSystemTimeInSeconds()
50+
{
51+
return GetTimeMicros()/1000000;
52+
}
53+
4954
/** Return a time useful for the debug log */
5055
int64_t GetLogTimeMicros()
5156
{

src/utiltime.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,20 @@
99
#include <stdint.h>
1010
#include <string>
1111

12+
/**
13+
* GetTimeMicros() and GetTimeMillis() both return the system time, but in
14+
* different units. GetTime() returns the sytem time in seconds, but also
15+
* supports mocktime, where the time can be specified by the user, eg for
16+
* testing (eg with the setmocktime rpc, or -mocktime argument).
17+
*
18+
* TODO: Rework these functions to be type-safe (so that we don't inadvertently
19+
* compare numbers with different units, or compare a mocktime to system time).
20+
*/
21+
1222
int64_t GetTime();
1323
int64_t GetTimeMillis();
1424
int64_t GetTimeMicros();
25+
int64_t GetSystemTimeInSeconds(); // Like GetTime(), but not mockable
1526
int64_t GetLogTimeMicros();
1627
void SetMockTime(int64_t nMockTimeIn);
1728
void MilliSleep(int64_t n);

0 commit comments

Comments
 (0)