// Copyright (c) 2014 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_TIMEDATA_H #define BITCOIN_TIMEDATA_H #include #include #include #include #include "chain.h" static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT = 0; static const int64_t LIMIT_MAX_TIME_ADJUSTMENT = 25 * 60; static_assert(LIMIT_MAX_TIME_ADJUSTMENT * 2 < MAX_FUTURE_BLOCK_TIME_MTP, "LIMIT_MAX_TIME_ADJUSTMENT is too high given MAX_FUTURE_BLOCK_TIME_MTP"); static_assert(MAX_FUTURE_BLOCK_TIME_MTP + LIMIT_MAX_TIME_ADJUSTMENT < MAX_FUTURE_BLOCK_TIME_ADJUSTED, "LIMIT_MAX_TIME_ADJUSTMENT is too high given MAX_FUTURE_BLOCK_TIME_MTP and MAX_FUTURE_BLOCK_TIME_ADJUSTED"); class CNetAddr; /** * Median filter over a stream of values. * Returns the median of the last N numbers */ template class CMedianFilter { private: std::vector vValues; std::vector 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 { int 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 vValues.size(); } std::vector sorted() const { return vSorted; } }; /** Functions to keep track of adjusted P2P time */ int64_t GetTimeOffset(); int64_t GetAdjustedTime(); void AddTimeData(const CNetAddr& ip, int64_t nTime); #endif // BITCOIN_TIMEDATA_H