0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-09 10:43:19 -05:00

Merge bitcoin/bitcoin#28956: Nuke adjusted time from validation (attempt 2)

ff9039f6ea Remove GetAdjustedTime (dergoegge)

Pull request description:

  This picks up parts of #25908.

  The use of adjusted time is removed from validation code while the warning to users if their clock is out of sync with the rest of the network remains.

ACKs for top commit:
  naumenkogs:
    ACK ff9039f6ea
  achow101:
    ACK ff9039f6ea
  maflcko:
    lgtm ACK ff9039f6ea 🤽
  stickies-v:
    ACK ff9039f6ea

Tree-SHA512: d1f6b9445c236915503fd2ea828f0d3b92285a5dbc677b168453276115e349972edbad37194d8becd9136d8e7219b576af64ec51c72bdb1923e57e405c0483fc
This commit is contained in:
Ava Chow 2024-01-31 15:48:51 -05:00
commit 3c13f5d612
No known key found for this signature in database
GPG key ID: 17565732E08E5E41
13 changed files with 15 additions and 29 deletions

View file

@ -117,7 +117,6 @@ int main(int argc, char* argv[])
const ChainstateManager::Options chainman_opts{ const ChainstateManager::Options chainman_opts{
.chainparams = *chainparams, .chainparams = *chainparams,
.datadir = abs_datadir, .datadir = abs_datadir,
.adjusted_time_callback = NodeClock::now,
.notifications = *notifications, .notifications = *notifications,
}; };
const node::BlockManager::Options blockman_opts{ const node::BlockManager::Options blockman_opts{

View file

@ -41,7 +41,7 @@ HeadersSyncState::HeadersSyncState(NodeId id, const Consensus::Params& consensus
// exceeds this bound, because it's not possible for a consensus-valid // exceeds this bound, because it's not possible for a consensus-valid
// chain to be longer than this (at the current time -- in the future we // chain to be longer than this (at the current time -- in the future we
// could try again, if necessary, to sync a longer chain). // could try again, if necessary, to sync a longer chain).
m_max_commitments = 6*(Ticks<std::chrono::seconds>(GetAdjustedTime() - NodeSeconds{std::chrono::seconds{chain_start->GetMedianTimePast()}}) + MAX_FUTURE_BLOCK_TIME) / HEADER_COMMITMENT_PERIOD; m_max_commitments = 6*(Ticks<std::chrono::seconds>(NodeClock::now() - NodeSeconds{std::chrono::seconds{chain_start->GetMedianTimePast()}}) + MAX_FUTURE_BLOCK_TIME) / HEADER_COMMITMENT_PERIOD;
LogPrint(BCLog::NET, "Initial headers sync started with peer=%d: height=%i, max_commitments=%i, min_work=%s\n", m_id, m_current_height, m_max_commitments, m_minimum_required_work.ToString()); LogPrint(BCLog::NET, "Initial headers sync started with peer=%d: height=%i, max_commitments=%i, min_work=%s\n", m_id, m_current_height, m_max_commitments, m_minimum_required_work.ToString());
} }

View file

@ -1448,7 +1448,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
ChainstateManager::Options chainman_opts{ ChainstateManager::Options chainman_opts{
.chainparams = chainparams, .chainparams = chainparams,
.datadir = args.GetDataDirNet(), .datadir = args.GetDataDirNet(),
.adjusted_time_callback = GetAdjustedTime,
.notifications = *node.notifications, .notifications = *node.notifications,
}; };
Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction

View file

@ -32,7 +32,6 @@ namespace kernel {
struct ChainstateManagerOpts { struct ChainstateManagerOpts {
const CChainParams& chainparams; const CChainParams& chainparams;
fs::path datadir; fs::path datadir;
const std::function<NodeClock::time_point()> adjusted_time_callback{nullptr};
std::optional<bool> check_block_index{}; std::optional<bool> check_block_index{};
bool checkpoints_enabled{DEFAULT_CHECKPOINTS_ENABLED}; bool checkpoints_enabled{DEFAULT_CHECKPOINTS_ENABLED};
//! If set, it will override the minimum work we will assume exists on some valid chain. //! If set, it will override the minimum work we will assume exists on some valid chain.

View file

@ -1334,7 +1334,7 @@ int64_t PeerManagerImpl::ApproximateBestBlockDepth() const
bool PeerManagerImpl::CanDirectFetch() bool PeerManagerImpl::CanDirectFetch()
{ {
return m_chainman.ActiveChain().Tip()->Time() > GetAdjustedTime() - m_chainparams.GetConsensus().PowTargetSpacing() * 20; return m_chainman.ActiveChain().Tip()->Time() > NodeClock::now() - 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)
@ -5592,7 +5592,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
if (!state.fSyncStarted && CanServeBlocks(*peer) && !m_chainman.m_blockman.LoadingBlocks()) { if (!state.fSyncStarted && CanServeBlocks(*peer) && !m_chainman.m_blockman.LoadingBlocks()) {
// 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->Time() > GetAdjustedTime() - 24h) { if ((nSyncStarted == 0 && sync_blocks_and_headers_from_peer) || m_chainman.m_best_header->Time() > NodeClock::now() - 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
@ -5612,7 +5612,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} *
Ticks<std::chrono::seconds>(GetAdjustedTime() - m_chainman.m_best_header->Time()) / consensusParams.nPowTargetSpacing Ticks<std::chrono::seconds>(NodeClock::now() - m_chainman.m_best_header->Time()) / consensusParams.nPowTargetSpacing
); );
nSyncStarted++; nSyncStarted++;
} }
@ -5916,7 +5916,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
// Check for headers sync timeouts // Check for headers sync timeouts
if (state.fSyncStarted && peer->m_headers_sync_timeout < std::chrono::microseconds::max()) { if (state.fSyncStarted && peer->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->Time() <= GetAdjustedTime() - 24h) { if (m_chainman.m_best_header->Time() <= NodeClock::now() - 24h) {
if (current_time > peer->m_headers_sync_timeout && nSyncStarted == 1 && (m_num_preferred_download_peers - state.fPreferredDownload >= 1)) { if (current_time > peer->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.

View file

@ -31,7 +31,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<int64_t>(pindexPrev->GetMedianTimePast() + 1, TicksSinceEpoch<std::chrono::seconds>(GetAdjustedTime()))}; int64_t nNewTime{std::max<int64_t>(pindexPrev->GetMedianTimePast() + 1, TicksSinceEpoch<std::chrono::seconds>(NodeClock::now()))};
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 = TicksSinceEpoch<std::chrono::seconds>(GetAdjustedTime()); pblock->nTime = TicksSinceEpoch<std::chrono::seconds>(NodeClock::now());
m_lock_time_cutoff = pindexPrev->GetMedianTimePast(); m_lock_time_cutoff = pindexPrev->GetMedianTimePast();
int nPackagesSelected = 0; int nPackagesSelected = 0;
@ -171,7 +171,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
BlockValidationState state; BlockValidationState state;
if (m_options.test_block_validity && !TestBlockValidity(state, chainparams, m_chainstate, *pblock, pindexPrev, if (m_options.test_block_validity && !TestBlockValidity(state, chainparams, m_chainstate, *pblock, pindexPrev,
GetAdjustedTime, /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/false)) { /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/false)) {
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString())); throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, state.ToString()));
} }
const auto time_2{SteadyClock::now()}; const auto time_2{SteadyClock::now()};

View file

@ -383,7 +383,7 @@ static RPCHelpMan generateblock()
LOCK(cs_main); LOCK(cs_main);
BlockValidationState state; BlockValidationState state;
if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), GetAdjustedTime, false, false)) { if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), false, false)) {
throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString())); throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString()));
} }
} }
@ -697,7 +697,7 @@ static RPCHelpMan getblocktemplate()
if (block.hashPrevBlock != pindexPrev->GetBlockHash()) if (block.hashPrevBlock != pindexPrev->GetBlockHash())
return "inconclusive-not-best-prevblk"; return "inconclusive-not-best-prevblk";
BlockValidationState state; BlockValidationState state;
TestBlockValidity(state, chainman.GetParams(), active_chainstate, block, pindexPrev, GetAdjustedTime, false, true); TestBlockValidity(state, chainman.GetParams(), active_chainstate, block, pindexPrev, false, true);
return BIP22ValidationResult(state); return BIP22ValidationResult(state);
} }

