Merge bitcoin/bitcoin#34779: BIP 323: reserve version bits 5-28 as extra nonce space

107d4178d9 versionbits: update VersionBitsCache doc comment to match current behaviour (Antoine Poinsot)
94e3ac0b21 doc: release notes and bips doc update for #34779 (Antoine Poinsot)
1d5240574a qa: test we don't warn for ignored unknown version bits deployments (Antoine Poinsot)
f802edf57c versionbits: Limit live activation params and activation warnings per BIP323 (Anthony Towns)

Pull request description:

  This implements https://github.com/bitcoin/bips/pull/2116, which repurposes 24 version bits as extra nonce space for miners rather than soft fork deployment coordination. 24 bits allows a miner to perform up to 72 PH before needing a fresh job from its controller. The current 16 bits in use by miners only allow up to 280 TH, which [apparently led some ASIC designers to start rolling the timestamp field](https://github.com/bitaxeorg/ESP-Miner/pull/1553#issuecomment-3937736319) on their beefier machines.

  Mailing list discussion available [here](https://gnusha.org/pi/bitcoindev/6fa0cb45-37d6-4b41-9ff8-03730fd96d6e@mattcorallo.com/). A previous shot at this is https://github.com/bitcoin/bitcoin/pull/13972 (with a smaller extranonce space).

  This change only affects the warning logic.

ACKs for top commit:
  ajtowns:
    ACK 107d4178d9
  achow101:
    ACK 107d4178d9
  sedited:
    Re-ACK 107d4178d9
  optout21:
    ACK 107d4178d9

Tree-SHA512: cfaf5d7de1e8c020a4d7f4b1096b6c3e0e3b41ea840a4652ebcdabc345c5c557161c8304f1d7d6de541a2bf1df3c855ad7b64e49dd8c8af3937876d134bb5aba
This commit is contained in:
Ava Chow
2026-06-03 11:56:14 -07:00
7 changed files with 58 additions and 8 deletions

View File

@@ -49,6 +49,7 @@ BIPs that are implemented by Bitcoin Core:
* [`BIP 173`](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki): Bech32 addresses for native Segregated Witness outputs are supported as of **v0.16.0** ([PR 11167](https://github.com/bitcoin/bitcoin/pull/11167)). Bech32 addresses are generated by default as of **v0.20.0** ([PR 16884](https://github.com/bitcoin/bitcoin/pull/16884)).
* [`BIP 174`](https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki): RPCs to operate on Partially Signed Bitcoin Transactions (PSBT) are present as of **v0.17.0** ([PR 13557](https://github.com/bitcoin/bitcoin/pull/13557)).
* [`BIP 176`](https://github.com/bitcoin/bips/blob/master/bip-0176.mediawiki): Bits Denomination [QT only] is supported as of **v0.16.0** ([PR 12035](https://github.com/bitcoin/bitcoin/pull/12035)).
* [`BIP 323`](https://github.com/bitcoin/bips/blob/master/bip-0323.mediawiki): BIP 9 bits 5 to 28 (inclusive) are ignored for soft-fork signalling and unknown soft fork warnings as of **v32.0**.
* [`BIP 324`](https://github.com/bitcoin/bips/blob/master/bip-0324.mediawiki): The v2 transport protocol specified by BIP324 and the associated `NODE_P2P_V2` service bit are supported as of **v26.0**, but off by default ([PR 28331](https://github.com/bitcoin/bitcoin/pull/28331)). On by default as of **v27.0** ([PR 29347](https://github.com/bitcoin/bitcoin/pull/29347)).
* [`BIP 325`](https://github.com/bitcoin/bips/blob/master/bip-0325.mediawiki): Signet test network is supported as of **v0.21.0** ([PR 18267](https://github.com/bitcoin/bitcoin/pull/18267)).
* [`BIP 327`](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki): Key aggregation via `musig()` descriptors is supported as of **v30.0** ([PR 31244](https://github.com/bitcoin/bitcoin/pull/31244)). Signing is supported as of **v31.0** ([PR 29675](https://github.com/bitcoin/bitcoin/pull/29675))

View File

@@ -0,0 +1,5 @@
Logging
-------
- BIP 9 bits 5 to 28 inclusive are now ignored for soft fork signaling, as per BIP 323. We won't
warn about unknown deployments when receiving blocks that set any of those bits in their version.

View File

@@ -14,6 +14,7 @@
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <test/util/versionbits.h>
#include <cstdint>
#include <limits>
@@ -31,7 +32,7 @@ public:
{
assert(dep.period > 0);
assert(dep.threshold <= dep.period);
assert(0 <= dep.bit && dep.bit < 32 && dep.bit < VERSIONBITS_NUM_BITS);
assert(0 <= dep.bit && dep.bit < 32 && dep.bit < VERSIONBITS_MAX_NUM_BITS);
assert(0 <= dep.min_activation_height);
}
@@ -126,7 +127,7 @@ FUZZ_TARGET(versionbits, .init = initialize)
assert(0 < dep.threshold && dep.threshold <= dep.period); // must be able to both pass and fail threshold!
// select deployment parameters: bit, start time, timeout
dep.bit = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, VERSIONBITS_NUM_BITS - 1);
dep.bit = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, VERSIONBITS_MAX_NUM_BITS - 1);
if (always_active_test) {
dep.nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;

View File

@@ -0,0 +1,13 @@
// Copyright (c) 2026-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_TEST_UTIL_VERSIONBITS_H
#define BITCOIN_TEST_UTIL_VERSIONBITS_H
#include <versionbits.h>
/** Total possible bits available for versionbits per original BIP 9 specification */
static constexpr int VERSIONBITS_MAX_NUM_BITS{29};
#endif // BITCOIN_TEST_UTIL_VERSIONBITS_H

View File

@@ -8,6 +8,7 @@
#include <test/util/random.h>
#include <test/util/common.h>
#include <test/util/setup_common.h>
#include <test/util/versionbits.h>
#include <util/chaintype.h>
#include <versionbits.h>
#include <versionbits_impl.h>
@@ -454,9 +455,19 @@ BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
// not take precedence over STARTED/LOCKED_IN. So all softforks on
// the same bit might overlap, even when non-overlapping start-end
// times are picked.
const uint32_t dep_mask{uint32_t{1} << chainParams->GetConsensus().vDeployments[dep].bit};
const auto& dep_info = chainParams->GetConsensus().vDeployments[dep];
const uint32_t dep_mask{uint32_t{1} << dep_info.bit};
BOOST_CHECK(!(chain_all_vbits & dep_mask));
chain_all_vbits |= dep_mask;
BOOST_CHECK(0 <= dep_info.bit && dep_info.bit < VERSIONBITS_MAX_NUM_BITS);
if (chain_type != ChainType::REGTEST) {
if (dep == Consensus::DEPLOYMENT_TESTDUMMY) {
BOOST_CHECK_EQUAL(dep_info.nStartTime, Consensus::BIP9Deployment::NEVER_ACTIVE);
BOOST_CHECK_EQUAL(dep_info.nTimeout, Consensus::BIP9Deployment::NO_TIMEOUT);
} else {
BOOST_CHECK(dep_info.bit < VERSIONBITS_NUM_BITS);
}
}
check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
}
}

View File

@@ -21,8 +21,8 @@ static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION = 4;
static const int32_t VERSIONBITS_TOP_BITS = 0x20000000UL;
/** What bitmask determines whether versionbits is in use */
static const int32_t VERSIONBITS_TOP_MASK = 0xE0000000UL;
/** Total bits available for versionbits */
static const int32_t VERSIONBITS_NUM_BITS = 29;
/** Total bits available for versionbits (BIP 323) */
static const int32_t VERSIONBITS_NUM_BITS = 5;
/** Opaque type for BIP9 state. See versionbits_impl.h for details. */
enum class ThresholdState : uint8_t;
@@ -72,7 +72,8 @@ struct BIP9GBTStatus {
};
/** BIP 9 allows multiple softforks to be deployed in parallel. We cache
* per-period state for every one of them. */
* per-period state for every one we implement and warning state for each
* BIP 323 allowed bit. */
class VersionBitsCache
{
private:

View File

@@ -18,8 +18,13 @@ from test_framework.test_framework import BitcoinTestFramework
VB_PERIOD = 144 # versionbits period length for regtest
VB_THRESHOLD = 108 # versionbits activation threshold for regtest
VB_TOP_BITS = 0x20000000
VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment
# Choose a bit unassigned to any deployment, or start the
# node with the deployment matching this bit disabled.
VB_UNKNOWN_BIT = 3
VB_UNKNOWN_VERSION = VB_TOP_BITS | (1 << VB_UNKNOWN_BIT)
VB_IGNORED_BIT = 5
VB_IGNORED_VERSION = VB_TOP_BITS | (1 << VB_IGNORED_BIT)
WARN_UNKNOWN_RULES_ACTIVE = f"Unknown new rules activated (versionbit {VB_UNKNOWN_BIT})"
VB_PATTERN = re.compile("Unknown new rules activated.*versionbit")
@@ -76,11 +81,24 @@ class VersionBitsWarningTest(BitcoinTestFramework):
assert not VB_PATTERN.match(",".join(node.getmininginfo()["warnings"]))
assert not VB_PATTERN.match(",".join(node.getnetworkinfo()["warnings"]))
self.log.info("Check that there is no warning if previous VB_BLOCKS have VB_PERIOD blocks with ignored versionbits version.")
# Build one period of blocks with VB_THRESHOLD blocks signaling some unknown bit
self.send_blocks_with_version(peer, VB_THRESHOLD, VB_IGNORED_VERSION)
self.generatetoaddress(node, VB_PERIOD - VB_THRESHOLD, node_deterministic_address)
# Move the ignored deployment state to ACTIVE and make sure we're out of IBD.
self.generatetoaddress(node, VB_PERIOD, node_deterministic_address)
self.wait_until(lambda: not node.getblockchaininfo()['initialblockdownload'])
# Check that we're not getting any versionbit-related warnings in get*info()
assert not VB_PATTERN.match(", ".join(node.getmininginfo()["warnings"]))
assert not VB_PATTERN.match(", ".join(node.getnetworkinfo()["warnings"]))
self.log.info("Check that there is a warning if previous VB_BLOCKS have >=VB_THRESHOLD blocks with unknown versionbits 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)
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.
self.generatetoaddress(node, VB_PERIOD, node_deterministic_address)