|
|
|
// Copyright (c) 2014 The Bitcoin Core developers
|
|
|
|
// Copyright (c) 2019-2020 The Hush developers
|
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* Copyright © 2014-2019 The SuperNET Developers. *
|
|
|
|
* *
|
|
|
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
|
|
|
* the top-level directory of this distribution for the individual copyright *
|
|
|
|
* holder information and the developer policies on copyright and licensing. *
|
|
|
|
* *
|
|
|
|
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
|
|
|
* SuperNET software, including this file may be copied, modified, propagated *
|
|
|
|
* or distributed except according to the terms contained in the LICENSE file *
|
|
|
|
* *
|
|
|
|
* Removal or modification of this copyright notice is prohibited. *
|
|
|
|
* *
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
|
|
#include "timedata.h"
|
|
|
|
|
|
|
|
#include "netbase.h"
|
|
|
|
#include "sync.h"
|
|
|
|
#include "ui_interface.h"
|
|
|
|
#include "util.h"
|
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
10 years ago
|
|
|
#include "utilstrencodings.h"
|
|
|
|
|
|
|
|
#include <boost/foreach.hpp>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
static CCriticalSection cs_nTimeOffset;
|
|
|
|
static int64_t nTimeOffset = 0;
|
|
|
|
#define KOMODO_ASSETCHAIN_MAXLEN 65
|
|
|
|
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* "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();
|
|
|
|
}
|
|
|
|
|
Split up util.cpp/h
Split up util.cpp/h into:
- string utilities (hex, base32, base64): no internal dependencies, no dependency on boost (apart from foreach)
- money utilities (parsesmoney, formatmoney)
- time utilities (gettime*, sleep, format date):
- and the rest (logging, argument parsing, config file parsing)
The latter is basically the environment and OS handling,
and is stripped of all utility functions, so we may want to
rename it to something else than util.cpp/h for clarity (Matt suggested
osinterface).
Breaks dependency of sha256.cpp on all the things pulled in by util.
10 years ago
|
|
|
static int64_t abs64(int64_t n)
|
|
|
|
{
|
|
|
|
return (n >= 0 ? n : -n);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define BITCOIN_TIMEDATA_MAX_SAMPLES 200
|
|
|
|
|
|
|
|
void AddTimeData(const CNetAddr& ip, int64_t nOffsetSample)
|
|
|
|
{
|
|
|
|
LOCK(cs_nTimeOffset);
|
|
|
|
// Ignore duplicates
|
|
|
|
static set<CNetAddr> setKnown;
|
|
|
|
if (setKnown.size() == BITCOIN_TIMEDATA_MAX_SAMPLES)
|
|
|
|
return;
|
|
|
|
if (!setKnown.insert(ip).second)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Add data
|
|
|
|
static CMedianFilter<int64_t> vTimeOffsets(BITCOIN_TIMEDATA_MAX_SAMPLES, 0);
|
|
|
|
vTimeOffsets.input(nOffsetSample);
|
|
|
|
LogPrintf("Added time data, samples %d, offset %+d (%+d minutes)\n", vTimeOffsets.size(), nOffsetSample, nOffsetSample/60);
|
|
|
|
|
|
|
|
// There is a known issue here (see issue #4521):
|
|
|
|
//
|
|
|
|
// - The structure vTimeOffsets contains up to 200 elements, after which
|
|
|
|
// any new element added to it will not increase its size, replacing the
|
|
|
|
// oldest element.
|
|
|
|
//
|
|
|
|
// - The condition to update nTimeOffset includes checking whether the
|
|
|
|
// number of elements in vTimeOffsets is odd, which will never happen after
|
|
|
|
// there are 200 elements.
|
|
|
|
//
|
|
|
|
// But in this case the 'bug' is protective against some attacks, and may
|
|
|
|
// actually explain why we've never seen attacks which manipulate the
|
|
|
|
// clock offset.
|
|
|
|
//
|
|
|
|
// So we should hold off on fixing this and clean it up as part of
|
|
|
|
// a timing cleanup that strengthens it in a number of other ways.
|
|
|
|
//
|
|
|
|
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) < 30) // thanks to zawy for pointing this out!! zcash issues 4021 //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;
|
|
|
|
if( strncmp(ASSETCHAINS_SYMBOL, "HUSH3",5) == 0 ) {
|
|
|
|
strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Hush will not work properly.");
|
|
|
|
} else {
|
|
|
|
strMessage = _("Warning: Please check that your computer's date and time are correct! If your clock is wrong Komodo 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);
|
|
|
|
}
|
|
|
|
}
|