Defer N/100 blocks signalling warning to 76/100 for BIP320 bits

This commit is contained in:
Luke Dashjr 2024-01-06 03:11:34 +00:00
parent ff929ecfec
commit c32468f51d
2 changed files with 22 additions and 3 deletions

View File

@ -2753,7 +2753,6 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew)
// Check the version of the last 100 blocks to see if we need to upgrade: // Check the version of the last 100 blocks to see if we need to upgrade:
int unexpected_bit_count[VERSIONBITS_NUM_BITS], nonversionbit_count = 0; 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; for (size_t i = 0; i < VERSIONBITS_NUM_BITS; ++i) unexpected_bit_count[i] = 0;
static constexpr int WARNING_THRESHOLD = 100/2;
std::set<uint8_t> warning_threshold_hit_bits; std::set<uint8_t> warning_threshold_hit_bits;
int32_t warning_threshold_hit_int{-1}; int32_t warning_threshold_hit_int{-1};
for (int i = 0; i < 100 && pindex != nullptr; i++) for (int i = 0; i < 100 && pindex != nullptr; i++)
@ -2765,13 +2764,15 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew)
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; ++bit) { for (int bit = 0; bit < VERSIONBITS_NUM_BITS; ++bit) {
const int32_t mask = 1 << bit; const int32_t mask = 1 << bit;
if ((pindex->nVersion & mask) && !(nExpectedVersion & mask)) { if ((pindex->nVersion & mask) && !(nExpectedVersion & mask)) {
if (++unexpected_bit_count[bit] > WARNING_THRESHOLD) { const int warning_threshold = (bit > 12 ? 75 : 50);
if (++unexpected_bit_count[bit] > warning_threshold) {
warning_threshold_hit_bits.insert(bit); warning_threshold_hit_bits.insert(bit);
} }
} }
} }
} else { } else {
// Non-versionbits upgrade // Non-versionbits upgrade
static constexpr int WARNING_THRESHOLD = 100/2;
if (++nonversionbit_count > WARNING_THRESHOLD) { if (++nonversionbit_count > WARNING_THRESHOLD) {
if (warning_threshold_hit_int == -1) { if (warning_threshold_hit_int == -1) {
warning_threshold_hit_int = pindex->nVersion; warning_threshold_hit_int = pindex->nVersion;

View File

@ -18,13 +18,17 @@ from test_framework.test_framework import BitcoinTestFramework
VB_PERIOD = 144 # versionbits period length for regtest VB_PERIOD = 144 # versionbits period length for regtest
VB_THRESHOLD = 108 # versionbits activation threshold for regtest VB_THRESHOLD = 108 # versionbits activation threshold for regtest
VB_TOP_BITS = 0x20000000 VB_TOP_BITS = 0x20000000
VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment VB_UNKNOWN_BIT = 12 # Choose a bit unassigned to any deployment
VB_UNKNOWN_VERSION = VB_TOP_BITS | (1 << VB_UNKNOWN_BIT) VB_UNKNOWN_VERSION = VB_TOP_BITS | (1 << VB_UNKNOWN_BIT)
VB_BIP320_BIT = 13
VB_BIP320_VERSION = VB_TOP_BITS | (1 << VB_BIP320_BIT)
VB_BIP320_THRESHOLD = 76
UNKNOWN_VERSION_SCHEMA = 0x60000000 UNKNOWN_VERSION_SCHEMA = 0x60000000
UNKNOWN_VERSION_SCHEMA_THRESHOLD = 51 UNKNOWN_VERSION_SCHEMA_THRESHOLD = 51
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_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_BIT_MINED = f"Warning: Miners are attempting to activate unknown new rules (bit {VB_UNKNOWN_BIT})"
WARN_BIP320_BIT_MINED = f"Warning: Miners are attempting to activate unknown new rules (bit {VB_BIP320_BIT})"
WARN_UNKNOWN_RULES_ACTIVE = f"Unknown new rules activated (versionbit {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") VB_PATTERN = re.compile("Unknown new rules activated.*versionbit")
@ -107,6 +111,20 @@ class VersionBitsWarningTest(BitcoinTestFramework):
assert(WARN_UNKNOWN_BIT_MINED in node.getmininginfo()["warnings"]) assert(WARN_UNKNOWN_BIT_MINED in node.getmininginfo()["warnings"])
assert(WARN_UNKNOWN_BIT_MINED in node.getnetworkinfo()["warnings"]) assert(WARN_UNKNOWN_BIT_MINED in node.getnetworkinfo()["warnings"])
self.log.info("Check that there is a warning if >75 blocks in the last 100 were a BIP320 version")
self.send_blocks_with_version(peer, VB_BIP320_THRESHOLD - 1, VB_BIP320_VERSION)
# Check that get*info() doesn't shows the 76/100 unknown block version warning yet.
assert(WARN_BIP320_BIT_MINED not in node.getmininginfo()["warnings"])
assert(WARN_BIP320_BIT_MINED not in node.getnetworkinfo()["warnings"])
self.send_blocks_with_version(peer, 1, VB_BIP320_VERSION)
# Check that get*info() shows the 76/100 unknown block version warning.
assert(WARN_BIP320_BIT_MINED in node.getmininginfo()["warnings"])
assert(WARN_BIP320_BIT_MINED in node.getnetworkinfo()["warnings"])
self.generatetoaddress(node, 1, node_deterministic_address)
assert(WARN_BIP320_BIT_MINED in node.getmininginfo()["warnings"])
assert(WARN_BIP320_BIT_MINED in node.getnetworkinfo()["warnings"])
self.generatetoaddress(node, VB_PERIOD - VB_BIP320_THRESHOLD - 1, node_deterministic_address)
self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits version.") 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 # Mine a period worth of expected blocks so the generic block-version warning
# is cleared. This will move the versionbit state to ACTIVE. # is cleared. This will move the versionbit state to ACTIVE.