View file

@ -184,7 +184,6 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vecto
const ChainstateManager::Options chainman_opts{ const ChainstateManager::Options chainman_opts{
.chainparams = chainparams, .chainparams = chainparams,
.datadir = m_args.GetDataDirNet(), .datadir = m_args.GetDataDirNet(),
.adjusted_time_callback = GetAdjustedTime,
.check_block_index = true, .check_block_index = true,
.notifications = *m_node.notifications, .notifications = *m_node.notifications,
.worker_threads_num = 2, .worker_threads_num = 2,

View file

@ -383,7 +383,6 @@ struct SnapshotTestSetup : TestChain100Setup {
const ChainstateManager::Options chainman_opts{ const ChainstateManager::Options chainman_opts{
.chainparams = ::Params(), .chainparams = ::Params(),
.datadir = chainman.m_options.datadir, .datadir = chainman.m_options.datadir,
.adjusted_time_callback = GetAdjustedTime,
.notifications = *m_node.notifications, .notifications = *m_node.notifications,
}; };
const BlockManager::Options blockman_opts{ const BlockManager::Options blockman_opts{

View file

@ -33,11 +33,6 @@ int64_t GetTimeOffset()
return nTimeOffset; return nTimeOffset;
} }
NodeClock::time_point GetAdjustedTime()
{
return NodeClock::now() + std::chrono::seconds{GetTimeOffset()};
}
#define BITCOIN_TIMEDATA_MAX_SAMPLES 200 #define BITCOIN_TIMEDATA_MAX_SAMPLES 200
static std::set<CNetAddr> g_sources; static std::set<CNetAddr> g_sources;

View file

@ -75,11 +75,10 @@ public:
/** Functions to keep track of adjusted P2P time */ /** Functions to keep track of adjusted P2P time */
int64_t GetTimeOffset(); int64_t GetTimeOffset();
NodeClock::time_point GetAdjustedTime();
void AddTimeData(const CNetAddr& ip, int64_t nTime); void AddTimeData(const CNetAddr& ip, int64_t nTime);
/** /**
* Reset the internal state of GetTimeOffset(), GetAdjustedTime() and AddTimeData(). * Reset the internal state of GetTimeOffset() and AddTimeData().
*/ */
void TestOnlyResetTimeData(); void TestOnlyResetTimeData();

View file

@ -3777,7 +3777,7 @@ arith_uint256 CalculateHeadersWork(const std::vector<CBlockHeader>& headers)
* 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, NodeClock::time_point now) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidationState& state, BlockManager& blockman, const ChainstateManager& chainman, const CBlockIndex* pindexPrev) EXCLUSIVE_LOCKS_REQUIRED(::cs_main)
{ {
AssertLockHeld(::cs_main); AssertLockHeld(::cs_main);
assert(pindexPrev != nullptr); assert(pindexPrev != nullptr);
@ -3805,7 +3805,7 @@ 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.Time() > now + std::chrono::seconds{MAX_FUTURE_BLOCK_TIME}) { if (block.Time() > NodeClock::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");
} }
@ -3945,7 +3945,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
LogPrint(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString()); LogPrint(BCLog::VALIDATION, "header %s has prev block invalid: %s\n", hash.ToString(), block.hashPrevBlock.ToString());
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
} }
if (!ContextualCheckBlockHeader(block, state, m_blockman, *this, pindexPrev, m_options.adjusted_time_callback())) { if (!ContextualCheckBlockHeader(block, state, m_blockman, *this, pindexPrev)) {
LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString()); LogPrint(BCLog::VALIDATION, "%s: Consensus::ContextualCheckBlockHeader: %s, %s\n", __func__, hash.ToString(), state.ToString());
return false; return false;
} }
@ -4230,7 +4230,6 @@ bool TestBlockValidity(BlockValidationState& state,
Chainstate& chainstate, Chainstate& chainstate,
const CBlock& block, const CBlock& block,
CBlockIndex* pindexPrev, CBlockIndex* pindexPrev,
const std::function<NodeClock::time_point()>& adjusted_time_callback,
bool fCheckPOW, bool fCheckPOW,
bool fCheckMerkleRoot) bool fCheckMerkleRoot)
{ {
@ -4244,7 +4243,7 @@ bool TestBlockValidity(BlockValidationState& state,
indexDummy.phashBlock = &block_hash; indexDummy.phashBlock = &block_hash;
// NOTE: CheckBlockHeader is called by CheckBlock // NOTE: CheckBlockHeader is called by CheckBlock
if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainstate.m_chainman, pindexPrev, adjusted_time_callback())) if (!ContextualCheckBlockHeader(block, state, chainstate.m_blockman, chainstate.m_chainman, pindexPrev))
return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString()); return error("%s: Consensus::ContextualCheckBlockHeader: %s", __func__, state.ToString());
if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot)) if (!CheckBlock(block, state, chainparams.GetConsensus(), fCheckPOW, fCheckMerkleRoot))
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString()); return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
@ -5780,7 +5779,6 @@ static ChainstateManager::Options&& Flatten(ChainstateManager::Options&& opts)
if (!opts.check_block_index.has_value()) opts.check_block_index = opts.chainparams.DefaultConsistencyChecks(); if (!opts.check_block_index.has_value()) opts.check_block_index = opts.chainparams.DefaultConsistencyChecks();
if (!opts.minimum_chain_work.has_value()) opts.minimum_chain_work = UintToArith256(opts.chainparams.GetConsensus().nMinimumChainWork); if (!opts.minimum_chain_work.has_value()) opts.minimum_chain_work = UintToArith256(opts.chainparams.GetConsensus().nMinimumChainWork);
if (!opts.assumed_valid_block.has_value()) opts.assumed_valid_block = opts.chainparams.GetConsensus().defaultAssumeValid; if (!opts.assumed_valid_block.has_value()) opts.assumed_valid_block = opts.chainparams.GetConsensus().defaultAssumeValid;
Assert(opts.adjusted_time_callback);
return std::move(opts); return std::move(opts);
} }

View file

@ -377,7 +377,6 @@ bool TestBlockValidity(BlockValidationState& state,
Chainstate& chainstate, Chainstate& chainstate,
const CBlock& block, const CBlock& block,
CBlockIndex* pindexPrev, CBlockIndex* pindexPrev,
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);