${CMAKE_CURRENT_SOURCE_DIR}/src/version.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/sync.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/util.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/timedata.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/netbase.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/ntp.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/key.cpp
${CMAKE_CURRENT_SOURCE_DIR}/script.cpp
${CMAKE_CURRENT_SOURCE_DIR}/stun.cpp
${CMAKE_CURRENT_SOURCE_DIR}/sync.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/timedata.cpp
${CMAKE_CURRENT_SOURCE_DIR}/uint256.cpp
${CMAKE_CURRENT_SOURCE_DIR}/util.cpp
${CMAKE_CURRENT_SOURCE_DIR}/version.cpp
#include "netbase.h"
#include "protocol.h"
+#include "timedata.h"
#include "util.h"
#include "sync.h"
// Alert system
//
-#include <map>
-
#include "alert.h"
#include "key.h"
#include "net.h"
#ifndef _BITCOINALERT_H_
#define _BITCOINALERT_H_ 1
-#include <set>
-#include <string>
-
+#include "serialize.h"
#include "uint256.h"
#include "util.h"
+#include <set>
+#include <string>
+
class CNode;
/** Alerts are for notifying old versions if they become too obsolete and
#define BITCOIN_CHECKPOINT_H
#include "util.h"
+#include "serialize.h"
#include "sync.h"
#include "uint256.h"
--- /dev/null
+#include "timedata.h"
+#include "netbase.h"
+#include "sync.h"
+#include "interface.h"
+
+#include <climits>
+
+static CCriticalSection cs_nTimeOffset;
+static uint32_t NOVACOIN_TIMEDATA_MAX_SAMPLES = 200;
+
+// Trusted NTP offset or median of NTP samples.
+extern int64_t nNtpOffset;
+
+// Median of time samples given by other nodes.
+static int64_t nNodesOffset = std::numeric_limits<int64_t>::max();
+
+//
+// "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)
+//
+
+// Select time offset:
+int64_t GetTimeOffset()
+{
+ LOCK(cs_nTimeOffset);
+ // If NTP and system clock are in agreement within 40 minutes, then use NTP.
+ if (std::abs(nNtpOffset) < 40 * 60)
+ return nNtpOffset;
+
+ // If not, then choose between median peer time and system clock.
+ if (std::abs(nNodesOffset) < 70 * 60)
+ return nNodesOffset;
+
+ return 0;
+}
+
+int64_t GetNodesOffset()
+{
+ return nNodesOffset;
+}
+
+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 std::set<CNetAddr> setKnown;
+ if (setKnown.size() == NOVACOIN_TIMEDATA_MAX_SAMPLES)
+ return;
+ if (!setKnown.insert(ip).second)
+ return;
+
+ // Add data
+ static CMedianFilter<int64_t> vTimeOffsets(NOVACOIN_TIMEDATA_MAX_SAMPLES,0);
+ vTimeOffsets.input(nOffsetSample);
+ printf("Added time data, samples %d, offset %+" PRId64 " (%+" PRId64 " minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
+ if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
+ {
+ int64_t nMedian = vTimeOffsets.median();
+ std::vector<int64_t> vSorted = vTimeOffsets.sorted();
+ // Only let other nodes change our time by so much
+ if (std::abs(nMedian) < 70 * 60)
+ {
+ nNodesOffset = nMedian;
+ }
+ else
+ {
+ nNodesOffset = std::numeric_limits<int64_t>::max();
+
+ static bool fDone;
+ if (!fDone)
+ {
+ bool fMatch = false;
+
+ // If nobody has a time different than ours but within 5 minutes of ours, give a warning
+ for (int64_t nOffset : vSorted)
+ if (nOffset != 0 && std::abs(nOffset) < 5 * 60)
+ fMatch = true;
+
+ if (!fMatch)
+ {
+ fDone = true;
+ std::string strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong NovaCoin will not work properly.");
+ strMiscWarning = strMessage;
+ printf("*** %s\n", strMessage.c_str());
+ uiInterface.ThreadSafeMessageBox(strMessage+" ", std::string("NovaCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION);
+ }
+ }
+ }
+ if (fDebug) {
+ for (int64_t n : vSorted)
+ printf("%+" PRId64 " ", n);
+ printf("| ");
+ }
+ if (nNodesOffset != std::numeric_limits<int64_t>::max())
+ printf("nNodesOffset = %+" PRId64 " (%+" PRId64 " minutes)\n", nNodesOffset, nNodesOffset/60);
+ }
+}
--- /dev/null
+// 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 NOVACOIN_TIMEDATA_H
+#define NOVACOIN_TIMEDATA_H
+
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+class CNetAddr;
+
+/** Median filter over a stream of values.
+ * Returns the median of the last N numbers
+ */
+template <typename T> class CMedianFilter
+{
+private:
+ std::vector<T> vValues;
+ std::vector<T> vSorted;
+ unsigned int nSize;
+public:
+ CMedianFilter(unsigned int size, T initial_value):
+ nSize(size)
+ {
+ vValues.reserve(size);
+ vValues.push_back(initial_value);
+ vSorted = vValues;
+ }
+
+ void input(T value)
+ {
+ if(vValues.size() == nSize)
+ {
+ vValues.erase(vValues.begin());
+ }
+ vValues.push_back(value);
+
+ vSorted.resize(vValues.size());
+ std::copy(vValues.begin(), vValues.end(), vSorted.begin());
+ std::sort(vSorted.begin(), vSorted.end());
+ }
+
+ T median() const
+ {
+ size_t size = vSorted.size();
+ assert(size>0);
+ if(size & 1) // Odd number of elements
+ {
+ return vSorted[size/2];
+ }
+ else // Even number of elements
+ {
+ return (vSorted[size/2-1] + vSorted[size/2]) / 2;
+ }
+ }
+
+ int size() const
+ {
+ return static_cast<int>(vValues.size());
+ }
+
+ std::vector<T> sorted () const
+ {
+ return vSorted;
+ }
+};
+
+// Functions to keep track of adjusted P2P time
+int64_t GetAdjustedTime();
+int64_t GetTimeOffset();
+int64_t GetNodesOffset();
+void AddTimeData(const CNetAddr& ip, int64_t nTime);
+
+#endif // NOVACOIN_TIMEDATA_H
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "util.h"
+#include "allocators.h"
#include "interface.h"
#include "sync.h"
#include "version.h"
bool fTestNet = false;
bool fNoListen = false;
bool fLogTimestamps = false;
-CMedianFilter<int64_t> vTimeOffsets(200,0);
bool fReopenDebugLog = false;
// Extended DecodeDumpTime implementation, see this page for details:
-
-
-
-
-//
-// "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)
-//
-
// System clock
int64_t GetTime()
{
return now;
}
-// Trusted NTP offset or median of NTP samples.
-extern int64_t nNtpOffset;
-
-// Median of time samples given by other nodes.
-static int64_t nNodesOffset = INT64_MAX;
-
-// Select time offset:
-int64_t GetTimeOffset()
-{
- // If NTP and system clock are in agreement within 40 minutes, then use NTP.
- if (abs64(nNtpOffset) < 40 * 60)
- return nNtpOffset;
-
- // If not, then choose between median peer time and system clock.
- if (abs64(nNodesOffset) < 70 * 60)
- return nNodesOffset;
-
- return 0;
-}
-
-int64_t GetNodesOffset()
-{
- return nNodesOffset;
-}
-
-int64_t GetAdjustedTime()
-{
- return GetTime() + GetTimeOffset();
-}
-
-void AddTimeData(const CNetAddr& ip, int64_t nTime)
-{
- int64_t nOffsetSample = nTime - GetTime();
-
- // Ignore duplicates
- static set<CNetAddr> setKnown;
- if (!setKnown.insert(ip).second)
- return;
-
- // Add data
- vTimeOffsets.input(nOffsetSample);
- printf("Added time data, samples %d, offset %+" PRId64 " (%+" PRId64 " minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
- if (vTimeOffsets.size() >= 5 && vTimeOffsets.size() % 2 == 1)
- {
- int64_t nMedian = vTimeOffsets.median();
- std::vector<int64_t> vSorted = vTimeOffsets.sorted();
- // Only let other nodes change our time by so much
- if (abs64(nMedian) < 70 * 60)
- {
- nNodesOffset = nMedian;
- }
- else
- {
- nNodesOffset = INT64_MAX;
-
- static bool fDone;
- if (!fDone)
- {
- bool fMatch = false;
-
- // If nobody has a time different than ours but within 5 minutes of ours, give a warning
- for (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 NovaCoin will not work properly.");
- strMiscWarning = strMessage;
- printf("*** %s\n", strMessage.c_str());
- uiInterface.ThreadSafeMessageBox(strMessage+" ", string("NovaCoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION);
- }
- }
- }
- if (fDebug) {
- for (int64_t n : vSorted)
- printf("%+" PRId64 " ", n);
- printf("| ");
- }
- if (nNodesOffset != INT64_MAX)
- printf("nNodesOffset = %+" PRId64 " (%+" PRId64 " minutes)\n", nNodesOffset, nNodesOffset/60);
- }
-}
-
string FormatVersion(int nVersion)
{
if (nVersion%100 == 0)
#endif
#include <inttypes.h>
-#include "netbase.h" // for AddTimeData
static const int32_t nOneHour = 60 * 60;
static const int32_t nOneDay = 24 * 60 * 60;
int64_t GetTime();
int64_t GetTimeMillis();
int64_t GetTimeMicros();
-
-int64_t GetAdjustedTime();
-int64_t GetTimeOffset();
-int64_t GetNodesOffset();
std::string FormatFullVersion();
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
-void AddTimeData(const CNetAddr& ip, int64_t nTime);
void runCommand(std::string strCommand);
return accumulator == 0;
}
-/** Median filter over a stream of values.
- * Returns the median of the last N numbers
- */
-template <typename T> class CMedianFilter
-{
-private:
- std::vector<T> vValues;
- std::vector<T> vSorted;
- unsigned int nSize;
-public:
- CMedianFilter(unsigned int size, T initial_value):
- nSize(size)
- {
- vValues.reserve(size);
- vValues.push_back(initial_value);
- vSorted = vValues;
- }
-
- void input(T value)
- {
- if(vValues.size() == nSize)
- {
- vValues.erase(vValues.begin());
- }
- vValues.push_back(value);
-
- vSorted.resize(vValues.size());
- std::copy(vValues.begin(), vValues.end(), vSorted.begin());
- std::sort(vSorted.begin(), vSorted.end());
- }
-
- T median() const
- {
- size_t size = vSorted.size();
- assert(size>0);
- if(size & 1) // Odd number of elements
- {
- return vSorted[size/2];
- }
- else // Even number of elements
- {
- return (vSorted[size/2-1] + vSorted[size/2]) / 2;
- }
- }
-
- int size() const
- {
- return static_cast<int>(vValues.size());
- }
-
- std::vector<T> sorted () const
- {
- return vSorted;
- }
-};
-
bool NewThread(void(*pfn)(void*), void* parg);
#ifdef WIN32
}
#endif
-