test: Characterize lagging-clock headers presync

The node currently continues low-work headers presync and requests more headers when its clock is more than `MAX_FUTURE_BLOCK_TIME` behind the chain-start MTP.

Record this behavior before the follow-up rejects the invalid elapsed-time calculation.

The unit test covers HeadersSyncState() behavior while the functional test covers net_processing.cpp behavior.

Co-authored-by: Lőrinc <pap.lorinc@gmail.com>
This commit is contained in:
Hodlinator
2026-08-19 09:41:04 +02:00
parent 55dfc24414
commit 1883cecb4d
2 changed files with 21 additions and 0 deletions

View File

@@ -10,6 +10,7 @@
#include <pow.h>
#include <test/util/common.h>
#include <test/util/setup_common.h>
#include <test/util/time.h>
#include <validation.h>
#include <cstddef>
@@ -252,4 +253,16 @@ BOOST_AUTO_TEST_CASE(too_little_work)
/*exp_locator_hash=*/std::nullopt);
}
BOOST_AUTO_TEST_CASE(system_clock_lagging_behind_chain_start)
{
FakeNodeClock clock{(chain_start.GetBlockTime() - MAX_FUTURE_BLOCK_TIME) * 1s};
BOOST_CHECK_NO_THROW(CreateState());
clock -= 1s;
// TODO: Fix - Being more than MAX_FUTURE_BLOCK_TIME behind the starting
// block leads HeadersSyncState() to compute a negative max_seconds_since_start
// which leads to very high HeadersSyncState::m_max_commitments.
BOOST_CHECK_NO_THROW(CreateState());
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -15,6 +15,7 @@ from test_framework.messages import (
)
from test_framework.blocktools import (
MAX_FUTURE_BLOCK_TIME,
NORMAL_GBT_REQUEST_PARAMS,
create_block,
)
@@ -144,6 +145,13 @@ class RejectLowDifficultyHeadersTest(BitcoinTestFramework):
# getpeerinfo should show a sync in progress
assert_equal(node.getpeerinfo()[0]['presynced_headers'], 2000)
self.log.info("Test whether a lagging clock aborts low-work headers sync")
node.disconnect_p2ps()
node.setmocktime(node.getblockheader(node.getblockhash(0))['mediantime'] - MAX_FUTURE_BLOCK_TIME - 1)
p2p = node.add_p2p_connection(P2PInterface())
p2p.send_without_ping(headers_message)
p2p.wait_for_getheaders(timeout=30, block_hash=hashPrevBlock) # TODO: A negative elapsed interval should trigger fatal shutdown.
def test_large_reorgs_can_succeed(self):
self.log.info("Test that a 2000+ block reorg, starting from a point that is more than 2000 blocks before a locator entry, can succeed")