Skip to content

Commit

Permalink
Restore warning for individual unknown version bits, as well as unkno…
Browse files Browse the repository at this point in the history
…wn version schemas
  • Loading branch information
luke-jr committed Aug 20, 2020
1 parent e9b3012 commit dd0ff04
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/validation.cpp
Expand Up @@ -2456,15 +2456,40 @@ void static UpdateTip(const CBlockIndex* pindexNew, const CChainParams& chainPar
}
}
// 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 = ComputeBlockVersion(pindex->pprev, chainParams.GetConsensus());
if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0)
if (pindex->nVersion > VERSIONBITS_LAST_OLD_BLOCK_VERSION && (pindex->nVersion & ~nExpectedVersion) != 0) {
++nUpgraded;
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 (nUpgraded > 0)
AppendWarning(warning_messages, strprintf(_("%d of last 100 blocks have unexpected version"), nUpgraded));
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:
DoWarning(strWarning);
}
}
LogPrintf("%s: new best=%s height=%d version=0x%08x log2_work=%f tx=%lu date='%s' progress=%f cache=%.1fMiB(%utxo)%s\n", __func__,
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
Expand Down
18 changes: 18 additions & 0 deletions test/functional/feature_notifications.py
Expand Up @@ -139,6 +139,24 @@ def run_test(self):

# 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.nodes[1].generatetoaddress(51, ADDRESS_BCRT1_UNSPENDABLE)
self.sync_all()

# Give bitcoind 10 seconds to write the alert notification
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.nodes[1].generatetoaddress(2, ADDRESS_BCRT1_UNSPENDABLE)
self.sync_all()

self.log.info("-alertnotify should not continue notifying for more unknown version blocks")
assert_equal(len(os.listdir(self.alertnotify_dir)), 0)

def expect_wallet_notify(self, tx_ids):
wait_until(lambda: len(os.listdir(self.walletnotify_dir)) >= len(tx_ids), timeout=10)
assert_equal(sorted(notify_outputname(self.wallet, tx_id) for tx_id in tx_ids), sorted(os.listdir(self.walletnotify_dir)))
Expand Down
26 changes: 26 additions & 0 deletions test/functional/feature_versionbits_warning.py
Expand Up @@ -21,7 +21,10 @@
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 = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT)
VB_PATTERN = re.compile("Warning: unknown new rules activated.*versionbit")

Expand Down Expand Up @@ -77,10 +80,33 @@ def run_test(self):
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(node.p2p, 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
node.generatetoaddress(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"])
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(node.p2p, VB_THRESHOLD, VB_UNKNOWN_VERSION)
node.generatetoaddress(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.
Expand Down

0 comments on commit dd0ff04

Please sign in to comment.