Skip to content

core(version-gate): add cross-coin verify_version_transition rule SSOT (additive) - #597

Merged
frstrtr merged 1 commit into
masterfrom
btc/core-version-gate-transition-seam
Jul 1, 2026
Merged

core(version-gate): add cross-coin verify_version_transition rule SSOT (additive)#597
frstrtr merged 1 commit into
masterfrom
btc/core-version-gate-transition-seam

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Summary

Adds a cross-coin SSOT for the v36-native share-version-transition RULE to src/core/version_gate.hpp (namespace core::version_gate) as a templated verify_version_transition(...). This standardizes the boundary admit/reject decision SHAPE that is currently inlined per-coin:

  • BTC: src/impl/btc/share_check.hpp (~1756-1815)
  • DASH: src/impl/dash/share_check.hpp (~656)

Only the RULE moves to core. Per-coin version extraction and window-weight plumbing (the get_desired_version_weights lookups, parent-version resolution, window framing) stay in each coin's caller — that is legitimate per-coin divergence and is NOT standardized here. The function takes an ALREADY-EXTRACTED (parent_version, share_version) pair, a PRECOMPUTED PPLNS-weighted desired-version tally for the [CHAIN_LENGTH*9/10, CHAIN_LENGTH] window, and a have_history flag.

Rule (p2pool data.py check())

  • same-version: always valid (correct when minted), regardless of history
  • +1 upgrade: needs >= 60% PPLNS-weighted support for the new version in the window and CHAIN_LENGTH history (new*100 < total*60 rejects)
  • -1 (AutoRatchet deactivation): valid
  • any other jump: throws when history exists
  • with insufficient history: only a +1 upgrade is rejected ("switch without enough history"); other shapes pass — matching the BTC inline gate exactly

Encoded byte-for-byte from the BTC canonical inline block (verified equivalent during authoring).

Scope / contract

  • Additive / no callers this PR — the new function is not invoked anywhere yet.
  • Behavior-preserving — no existing code path changes.
  • LTC + DOGE preservation N/A — no caller change in this PR, so nothing to preserve yet.
  • This is step 1 of the integrator-sequenced Axis-3 standardization: step 2 wires BTC onto this SSOT, step 3 migrates DASH (which threads its own floor for its obsolescence branch via the carried parameter).
  • The seam lands in shared core/ as an EXCEPTIONAL per-coin-isolation case: the version-gate is a cross-coin consensus standard, so the rule SHAPE belongs in core even though most accept-path logic stays per-coin.

Tests

KAT added to the core_test target (src/core/test/version_gate_test.cpp, uint288 weights):

  • same version (36/36): no throw
  • +1 upgrade >= 60% + history: no throw
  • +1 upgrade < 60% + history: throws
  • +1 upgrade, no history: throws (switch without enough history)
  • -1 downgrade (36/35) + history: no throw
  • multi-jump (34/36) + history: throws (invalid version jump)
  • multi-jump (34/36), no history: no throw
  • exact 60% boundary: no throw (60% passes under *100 < *60)

core_test: 54/54 pass (8 new in VersionGateTransition).

Merge gating

Needs all four coin smokes green before tap. Do not self-merge.

…T (additive)

Add the canonical v36-native share-version-transition RULE to
core::version_gate as a templated function verify_version_transition.
This standardizes the boundary admit/reject decision SHAPE that is
currently inlined per-coin (BTC share_check.hpp ~1756-1815; DASH
share_check.hpp ~656).

The function applies the decision to an ALREADY-EXTRACTED
(parent_version, share_version) pair plus a PRECOMPUTED PPLNS-WEIGHTED
desired-version tally for the [CHAIN_LENGTH*9/10, CHAIN_LENGTH] window
and a have_history flag. Per-coin version extraction and window-weight
plumbing stay in each coin caller (legitimate per-coin divergence).

