Skip to content

Versionbits extensions for BIP-110#1

Open
dathonohm wants to merge 7 commits into
v31from
bip110-core-pr1
Open

Versionbits extensions for BIP-110#1
dathonohm wants to merge 7 commits into
v31from
bip110-core-pr1

Conversation

@dathonohm

@dathonohm dathonohm commented Mar 27, 2026

Copy link
Copy Markdown

(Also submitted upstream as bitcoin#34929.)

This PR implements the Deployment portion of BIP-110. There is a second PR (upstream), 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's lockinontimeout=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)), with vbrequired set in getblocktemplate output (similar to BIP8's MUST_SIGNAL phase)

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 (upstream).

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_duration must be a multiple of period

Mandatory signaling

  • Blocks that don't signal during the mandatory signaling period (max_activation_height - 2*period through max_activation_height - period - 1) are rejected
  • getblocktemplate sets vbrequired bits during this window

RPC

  • getdeploymentinfo: new max_activation_height field in bip9 object when set
  • getdeploymentinfo: new height_end field when ACTIVE with active_duration
  • status field 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 timeout and max_activation_height
  • Validates active_duration is a multiple of period

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_duration and EXPIRED state

Note: enforcement-level testing (consensus rules activating/deactivating via DeploymentActiveAfter) is in PR 2 (upstream), 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.

@8144225309

This comment was marked as spam.

@dathonohm dathonohm changed the base branch from master to v31 July 3, 2026 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants