assumevalid: log every script validation state change
What changed, and why it matters
This commit only adds user-facing log messages that announce when Bitcoin Core turns signature checking on or off during initial block download. It does not change whether signatures are checked, only how clearly the node tells the user about it. There is no security vulnerability here.
No action needed; this is a logging-only usability improvement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces a new member m_prev_script_checks_logged on Chainstate and a log line inside ConnectBlock that fires whenever fScriptChecks changes, but only for ChainstateRole::NORMAL and not during assumeutxo background validation. The functional test is updated to expect the new log strings. The validation logic itself is untouched.
Changed components
src/validation.cppsrc/validation.htest/functional/feature_assumevalid.pyInspect captured patch +13 / −6
diff --git a/src/validation.cpp b/src/validation.cpp
index cf5f5469..27ad61d3 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2580,6 +2580,11 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
Ticks<SecondsDouble>(m_chainman.time_forks),
Ticks<MillisecondsDouble>(m_chainman.time_forks) / m_chainman.num_blocks_total);
+ if (fScriptChecks != m_prev_script_checks_logged && GetRole() == ChainstateRole::NORMAL) {
+ LogInfo("%s signature validations at block #%d (%s).", fScriptChecks ? "Enabling" : "Disabling", pindex->nHeight, block_hash.ToString());
+ m_prev_script_checks_logged = fScriptChecks;
+ }
+
CBlockUndo blockundo;
// Precomputed transaction data pointers must not be invalidated
diff --git a/src/validation.h b/src/validation.h
index c25dd2de..870d56d1 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -550,6 +550,8 @@ protected:
//! Cached result of LookupBlockIndex(*m_from_snapshot_blockhash)
mutable const CBlockIndex* m_cached_snapshot_base GUARDED_BY(::cs_main){nullptr};
+ std::atomic_bool m_prev_script_checks_logged{true};
+
public:
//! Reference to a BlockManager instance which itself is shared across all
//! Chainstate instances.
diff --git a/test/functional/feature_assumevalid.py b/test/functional/feature_assumevalid.py
index 7d097b13..5f7fff82 100755
--- a/test/functional/feature_assumevalid.py
+++ b/test/functional/feature_assumevalid.py
@@ -153,12 +153,12 @@ class AssumeValidTest(BitcoinTestFramework):
p2p1 = self.nodes[1].add_p2p_connection(BaseNode())
p2p1.send_header_for_blocks(self.blocks[0:2000])
p2p1.send_header_for_blocks(self.blocks[2000:])
-
- # Send all blocks to node1. All blocks will be accepted.
- for i in range(2202):
- p2p1.send_without_ping(msg_block(self.blocks[i]))
- # Syncing 2200 blocks can take a while on slow systems. Give it plenty of time to sync.
- p2p1.sync_with_ping(timeout=960)
+ with self.nodes[1].assert_debug_log(expected_msgs=['Disabling signature validations at block #1', 'Enabling signature validations at block #103']):
+ # Send all blocks to node1. All blocks will be accepted.
+ for i in range(2202):
+ p2p1.send_without_ping(msg_block(self.blocks[i]))
+ # Syncing 2200 blocks can take a while on slow systems. Give it plenty of time to sync.
+ p2p1.sync_with_ping(timeout=960)
assert_equal(self.nodes[1].getblock(self.nodes[1].getbestblockhash())['height'], 2202)
p2p2 = self.nodes[2].add_p2p_connection(BaseNode())
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.