diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj
index 741f68e994..b9cf2c0ab7 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj
+++ b/Builds/VisualStudio2013/RippleD.vcxproj
@@ -2071,13 +2071,13 @@
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
-
+
True
True
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
-
+
True
@@ -2085,6 +2085,12 @@
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+
+ True
+ True
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+ ..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+
@@ -2121,6 +2127,8 @@
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
..\..\src\soci\src\core;..\..\src\sqlite;%(AdditionalIncludeDirectories)
+
+
diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters
index c8afd1126e..f102266f88 100644
--- a/Builds/VisualStudio2013/RippleD.vcxproj.filters
+++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters
@@ -2805,15 +2805,18 @@
ripple\core\impl
-
+
ripple\core\impl
-
+
ripple\core\impl
ripple\core\impl
+
+ ripple\core\impl
+
ripple\core
@@ -2850,6 +2853,9 @@
ripple\core\tests
+
+ ripple\core
+
ripple\crypto
diff --git a/src/ripple/app/ledger/Ledger.cpp b/src/ripple/app/ledger/Ledger.cpp
index 8584a22d81..6e9c157898 100644
--- a/src/ripple/app/ledger/Ledger.cpp
+++ b/src/ripple/app/ledger/Ledger.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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;
diff --git a/src/ripple/app/ledger/impl/LedgerConsensusImp.cpp b/src/ripple/app/ledger/impl/LedgerConsensusImp.cpp
index 13f51a2a6b..656ba703a4 100644
--- a/src/ripple/app/ledger/impl/LedgerConsensusImp.cpp
+++ b/src/ripple/app/ledger/impl/LedgerConsensusImp.cpp
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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 set)
{
// Build validation
auto v = std::make_shared (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 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 (
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::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 (mPreviousLedger->getHash (),
- consensus_.validationTimestamp (getApp().getOPs ().getNetworkTimeNC ()),
+ consensus_.validationTimestamp (getApp().timeKeeper().now().time_since_epoch().count()),
mValPublic, false);
addLoad(v);
v->setTrusted ();
diff --git a/src/ripple/app/ledger/impl/LedgerMaster.cpp b/src/ripple/app/ledger/impl/LedgerMaster.cpp
index ecf6438008..45e5e47708 100644
--- a/src/ripple/app/ledger/impl/LedgerMaster.cpp
+++ b/src/ripple/app/ledger/impl/LedgerMaster.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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 (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 (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 (lastLedger->info().closeTime);
if (age > 60)
{
diff --git a/src/ripple/app/main/Application.cpp b/src/ripple/app/main/Application.cpp
index 4873923c7d..f4dce25d08 100644
--- a/src/ripple/app/main/Application.cpp
+++ b/src/ripple/app/main/Application.cpp
@@ -50,10 +50,10 @@
#include
#include
#include
-#include
#include
+#include
+#include
#include
-#include
#include
#include
#include
@@ -259,6 +259,8 @@ public:
beast::Journal m_journal;
Application::MutexType m_masterMutex;
+ std::unique_ptr timeKeeper_;
+
// Required by the SHAMapStore
TransactionMaster m_txMaster;
@@ -289,7 +291,6 @@ public:
std::unique_ptr m_networkOPs;
std::unique_ptr m_deprecatedUNL;
std::unique_ptr serverHandler_;
- std::unique_ptr m_sntpClient;
std::unique_ptr m_validators;
std::unique_ptr m_amendmentTable;
std::unique_ptr 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;
diff --git a/src/ripple/app/main/Application.h b/src/ripple/app/main/Application.h
index 4afd9a1393..9dc4a86f11 100644
--- a/src/ripple/app/main/Application.h
+++ b/src/ripple/app/main/Application.h
@@ -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;
diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp
index ab99c57949..ef2750857b 100644
--- a/src/ripple/app/misc/NetworkOPs.cpp
+++ b/src/ripple/app/misc/NetworkOPs.cpp
@@ -48,6 +48,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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& 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 (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)
diff --git a/src/ripple/app/misc/NetworkOPs.h b/src/ripple/app/misc/NetworkOPs.h
index 52dde31d40..4b3fd56ffd 100644
--- a/src/ripple/app/misc/NetworkOPs.h
+++ b/src/ripple/app/misc/NetworkOPs.h
@@ -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;
diff --git a/src/ripple/app/misc/UniqueNodeList.cpp b/src/ripple/app/misc/UniqueNodeList.cpp
index ecc1a5fbdf..8c236f86af 100644
--- a/src/ripple/app/misc/UniqueNodeList.cpp
+++ b/src/ripple/app/misc/UniqueNodeList.cpp
@@ -31,6 +31,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -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 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);
diff --git a/src/ripple/app/misc/Validations.cpp b/src/ripple/app/misc/Validations.cpp
index 03358098a2..5a9d43d591 100644
--- a/src/ripple/app/misc/Validations.cpp
+++ b/src/ripple/app/misc/Validations.cpp
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include //
#include
#include
@@ -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 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 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 ();
diff --git a/src/ripple/core/TimeKeeper.h b/src/ripple/core/TimeKeeper.h
new file mode 100644
index 0000000000..963ac8aa2e
--- /dev/null
+++ b/src/ripple/core/TimeKeeper.h
@@ -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
+#include
+#include
+#include
+
+namespace ripple {
+
+/** Manages various times used by the server. */
+class TimeKeeper
+ : public beast::abstract_clock
+{
+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 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
+make_TimeKeeper(beast::Journal j);
+
+} // ripple
+
+#endif
diff --git a/src/ripple/core/impl/SNTPClient.cpp b/src/ripple/core/impl/SNTPClock.cpp
similarity index 73%
rename from src/ripple/core/impl/SNTPClient.cpp
rename to src/ripple/core/impl/SNTPClock.cpp
index 90ab29d5c6..990ada97e5 100644
--- a/src/ripple/core/impl/SNTPClient.cpp
+++ b/src/ripple/core/impl/SNTPClock.cpp
@@ -21,11 +21,12 @@
#include
#include
#include
-#include
+#include
#include
#include
#include
#include
+#include
#include
#include