diff --git a/src/Makefile.am b/src/Makefile.am index 7e7fa0c3ca..cd54b0496a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -80,6 +80,7 @@ BITCOIN_CORE_H = \ serialize.h \ sync.h \ threadsafety.h \ + timedata.h \ tinyformat.h \ txdb.h \ txmempool.h \ @@ -129,6 +130,7 @@ libbitcoin_server_a_SOURCES = \ rpcnet.cpp \ rpcrawtransaction.cpp \ rpcserver.cpp \ + timedata.cpp \ txdb.cpp \ txmempool.cpp \ $(JSON_H) \ diff --git a/src/addrman.h b/src/addrman.h index 5328a93b45..c4c296560e 100644 --- a/src/addrman.h +++ b/src/addrman.h @@ -8,6 +8,7 @@ #include "netbase.h" #include "protocol.h" #include "sync.h" +#include "timedata.h" #include "util.h" #include diff --git a/src/alert.cpp b/src/alert.cpp index 638f0d7a1c..258a2b52c4 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -8,6 +8,7 @@ #include "chainparams.h" #include "key.h" #include "net.h" +#include "timedata.h" #include "ui_interface.h" #include "util.h" diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 61da3373fd..e48dbcac9d 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -12,6 +12,7 @@ #include "main.h" #include "paymentserver.h" #include "transactionrecord.h" +#include "timedata.h" #include "ui_interface.h" #include "wallet.h" diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 5a3728f498..eec2b57e8c 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -5,6 +5,7 @@ #include "transactionrecord.h" #include "base58.h" +#include "timedata.h" #include "wallet.h" #include diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 5181aa23d8..2694e2bcf1 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -9,6 +9,7 @@ #include "net.h" #include "netbase.h" #include "rpcserver.h" +#include "timedata.h" #include "util.h" #ifdef ENABLE_WALLET #include "wallet.h" diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 6fc86eedfb..a54872ccc4 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -9,6 +9,7 @@ #include "netbase.h" #include "protocol.h" #include "sync.h" +#include "timedata.h" #include "util.h" #include diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index f376ab6b63..4f27cef087 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -8,6 +8,7 @@ #include "init.h" #include "net.h" #include "netbase.h" +#include "timedata.h" #include "util.h" #include "wallet.h" #include "walletdb.h" diff --git a/src/timedata.cpp b/src/timedata.cpp new file mode 100644 index 0000000000..8a095d26dc --- /dev/null +++ b/src/timedata.cpp @@ -0,0 +1,91 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "timedata.h" + +#include "netbase.h" +#include "sync.h" +#include "ui_interface.h" +#include "util.h" + +#include + +using namespace std; + +static CCriticalSection cs_nTimeOffset; +static int64_t nTimeOffset = 0; + +// +// "Never go to sea with two chronometers; take one or three." +// Our three time sources are: +// - System clock +// - Median of other nodes clocks +// - The user (asking the user to fix the system clock if the first two disagree) +// +// +int64_t GetTimeOffset() +{ + LOCK(cs_nTimeOffset); + return nTimeOffset; +} + +int64_t GetAdjustedTime() +{ + return GetTime() + GetTimeOffset(); +} + +void AddTimeData(const CNetAddr& ip, int64_t nTime) +{ + int64_t nOffsetSample = nTime - GetTime(); + + LOCK(cs_nTimeOffset); + // Ignore duplicates + static set setKnown; + if (!setKnown.insert(ip).second) + return; + + // Add data + static CMedianFilter vTimeOffsets(200,0); + vTimeOffsets.input(nOffsetSample); + LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); + if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) + { + int64_t nMedian = vTimeOffsets.median(); + std::vector vSorted = vTimeOffsets.sorted(); + // Only let other nodes change our time by so much + if (abs64(nMedian) < 70 * 60) + { + nTimeOffset = nMedian; + } + else + { + nTimeOffset = 0; + + static bool fDone; + if (!fDone) + { + // If nobody has a time different than ours but within 5 minutes of ours, give a warning + bool fMatch = false; + BOOST_FOREACH(int64_t nOffset, vSorted) + if (nOffset != 0 && abs64(nOffset) < 5 * 60) + fMatch = true; + + if (!fMatch) + { + fDone = true; + string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin will not work properly."); + strMiscWarning = strMessage; + LogPrintf("*** %s\n", strMessage); + uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); + } + } + } + if (fDebug) { + BOOST_FOREACH(int64_t n, vSorted) + LogPrintf("%+d ", n); + LogPrintf("| "); + } + LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60); + } +} diff --git a/src/timedata.h b/src/timedata.h new file mode 100644 index 0000000000..0e7bdc2c1f --- /dev/null +++ b/src/timedata.h @@ -0,0 +1,17 @@ +// Copyright (c) 2014 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_TIMEDATA_H +#define BITCOIN_TIMEDATA_H + +#include + +class CNetAddr; + +/* Functions to keep track of adjusted P2P time */ +int64_t GetTimeOffset(); +int64_t GetAdjustedTime(); +void AddTimeData(const CNetAddr& ip, int64_t nTime); + +#endif diff --git a/src/util.cpp b/src/util.cpp index 30590912ff..a19c015da6 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -6,7 +6,6 @@ #include "util.h" #include "chainparams.h" -#include "netbase.h" #include "sync.h" #include "ui_interface.h" #include "uint256.h" @@ -1157,13 +1156,6 @@ void ShrinkDebugFile() fclose(file); } -// -// "Never go to sea with two chronometers; take one or three." -// Our three time sources are: -// - System clock -// - Median of other nodes clocks -// - The user (asking the user to fix the system clock if the first two disagree) -// static int64_t nMockTime = 0; // For unit testing int64_t GetTime() @@ -1178,75 +1170,6 @@ void SetMockTime(int64_t nMockTimeIn) nMockTime = nMockTimeIn; } -static CCriticalSection cs_nTimeOffset; -static int64_t nTimeOffset = 0; - -int64_t GetTimeOffset() -{ - LOCK(cs_nTimeOffset); - return nTimeOffset; -} - -int64_t GetAdjustedTime() -{ - return GetTime() + GetTimeOffset(); -} - -void AddTimeData(const CNetAddr& ip, int64_t nTime) -{ - int64_t nOffsetSample = nTime - GetTime(); - - LOCK(cs_nTimeOffset); - // Ignore duplicates - static set setKnown; - if (!setKnown.insert(ip).second) - return; - - // Add data - static CMedianFilter vTimeOffsets(200,0); - vTimeOffsets.input(nOffsetSample); - LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60); - if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1) - { - int64_t nMedian = vTimeOffsets.median(); - std::vector vSorted = vTimeOffsets.sorted(); - // Only let other nodes change our time by so much - if (abs64(nMedian) < 70 * 60) - { - nTimeOffset = nMedian; - } - else - { - nTimeOffset = 0; - - static bool fDone; - if (!fDone) - { - // If nobody has a time different than ours but within 5 minutes of ours, give a warning - bool fMatch = false; - BOOST_FOREACH(int64_t nOffset, vSorted) - if (nOffset != 0 && abs64(nOffset) < 5 * 60) - fMatch = true; - - if (!fMatch) - { - fDone = true; - string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Bitcoin will not work properly."); - strMiscWarning = strMessage; - LogPrintf("*** %s\n", strMessage); - uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_WARNING); - } - } - } - if (fDebug) { - BOOST_FOREACH(int64_t n, vSorted) - LogPrintf("%+d ", n); - LogPrintf("| "); - } - LogPrintf("nTimeOffset = %+d (%+d minutes)\n", nTimeOffset, nTimeOffset/60); - } -} - uint32_t insecure_rand_Rz = 11; uint32_t insecure_rand_Rw = 11; void seed_insecure_rand(bool fDeterministic) diff --git a/src/util.h b/src/util.h index 5eb6f03826..6057c72e66 100644 --- a/src/util.h +++ b/src/util.h @@ -32,7 +32,6 @@ #include #include -class CNetAddr; class uint256; static const int64_t COIN = 100000000; @@ -191,11 +190,8 @@ uint64_t GetRand(uint64_t nMax); uint256 GetRandHash(); int64_t GetTime(); void SetMockTime(int64_t nMockTimeIn); -int64_t GetAdjustedTime(); -int64_t GetTimeOffset(); std::string FormatFullVersion(); std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); -void AddTimeData(const CNetAddr& ip, int64_t nTime); void runCommand(std::string strCommand); diff --git a/src/wallet.cpp b/src/wallet.cpp index e74980e9e7..f6fd6e958d 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -9,6 +9,7 @@ #include "checkpoints.h" #include "coincontrol.h" #include "net.h" +#include "timedata.h" #include #include