mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-13 03:30:42 +02:00
Restore warning for individual unknown version bits, as well as unknown version schemas
This commit is contained in:
parent
ee43549507
commit
9b32a6f5d5
@ -2753,6 +2753,40 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
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;
|
||||
for (int i = 0; i < 100 && pindex != nullptr; i++)
|
||||
{
|
||||
int32_t nExpectedVersion = m_chainman.m_versionbitscache.ComputeBlockVersion(pindex->pprev, params.GetConsensus());
|
||||
if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0)
|
||||
{
|
||||
if ((pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) {
|
||||
for (int bit = 0; bit < VERSIONBITS_NUM_BITS; ++bit) {
|
||||
const int32_t mask = 1 << bit;
|
||||
if ((nExpectedVersion & mask) != (pindex->nVersion & mask)) {
|
||||
if (++unexpected_bit_count[bit] > WARNING_THRESHOLD) {
|
||||
warning_threshold_hit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Non-versionbits upgrade
|
||||
if (++nonversionbit_count > WARNING_THRESHOLD) {
|
||||
warning_threshold_hit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
pindex = pindex->pprev;
|
||||
}
|
||||
if (warning_threshold_hit) {
|
||||
auto strWarning = _("Warning: Unrecognised block version being mined! Unknown rules may or may not be in effect");
|
||||
// notify GetWarnings(), called by Qt and the JSON-RPC code to warn the user:
|
||||
m_chainman.GetNotifications().warning(strWarning);
|
||||
}
|
||||
}
|
||||
UpdateTipLog(coins_tip, pindexNew, params, __func__, "", warning_messages.original);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ class NotificationsTest(BitcoinTestFramework):
|
||||
f"-blocknotify=echo > {os.path.join(self.blocknotify_dir, '%s')}",
|
||||
f"-shutdownnotify=echo > {self.shutdownnotify_file}",
|
||||
], [
|
||||
"-blockversion=211",
|
||||
f"-walletnotify=echo %h_%b > {os.path.join(self.walletnotify_dir, notify_outputname('%w', '%s'))}",
|
||||
]]
|
||||
self.wallet_names = [self.default_wallet_name, self.wallet]
|
||||
@ -163,6 +164,22 @@ class NotificationsTest(BitcoinTestFramework):
|
||||
|
||||
# TODO: add test for `-alertnotify` large fork notifications
|
||||
|
||||
# Mine 51 unknown-version blocks. -alertnotify should trigger on the 51st.
|
||||
self.log.info("test -alertnotify")
|
||||
self.generatetoaddress(self.nodes[1], 51, ADDRESS_BCRT1_UNSPENDABLE)
|
||||
|
||||
# Give bitcoind 10 seconds to write the alert notification
|
||||
self.wait_until(lambda: len(os.listdir(self.alertnotify_dir)), timeout=10)
|
||||
|
||||
for notify_file in os.listdir(self.alertnotify_dir):
|
||||
os.remove(os.path.join(self.alertnotify_dir, notify_file))
|
||||
|
||||
# Mine more up-version blocks, should not get more alerts:
|
||||
self.generatetoaddress(self.nodes[1], 2, ADDRESS_BCRT1_UNSPENDABLE)
|
||||
|
||||
self.log.info("-alertnotify should not continue notifying for more unknown version blocks")
|
||||
assert_equal(len(os.listdir(self.alertnotify_dir)), 0)
|
||||
|
||||
self.log.info("test -shutdownnotify")
|
||||
self.stop_nodes()
|
||||
self.wait_until(lambda: os.path.isfile(self.shutdownnotify_file), timeout=10)
|
||||
|
@ -20,7 +20,10 @@ VB_THRESHOLD = 108 # versionbits activation threshold for regtest
|
||||
VB_TOP_BITS = 0x20000000
|
||||
VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment
|
||||
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_ACTIVE = f"Unknown new rules activated (versionbit {VB_UNKNOWN_BIT})"
|
||||
VB_PATTERN = re.compile("Unknown new rules activated.*versionbit")
|
||||
|
||||
@ -76,10 +79,33 @@ class VersionBitsWarningTest(BitcoinTestFramework):
|
||||
assert not VB_PATTERN.match(node.getmininginfo()["warnings"])
|
||||
assert not VB_PATTERN.match(node.getnetworkinfo()["warnings"])
|
||||
|
||||
self.log.info("Check that there is a warning if >50 blocks in the last 100 were an unknown version schema")
|
||||
# Build UNKNOWN_VERSION_SCHEMA_THRESHOLD blocks signaling some unknown schema
|
||||
self.send_blocks_with_version(peer, UNKNOWN_VERSION_SCHEMA_THRESHOLD, UNKNOWN_VERSION_SCHEMA)
|
||||
# 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"])
|
||||
# Close the period normally
|
||||
self.generatetoaddress(node, VB_PERIOD - UNKNOWN_VERSION_SCHEMA_THRESHOLD, node_deterministic_address)
|
||||
# Make sure the warning remains
|
||||
assert(WARN_UNKNOWN_RULES_MINED in node.getmininginfo()["warnings"])
|
||||
assert(WARN_UNKNOWN_RULES_MINED in node.getnetworkinfo()["warnings"])
|
||||
|
||||
# Stop-start the node, and make sure the warning is gone
|
||||
self.restart_node(0)
|
||||
assert(WARN_UNKNOWN_RULES_MINED not in node.getmininginfo()["warnings"])
|
||||
assert(WARN_UNKNOWN_RULES_MINED not in node.getnetworkinfo()["warnings"])
|
||||
peer = node.add_p2p_connection(P2PInterface())
|
||||
|
||||
self.log.info("Check that there is a warning if >50 blocks in the last 100 were an unknown version")
|
||||
# Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit
|
||||
self.send_blocks_with_version(peer, VB_THRESHOLD, VB_UNKNOWN_VERSION)
|
||||
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"])
|
||||
|
||||
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
|
||||
# is cleared. This will move the versionbit state to ACTIVE.
|
||||
|
Loading…
Reference in New Issue
Block a user