Skip to content

ltc: couple AutoRatchet mint gate to the work-weighted accept gate (fix #97 crossing wedge) - #288

Merged
frstrtr merged 1 commit into
masterfrom
ltc-doge/ratchet-mint-accept-coupling
Jun 21, 2026
Merged

ltc: couple AutoRatchet mint gate to the work-weighted accept gate (fix #97 crossing wedge)#288
frstrtr merged 1 commit into
masterfrom
ltc-doge/ratchet-mint-accept-coupling

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Problem

The #97 v35->v36 crossing soak wedged. Root cause (source-localized at share_check.hpp:1753-1754 vs ltc/auto_ratchet.hpp): the mint/activate gate and the accept gate use different metrics.

  • Accept gate (consensus; share_check step 2, mirrors p2pool check() data.py:1399): a V36 boundary share is admitted only when desired-version reaches 60% by WORK over the [9/10*CL, CL] window. Canonical get_desired_version_counts (data.py:2651) weights each share by target_to_average_attempts(target) -- it is work-weighted despite the name.
  • Mint/activate gate (AutoRatchet): activated on a 95% by flat COUNT desired-version tally (one vote per share); tail guard also flat count.

Under heterogeneous hashrate a small miner set pushes the COUNT past 95% while the work-weighted tail is still below 60%. AutoRatchet activates, the node mints a V36 boundary share, and every peer rejects it -> the crossing freezes.

Fix

Switch the AutoRatchet tail guard from flat-count get_desired_version_counts to work-weighted get_desired_version_weights, over the same window at the same 60% threshold the accept gate enforces. Activation now strictly implies the accept rule, so a minted boundary share can never be rejected. Arithmetic mirrors the proven accept-gate path exactly (tail_target * 100 < tail_total * 60).

Supersedes the earlier F10 finding-#1 decision to keep activation flat-count; the production soak proved it unsafe. Covers LTC and DOGE (merged; rides the LTC AutoRatchet).

Verification

  • Builds clean: c2pool LTC target relinked, no new errors.
  • Empirical mechanism-validation in progress on .157 (unwedged via a hand-fed v35 rig): work-weighted desire 98.5%, v36-contiguous-from-tip 33->178, share_pct 8.25->44.5%.
  • Shippable PASS = a clean crossing on THIS fixed binary (no hand-fed v35 rig needed). Re-soak before contabo prod cutover.

Merge

Hold -- reviewer-authored. Integrator/operator merges after CI green + re-soak.

The v35->v36 crossing soak (#97) wedged: AutoRatchet activated on a
95%-by-COUNT desired-version tally, but the consensus accept gate
(share_check step 2 / p2pool check() data.py:1399) admits a V36 boundary
share only when desired-version reaches 60% by WORK over the
[9/10*CL, CL] window -- canonical get_desired_version_counts
(data.py:2651) weights each share by target_to_average_attempts(target).
Under heterogeneous hashrate a small miner set can carry the COUNT past
95% while the work-weighted tail sits below 60%, so the activated node
mints a V36 boundary share that every peer rejects, freezing the crossing.

Switch AutoRatchet tail guard from flat-count get_desired_version_counts
to work-weighted get_desired_version_weights, over the same window at the
same 60% threshold the accept gate enforces. Activation now strictly
implies the accept rule, so a minted boundary share can never be rejected.
Supersedes the earlier F10 keep-activation-flat-count choice, which the
soak proved unsafe. Covers LTC and DOGE (merged, rides LTC AutoRatchet).
@frstrtr
frstrtr merged commit a5131ce into master Jun 21, 2026
19 checks passed
frstrtr added a commit that referenced this pull request Jun 23, 2026
…pling

ltc: couple AutoRatchet mint gate to the work-weighted accept gate (fix #97 crossing wedge)
frstrtr added a commit that referenced this pull request Jun 23, 2026
rest_v36_status() returned a hardcoded auto_ratchet.state="voting" with
v35_shares=0/v36_shares=0/v36_percentage=0.0 regardless of actual chain
state, only ever filling height/sample_size. On a node mid-cross this lied
about the V35->V36 transition (the founding-charter stub class) while the
sibling rest_version_signaling() already derived the truthful state and
percentages from the same chain data.

/v36_status now sources auto_ratchet.state and the v35/v36 share counts +
percentage from rest_version_signaling(). Non-transition coins (its early
{} return) leave truthful zeros; a too-short chain early-returns before the
overall_* fields, handled by .value() defaults. Read/web path only; pool
aggregates and consensus untouched.

Serves the live LTC prod V35->V36 cross (#288) crossing-visibility charter.
frstrtr added a commit that referenced this pull request Jun 24, 2026
…#427)

G2 greenlight gate (G1 byte-parity -> G2 ratchet-migration -> G3 testnet).
Self-provisions the dual-pool testbed on the VM115 isolated scrypt net
(ver35 oracle p2pool-dgb-scrypt <-> v36 c2pool-dgb, one sharechain id
4B62545B1A631AFE, diff-1, bucket-1 isolated). Drives the 5 staged checks:

  C1 baseline cohabit   (live-peer GATED on rigs)
  C2 VOTING mint base35/votes36         sim 3/3
  C3 #288 staged accept gate 60%-by-work sim 9/9
  C4 ratchet + restart persistence       sim 3/3
  C5 scrypt-only; 4 algos N/A-by-continuity  12/12

Sim mode proves the staged-gate logic now via existing AutoRatchet KATs;
LIVE work-weighted rows GATED until the R1-LTC scrypt window is brokered
off the LTC crossing-soak. Conforms to DGBs own oracle (terminal ver35,
SUCCESSOR=None), not the LTC v35 transition. Additive scripts only -- no
consensus surface, no shared/other-coin tree touched.

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jun 24, 2026
Lift the per-version accumulation core of ShareTracker::get_desired_version_weights
(and its flat-count diagnostic sibling get_desired_version_counts) into
coin/desired_version_tally.hpp as free functions over already-resolved
(desired_version, work) pairs. The work-weighted map is the consensus input to the
V36 60%-by-work switch rule (share_check step 2) and the #288 AutoRatchet activation
tail guard; the flat-count map is diagnostics-only and never the gate.

Oracle: p2pool-dgb-scrypt data.py:918-922 get_desired_version_counts, which is
already work-weighted (res[dv] += target_to_average_attempts(share.target)). The
per-share weight equals ShareIndex::work = chain::target_to_average_attempts(
bits_to_target(m_bits)); the KAT anchors that equivalence non-circularly via ttaa
over 2^k-1 targets (hand-derived 2^(256-k)).

FENCED, additive, header-only: share_tracker.hpp is NOT rewired (byte-identity
delegation is the follow-on). The chain-walk and lookbehind clamp stay in
ShareTracker (clamp is the separate chain_walk_window SSOT). Consensus-neutral.
Registered in both the dir CMakeLists.txt and the build.yml --target allowlist.
KAT 6/6 green.

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jun 24, 2026
…430)

Surfaces ratchet state at a glance from the existing /v36_status JSON
(VOTING/ACTIVATED, vote %, work-weighted signaling, current->target
share version) -- the same internal state debug.log uses, never a stub.

Charter #3 (crossing visibility): makes the live V35->V36 cross legible
to the operator directly in the dashboard, serving LTC prod #288.

Static drop-in to the on-disk --dashboard-dir; card defaults hidden and
renders only on a successful fetch, so it degrades gracefully on coins
or nodes where /v36_status is empty. Non-consensus web layer only.

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jun 25, 2026
#440)

Mirror of DGB #427 --sim-votes for BTC: gives the G2 staged-migration harness
(scripts/btc_g2_ratchet_staged_migration_harness.sh) a rig-free verdict source
for its C2/C3/C4 rows, which were GATED on a SHA256d rig window because BTC had
no AutoRatchet sim KAT (DGB proves the same rows via its existing AutoRatchet
KATs). Authorized as path (b).

  C2  VOTING mints the V35 baseline while voting V36 (empty-tracker bootstrap)
  C3  #288 accept gate is 60%-by-WORK, and a 95%-by-COUNT activation can NOT
      outrun it under heterogeneous hashrate (mint-cannot-outrun-accept) —
      pinned via a verbatim replica of the live inline tail-guard expression
      in AutoRatchet::get_share_version, plus a staged 1-by-1 migration whose
      work tally advances monotonically and activates only at full crossing
  C4  ratchet state persists across restart (CONFIRMED survives reconstruct)

Rides the already-allowlisted btc_share_test target (build.yml lines 71/204),
so it FIRES in CI with no allowlist/drift-guard change. Test-only, btc-tree
local, no consensus / shared-base / build.yml / CMake-shared surface.

6/6 new pass; full btc_share_test 21/21 green.

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jun 26, 2026
Extends the rig-free AutoRatchet SIM KAT (arming the G2 staged-migration
harness) with the C5 row: the V36 SCRYPT-ONLY posture and its load-bearing
intersection with the #288 work-weighted accept gate.

  C5  posture disposition vs coin/dgb_block_algo.hpp SSOT: Scrypt header ->
      VALIDATE_SCRYPT (the only validated PoW lane); SHA256d/Skein/Qubit/Odo
      + legacy Groestl -> ACCEPT_BY_CONTINUITY (work-neutral); unknown algo
      nibbles -> REJECT.
  C5/work-neutral  accept-by-continuity blocks credit ZERO work, so a >=95%-
      by-headcount V36 majority carried by non-Scrypt algos canNOT outrun the
      60%-by-work ratchet accept gate -- the multi-algo analogue of
      C3_MintCannotOutrunAccept. Only Scrypt votes ever move the gate.

Pins the consensus SSOT (dgb_block_algo.hpp, itself guarded vs upstream
DigiByte Core by algo_select_test); no consensus surface mutated. FENCED to
src/impl/dgb/ test-tree. 9/9 (was 7/7).
frstrtr added a commit that referenced this pull request Jun 27, 2026
…577)

Fenced, additive, rig-free known-answer test for the BCH G2 staged 1-by-1
miner-migration gate. Pins the canonical 60%-by-WORK version-switch ACCEPT
gate that bch::check_share enforces inline (src/impl/bch/share_check.hpp:1774):

    if (new_ver_weight * 100 < total_weight * 60)
        throw "switch without enough hash power upgraded";

via a verbatim replica of the live tail-guard (same non-circular localisation
btc/DGB use; guard stays inline, no lifted SSOT). Arms the staged-migration
rows without a SHA256d bitaxe rig.

Properties pinned (15 asserts, all green):
  - 60%-by-WORK boundary at the exact crossing (59 hold / 60-100 pass / 0 hold)
  - mint-cannot-outrun-accept (#288): 95%-by-COUNT under heterogeneous hashrate
    can NOT outrun the 60%-by-work gate -> a minted V36 boundary share its peers
    would reject is prevented
  - work-weighted NOT flat-count (#290/#326 regression guard): gate diverges
    from a head-count in both directions; #326 dropped the 95%-flat-count punish
  - monotonic staged migration: 5 equal-work miners, tally advances monotone,
    accept gate crosses at stage 3/5 (60%) and stays on
  - downgrade asymmetry: V35-after-V36 (AutoRatchet deactivation) is un-gated

Test-only, bch-tree-local: pure int main()+assert over <core/pack_types.hpp>
uint288, no consensus / shared-base / CMake-shared surface. Registered in the
bch test CMakeLists foreach and BOTH build.yml COIN_BCH --target allowlists.

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jun 28, 2026
Rig-free C++ counterpart of the G2 staged-migration harness --sim-votes
path: proves the AutoRatchet staged-gate LOGIC over hand-derived oracle
votes WITHOUT a Scrypt rig or a live digibyted parent.

  C2  VOTING mints the DGB baseline (v35, SUCCESSOR=None) while voting V36
  C3  #288 accept gate is 60%-by-WORK; a 95%-by-COUNT activation cannot
      outrun it (mint-cannot-outrun-accept); staged tally monotone
  C4  CONFIRMED state persists across restart; fresh node mints baseline

Pinned to DGB own oracle frstrtr/p2pool-dgb-scrypt @22761e7 (terminal v35
-> v36), NOT the ltc v35 transition: VOTING output = base_version=35 ctor
param. C3 replicates the live inline 60%-by-WORK tail guard verbatim, the
same non-circular pin as dgb_auto_ratchet_tail_guard_test. No consensus
surface mutated; src/impl/dgb/ test-tree only + build.yml allowlist. 7/7.
frstrtr added a commit that referenced this pull request Jun 28, 2026
Extends the rig-free AutoRatchet SIM KAT (arming the G2 staged-migration
harness) with the C5 row: the V36 SCRYPT-ONLY posture and its load-bearing
intersection with the #288 work-weighted accept gate.

  C5  posture disposition vs coin/dgb_block_algo.hpp SSOT: Scrypt header ->
      VALIDATE_SCRYPT (the only validated PoW lane); SHA256d/Skein/Qubit/Odo
      + legacy Groestl -> ACCEPT_BY_CONTINUITY (work-neutral); unknown algo
      nibbles -> REJECT.
  C5/work-neutral  accept-by-continuity blocks credit ZERO work, so a >=95%-
      by-headcount V36 majority carried by non-Scrypt algos canNOT outrun the
      60%-by-work ratchet accept gate -- the multi-algo analogue of
      C3_MintCannotOutrunAccept. Only Scrypt votes ever move the gate.

Pins the consensus SSOT (dgb_block_algo.hpp, itself guarded vs upstream
DigiByte Core by algo_select_test); no consensus surface mutated. FENCED to
src/impl/dgb/ test-tree. 9/9 (was 7/7).
frstrtr added a commit that referenced this pull request Jul 1, 2026
Rig-free C++ counterpart of the G2 staged-migration harness --sim-votes
path: proves the AutoRatchet staged-gate LOGIC over hand-derived oracle
votes WITHOUT a Scrypt rig or a live digibyted parent.

  C2  VOTING mints the DGB baseline (v35, SUCCESSOR=None) while voting V36
  C3  #288 accept gate is 60%-by-WORK; a 95%-by-COUNT activation cannot
      outrun it (mint-cannot-outrun-accept); staged tally monotone
  C4  CONFIRMED state persists across restart; fresh node mints baseline

Pinned to DGB own oracle frstrtr/p2pool-dgb-scrypt @22761e7 (terminal v35
-> v36), NOT the ltc v35 transition: VOTING output = base_version=35 ctor
param. C3 replicates the live inline 60%-by-WORK tail guard verbatim, the
same non-circular pin as dgb_auto_ratchet_tail_guard_test. No consensus
surface mutated; src/impl/dgb/ test-tree only + build.yml allowlist. 7/7.
frstrtr added a commit that referenced this pull request Jul 1, 2026
Extends the rig-free AutoRatchet SIM KAT (arming the G2 staged-migration
harness) with the C5 row: the V36 SCRYPT-ONLY posture and its load-bearing
intersection with the #288 work-weighted accept gate.

  C5  posture disposition vs coin/dgb_block_algo.hpp SSOT: Scrypt header ->
      VALIDATE_SCRYPT (the only validated PoW lane); SHA256d/Skein/Qubit/Odo
      + legacy Groestl -> ACCEPT_BY_CONTINUITY (work-neutral); unknown algo
      nibbles -> REJECT.
  C5/work-neutral  accept-by-continuity blocks credit ZERO work, so a >=95%-
      by-headcount V36 majority carried by non-Scrypt algos canNOT outrun the
      60%-by-work ratchet accept gate -- the multi-algo analogue of
      C3_MintCannotOutrunAccept. Only Scrypt votes ever move the gate.

Pins the consensus SSOT (dgb_block_algo.hpp, itself guarded vs upstream
DigiByte Core by algo_select_test); no consensus surface mutated. FENCED to
src/impl/dgb/ test-tree. 9/9 (was 7/7).
frstrtr added a commit that referenced this pull request Jul 2, 2026
Rig-free C++ counterpart of the G2 staged-migration harness --sim-votes
path: proves the AutoRatchet staged-gate LOGIC over hand-derived oracle
votes WITHOUT a Scrypt rig or a live digibyted parent.

  C2  VOTING mints the DGB baseline (v35, SUCCESSOR=None) while voting V36
  C3  #288 accept gate is 60%-by-WORK; a 95%-by-COUNT activation cannot
      outrun it (mint-cannot-outrun-accept); staged tally monotone
  C4  CONFIRMED state persists across restart; fresh node mints baseline

Pinned to DGB own oracle frstrtr/p2pool-dgb-scrypt @22761e7 (terminal v35
-> v36), NOT the ltc v35 transition: VOTING output = base_version=35 ctor
param. C3 replicates the live inline 60%-by-WORK tail guard verbatim, the
same non-circular pin as dgb_auto_ratchet_tail_guard_test. No consensus
surface mutated; src/impl/dgb/ test-tree only + build.yml allowlist. 7/7.
frstrtr added a commit that referenced this pull request Jul 2, 2026
Extends the rig-free AutoRatchet SIM KAT (arming the G2 staged-migration
harness) with the C5 row: the V36 SCRYPT-ONLY posture and its load-bearing
intersection with the #288 work-weighted accept gate.

  C5  posture disposition vs coin/dgb_block_algo.hpp SSOT: Scrypt header ->
      VALIDATE_SCRYPT (the only validated PoW lane); SHA256d/Skein/Qubit/Odo
      + legacy Groestl -> ACCEPT_BY_CONTINUITY (work-neutral); unknown algo
      nibbles -> REJECT.
  C5/work-neutral  accept-by-continuity blocks credit ZERO work, so a >=95%-
      by-headcount V36 majority carried by non-Scrypt algos canNOT outrun the
      60%-by-work ratchet accept gate -- the multi-algo analogue of
      C3_MintCannotOutrunAccept. Only Scrypt votes ever move the gate.

Pins the consensus SSOT (dgb_block_algo.hpp, itself guarded vs upstream
DigiByte Core by algo_select_test); no consensus surface mutated. FENCED to
src/impl/dgb/ test-tree. 9/9 (was 7/7).
frstrtr added a commit that referenced this pull request Jul 12, 2026
Re-cuts the LTC (+DOGE aux) crossing soak-harness so it lands the moment the
swarm (VM119/120/121) has a target, per integrator UID2071. Mirrors the dgb/dash
G2 harnesses but THREE-TIER per operator 2026-07-03 wire-compat:
  T-A jtoomim v35-only (raw-tx)  T-B p2pool-merged-v36 (python, v36 dest)
  T-C c2pool-ltc (C++, AutoRatchet, DOGE aux embedded)  -- on ONE sharechain.

Staged with the 3301 accept-floor (params.hpp:65), the PR#95 8-byte identifier
(e037d5b8c6923410), and --fresh-ratchet (archives prior ratchet state, never
destroys). Staging: forward natural-fill -> ratchet cross (.37/.38/.39 repoint)
-> reverse. 5 checks: three-tier cohabit, vote-visibility (zero v36-byte leak
into v35 shares), #288 staged accept gate, ratchet+persist+reverse, byte-compat
differential.

Found gap recorded in-script: LTC lacks the dgb/btc AutoRatchet sim/tail-guard/
desired-version KATs its own state machine is the reference for; --sim-votes
rows are [GATED: ltc-ratchet-kats] until those ports land (next milestone). Rig
rows GATED until start-tap frees R1-LTC onto the v36 tier. Deploy-only; natural-
vote hard gate preserved; never force-activates.
frstrtr added a commit that referenced this pull request Jul 16, 2026
…Tracker

Additive, fenced KAT (no production code touched). Pins the pure-integer
window idiom governing every backward sharechain accessor:
  actual = min(lookbehind, height); if (actual <= 0) -> empty result
open-coded inline in four share_tracker.hpp accessors (get_average_stale_prop,
get_stale_counts, get_desired_version_counts, get_desired_version_weights).

Drives the clamp+guard through the REAL ltc::ShareTracker chain-walk API over a
dense (H, lookbehind) matrix; the realized walk length is asserted against an
independent inline min() oracle. The clamp feeds the check()-phase 60%
work-weighted v36 switch gate and the #288 AutoRatchet VOTING tail guard.

Registered into the share_test target so it cannot become a #143 NOT_BUILT
sentinel. 5/5 PASS on Linux x86_64.
frstrtr added a commit that referenced this pull request Jul 16, 2026
…Tracker (#716)

Additive, fenced KAT (no production code touched). Pins the pure-integer
window idiom governing every backward sharechain accessor:
  actual = min(lookbehind, height); if (actual <= 0) -> empty result
open-coded inline in four share_tracker.hpp accessors (get_average_stale_prop,
get_stale_counts, get_desired_version_counts, get_desired_version_weights).

Drives the clamp+guard through the REAL ltc::ShareTracker chain-walk API over a
dense (H, lookbehind) matrix; the realized walk length is asserted against an
independent inline min() oracle. The clamp feeds the check()-phase 60%
work-weighted v36 switch gate and the #288 AutoRatchet VOTING tail guard.

Registered into the share_test target so it cannot become a #143 NOT_BUILT
sentinel. 5/5 PASS on Linux x86_64.

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