mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-26 22:15:52 +00:00
Add TimeKeeper:
This class tracks Ripple network time and closing time. Conflicts: src/ripple/ledger/ReadView.h
This commit is contained in:
@@ -2071,13 +2071,13 @@
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\SNTPClient.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\SNTPClock.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\core\impl\SNTPClient.h">
|
||||
<ClInclude Include="..\..\src\ripple\core\impl\SNTPClock.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\SociDB.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
@@ -2085,6 +2085,12 @@
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\TimeKeeper.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug|x64'">True</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release|x64'">True</ExcludedFromBuild>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\core\Job.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\core\JobQueue.h">
|
||||
@@ -2121,6 +2127,8 @@
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='debug.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='release.classic|x64'">..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\core\TimeKeeper.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\crypto\Base58.h">
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\crypto\Base58Data.h">
|
||||
|
||||
@@ -2805,15 +2805,18 @@
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\LoadMonitor.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\SNTPClient.cpp">
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\SNTPClock.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\core\impl\SNTPClient.h">
|
||||
<ClInclude Include="..\..\src\ripple\core\impl\SNTPClock.h">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\SociDB.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\core\impl\TimeKeeper.cpp">
|
||||
<Filter>ripple\core\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\core\Job.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
@@ -2850,6 +2853,9 @@
|
||||
<ClCompile Include="..\..\src\ripple\core\tests\SociDB.test.cpp">
|
||||
<Filter>ripple\core\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="..\..\src\ripple\core\TimeKeeper.h">
|
||||
<Filter>ripple\core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\crypto\Base58.h">
|
||||
<Filter>ripple\crypto</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/core/JobQueue.h>
|
||||
#include <ripple/core/SociDB.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <ripple/nodestore/Database.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
@@ -223,7 +224,7 @@ Ledger::Ledger (open_ledger_t, Ledger const& prevLedger)
|
||||
// VFALCO Remove this call to getApp
|
||||
if (prevLedger.info_.closeTime == 0)
|
||||
info_.closeTime = roundCloseTime (
|
||||
getApp().getOPs ().getCloseTimeNC (), info_.closeTimeResolution);
|
||||
getApp().timeKeeper().closeTime().time_since_epoch().count(), info_.closeTimeResolution);
|
||||
else
|
||||
info_.closeTime =
|
||||
prevLedger.info_.closeTime + info_.closeTimeResolution;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/core/JobQueue.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <ripple/overlay/Overlay.h>
|
||||
#include <ripple/overlay/predicates.h>
|
||||
@@ -721,7 +722,7 @@ void LedgerConsensusImp::statePreClose ()
|
||||
if (mHaveCorrectLCL && getCloseAgree(mPreviousLedger->info()))
|
||||
{
|
||||
// we can use consensus timing
|
||||
sinceClose = 1000 * (getApp().getOPs ().getCloseTimeNC ()
|
||||
sinceClose = 1000 * (getApp().timeKeeper().closeTime().time_since_epoch().count()
|
||||
- mPreviousLedger->info().closeTime);
|
||||
idleInterval = 2 * mPreviousLedger->info().closeTimeResolution;
|
||||
|
||||
@@ -731,7 +732,7 @@ void LedgerConsensusImp::statePreClose ()
|
||||
else
|
||||
{
|
||||
// Use the time we saw the last ledger close
|
||||
sinceClose = 1000 * (getApp().getOPs ().getCloseTimeNC ()
|
||||
sinceClose = 1000 * (getApp().timeKeeper().closeTime().time_since_epoch().count()
|
||||
- consensus_.getLastCloseTime ());
|
||||
idleInterval = LEDGER_IDLE_INTERVAL;
|
||||
}
|
||||
@@ -1041,7 +1042,7 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
|
||||
{
|
||||
// Build validation
|
||||
auto v = std::make_shared<STValidation> (newLCLHash,
|
||||
consensus_.validationTimestamp (getApp().getOPs ().getNetworkTimeNC ()),
|
||||
consensus_.validationTimestamp (getApp().timeKeeper().now().time_since_epoch().count()),
|
||||
mValPublic, mProposing);
|
||||
v->setFieldU32 (sfLedgerSequence, newLCL->info().seq);
|
||||
addLoad(v); // Our network load
|
||||
@@ -1195,7 +1196,8 @@ void LedgerConsensusImp::accept (std::shared_ptr<SHAMap> set)
|
||||
WriteLog (lsINFO, LedgerConsensus)
|
||||
<< "Our close offset is estimated at "
|
||||
<< offset << " (" << closeCount << ")";
|
||||
getApp().getOPs ().closeTimeOffset (offset);
|
||||
getApp().timeKeeper().adjustCloseTime(
|
||||
std::chrono::seconds(offset));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1280,7 +1282,7 @@ void LedgerConsensusImp::addDisputedTransaction (
|
||||
protocol::TMTransaction msg;
|
||||
msg.set_rawtransaction (& (tx.front ()), tx.size ());
|
||||
msg.set_status (protocol::tsNEW);
|
||||
msg.set_receivetimestamp (getApp().getOPs ().getNetworkTimeNC ());
|
||||
msg.set_receivetimestamp (getApp().timeKeeper().now().time_since_epoch().count());
|
||||
getApp ().overlay ().foreach (send_always (
|
||||
std::make_shared<Message> (
|
||||
msg, protocol::mtTRANSACTION)));
|
||||
@@ -1355,7 +1357,7 @@ void LedgerConsensusImp::statusChange (protocol::NodeEvent event, Ledger& ledger
|
||||
s.set_newevent (event);
|
||||
|
||||
s.set_ledgerseq (ledger.info().seq);
|
||||
s.set_networktime (getApp().getOPs ().getNetworkTimeNC ());
|
||||
s.set_networktime (getApp().timeKeeper().now().time_since_epoch().count());
|
||||
s.set_ledgerhashprevious(ledger.info().parentHash.begin (),
|
||||
std::decay_t<decltype(ledger.info().parentHash)>::bytes);
|
||||
s.set_ledgerhash (ledger.getHash ().begin (),
|
||||
@@ -1650,7 +1652,7 @@ void LedgerConsensusImp::closeLedger ()
|
||||
checkOurValidation ();
|
||||
state_ = State::establish;
|
||||
mConsensusStartTime = std::chrono::steady_clock::now ();
|
||||
mCloseTime = getApp().getOPs ().getCloseTimeNC ();
|
||||
mCloseTime = getApp().timeKeeper().closeTime().time_since_epoch().count();
|
||||
consensus_.setLastCloseTime (mCloseTime);
|
||||
statusChange (protocol::neCLOSING_LEDGER, *mPreviousLedger);
|
||||
ledgerMaster_.applyHeldTransactions ();
|
||||
@@ -1682,7 +1684,7 @@ void LedgerConsensusImp::checkOurValidation ()
|
||||
}
|
||||
|
||||
auto v = std::make_shared<STValidation> (mPreviousLedger->getHash (),
|
||||
consensus_.validationTimestamp (getApp().getOPs ().getNetworkTimeNC ()),
|
||||
consensus_.validationTimestamp (getApp().timeKeeper().now().time_since_epoch().count()),
|
||||
mValPublic, false);
|
||||
addLoad(v);
|
||||
v->setTrusted ();
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <ripple/basics/TaggedCache.h>
|
||||
#include <ripple/basics/UptimeTimer.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/overlay/Overlay.h>
|
||||
#include <ripple/overlay/Peer.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
@@ -172,7 +173,8 @@ public:
|
||||
return 999999;
|
||||
}
|
||||
|
||||
std::int64_t ret = getApp().getOPs().getCloseTimeNC();
|
||||
// VFALCO int widening?
|
||||
std::int64_t ret = getApp().timeKeeper().closeTime().time_since_epoch().count();
|
||||
ret -= static_cast<std::int64_t> (pubClose);
|
||||
ret = (ret > 0) ? ret : 0;
|
||||
|
||||
@@ -189,7 +191,7 @@ public:
|
||||
return 999999;
|
||||
}
|
||||
|
||||
std::int64_t ret = getApp().getOPs().getCloseTimeNC();
|
||||
std::int64_t ret = getApp().timeKeeper().closeTime().time_since_epoch().count();
|
||||
ret -= static_cast<std::int64_t> (valClose);
|
||||
ret = (ret > 0) ? ret : 0;
|
||||
|
||||
@@ -1170,7 +1172,7 @@ public:
|
||||
|
||||
if (!standalone_)
|
||||
{ // don't pathfind with a ledger that's more than 60 seconds old
|
||||
std::int64_t age = getApp().getOPs().getCloseTimeNC();
|
||||
std::int64_t age = getApp().timeKeeper().closeTime().time_since_epoch().count();
|
||||
age -= static_cast<std::int64_t> (lastLedger->info().closeTime);
|
||||
if (age > 60)
|
||||
{
|
||||
|
||||
@@ -50,10 +50,10 @@
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/json/json_reader.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/core/ConfigSections.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/ledger/CachedSLEs.h>
|
||||
#include <ripple/core/impl/SNTPClient.h>
|
||||
#include <ripple/nodestore/Database.h>
|
||||
#include <ripple/nodestore/DummyScheduler.h>
|
||||
#include <ripple/nodestore/Manager.h>
|
||||
@@ -259,6 +259,8 @@ public:
|
||||
beast::Journal m_journal;
|
||||
Application::MutexType m_masterMutex;
|
||||
|
||||
std::unique_ptr<TimeKeeper> timeKeeper_;
|
||||
|
||||
// Required by the SHAMapStore
|
||||
TransactionMaster m_txMaster;
|
||||
|
||||
@@ -289,7 +291,6 @@ public:
|
||||
std::unique_ptr <NetworkOPs> m_networkOPs;
|
||||
std::unique_ptr <UniqueNodeList> m_deprecatedUNL;
|
||||
std::unique_ptr <ServerHandler> serverHandler_;
|
||||
std::unique_ptr <SNTPClient> m_sntpClient;
|
||||
std::unique_ptr <Validators::Manager> m_validators;
|
||||
std::unique_ptr <AmendmentTable> m_amendmentTable;
|
||||
std::unique_ptr <LoadFeeTrack> mFeeTrack;
|
||||
@@ -333,6 +334,9 @@ public:
|
||||
|
||||
, m_journal (m_logs.journal("Application"))
|
||||
|
||||
, timeKeeper_ (make_TimeKeeper(
|
||||
deprecatedLogs().journal("TimeKeeper")))
|
||||
|
||||
, m_nodeStoreScheduler (*this)
|
||||
|
||||
, m_shaMapStore (make_SHAMapStore (setup_SHAMapStore (
|
||||
@@ -403,9 +407,6 @@ public:
|
||||
, serverHandler_ (make_ServerHandler (*m_networkOPs, get_io_service (),
|
||||
*m_jobQueue, *m_networkOPs, *m_resourceManager, *m_collectorManager))
|
||||
|
||||
, m_sntpClient (make_SNTPClient(
|
||||
deprecatedLogs().journal("SNTPClient")))
|
||||
|
||||
, m_validators (Validators::make_Manager(*this, get_io_service(),
|
||||
m_logs.journal("UVL"), getConfig ()))
|
||||
|
||||
@@ -470,6 +471,12 @@ public:
|
||||
return family_;
|
||||
}
|
||||
|
||||
TimeKeeper&
|
||||
timeKeeper()
|
||||
{
|
||||
return *timeKeeper_;
|
||||
}
|
||||
|
||||
JobQueue& getJobQueue ()
|
||||
{
|
||||
return *m_jobQueue;
|
||||
@@ -625,10 +632,6 @@ public:
|
||||
{
|
||||
return mTxnDB != nullptr;
|
||||
}
|
||||
bool getSystemTimeOffset (int& offset)
|
||||
{
|
||||
return m_sntpClient->getOffset (offset);
|
||||
}
|
||||
|
||||
DatabaseCon& getTxnDB ()
|
||||
{
|
||||
@@ -724,7 +727,7 @@ public:
|
||||
}
|
||||
|
||||
if (!getConfig ().RUN_STANDALONE)
|
||||
m_sntpClient->init (getConfig ().SNTP_SERVERS);
|
||||
timeKeeper_->run(getConfig ().SNTP_SERVERS);
|
||||
|
||||
if (!initSqliteDbs ())
|
||||
{
|
||||
@@ -1139,7 +1142,7 @@ bool ApplicationImp::loadOldLedger (
|
||||
|
||||
|
||||
std::uint32_t seq = 1;
|
||||
std::uint32_t closeTime = getApp().getOPs().getCloseTimeNC ();
|
||||
auto closeTime = getApp().timeKeeper().closeTime().time_since_epoch().count();
|
||||
std::uint32_t closeTimeResolution = 30;
|
||||
bool closeTimeEstimated = false;
|
||||
std::uint64_t totalDrops = 0;
|
||||
|
||||
@@ -60,6 +60,7 @@ class PathRequests;
|
||||
class PendingSaves;
|
||||
class AccountIDCache;
|
||||
class STLedgerEntry;
|
||||
class TimeKeeper;
|
||||
class TransactionMaster;
|
||||
class Validations;
|
||||
|
||||
@@ -93,6 +94,7 @@ public:
|
||||
virtual boost::asio::io_service& getIOService () = 0;
|
||||
virtual CollectorManager& getCollectorManager () = 0;
|
||||
virtual shamap::Family& family() = 0;
|
||||
virtual TimeKeeper& timeKeeper() = 0;
|
||||
virtual JobQueue& getJobQueue () = 0;
|
||||
virtual NodeCache& getTempNodeCache () = 0;
|
||||
virtual CachedSLEs& cachedSLEs() = 0;
|
||||
@@ -132,7 +134,6 @@ public:
|
||||
//
|
||||
virtual DatabaseCon& getWalletDB () = 0;
|
||||
|
||||
virtual bool getSystemTimeOffset (int& offset) = 0;
|
||||
virtual bool isShutdown () = 0;
|
||||
virtual bool running () = 0;
|
||||
virtual void setup () = 0;
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <ripple/protocol/JsonFields.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/crypto/RandomNumbers.h>
|
||||
#include <ripple/crypto/RFC1751.h>
|
||||
#include <ripple/json/to_string.h>
|
||||
@@ -128,7 +129,6 @@ public:
|
||||
, m_clusterTimer (this)
|
||||
, mConsensus (make_Consensus ())
|
||||
, m_ledgerMaster (ledgerMaster)
|
||||
, mCloseTimeOffset (0)
|
||||
, mLastLoadBase (256)
|
||||
, mLastLoadFactor (256)
|
||||
, m_job_queue (job_queue)
|
||||
@@ -139,21 +139,7 @@ public:
|
||||
|
||||
~NetworkOPsImp() override = default;
|
||||
|
||||
// Network information.
|
||||
// Our best estimate of wall time in seconds from 1/1/2000.
|
||||
std::uint32_t getNetworkTimeNC () const override;
|
||||
|
||||
// Our best estimate of current ledger close time.
|
||||
std::uint32_t getCloseTimeNC () const override;
|
||||
private:
|
||||
std::uint32_t getCloseTimeNC (int& offset) const;
|
||||
|
||||
public:
|
||||
void closeTimeOffset (int) override;
|
||||
|
||||
/** On return the offset param holds the System time offset in seconds.
|
||||
*/
|
||||
boost::posix_time::ptime getNetworkTimePT(int& offset) const;
|
||||
OperatingMode getOperatingMode () const override
|
||||
{
|
||||
return mMode;
|
||||
@@ -461,8 +447,6 @@ private:
|
||||
LedgerMaster& m_ledgerMaster;
|
||||
InboundLedger::pointer mAcquiringLedger;
|
||||
|
||||
int mCloseTimeOffset;
|
||||
|
||||
SubInfoMapType mSubAccount;
|
||||
SubInfoMapType mSubRTAccount;
|
||||
|
||||
@@ -592,7 +576,7 @@ void NetworkOPsImp::processClusterTimer ()
|
||||
{
|
||||
bool synced = (m_ledgerMaster.getValidatedLedgerAge() <= 240);
|
||||
ClusterNodeStatus us("", synced ? getApp().getFeeTrack().getLocalFee() : 0,
|
||||
getNetworkTimeNC());
|
||||
getApp().timeKeeper().now().time_since_epoch().count());
|
||||
auto& unl = getApp().getUNL();
|
||||
if (!unl.nodeUpdate(getApp().getLocalCredentials().getNodePublic(), us))
|
||||
{
|
||||
@@ -652,56 +636,6 @@ std::string NetworkOPsImp::strOperatingMode () const
|
||||
return paStatusToken[mMode];
|
||||
}
|
||||
|
||||
boost::posix_time::ptime NetworkOPsImp::getNetworkTimePT (int& offset) const
|
||||
{
|
||||
offset = 0;
|
||||
getApp().getSystemTimeOffset (offset);
|
||||
|
||||
if (std::abs (offset) >= 60)
|
||||
m_journal.warning << "Large system time offset (" << offset << ").";
|
||||
|
||||
// VFALCO TODO Replace this with a beast call
|
||||
return boost::posix_time::microsec_clock::universal_time () +
|
||||
boost::posix_time::seconds (offset);
|
||||
}
|
||||
|
||||
std::uint32_t NetworkOPsImp::getNetworkTimeNC () const
|
||||
{
|
||||
int offset;
|
||||
return iToSeconds (getNetworkTimePT (offset));
|
||||
}
|
||||
|
||||
std::uint32_t NetworkOPsImp::getCloseTimeNC () const
|
||||
{
|
||||
int offset;
|
||||
return getCloseTimeNC (offset);
|
||||
}
|
||||
|
||||
std::uint32_t NetworkOPsImp::getCloseTimeNC (int& offset) const
|
||||
{
|
||||
return iToSeconds (getNetworkTimePT (offset) +
|
||||
boost::posix_time::seconds (mCloseTimeOffset));
|
||||
}
|
||||
|
||||
void NetworkOPsImp::closeTimeOffset (int offset)
|
||||
{
|
||||
// take large offsets, ignore small offsets, push towards our wall time
|
||||
if (offset > 1)
|
||||
mCloseTimeOffset += (offset + 3) / 4;
|
||||
else if (offset < -1)
|
||||
mCloseTimeOffset += (offset - 3) / 4;
|
||||
else
|
||||
mCloseTimeOffset = (mCloseTimeOffset * 3) / 4;
|
||||
|
||||
if (mCloseTimeOffset != 0)
|
||||
{
|
||||
m_journal.info << "Close time offset now " << mCloseTimeOffset;
|
||||
|
||||
if (std::abs (mCloseTimeOffset) >= 60)
|
||||
m_journal.warning << "Large close time offset (" << mCloseTimeOffset << ").";
|
||||
}
|
||||
}
|
||||
|
||||
void NetworkOPsImp::submitTransaction (Job&, STTx::pointer iTrans)
|
||||
{
|
||||
if (isNeedNetworkLedger ())
|
||||
@@ -1044,7 +978,7 @@ void NetworkOPsImp::apply (std::unique_lock<std::mutex>& batchLock)
|
||||
e.transaction->getSTransaction()->add (s);
|
||||
tx.set_rawtransaction (&s.getData().front(), s.getLength());
|
||||
tx.set_status (protocol::tsCURRENT);
|
||||
tx.set_receivetimestamp (getApp().getOPs().getNetworkTimeNC());
|
||||
tx.set_receivetimestamp (getApp().timeKeeper().now().time_since_epoch().count());
|
||||
// FIXME: This should be when we received it
|
||||
getApp().overlay().foreach (send_if_not (
|
||||
std::make_shared<Message> (tx, protocol::mtTRANSACTION),
|
||||
@@ -1198,7 +1132,7 @@ void NetworkOPsImp::tryStartConsensus ()
|
||||
// check if the ledger is good enough to go to omFULL
|
||||
// Note: Do not go to omFULL if we don't have the previous ledger
|
||||
// check if the ledger is bad enough to go to omCONNECTED -- TODO
|
||||
if (getApp().getOPs ().getNetworkTimeNC () <
|
||||
if (getApp().timeKeeper().now().time_since_epoch().count() <
|
||||
m_ledgerMaster.getCurrentLedger ()->info().closeTime)
|
||||
{
|
||||
setMode (omFULL);
|
||||
@@ -1401,7 +1335,7 @@ void NetworkOPsImp::switchLastClosedLedger (
|
||||
protocol::TMStatusChange s;
|
||||
s.set_newevent (protocol::neSWITCHED_LEDGER);
|
||||
s.set_ledgerseq (newLCL->info().seq);
|
||||
s.set_networktime (getApp().getOPs ().getNetworkTimeNC ());
|
||||
s.set_networktime (getApp().timeKeeper().now().time_since_epoch().count());
|
||||
uint256 hash = newLCL->info().parentHash;
|
||||
s.set_ledgerhashprevious (hash.begin (), hash.size ());
|
||||
hash = newLCL->getHash ();
|
||||
@@ -2063,22 +1997,24 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
|
||||
lpClosed->getReserveInc () * baseFee / baseRef))
|
||||
/ SYSTEM_CURRENCY_PARTS;
|
||||
|
||||
int offset;
|
||||
std::uint32_t closeTime (getCloseTimeNC (offset));
|
||||
if (std::abs (offset) >= 60)
|
||||
l[jss::system_time_offset] = offset;
|
||||
auto const nowOffset = getApp().timeKeeper().nowOffset();
|
||||
if (std::abs (nowOffset.count()) >= 60)
|
||||
l[jss::system_time_offset] = nowOffset.count();
|
||||
|
||||
auto const closeOffset = getApp().timeKeeper().closeOffset();
|
||||
if (std::abs (closeOffset.count()) >= 60)
|
||||
l[jss::close_time_offset] = closeOffset.count();
|
||||
|
||||
// VFALCO How do we fix this?
|
||||
/*
|
||||
std::uint32_t lCloseTime (lpClosed->info().closeTime);
|
||||
if (std::abs (mCloseTimeOffset) >= 60)
|
||||
l[jss::close_time_offset] = mCloseTimeOffset;
|
||||
|
||||
if (lCloseTime <= closeTime)
|
||||
{
|
||||
std::uint32_t age = closeTime - lCloseTime;
|
||||
|
||||
if (age < 1000000)
|
||||
l[jss::age] = Json::UInt (age);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
if (valid)
|
||||
|
||||
@@ -101,12 +101,6 @@ public:
|
||||
// Network information
|
||||
//
|
||||
|
||||
// Our best estimate of wall time in seconds from 1/1/2000
|
||||
virtual std::uint32_t getNetworkTimeNC () const = 0;
|
||||
// Our best estimate of current ledger close time
|
||||
virtual std::uint32_t getCloseTimeNC () const = 0;
|
||||
virtual void closeTimeOffset (int) = 0;
|
||||
|
||||
virtual OperatingMode getOperatingMode () const = 0;
|
||||
virtual std::string strOperatingMode () const = 0;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <ripple/basics/Time.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/crypto/Base58.h>
|
||||
#include <ripple/net/HTTPClient.h>
|
||||
#include <ripple/protocol/JsonFields.h>
|
||||
@@ -695,7 +696,7 @@ UniqueNodeListImp::getClusterStatus()
|
||||
|
||||
std::uint32_t UniqueNodeListImp::getClusterFee()
|
||||
{
|
||||
int thresh = getApp().getOPs().getNetworkTimeNC() - 90;
|
||||
auto const thresh = getApp().timeKeeper().now().time_since_epoch().count() - 90;
|
||||
|
||||
std::vector<std::uint32_t> fees;
|
||||
{
|
||||
@@ -723,7 +724,7 @@ void UniqueNodeListImp::addClusterStatus (Json::Value& obj)
|
||||
ScopedUNLLockType sl (mUNLLock);
|
||||
if (m_clusterNodes.size() > 1) // nodes other than us
|
||||
{
|
||||
int now = getApp().getOPs().getNetworkTimeNC();
|
||||
auto const now = getApp().timeKeeper().now().time_since_epoch().count();
|
||||
std::uint32_t ref = getApp().getFeeTrack().getLoadBase();
|
||||
Json::Value& nodes = (obj[jss::cluster] = Json::objectValue);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <ripple/core/JobQueue.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
@@ -86,7 +87,7 @@ private:
|
||||
if (!val->isTrusted() && getApp().getUNL().nodeInUNL (signer))
|
||||
val->setTrusted();
|
||||
|
||||
std::uint32_t now = getApp().getOPs().getCloseTimeNC();
|
||||
auto const now = getApp().timeKeeper().closeTime().time_since_epoch().count();
|
||||
std::uint32_t valClose = val->getSignTime();
|
||||
|
||||
if ((now > (valClose - LEDGER_EARLY_INTERVAL)) && (now < (valClose + LEDGER_VAL_INTERVAL)))
|
||||
@@ -176,7 +177,8 @@ private:
|
||||
|
||||
if (set)
|
||||
{
|
||||
std::uint32_t now = getApp().getOPs ().getNetworkTimeNC ();
|
||||
auto const now =
|
||||
getApp().timeKeeper().now().time_since_epoch().count();
|
||||
for (auto& it: *set)
|
||||
{
|
||||
bool isTrusted = it.second->isTrusted ();
|
||||
@@ -304,7 +306,8 @@ private:
|
||||
|
||||
std::list<STValidation::pointer> getCurrentTrustedValidations ()
|
||||
{
|
||||
std::uint32_t cutoff = getApp().getOPs ().getNetworkTimeNC () - LEDGER_VAL_INTERVAL;
|
||||
// VFALCO LEDGER_VAL_INTERVAL should be a NetClock::duration
|
||||
auto const cutoff = getApp().timeKeeper().now().time_since_epoch().count() - LEDGER_VAL_INTERVAL;
|
||||
|
||||
std::list<STValidation::pointer> ret;
|
||||
|
||||
@@ -339,7 +342,7 @@ private:
|
||||
LedgerToValidationCounter getCurrentValidations (
|
||||
uint256 currentLedger, uint256 priorLedger)
|
||||
{
|
||||
std::uint32_t cutoff = getApp().getOPs ().getNetworkTimeNC () - LEDGER_VAL_INTERVAL;
|
||||
auto const cutoff = getApp().timeKeeper().now().time_since_epoch().count() - LEDGER_VAL_INTERVAL;
|
||||
bool valCurrentLedger = currentLedger.isNonZero ();
|
||||
bool valPriorLedger = priorLedger.isNonZero ();
|
||||
|
||||
|
||||
100
src/ripple/core/TimeKeeper.h
Normal file
100
src/ripple/core/TimeKeeper.h
Normal file
@@ -0,0 +1,100 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_CORE_TIMEKEEPER_H_INCLUDED
|
||||
#define RIPPLE_CORE_TIMEKEEPER_H_INCLUDED
|
||||
|
||||
#include <beast/chrono/abstract_clock.h>
|
||||
#include <ripple/basics/chrono.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Manages various times used by the server. */
|
||||
class TimeKeeper
|
||||
: public beast::abstract_clock<NetClock>
|
||||
{
|
||||
public:
|
||||
virtual ~TimeKeeper() = default;
|
||||
|
||||
/** Launch the internal thread.
|
||||
|
||||
The internal thread synchronizes local network time
|
||||
using the provided list of SNTP servers.
|
||||
*/
|
||||
virtual
|
||||
void
|
||||
run (std::vector<std::string> const& servers) = 0;
|
||||
|
||||
/** Returns the estimate of wall time, in network time.
|
||||
|
||||
The network time is wall time adjusted for the Ripple
|
||||
epoch, the beginning of January 1st, 2000. Each server
|
||||
can compute a different value for network time. Other
|
||||
servers value for network time is not directly observable,
|
||||
but good guesses can be made by looking at validators'
|
||||
positions on close times.
|
||||
|
||||
Servers compute network time by adjusting a local wall
|
||||
clock using SNTP and then adjusting for the epoch.
|
||||
*/
|
||||
virtual
|
||||
time_point
|
||||
now() const = 0;
|
||||
|
||||
/** Returns the close time, in network time.
|
||||
|
||||
Close time is the time the network would agree that
|
||||
a ledger closed, if a ledger closed right now.
|
||||
|
||||
The close time represents the notional "center"
|
||||
of the network. Each server assumes its clock
|
||||
is correct, and tries to pull the close time towards
|
||||
its measure of network time.
|
||||
*/
|
||||
virtual
|
||||
time_point
|
||||
closeTime() const = 0;
|
||||
|
||||
/** Adjust the close time.
|
||||
|
||||
This is called in response to received validations.
|
||||
*/
|
||||
virtual
|
||||
void
|
||||
adjustCloseTime (duration amount) = 0;
|
||||
|
||||
virtual
|
||||
duration
|
||||
nowOffset() const = 0;
|
||||
|
||||
virtual
|
||||
duration
|
||||
closeOffset() const = 0;
|
||||
|
||||
};
|
||||
|
||||
extern
|
||||
std::unique_ptr<TimeKeeper>
|
||||
make_TimeKeeper(beast::Journal j);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -21,11 +21,12 @@
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/basics/ThreadName.h>
|
||||
#include <ripple/crypto/RandomNumbers.h>
|
||||
#include <ripple/core/impl/SNTPClient.h>
|
||||
#include <ripple/core/impl/SNTPClock.h>
|
||||
#include <beast/asio/placeholders.h>
|
||||
#include <beast/threads/Thread.h>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <cmath>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
@@ -69,7 +70,7 @@ static uint8_t SNTPQueryData[48] =
|
||||
#define NTP_OFF_XMITTS_FRAC 11
|
||||
|
||||
class SNTPClientImp
|
||||
: public SNTPClient
|
||||
: public SNTPClock
|
||||
{
|
||||
private:
|
||||
struct Query
|
||||
@@ -78,7 +79,7 @@ private:
|
||||
time_t sent; // VFALCO time_t, really?
|
||||
std::uint32_t nonce;
|
||||
|
||||
Query (time_t j = (time_t) -1)
|
||||
Query (time_t j = time_t(-1))
|
||||
: replied (false)
|
||||
, sent (j)
|
||||
{
|
||||
@@ -86,7 +87,7 @@ private:
|
||||
};
|
||||
|
||||
beast::Journal j_;
|
||||
std::mutex mutex_;
|
||||
std::mutex mutable mutex_;
|
||||
std::thread thread_;
|
||||
boost::asio::io_service io_service_;
|
||||
boost::optional<
|
||||
@@ -114,9 +115,45 @@ public:
|
||||
, timer_ (io_service_)
|
||||
, resolver_ (io_service_)
|
||||
, offset_ (0)
|
||||
, lastUpdate_ ((time_t) -1)
|
||||
, lastUpdate_ (time_t(-1))
|
||||
, buf_ (256)
|
||||
{
|
||||
}
|
||||
|
||||
~SNTPClientImp ()
|
||||
{
|
||||
if (thread_.joinable())
|
||||
{
|
||||
error_code ec;
|
||||
timer_.cancel(ec);
|
||||
socket_.cancel(ec);
|
||||
work_ = boost::none;
|
||||
thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
run (const std::vector<std::string>& servers) override
|
||||
{
|
||||
std::vector<std::string>::const_iterator it = servers.begin ();
|
||||
|
||||
if (it == servers.end ())
|
||||
{
|
||||
JLOG(j_.info) <<
|
||||
"SNTP: no server specified";
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
for (auto const& item : servers)
|
||||
servers_.emplace_back(
|
||||
item, time_t(-1));
|
||||
}
|
||||
queryAll();
|
||||
|
||||
using namespace boost::asio;
|
||||
socket_.open (ip::udp::v4 ());
|
||||
socket_.async_receive_from (buffer (buf_, 256),
|
||||
@@ -129,25 +166,38 @@ public:
|
||||
timer_.async_wait(std::bind(
|
||||
&SNTPClientImp::onTimer, this,
|
||||
beast::asio::placeholders::error));
|
||||
thread_ = std::thread(&SNTPClientImp::run, this);
|
||||
|
||||
// VFALCO Is it correct to launch the thread
|
||||
// here after queuing I/O?
|
||||
//
|
||||
thread_ = std::thread(&SNTPClientImp::doRun, this);
|
||||
}
|
||||
|
||||
~SNTPClientImp ()
|
||||
time_point
|
||||
now() const override
|
||||
{
|
||||
error_code ec;
|
||||
timer_.cancel(ec);
|
||||
socket_.cancel(ec);
|
||||
work_ = boost::none;
|
||||
thread_.join();
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
auto const when = clock_type::now();
|
||||
if ((lastUpdate_ == (time_t)-1) ||
|
||||
((lastUpdate_ + NTP_TIMESTAMP_VALID) < time(nullptr)))
|
||||
return when;
|
||||
return when + std::chrono::seconds(offset_);
|
||||
}
|
||||
|
||||
void run ()
|
||||
|
||||
duration
|
||||
offset() const override
|
||||
{
|
||||
setCallingThreadName("SNTPClient");
|
||||
io_service_.run();
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
return std::chrono::seconds(offset_);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void doRun ()
|
||||
{
|
||||
setCallingThreadName("SNTPClock");
|
||||
io_service_.run();
|
||||
}
|
||||
|
||||
void
|
||||
onTimer (error_code const& ec)
|
||||
@@ -158,7 +208,7 @@ public:
|
||||
if (ec)
|
||||
{
|
||||
JLOG(j_.error) <<
|
||||
"SNTPClient::onTimer: " << ec.message();
|
||||
"SNTPClock::onTimer: " << ec.message();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -190,29 +240,41 @@ public:
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
auto const query = queries_.find (ep_);
|
||||
if (query == queries_.end ())
|
||||
{
|
||||
JLOG(j_.debug) <<
|
||||
"SNTP: Reply from " << ep_ << " found without matching query";
|
||||
}
|
||||
else if (query->second.replied)
|
||||
{
|
||||
JLOG(j_.debug) <<
|
||||
"SNTP: Duplicate response from " << ep_;
|
||||
}
|
||||
else
|
||||
{
|
||||
query->second.replied = true;
|
||||
|
||||
if (time (nullptr) > (query->second.sent + 1))
|
||||
{
|
||||
JLOG(j_.warning) <<
|
||||
"SNTP: Late response from " << ep_;
|
||||
}
|
||||
else if (bytes_xferd < 48)
|
||||
{
|
||||
JLOG(j_.warning) <<
|
||||
"SNTP: Short reply from " << ep_ <<
|
||||
" (" << bytes_xferd << ") " << buf_.size ();
|
||||
}
|
||||
else if (reinterpret_cast<std::uint32_t*>(
|
||||
&buf_[0])[NTP_OFF_ORGTS_FRAC] !=
|
||||
query->second.nonce)
|
||||
{
|
||||
JLOG(j_.warning) <<
|
||||
"SNTP: Reply from " << ep_ << "had wrong nonce";
|
||||
}
|
||||
else
|
||||
{
|
||||
processReply ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,26 +286,10 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void init (const std::vector<std::string>& servers)
|
||||
{
|
||||
std::vector<std::string>::const_iterator it = servers.begin ();
|
||||
|
||||
if (it == servers.end ())
|
||||
{
|
||||
JLOG(j_.info) <<
|
||||
"SNTP: no server specified";
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto const& it : servers)
|
||||
addServer (it);
|
||||
queryAll ();
|
||||
}
|
||||
|
||||
void addServer (std::string const& server)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
servers_.push_back (std::make_pair (server, (time_t) - 1));
|
||||
servers_.push_back (std::make_pair (server, time_t(-1)));
|
||||
}
|
||||
|
||||
void queryAll ()
|
||||
@@ -253,27 +299,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool getOffset (int& offset)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
|
||||
if ((lastUpdate_ == (time_t) - 1) || ((lastUpdate_ + NTP_TIMESTAMP_VALID) < time (nullptr)))
|
||||
return false;
|
||||
|
||||
offset = offset_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool doQuery ()
|
||||
{
|
||||
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
std::vector< std::pair<std::string, time_t> >::iterator best = servers_.end ();
|
||||
|
||||
for (std::vector< std::pair<std::string, time_t> >::iterator it = servers_.begin (), end = best;
|
||||
it != end; ++it)
|
||||
if ((best == end) || (it->second == (time_t) - 1) || (it->second < best->second))
|
||||
best = it;
|
||||
for (auto iter = servers_.begin (), end = best;
|
||||
iter != end; ++iter)
|
||||
if ((best == end) || (iter->second == time_t(-1)) || (iter->second < best->second))
|
||||
best = iter;
|
||||
|
||||
if (best == servers_.end ())
|
||||
{
|
||||
@@ -284,7 +318,7 @@ public:
|
||||
|
||||
time_t now = time (nullptr);
|
||||
|
||||
if ((best->second != (time_t) - 1) && ((best->second + NTP_MIN_QUERY) >= now))
|
||||
if ((best->second != time_t(-1)) && ((best->second + NTP_MIN_QUERY) >= now))
|
||||
{
|
||||
JLOG(j_.trace) <<
|
||||
"SNTP: All servers recently queried";
|
||||
@@ -300,44 +334,53 @@ public:
|
||||
beast::asio::placeholders::error,
|
||||
beast::asio::placeholders::iterator));
|
||||
JLOG(j_.trace) <<
|
||||
"SNTP: Resolve pending for " << best->first;
|
||||
"SNTPClock: Resolve pending for " << best->first;
|
||||
return true;
|
||||
}
|
||||
|
||||
void resolveComplete (const error_code& error, boost::asio::ip::udp::resolver::iterator it)
|
||||
void resolveComplete (error_code const& ec,
|
||||
boost::asio::ip::udp::resolver::iterator it)
|
||||
{
|
||||
if (!error)
|
||||
using namespace boost::asio;
|
||||
if (ec == error::operation_aborted)
|
||||
return;
|
||||
if (ec)
|
||||
{
|
||||
boost::asio::ip::udp::resolver::iterator sel = it;
|
||||
int i = 1;
|
||||
JLOG(j_.trace) <<
|
||||
"SNTPClock::resolveComplete: " << ec.message();
|
||||
return;
|
||||
}
|
||||
|
||||
while (++it != boost::asio::ip::udp::resolver::iterator ())
|
||||
if ((rand () % ++i) == 0)
|
||||
sel = it;
|
||||
ip::udp::resolver::iterator sel = it;
|
||||
int i = 1;
|
||||
|
||||
if (sel != boost::asio::ip::udp::resolver::iterator ())
|
||||
while (++it != ip::udp::resolver::iterator())
|
||||
if ((rand () % ++i) == 0)
|
||||
sel = it;
|
||||
|
||||
if (sel != ip::udp::resolver::iterator ())
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
Query& query = queries_[*sel];
|
||||
time_t now = time (nullptr);
|
||||
|
||||
if ((query.sent == now) || ((query.sent + 1) == now))
|
||||
{
|
||||
std::lock_guard<std::mutex> lock (mutex_);
|
||||
Query& query = queries_[*sel];
|
||||
time_t now = time (nullptr);
|
||||
|
||||
if ((query.sent == now) || ((query.sent + 1) == now))
|
||||
{
|
||||
// This can happen if the same IP address is reached through multiple names
|
||||
JLOG(j_.trace) <<
|
||||
"SNTP: Redundant query suppressed";
|
||||
return;
|
||||
}
|
||||
|
||||
query.replied = false;
|
||||
query.sent = now;
|
||||
random_fill (&query.nonce);
|
||||
reinterpret_cast<std::uint32_t*> (SNTPQueryData)[NTP_OFF_XMITTS_INT] = static_cast<std::uint32_t> (time (nullptr)) + NTP_UNIX_OFFSET;
|
||||
reinterpret_cast<std::uint32_t*> (SNTPQueryData)[NTP_OFF_XMITTS_FRAC] = query.nonce;
|
||||
socket_.async_send_to (boost::asio::buffer (SNTPQueryData, 48), *sel,
|
||||
std::bind (&SNTPClientImp::onSend, this,
|
||||
beast::asio::placeholders::error, beast::asio::placeholders::bytes_transferred));
|
||||
// This can happen if the same IP address is reached through multiple names
|
||||
JLOG(j_.trace) <<
|
||||
"SNTP: Redundant query suppressed";
|
||||
return;
|
||||
}
|
||||
|
||||
query.replied = false;
|
||||
query.sent = now;
|
||||
random_fill (&query.nonce);
|
||||
reinterpret_cast<std::uint32_t*> (SNTPQueryData)[NTP_OFF_XMITTS_INT] = static_cast<std::uint32_t> (time (nullptr)) + NTP_UNIX_OFFSET;
|
||||
reinterpret_cast<std::uint32_t*> (SNTPQueryData)[NTP_OFF_XMITTS_FRAC] = query.nonce;
|
||||
socket_.async_send_to(buffer(SNTPQueryData, 48),
|
||||
*sel, std::bind (&SNTPClientImp::onSend, this,
|
||||
beast::asio::placeholders::error,
|
||||
beast::asio::placeholders::bytes_transferred));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +392,7 @@ public:
|
||||
if (ec)
|
||||
{
|
||||
JLOG(j_.warning) <<
|
||||
"SNTPClient::onSend: " << ec.message();
|
||||
"SNTPClock::onSend: " << ec.message();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -414,8 +457,8 @@ public:
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::unique_ptr<SNTPClient>
|
||||
make_SNTPClient (beast::Journal j)
|
||||
std::unique_ptr<SNTPClock>
|
||||
make_SNTPClock (beast::Journal j)
|
||||
{
|
||||
return std::make_unique<SNTPClientImp>(j);
|
||||
}
|
||||
@@ -17,29 +17,36 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_NET_SNTPCLIENT_H_INCLUDED
|
||||
#define RIPPLE_NET_SNTPCLIENT_H_INCLUDED
|
||||
#ifndef RIPPLE_NET_SNTPCLOCK_H_INCLUDED
|
||||
#define RIPPLE_NET_SNTPCLOCK_H_INCLUDED
|
||||
|
||||
#include <beast/chrono/abstract_clock.h>
|
||||
#include <beast/utility/Journal.h>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class SNTPClient
|
||||
/** A clock based on system_clock and adjusted for SNTP. */
|
||||
class SNTPClock
|
||||
: public beast::abstract_clock<
|
||||
std::chrono::system_clock>
|
||||
{
|
||||
public:
|
||||
virtual ~SNTPClient() = default;
|
||||
virtual void init (std::vector <std::string> const& servers) = 0;
|
||||
virtual void addServer (std::string const& mServer) = 0;
|
||||
virtual void queryAll () = 0;
|
||||
virtual bool getOffset (int& offset) = 0;
|
||||
virtual
|
||||
void
|
||||
run (std::vector <std::string> const& servers) = 0;
|
||||
|
||||
virtual
|
||||
duration
|
||||
offset() const = 0;
|
||||
};
|
||||
|
||||
extern
|
||||
std::unique_ptr<SNTPClient>
|
||||
make_SNTPClient (beast::Journal);
|
||||
std::unique_ptr<SNTPClock>
|
||||
make_SNTPClock (beast::Journal);
|
||||
|
||||
} // ripple
|
||||
|
||||
133
src/ripple/core/impl/TimeKeeper.cpp
Normal file
133
src/ripple/core/impl/TimeKeeper.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/core/impl/SNTPClock.h>
|
||||
#include <beast/cxx14/memory.h> // <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class TimeKeeperImpl : public TimeKeeper
|
||||
{
|
||||
private:
|
||||
beast::Journal j_;
|
||||
std::mutex mutable mutex_;
|
||||
duration closeOffset_;
|
||||
std::unique_ptr<SNTPClock> clock_;
|
||||
|
||||
// Adjust system_clock::time_point for NetClock epoch
|
||||
static
|
||||
time_point
|
||||
adjust (std::chrono::system_clock::time_point when)
|
||||
{
|
||||
return time_point(
|
||||
std::chrono::duration_cast<duration>(
|
||||
when.time_since_epoch() -
|
||||
days(10957)));
|
||||
}
|
||||
|
||||
public:
|
||||
explicit
|
||||
TimeKeeperImpl (beast::Journal j)
|
||||
: j_ (j)
|
||||
, clock_ (make_SNTPClock(j))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
run (std::vector<
|
||||
std::string> const& servers) override
|
||||
{
|
||||
clock_->run(servers);
|
||||
}
|
||||
|
||||
time_point
|
||||
now() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return adjust(clock_->now());
|
||||
}
|
||||
|
||||
time_point
|
||||
closeTime() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return adjust(clock_->now()) + closeOffset_;
|
||||
}
|
||||
|
||||
void
|
||||
adjustCloseTime(
|
||||
NetClock::duration amount) override
|
||||
{
|
||||
using namespace std::chrono;
|
||||
auto const s = amount.count();
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
// Take large offsets, ignore small offsets,
|
||||
// push the close time towards our wall time.
|
||||
if (s > 1)
|
||||
closeOffset_ += seconds((s + 3) / 4);
|
||||
else if (s < -1)
|
||||
closeOffset_ += seconds((s - 3) / 4);
|
||||
else
|
||||
closeOffset_ = (closeOffset_ * 3) / 4;
|
||||
if (closeOffset_.count() != 0)
|
||||
{
|
||||
if (std::abs (closeOffset_.count()) < 60)
|
||||
{
|
||||
JLOG(j_.info) <<
|
||||
"TimeKeeper: Close time offset now " <<
|
||||
closeOffset_.count();
|
||||
}
|
||||
else
|
||||
{
|
||||
JLOG(j_.warning) <<
|
||||
"TimeKeeper: Large close time offset = " <<
|
||||
closeOffset_.count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
duration
|
||||
nowOffset() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return std::chrono::duration_cast<duration>(
|
||||
clock_->offset());
|
||||
}
|
||||
|
||||
duration
|
||||
closeOffset() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
return closeOffset_;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::unique_ptr<TimeKeeper>
|
||||
make_TimeKeeper (beast::Journal j)
|
||||
{
|
||||
return std::make_unique<TimeKeeperImpl>(j);
|
||||
}
|
||||
|
||||
} // ripple
|
||||
@@ -66,25 +66,30 @@ struct Fees
|
||||
/** Information about the notional ledger backing the view. */
|
||||
struct LedgerInfo
|
||||
{
|
||||
// Fields for all ledgers
|
||||
//
|
||||
// For all ledgers
|
||||
//
|
||||
|
||||
bool open = true;
|
||||
LedgerIndex seq = 0;
|
||||
std::uint32_t parentCloseTime = 0;
|
||||
|
||||
// Fields for closed ledgers
|
||||
//
|
||||
// For closed ledgers
|
||||
//
|
||||
|
||||
// Closed means "tx set already determined"
|
||||
uint256 hash = zero;
|
||||
uint256 txHash = zero;
|
||||
uint256 accountHash = zero;
|
||||
uint256 parentHash = zero;
|
||||
|
||||
//uint256 stateHash;
|
||||
std::uint64_t drops = 0;
|
||||
|
||||
// If validated is false, it means "not yet validated."
|
||||
// Once validated is true, it will never be set false at a later time.
|
||||
mutable
|
||||
bool validated = false;
|
||||
// VFALCO TODO Make this not mutable
|
||||
bool mutable validated = false;
|
||||
bool accepted = false;
|
||||
|
||||
// flags indicating how this ledger close took place
|
||||
int closeFlags = 0;
|
||||
@@ -103,7 +108,6 @@ struct LedgerInfo
|
||||
static
|
||||
std::uint32_t const sLCF_NoConsensusTime = 1;
|
||||
|
||||
|
||||
inline
|
||||
bool getCloseAgree (LedgerInfo const& info)
|
||||
{
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/basics/UptimeTimer.h>
|
||||
#include <ripple/core/JobQueue.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/json/json_reader.h>
|
||||
#include <ripple/resource/Fees.h>
|
||||
#include <ripple/server/ServerHandler.h>
|
||||
@@ -1144,7 +1145,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMProposeSet> const& m)
|
||||
set.set_hops(set.hops() + 1);
|
||||
|
||||
// VFALCO Magic numbers are bad
|
||||
if ((set.closetime() + 180) < getApp().getOPs().getCloseTimeNC())
|
||||
if ((set.closetime() + 180) < getApp().timeKeeper().closeTime().time_since_epoch().count())
|
||||
return;
|
||||
|
||||
auto const type = publicKeyType(
|
||||
@@ -1231,7 +1232,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMStatusChange> const& m)
|
||||
p_journal_.trace << "Status: Change";
|
||||
|
||||
if (!m->has_networktime ())
|
||||
m->set_networktime (getApp().getOPs ().getNetworkTimeNC ());
|
||||
m->set_networktime (getApp().timeKeeper().now().time_since_epoch().count());
|
||||
|
||||
if (!last_status_.has_newstatus () || m->has_newstatus ())
|
||||
last_status_ = *m;
|
||||
@@ -1410,7 +1411,7 @@ void
|
||||
PeerImp::onMessage (std::shared_ptr <protocol::TMValidation> const& m)
|
||||
{
|
||||
error_code ec;
|
||||
std::uint32_t closeTime = getApp().getOPs().getCloseTimeNC();
|
||||
auto const closeTime = getApp().timeKeeper().closeTime().time_since_epoch().count();
|
||||
|
||||
if (m->has_hops() && ! slot_->cluster())
|
||||
m->set_hops(m->hops() + 1);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/app/main/LocalCredentials.h>
|
||||
#include <ripple/app/misc/NetworkOPs.h>
|
||||
#include <ripple/core/TimeKeeper.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/BuildInfo.h>
|
||||
#include <ripple/overlay/impl/TMHello.h>
|
||||
@@ -116,7 +117,7 @@ buildHello (uint256 const& sharedValue, Application& app)
|
||||
h.set_protoversion (to_packed (BuildInfo::getCurrentProtocol()));
|
||||
h.set_protoversionmin (to_packed (BuildInfo::getMinimumProtocol()));
|
||||
h.set_fullversion (BuildInfo::getFullVersionString ());
|
||||
h.set_nettime (app.getOPs ().getNetworkTimeNC ());
|
||||
h.set_nettime (app.timeKeeper().now().time_since_epoch().count());
|
||||
h.set_nodepublic (app.getLocalCredentials ().getNodePublic (
|
||||
).humanNodePublic ());
|
||||
h.set_nodeproof (&vchSig[0], vchSig.size ());
|
||||
@@ -300,7 +301,7 @@ verifyHello (protocol::TMHello const& h, uint256 const& sharedValue,
|
||||
beast::Journal journal, Application& app)
|
||||
{
|
||||
std::pair<RippleAddress, bool> result = { {}, false };
|
||||
std::uint32_t const ourTime = app.getOPs().getNetworkTimeNC();
|
||||
auto const ourTime = app.timeKeeper().now().time_since_epoch().count();
|
||||
std::uint32_t const minTime = ourTime - clockToleranceDeltaSeconds;
|
||||
std::uint32_t const maxTime = ourTime + clockToleranceDeltaSeconds;
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
#include <ripple/core/impl/LoadMonitor.cpp>
|
||||
#include <ripple/core/impl/Job.cpp>
|
||||
#include <ripple/core/impl/JobQueue.cpp>
|
||||
#include <ripple/core/impl/SNTPClient.cpp>
|
||||
#include <ripple/core/impl/SNTPClock.cpp>
|
||||
#include <ripple/core/impl/TimeKeeper.cpp>
|
||||
|
||||
#include <ripple/core/tests/LoadFeeTrack.test.cpp>
|
||||
#include <ripple/core/tests/Config.test.cpp>
|
||||
|
||||
Reference in New Issue
Block a user