This PR implements the Deployment portion of BIP-110. There is a second PR, built on this one, that implements the BIP-110 consensus changes and deployment parameters. I have split these two features into separate PRs in order to facilitate review.
This first PR is a generic extension of the pre-existing BIP9 framework to add the BIP8-style activation and temporary deployment pieces BIP-110 needs, namely:
max_activation_height: mandatory activation deadline - forces LOCKED_IN one period before the specified height, regardless of miner signaling (similar to BIP8’slockinontimeout=true)active_duration: number of blocks a deployment remains active after activation, after which it transitions to a new terminal EXPIRED state- Mandatory signaling enforcement: blocks must signal for the deployment during the enforcement window (
[max_activation_height - 2*period, max_activation_height - period)), withvbrequiredset ingetblocktemplateoutput (similar to BIP8’sMUST_SIGNALphase)
Regtest command-line support for max_activation_height, active_duration, and threshold have also been added to aid in testing.
These features may be reused as necessary for future softforks.
Background and Motivation
See the corresponding sections on the dependent PR.
Features
New BIP9Deployment fields
max_activation_height(default:INT_MAX= disabled)active_duration(default:INT_MAX= permanent)
State machine changes
- STARTED -> LOCKED_IN forced when
height >= max_activation_height - period - ACTIVE -> EXPIRED when
height >= activation_height + active_duration(new terminal state) active_durationmust be a multiple ofperiod
Mandatory signaling
- Blocks that don’t signal during the mandatory signaling period (
max_activation_height - 2*periodthroughmax_activation_height - period - 1) are rejected getblocktemplatesetsvbrequiredbits during this window
RPC
getdeploymentinfo: newmax_activation_heightfield inbip9object when setgetdeploymentinfo: newheight_endfield when ACTIVE withactive_durationstatusfield now includes"expired"as a possible value
Regtest -vbparams support
- Extended format:
deployment:start:end[:min_activation_height[:max_activation_height[:active_duration[:threshold]]]] - Validates mutual exclusion of
timeoutandmax_activation_height - Validates
active_durationis a multiple ofperiod
Tests
- 11 unit tests covering forced lock-in, boundary conditions, EXPIRED transitions, cold cache recovery, parameter validation, and edge cases (zero duration, unaligned duration rejected)
- Functional test (
feature_bip9_max_activation_height.py): mandatory activation, normal signaling, early activation, permanent vs temporary deployments, custom threshold, and mandatory signaling enforcement (non-signaling block rejected) - Fuzz test updates for
active_durationand EXPIRED state
Note: enforcement-level testing (consensus rules activating/deactivating via DeploymentActiveAfter) is in PR 2, which provides a real deployment (REDUCED_DATA) to test against. TESTDUMMY has no consensus enforcement.
Size
~175 lines non-test C++/H. This puts these deployment changes for BIP-110 at about half the size of the deployment changes required for CSV (BIP-68/112/113), which weighed in at 371 lines.