From aa6e5154dbd88a962f9d7d1ee4f6c6c936c62f0d Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 5 Jan 2024 21:23:38 +0000 Subject: [PATCH] In unexpected version signalling warnings, list the specific bits involved --- src/validation.cpp | 24 +++++++++++++++---- .../functional/feature_versionbits_warning.py | 7 +++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index 5c40d42391..dbb046d8ca 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2754,7 +2754,8 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) int unexpected_bit_count[VERSIONBITS_NUM_BITS], nonversionbit_count = 0; for (size_t i = 0; i < VERSIONBITS_NUM_BITS; ++i) unexpected_bit_count[i] = 0; static constexpr int WARNING_THRESHOLD = 100/2; - bool warning_threshold_hit = false; + std::set warning_threshold_hit_bits; + int32_t warning_threshold_hit_int{-1}; for (int i = 0; i < 100 && pindex != nullptr; i++) { int32_t nExpectedVersion = m_chainman.m_versionbitscache.ComputeBlockVersion(pindex->pprev, params.GetConsensus()); @@ -2765,21 +2766,34 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) const int32_t mask = 1 << bit; if ((pindex->nVersion & mask) && !(nExpectedVersion & mask)) { if (++unexpected_bit_count[bit] > WARNING_THRESHOLD) { - warning_threshold_hit = true; + warning_threshold_hit_bits.insert(bit); } } } } else { // Non-versionbits upgrade if (++nonversionbit_count > WARNING_THRESHOLD) { - warning_threshold_hit = true; + if (warning_threshold_hit_int == -1) { + warning_threshold_hit_int = pindex->nVersion; + } else if (warning_threshold_hit_int != pindex->nVersion) { + warning_threshold_hit_int = -2; + } } } } pindex = pindex->pprev; } - if (warning_threshold_hit) { - const auto warning = _("Warning: Unrecognised block version being mined! Unknown rules may or may not be in effect"); + if (!warning_threshold_hit_bits.empty()) { + const auto warning = strprintf(_("Warning: Miners are attempting to activate unknown new rules (bit %s)! You may or may not need to act to remain secure"), Join(warning_threshold_hit_bits, ", ", [](const uint8_t bit){ return ::ToString(int(bit)); })); + AppendWarning(warning_messages, warning); + } + if (warning_threshold_hit_int != -1) { + bilingual_str warning; + if (warning_threshold_hit_int == -2) { + warning = _("Warning: Unrecognised block versions are being mined! Unknown rules may or may not be in effect"); + } else { + warning = strprintf(_("Warning: Unrecognised block version (0x%08x) is being mined! Unknown rules may or may not be in effect"), warning_threshold_hit_int); + } AppendWarning(warning_messages, warning); } } diff --git a/test/functional/feature_versionbits_warning.py b/test/functional/feature_versionbits_warning.py index 31292f3790..b8b43ef5bc 100755 --- a/test/functional/feature_versionbits_warning.py +++ b/test/functional/feature_versionbits_warning.py @@ -23,7 +23,8 @@ VB_UNKNOWN_VERSION = VB_TOP_BITS | (1 << VB_UNKNOWN_BIT) UNKNOWN_VERSION_SCHEMA = 0x60000000 UNKNOWN_VERSION_SCHEMA_THRESHOLD = 51 -WARN_UNKNOWN_RULES_MINED = "Warning: Unrecognised block version being mined! Unknown rules may or may not be in effect" +WARN_UNKNOWN_RULES_MINED = "Warning: Unrecognised block version (0x%08x) is being mined! Unknown rules may or may not be in effect" % (UNKNOWN_VERSION_SCHEMA,) +WARN_UNKNOWN_BIT_MINED = f"Warning: Miners are attempting to activate unknown new rules (bit {VB_UNKNOWN_BIT})" WARN_UNKNOWN_RULES_ACTIVE = f"Unknown new rules activated (versionbit {VB_UNKNOWN_BIT})" VB_PATTERN = re.compile("Unknown new rules activated.*versionbit") @@ -103,8 +104,8 @@ class VersionBitsWarningTest(BitcoinTestFramework): self.generatetoaddress(node, VB_PERIOD - VB_THRESHOLD, node_deterministic_address) # Check that get*info() shows the 51/100 unknown block version error. - assert(WARN_UNKNOWN_RULES_MINED in node.getmininginfo()["warnings"]) - assert(WARN_UNKNOWN_RULES_MINED in node.getnetworkinfo()["warnings"]) + assert(WARN_UNKNOWN_BIT_MINED in node.getmininginfo()["warnings"]) + assert(WARN_UNKNOWN_BIT_MINED in node.getnetworkinfo()["warnings"]) self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.") # Mine a period worth of expected blocks so the generic block-version warning