Rule (p2pool data.py check()): same-version always valid; +1 upgrade
needs >= 60% weighted support AND CHAIN_LENGTH history; -1 (AutoRatchet
deactivation) valid; any other jump throws when history exists; with
insufficient history only a +1 upgrade is rejected. Byte-for-byte
equivalent to the BTC inline gate.

Additive and behavior-preserving: NO callers in this PR.

Includes a core_test KAT (version_gate_test.cpp, uint288 weights)
covering same-version, +1 with/without 60% support, +1 without history,
-1 downgrade, multi-jump with/without history, and the exact-60% boundary.
@frstrtr
frstrtr force-pushed the btc/core-version-gate-transition-seam branch from 59b0825 to 2671434 Compare July 1, 2026 17:09
frstrtr added a commit that referenced this pull request Jul 1, 2026
… SSOT (step 2)

Replace the inline 60%-weighted version-transition boundary in
src/impl/btc/share_check.hpp with a call to the core SSOT added in #597.
Behavior-preserving / byte-for-byte: all six transition shapes
(same-version, +1, -1, multi-jump x history/no-history) and every
error string ("switch without enough hash power upgraded",
"invalid version jump from..to..", "switch without enough history")
are unchanged. The PPLNS-weighted desired-version window is still
fetched lazily only on the +1-with-history boundary; other shapes pass
an empty map the SSOT never reads. Floor defaults to
V36_ACTIVATION_VERSION (BTC has no obsolescence branch).

Stacked on #597 (needs core::version_gate::verify_version_transition to
compile); held behind it, expects rebase onto master once #597 lands.
@frstrtr
frstrtr merged commit f0d9cd4 into master Jul 1, 2026
22 checks passed
frstrtr added a commit that referenced this pull request Jul 1, 2026
… SSOT (step 2, stacked on #597) (#600)

* core(version-gate): add cross-coin verify_version_transition rule SSOT (additive)

Add the canonical v36-native share-version-transition RULE to
core::version_gate as a templated function verify_version_transition.
This standardizes the boundary admit/reject decision SHAPE that is
currently inlined per-coin (BTC share_check.hpp ~1756-1815; DASH
share_check.hpp ~656).

The function applies the decision to an ALREADY-EXTRACTED
(parent_version, share_version) pair plus a PRECOMPUTED PPLNS-WEIGHTED
desired-version tally for the [CHAIN_LENGTH*9/10, CHAIN_LENGTH] window
and a have_history flag. Per-coin version extraction and window-weight
plumbing stay in each coin caller (legitimate per-coin divergence).

Rule (p2pool data.py check()): same-version always valid; +1 upgrade
needs >= 60% weighted support AND CHAIN_LENGTH history; -1 (AutoRatchet
deactivation) valid; any other jump throws when history exists; with
insufficient history only a +1 upgrade is rejected. Byte-for-byte
equivalent to the BTC inline gate.

Additive and behavior-preserving: NO callers in this PR.

Includes a core_test KAT (version_gate_test.cpp, uint288 weights)
covering same-version, +1 with/without 60% support, +1 without history,
-1 downgrade, multi-jump with/without history, and the exact-60% boundary.

* core(version-gate): wire BTC accept seam to verify_version_transition SSOT (step 2)

Replace the inline 60%-weighted version-transition boundary in
src/impl/btc/share_check.hpp with a call to the core SSOT added in #597.
Behavior-preserving / byte-for-byte: all six transition shapes
(same-version, +1, -1, multi-jump x history/no-history) and every
error string ("switch without enough hash power upgraded",
"invalid version jump from..to..", "switch without enough history")
are unchanged. The PPLNS-weighted desired-version window is still
fetched lazily only on the +1-with-history boundary; other shapes pass
an empty map the SSOT never reads. Floor defaults to
V36_ACTIVATION_VERSION (BTC has no obsolescence branch).

Stacked on #597 (needs core::version_gate::verify_version_transition to
compile); held behind it, expects rebase onto master once #597 lands.

---------

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
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.

1 participant