Skip to content

Commit c56ba56

Browse files
OlegGirkoUdjinM6
authored andcommitted
net: Consistently use GetTimeMicros() for inactivity checks (#1588)
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 510c0a0 commit c56ba56

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
@@ -414,7 +414,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
414414
CNode* pnode = new CNode(GetNewNodeId(), nLocalServices, GetBestHeight(), hSocket, addrConnect, pszDest ? pszDest : "", false, true);
415415

416416
pnode->nServicesExpected = ServiceFlags(addrConnect.nServices & nRelevantServices);
417-
pnode->nTimeConnected = GetTime();
417+
pnode->nTimeConnected = GetSystemTimeInSeconds();
418418
if(fConnectToMasternode) {
419419
pnode->AddRef();
420420
pnode->fMasternode = true;
@@ -812,7 +812,7 @@ size_t CConnman::SocketSendData(CNode *pnode)
812812
assert(data.size() > pnode->nSendOffset);
813813
int nBytes = send(pnode->hSocket, &data[pnode->nSendOffset], data.size() - pnode->nSendOffset, MSG_NOSIGNAL | MSG_DONTWAIT);
814814
if (nBytes > 0) {
815-
pnode->nLastSend = GetTime();
815+
pnode->nLastSend = GetSystemTimeInSeconds();
816816
pnode->nSendBytes += nBytes;
817817
pnode->nSendOffset += nBytes;
818818
nSentSize += nBytes;
@@ -1338,7 +1338,7 @@ void CConnman::ThreadSocketHandler()
13381338
//
13391339
// Inactivity checking
13401340
//
1341-
int64_t nTime = GetTime();
1341+
int64_t nTime = GetSystemTimeInSeconds();
13421342
if (nTime - pnode->nTimeConnected > 60)
13431343
{
13441344
if (pnode->nLastRecv == 0 || pnode->nLastSend == 0)
@@ -2639,7 +2639,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
26392639
nLastRecv = 0;
26402640
nSendBytes = 0;
26412641
nRecvBytes = 0;
2642-
nTimeConnected = GetTime();
2642+
nTimeConnected = GetSystemTimeInSeconds();
26432643
nTimeOffset = 0;
26442644
addr = addrIn;
26452645
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;

src/qt/rpcconsole.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,11 +839,11 @@ void RPCConsole::updateNodeDetail(const CNodeCombinedStats *stats)
839839
peerAddrDetails += "<br />" + tr("via %1").arg(QString::fromStdString(stats->nodeStats.addrLocal));
840840
ui->peerHeading->setText(peerAddrDetails);
841841
ui->peerServices->setText(GUIUtil::formatServicesStr(stats->nodeStats.nServices));
842-
ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastSend) : tr("never"));
843-
ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nLastRecv) : tr("never"));
842+
ui->peerLastSend->setText(stats->nodeStats.nLastSend ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastSend) : tr("never"));
843+
ui->peerLastRecv->setText(stats->nodeStats.nLastRecv ? GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nLastRecv) : tr("never"));
844844
ui->peerBytesSent->setText(FormatBytes(stats->nodeStats.nSendBytes));
845845
ui->peerBytesRecv->setText(FormatBytes(stats->nodeStats.nRecvBytes));
846-
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetTime() - stats->nodeStats.nTimeConnected));
846+
ui->peerConnTime->setText(GUIUtil::formatDurationStr(GetSystemTimeInSeconds() - stats->nodeStats.nTimeConnected));
847847
ui->peerPingTime->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingTime));
848848
ui->peerPingWait->setText(GUIUtil::formatPingTime(stats->nodeStats.dPingWait));
849849
ui->timeoffset->setText(GUIUtil::formatTimeOffset(stats->nodeStats.nTimeOffset));

src/rpc/misc.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -506,22 +506,16 @@ UniValue setmocktime(const UniValue& params, bool fHelp)
506506
if (!Params().MineBlocksOnDemand())
507507
throw runtime_error("setmocktime for regression testing (-regtest mode) only");
508508

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

515516
RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
516517
SetMockTime(params[0].get_int64());
517518

518-
uint64_t t = GetTime();
519-
if(g_connman) {
520-
g_connman->ForEachNode([t](CNode* pnode) {
521-
pnode->nLastSend = pnode->nLastRecv = t;
522-
});
523-
}
524-
525519
return NullUniValue;
526520
}
527521

src/utiltime.cpp

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

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

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)