mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-05-31 18:22:04 +02:00
Merge bitcoin/bitcoin#25786: refactor: Make adjusted time type safe
eeee5ada23f2a71d245671556b6ecfdaabfeddf4 Make adjusted time type safe (MacroFake) fa3be799fe951a7ea9b4de78d5a907c6db71eeb8 Add time helpers (MacroFake) Pull request description: This makes follow-ups easier to review. Also, it makes sense by itself. ACKs for top commit: ryanofsky: Code review ACK eeee5ada23f2a71d245671556b6ecfdaabfeddf4. Confirmed type changes and equivalent code changes only. Tree-SHA512: 51bf1ae5428552177286113babdd49e82459d6c710a07b6e80a0a045d373cf51045ee010461aba98e0151d8d71b9b3b5f8f73e302d46ba4558e0b55201f99e9f
This commit is contained in:
commit
0f35f4ddf4
@ -82,7 +82,7 @@ int main(int argc, char* argv[])
|
|||||||
// SETUP: Chainstate
|
// SETUP: Chainstate
|
||||||
const ChainstateManager::Options chainman_opts{
|
const ChainstateManager::Options chainman_opts{
|
||||||
.chainparams = chainparams,
|
.chainparams = chainparams,
|
||||||
.adjusted_time_callback = static_cast<int64_t (*)()>(GetTime),
|
.adjusted_time_callback = NodeClock::now,
|
||||||
};
|
};
|
||||||
ChainstateManager chainman{chainman_opts};
|
ChainstateManager chainman{chainman_opts};
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
#include <util/time.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -275,6 +276,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool HaveTxsDownloaded() const { return nChainTx != 0; }
|
bool HaveTxsDownloaded() const { return nChainTx != 0; }
|
||||||
|
|
||||||
|
NodeSeconds Time() const
|
||||||
|
{
|
||||||
|
return NodeSeconds{std::chrono::seconds{nTime}};
|
||||||
|
}
|
||||||
|
|
||||||
int64_t GetBlockTime() const
|
int64_t GetBlockTime() const
|
||||||
{
|
{
|
||||||
return (int64_t)nTime;
|
return (int64_t)nTime;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -109,6 +110,10 @@ struct Params {
|
|||||||
bool fPowNoRetargeting;
|
bool fPowNoRetargeting;
|
||||||
int64_t nPowTargetSpacing;
|
int64_t nPowTargetSpacing;
|
||||||
int64_t nPowTargetTimespan;
|
int64_t nPowTargetTimespan;
|
||||||
|
std::chrono::seconds PowTargetSpacing() const
|
||||||
|
{
|
||||||
|
return std::chrono::seconds{nPowTargetSpacing};
|
||||||
|
}
|
||||||
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
|
int64_t DifficultyAdjustmentInterval() const { return nPowTargetTimespan / nPowTargetSpacing; }
|
||||||
/** The best chain should have at least this much work */
|
/** The best chain should have at least this much work */
|
||||||
uint256 nMinimumChainWork;
|
uint256 nMinimumChainWork;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
#ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
||||||
#define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
#define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
|
||||||
|
|
||||||
|
#include <util/time.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
@ -19,7 +21,7 @@ namespace kernel {
|
|||||||
*/
|
*/
|
||||||
struct ChainstateManagerOpts {
|
struct ChainstateManagerOpts {
|
||||||
const CChainParams& chainparams;
|
const CChainParams& chainparams;
|
||||||
const std::function<int64_t()> adjusted_time_callback{nullptr};
|
const std::function<NodeClock::time_point()> adjusted_time_callback{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
@ -1151,7 +1151,7 @@ bool PeerManagerImpl::TipMayBeStale()
|
|||||||
|
|
||||||
bool PeerManagerImpl::CanDirectFetch()
|
bool PeerManagerImpl::CanDirectFetch()
|
||||||
{
|
{
|
||||||
return m_chainman.ActiveChain().Tip()->GetBlockTime() > GetAdjustedTime() - m_chainparams.GetConsensus().nPowTargetSpacing * 20;
|
return m_chainman.ActiveChain().Tip()->Time() > GetAdjustedTime() - m_chainparams.GetConsensus().PowTargetSpacing() * 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
static bool PeerHasHeader(CNodeState *state, const CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||||
@ -4913,7 +4913,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
|
|
||||||
if (!state.fSyncStarted && CanServeBlocks(*peer) && !fImporting && !fReindex) {
|
if (!state.fSyncStarted && CanServeBlocks(*peer) && !fImporting && !fReindex) {
|
||||||
// Only actively request headers from a single peer, unless we're close to today.
|
// Only actively request headers from a single peer, unless we're close to today.
|
||||||
if ((nSyncStarted == 0 && sync_blocks_and_headers_from_peer) || m_chainman.m_best_header->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) {
|
if ((nSyncStarted == 0 && sync_blocks_and_headers_from_peer) || m_chainman.m_best_header->Time() > GetAdjustedTime() - 24h) {
|
||||||
const CBlockIndex* pindexStart = m_chainman.m_best_header;
|
const CBlockIndex* pindexStart = m_chainman.m_best_header;
|
||||||
/* If possible, start at the block preceding the currently
|
/* If possible, start at the block preceding the currently
|
||||||
best known header. This ensures that we always get a
|
best known header. This ensures that we always get a
|
||||||
@ -4933,7 +4933,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
// Convert HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER to microseconds before scaling
|
// Convert HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER to microseconds before scaling
|
||||||
// to maintain precision
|
// to maintain precision
|
||||||
std::chrono::microseconds{HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER} *
|
std::chrono::microseconds{HEADERS_DOWNLOAD_TIMEOUT_PER_HEADER} *
|
||||||
(GetAdjustedTime() - m_chainman.m_best_header->GetBlockTime()) / consensusParams.nPowTargetSpacing
|
Ticks<std::chrono::seconds>(GetAdjustedTime() - m_chainman.m_best_header->Time()) / consensusParams.nPowTargetSpacing
|
||||||
);
|
);
|
||||||
nSyncStarted++;
|
nSyncStarted++;
|
||||||
}
|
}
|
||||||
@ -5250,7 +5250,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
|
|||||||
// Check for headers sync timeouts
|
// Check for headers sync timeouts
|
||||||
if (state.fSyncStarted && state.m_headers_sync_timeout < std::chrono::microseconds::max()) {
|
if (state.fSyncStarted && state.m_headers_sync_timeout < std::chrono::microseconds::max()) {
|
||||||
// Detect whether this is a stalling initial-headers-sync peer
|
// Detect whether this is a stalling initial-headers-sync peer
|
||||||
if (m_chainman.m_best_header->GetBlockTime() <= GetAdjustedTime() - 24 * 60 * 60) {
|
if (m_chainman.m_best_header->Time() <= GetAdjustedTime() - 24h) {
|
||||||
if (current_time > state.m_headers_sync_timeout && nSyncStarted == 1 && (m_num_preferred_download_peers - state.fPreferredDownload >= 1)) {
|
if (current_time > state.m_headers_sync_timeout && nSyncStarted == 1 && (m_num_preferred_download_peers - state.fPreferredDownload >= 1)) {
|
||||||
// Disconnect a peer (without NetPermissionFlags::NoBan permission) if it is our only sync peer,
|
// Disconnect a peer (without NetPermissionFlags::NoBan permission) if it is our only sync peer,
|
||||||
// and we have others we could be using instead.
|
// and we have others we could be using instead.
|
||||||
|
@ -30,7 +30,7 @@ namespace node {
|
|||||||
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
|
int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
|
||||||
{
|
{
|
||||||
int64_t nOldTime = pblock->nTime;
|
int64_t nOldTime = pblock->nTime;
|
||||||
int64_t nNewTime = std::max(pindexPrev->GetMedianTimePast() + 1, GetAdjustedTime());
|
int64_t nNewTime{std::max<int64_t>(pindexPrev->GetMedianTimePast() + 1, TicksSinceEpoch<std::chrono::seconds>(GetAdjustedTime()))};
|
||||||
|
|
||||||
if (nOldTime < nNewTime) {
|
if (nOldTime < nNewTime) {
|
||||||
pblock->nTime = nNewTime;
|
pblock->nTime = nNewTime;
|
||||||
@ -133,7 +133,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
|||||||
pblock->nVersion = gArgs.GetIntArg("-blockversion", pblock->nVersion);
|
pblock->nVersion = gArgs.GetIntArg("-blockversion", pblock->nVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
pblock->nTime = GetAdjustedTime();
|
pblock->nTime = TicksSinceEpoch<std::chrono::seconds>(GetAdjustedTime());
|
||||||
m_lock_time_cutoff = pindexPrev->GetMedianTimePast();
|
m_lock_time_cutoff = pindexPrev->GetMedianTimePast();
|
||||||
|
|
||||||
int nPackagesSelected = 0;
|
int nPackagesSelected = 0;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <serialize.h>
|
#include <serialize.h>
|
||||||
#include <uint256.h>
|
#include <uint256.h>
|
||||||
|
#include <util/time.h>
|
||||||
|
|
||||||
/** Nodes collect new transactions into a block, hash them into a hash tree,
|
/** Nodes collect new transactions into a block, hash them into a hash tree,
|
||||||
* and scan through nonce values to make the block's hash satisfy proof-of-work
|
* and scan through nonce values to make the block's hash satisfy proof-of-work
|
||||||
@ -52,6 +53,11 @@ public:
|
|||||||
|
|
||||||
uint256 GetHash() const;
|
uint256 GetHash() const;
|
||||||
|
|
||||||
|
NodeSeconds Time() const
|
||||||
|
{
|
||||||
|
return NodeSeconds{std::chrono::seconds{nTime}};
|
||||||
|
}
|
||||||
|
|
||||||
int64_t GetBlockTime() const
|
int64_t GetBlockTime() const
|
||||||
{
|
{
|
||||||
return (int64_t)nTime;
|
return (int64_t)nTime;
|
||||||
|
@ -32,9 +32,9 @@ int64_t GetTimeOffset()
|
|||||||
return nTimeOffset;
|
return nTimeOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t GetAdjustedTime()
|
NodeClock::time_point GetAdjustedTime()
|
||||||
{
|
{
|
||||||
return GetTime() + GetTimeOffset();
|
return NodeClock::now() + std::chrono::seconds{GetTimeOffset()};
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BITCOIN_TIMEDATA_MAX_SAMPLES 200
|
#define BITCOIN_TIMEDATA_MAX_SAMPLES 200
|
||||||
|
@ -75,7 +75,7 @@ public:
|
|||||||
|
|
||||||
/** Functions to keep track of adjusted P2P time */
|
/** Functions to keep track of adjusted P2P time */
|
||||||
int64_t GetTimeOffset();
|
int64_t GetTimeOffset();
|
||||||
int64_t GetAdjustedTime();
|
NodeClock::time_point GetAdjustedTime();
|
||||||
void AddTimeData(const CNetAddr& ip, int64_t nTime);
|
void AddTimeData(const CNetAddr& ip, int64_t nTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3441,7 +3441,7 @@ std::vector<unsigned char> ChainstateManager::GenerateCoinbaseCommitment(CBlock&
|
|||||||
* in ConnectBlock().
|
* in ConnectBlock().
|
||||||
* Note that -reindex-chainstate skips the validation that happens here!
|
* Note that -reindex-chainstate skips the validation that happens here!
|
||||||
*/
|
*/
|
||||||
static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const ChainstateManager& chainman, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
|
static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const ChainstateManager& chainman, const CBlockIndex* pindexPrev, NodeClock::time_point now) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
|
||||||
{
|
{
|
||||||
AssertLockHeld(::cs_main);
|
AssertLockHeld(::cs_main);
|
||||||
assert(pindexPrev != nullptr);
|
assert(pindexPrev != nullptr);
|
||||||
@ -3469,8 +3469,9 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
|
|||||||
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-too-old", "block's timestamp is too early");
|
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-too-old", "block's timestamp is too early");
|
||||||
|
|
||||||
// Check timestamp
|
// Check timestamp
|
||||||
if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
|
if (block.Time() > now + std::chrono::seconds{MAX_FUTURE_BLOCK_TIME}) {
|
||||||
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
|
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
|
||||||
|
}
|
||||||
|
|
||||||
// Reject blocks with outdated version
|
// Reject blocks with outdated version
|
||||||
if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
|
if ((block.nVersion < 2 && DeploymentActiveAfter(pindexPrev, chainman, Consensus::DEPLOYMENT_HEIGHTINCB)) ||
|
||||||
@ -3831,7 +3832,7 @@ bool TestBlockValidity(BlockValidationState& state,
|
|||||||
CChainState& chainstate,
|
CChainState& chainstate,
|
||||||
const CBlock& block,
|
const CBlock& block,
|
||||||
CBlockIndex* pindexPrev,
|
CBlockIndex* pindexPrev,
|
||||||
const std::function<int64_t()>& adjusted_time_callback,
|
const std::function<NodeClock::time_point()>& adjusted_time_callback,
|
||||||
bool fCheckPOW,
|
bool fCheckPOW,
|
||||||
bool fCheckMerkleRoot)
|
bool fCheckMerkleRoot)
|
||||||
{
|
{
|
||||||
|
@ -336,7 +336,7 @@ bool TestBlockValidity(BlockValidationState& state,
|
|||||||
CChainState& chainstate,
|
CChainState& chainstate,
|
||||||
const CBlock& block,
|
const CBlock& block,
|
||||||
CBlockIndex* pindexPrev,
|
CBlockIndex* pindexPrev,
|
||||||
const std::function<int64_t()>& adjusted_time_callback,
|
const std::function<NodeClock::time_point()>& adjusted_time_callback,
|
||||||
bool fCheckPOW = true,
|
bool fCheckPOW = true,
|
||||||
bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
bool fCheckMerkleRoot = true) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||||
|
|
||||||
@ -840,7 +840,7 @@ private:
|
|||||||
|
|
||||||
const CChainParams m_chainparams;
|
const CChainParams m_chainparams;
|
||||||
|
|
||||||
const std::function<int64_t()> m_adjusted_time_callback;
|
const std::function<NodeClock::time_point()> m_adjusted_time_callback;
|
||||||
|
|
||||||
//! Internal helper for ActivateSnapshot().
|
//! Internal helper for ActivateSnapshot().
|
||||||
[[nodiscard]] bool PopulateAndValidateSnapshot(
|
[[nodiscard]] bool PopulateAndValidateSnapshot(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user