net: Phase-2 ACP broadcast checkpoints — Conclave-signed finality overlay #40

Closed
opened 2026-06-17 01:28:49 +00:00 by dobbscoin · 7 comments
dobbscoin commented 2026-06-17 01:28:49 +00:00

Goal

Stand up the Phase-2 broadcast-checkpoint overlay that gives OFF a real-time 51%-attack defense, paired with #6 Phase 1 (per-node rolling checkpoints). Conclave-signed CSyncCheckpoint messages gossiped to peers; recipients reject reorgs past the embedded height.

The architectural argument and the recommendation that promoted Phase 2 from deferred to a committed deliverable are in https://github.com/SubGeniusFinance/Offerings-to-Cthulhu/issues/6#issuecomment-4725038454.

Why this is separate from #6

  • #6 is a hardfork — changes block validation at h=1,055,555.
  • This is an overlay — no consensus change, no activation height. Nodes either honor ACP checkpoints (newer build) or they don't (older build); chains that never need to reorg past a checkpoint are unaffected either way.

Decoupling lets Phase 2 ship and start carrying finality before h=1,050,666, closing the 4,889-block unguarded gap between OFFSIG-window close and #6 activation — without touching the 1,055,555 consensus constant or being gated on the #6 hardfork timeline.

Plumbing — what already exists

The CSyncCheckpoint / ValidateSyncCheckpoint machinery is already vendored in src/checkpoints.cpp (ppcoin/Peercoin lineage). An audit of exactly what's wired vs. dormant is the first sub-task.

Work remaining

  1. Broadcaster — small daemon (or RPC-triggered loop) that signs a CSyncCheckpoint against the current chain tip at depth N and gossips it. Runs on the host that holds Conclave Key #1's privkey.
  2. Peer gossip path — extend the P2P message handlers to relay CSyncCheckpoint messages.
  3. Recipient validation — on CSyncCheckpoint receipt, validate signature against vConclaveKeys[0] (already in src/chainparams.cpp:188), accept if newer-than-stored, reject reorgs past the embedded height.
  4. RPC surface — getsynccheckpoint, sendcheckpoint, etc. — peer with the existing checkpoint RPCs.
  5. Cadence + depth — open design question. Suggest depth ~MAX_REORG_DEPTH (= 100) initially, broadcast on every Nth block.
  6. Test plan — regtest harness for the signing/validation path; testnet rehearsal; cluster dry-run before broadcasting to mainnet.

Custody — already decided

Reuse Conclave Key #1 (vConclaveKeys[0], pubkey 0238efde05d567979485df6cd6dcf3af2606348a1e260eedf9a6464df57f46b111, P2PKH Qcad56y76jCGgjkhGHPyCMY89uC9j9CBXC). Pubkey is already in src/chainparams.cpp:188 — no chainparams change required when the broadcaster ships. No new key generation.

Ratified by Conclave 2026-06-17. Tradeoff: faster path, at the cost of conflating canon-mining and ACP-signing duties on the same key. A future revision can separate them if the tradeoff stops feeling acceptable.

Activation goal

Dark-live before h=1,050,666 — broadcaster signing checkpoints, ACP-aware peers honoring them, carrying finality through the OFFSIG → #6 gap. Builds can start immediately; no dependency on #6, on the v2.0.x-rc-bipsoft soak, or on chain height.

Out of scope

  • AuxPoW — deferred (composes with ACP later; see #6 closing note).
  • Permanent OFFSIG extension — rejected (centralization regression).
  • "Accept-it" / no defense — rejected (named repeat attacker, live reclamation/bridge economy).

Open subquestions

  • Broadcast cadence — every N blocks, time-based, or hybrid?
  • Checkpoint depth — start at MAX_REORG_DEPTH = 100 and tune?
  • Whether the broadcaster needs to be peer-discoverable, or relies entirely on the gossip mesh
  • Whether to bundle in the same point release as #6 Phase 1, or ship earlier as a standalone
## Goal Stand up the Phase-2 broadcast-checkpoint overlay that gives OFF a real-time 51%-attack defense, paired with #6 Phase 1 (per-node rolling checkpoints). Conclave-signed `CSyncCheckpoint` messages gossiped to peers; recipients reject reorgs past the embedded height. The architectural argument and the recommendation that promoted Phase 2 from *deferred* to a committed deliverable are in https://github.com/SubGeniusFinance/Offerings-to-Cthulhu/issues/6#issuecomment-4725038454. ## Why this is separate from #6 - **#6 is a hardfork** — changes block validation at h=1,055,555. - **This is an overlay** — no consensus change, no activation height. Nodes either honor ACP checkpoints (newer build) or they don't (older build); chains that never need to reorg past a checkpoint are unaffected either way. Decoupling lets Phase 2 ship and start carrying finality *before* h=1,050,666, closing the 4,889-block unguarded gap between OFFSIG-window close and #6 activation — without touching the 1,055,555 consensus constant or being gated on the #6 hardfork timeline. ## Plumbing — what already exists The `CSyncCheckpoint` / `ValidateSyncCheckpoint` machinery is **already vendored** in `src/checkpoints.cpp` (ppcoin/Peercoin lineage). An audit of exactly what's wired vs. dormant is the first sub-task. ## Work remaining 1. **Broadcaster** — small daemon (or RPC-triggered loop) that signs a `CSyncCheckpoint` against the current chain tip at depth N and gossips it. Runs on the host that holds Conclave Key #1's privkey. 2. **Peer gossip path** — extend the P2P message handlers to relay `CSyncCheckpoint` messages. 3. **Recipient validation** — on `CSyncCheckpoint` receipt, validate signature against `vConclaveKeys[0]` (already in `src/chainparams.cpp:188`), accept if newer-than-stored, reject reorgs past the embedded height. 4. **RPC surface** — `getsynccheckpoint`, `sendcheckpoint`, etc. — peer with the existing checkpoint RPCs. 5. **Cadence + depth** — open design question. Suggest depth ~`MAX_REORG_DEPTH` (= 100) initially, broadcast on every Nth block. 6. **Test plan** — regtest harness for the signing/validation path; testnet rehearsal; cluster dry-run before broadcasting to mainnet. ## Custody — already decided Reuse **Conclave Key #1** (`vConclaveKeys[0]`, pubkey `0238efde05d567979485df6cd6dcf3af2606348a1e260eedf9a6464df57f46b111`, P2PKH `Qcad56y76jCGgjkhGHPyCMY89uC9j9CBXC`). Pubkey is already in `src/chainparams.cpp:188` — **no chainparams change required** when the broadcaster ships. No new key generation. Ratified by Conclave 2026-06-17. Tradeoff: faster path, at the cost of conflating canon-mining and ACP-signing duties on the same key. A future revision can separate them if the tradeoff stops feeling acceptable. ## Activation goal **Dark-live before h=1,050,666** — broadcaster signing checkpoints, ACP-aware peers honoring them, carrying finality through the OFFSIG → #6 gap. Builds can start immediately; no dependency on #6, on the v2.0.x-rc-bipsoft soak, or on chain height. ## Out of scope - AuxPoW — deferred (composes with ACP later; see #6 closing note). - Permanent OFFSIG extension — rejected (centralization regression). - "Accept-it" / no defense — rejected (named repeat attacker, live reclamation/bridge economy). ## Open subquestions - Broadcast cadence — every N blocks, time-based, or hybrid? - Checkpoint depth — start at `MAX_REORG_DEPTH = 100` and tune? - Whether the broadcaster needs to be peer-discoverable, or relies entirely on the gossip mesh - Whether to bundle in the same point release as #6 Phase 1, or ship earlier as a standalone
dobbscoin commented 2026-06-17 01:33:33 +00:00

Audit phase done — branch feat/issue-40-phase2-acp (36f319f), full writeup at contrib/phase2-acp/AUDIT.md.

Headline finding

The entire ACP stack is already implemented end-to-end in src/checkpoints.{cpp,h} — dormant, but architecturally complete and wired:

  • P2P receive: main.cpp:4492 (strCommand == "checkpoint" → ProcessSyncCheckpoint)
  • Block-validation hook: main.cpp:2825-2833 (AcceptBlock rejects on CheckSyncCheckpoint fail)
  • Startup-key wiring: init.cpp:574-577 (-checkpointkey=<WIF> → SetCheckpointPrivKey)
  • RPCs: sendcheckpoint, enforcecheckpoint registered at rpcserver.cpp:351-352
  • Post-tip-advance auto-broadcast: main.cpp:3033

The whole machinery has been sitting in the tree since the ppcoin/Peercoin fork era; nobody pointed it at our keys.

The single load-bearing change

src/checkpoints.cpp:525 — CSyncCheckpoint::strMainPubKey is still the stale ppcoin key. Replace with Conclave Key #1's pubkey (0238efde…46b111, already present at chainparams.cpp:188 as vConclaveKeys[0]). The corresponding privkey lives where the active canon miner runs.

Revised scope vs. the original #40 work list

Item from #40 body Status
Broadcaster exists (SendSyncCheckpoint) + auto-fires at tip advance
Peer gossip path exists (RelayTo + ProcessMessage handler)
Recipient validation exists (ValidateSyncCheckpoint + AcceptBlock hook)
RPC surface exists (sendcheckpoint, enforcecheckpoint)
Cadence + depth still a design call (-checkpointdepth arg exists)
Test plan needs writing (regtest harness, two-node peering)

Open subquestions (still real, just smaller)

  1. Broadcaster cadence — rely on the tip-advance auto-broadcast, or add a heartbeat re-broadcast?
  2. Checkpoint depth — MAX_REORG_DEPTH = 100 a sensible starting value for -checkpointdepth?
  3. Testnet pubkey — fresh or reuse?
  4. Cleanup: drop the hardcoded strMainPubKey in favor of reading Params().ConclaveKeys()[0] directly?

Sub-task list for the rest of #40:

  • 1-line pubkey constant change (+ testnet equivalent)
  • Operator runbook: deploy with -checkpointkey=<WIF> on Conclave Key #1 host
  • Regtest harness test (qa/rpc-tests/phase2_acp.py)
  • Optional cleanup: Params().ConclaveKeys()[0] substitution
  • Decide cadence / depth defaults
**Audit phase done** — branch `feat/issue-40-phase2-acp` (`36f319f`), full writeup at [`contrib/phase2-acp/AUDIT.md`](../blob/feat/issue-40-phase2-acp/contrib/phase2-acp/AUDIT.md). ### Headline finding The entire ACP stack is **already implemented end-to-end** in `src/checkpoints.{cpp,h}` — dormant, but architecturally complete and wired: - P2P receive: `main.cpp:4492` (`strCommand == "checkpoint"` → `ProcessSyncCheckpoint`) - Block-validation hook: `main.cpp:2825-2833` (`AcceptBlock` rejects on `CheckSyncCheckpoint` fail) - Startup-key wiring: `init.cpp:574-577` (`-checkpointkey=<WIF>` → `SetCheckpointPrivKey`) - RPCs: `sendcheckpoint`, `enforcecheckpoint` registered at `rpcserver.cpp:351-352` - Post-tip-advance auto-broadcast: `main.cpp:3033` The whole machinery has been sitting in the tree since the ppcoin/Peercoin fork era; nobody pointed it at our keys. ### The single load-bearing change `src/checkpoints.cpp:525` — `CSyncCheckpoint::strMainPubKey` is still the stale ppcoin key. Replace with Conclave Key #1's pubkey (`0238efde…46b111`, already present at `chainparams.cpp:188` as `vConclaveKeys[0]`). The corresponding privkey lives where the active canon miner runs. ### Revised scope vs. the original #40 work list | Item from #40 body | Status | |---|---| | Broadcaster | exists (`SendSyncCheckpoint`) + auto-fires at tip advance | | Peer gossip path | exists (`RelayTo` + `ProcessMessage` handler) | | Recipient validation | exists (`ValidateSyncCheckpoint` + `AcceptBlock` hook) | | RPC surface | exists (`sendcheckpoint`, `enforcecheckpoint`) | | Cadence + depth | still a design call (`-checkpointdepth` arg exists) | | Test plan | needs writing (regtest harness, two-node peering) | ### Open subquestions (still real, just smaller) 1. Broadcaster cadence — rely on the tip-advance auto-broadcast, or add a heartbeat re-broadcast? 2. Checkpoint depth — `MAX_REORG_DEPTH = 100` a sensible starting value for `-checkpointdepth`? 3. Testnet pubkey — fresh or reuse? 4. Cleanup: drop the hardcoded `strMainPubKey` in favor of reading `Params().ConclaveKeys()[0]` directly? Sub-task list for the rest of #40: - [ ] 1-line pubkey constant change (+ testnet equivalent) - [ ] Operator runbook: deploy with `-checkpointkey=<WIF>` on Conclave Key #1 host - [ ] Regtest harness test (`qa/rpc-tests/phase2_acp.py`) - [ ] Optional cleanup: `Params().ConclaveKeys()[0]` substitution - [ ] Decide cadence / depth defaults
dobbscoin commented 2026-06-17 01:56:18 +00:00

First-light done. Branch feat/issue-40-phase2-acp at c4338824.

The dormant ACP stack is now wired to the network's actual keys. End-to-end working on regtest: broadcaster signs → peer validates → both nodes accept the checkpoint.

What landed (5 files, +293/-10)

File What
src/checkpoints.cpp GetCheckpointMasterPubKeyHex() helper reading Params().ConclaveKeys()[0]; deleted stale ppcoin strMainPubKey/strTestPubKey constants
src/checkpoints.h Removed obsolete pubkey declarations
src/chainparams.cpp Added deterministic ACP test-fixture pubkey to testnet/regtest (with vConclaveKeys.clear() first — CTestNetParams inherits from CMainParams so the real mainnet keys are already loaded at that point; without the clear, ConclaveKeys()[0] resolves to Slot #1 on every network, including regtest)
qa/rpc-tests/phase2_acp.py Two-daemon regtest harness: peer them, mine 110 blocks, broadcaster signs+sends checkpoint at tip-50, asserts peer accepts via ProcessSyncCheckpoint log line
.gitignore Pulled forward from rc-bipsoft so depends/ caches and other build noise don't leak

Test results

  • test_Offerings: 113 cases / 32 suites — all PASS
  • qa/rpc-tests/phase2_acp.py:
    • PHASE 1 (peer + mine + sync): PASS
    • PHASE 2 (broadcaster sendcheckpoint): PASS — daemon returns checkpointmaster: true and broadcasts
    • PHASE 3 (peer accepts checkpoint): PASS

Mainnet operator activation (no further consensus change required)

  1. Restart daemon with -checkpointkey=<WIF for Conclave Key #1>.
  2. RPC sendcheckpoint <currenttip> for first-light.
  3. Tip-advance auto-broadcast (main.cpp:3033) takes over after.

Mainnet pubkey is already in chainparams.cpp at vConclaveKeys[0] — same key the OFFSIG signed-mining gate uses.

Subquestions still real

  • Broadcast cadence — tip-advance only, or add heartbeat? (current code: tip-advance only, via main.cpp:3033)
  • Negative regtest test — verify a fork past the checkpoint is rejected (needs competing-chain fixture)
  • Testnet rehearsal — pending rc-bipsoft merge to main (this branch is off main, which lacks the cc1a012 testnet genesis update)

Sub-task tally:

  • Refactor CheckSignature to read from Params().ConclaveKeys()[0]
  • Add testnet/regtest vConclaveKeys with a deterministic test fixture
  • Regtest harness for the positive path
  • Regtest harness for the negative path (forks past checkpoint rejected)
  • Testnet rehearsal
  • Operator runbook + mainnet first-light
**First-light done.** Branch `feat/issue-40-phase2-acp` at `c4338824`. The dormant ACP stack is now wired to the network's actual keys. End-to-end working on regtest: broadcaster signs → peer validates → both nodes accept the checkpoint. ### What landed (5 files, +293/-10) | File | What | |---|---| | `src/checkpoints.cpp` | `GetCheckpointMasterPubKeyHex()` helper reading `Params().ConclaveKeys()[0]`; deleted stale ppcoin `strMainPubKey`/`strTestPubKey` constants | | `src/checkpoints.h` | Removed obsolete pubkey declarations | | `src/chainparams.cpp` | Added deterministic ACP test-fixture pubkey to testnet/regtest (with `vConclaveKeys.clear()` first — `CTestNetParams` inherits from `CMainParams` so the real mainnet keys are already loaded at that point; without the clear, `ConclaveKeys()[0]` resolves to Slot #1 on every network, including regtest) | | `qa/rpc-tests/phase2_acp.py` | Two-daemon regtest harness: peer them, mine 110 blocks, broadcaster signs+sends checkpoint at tip-50, asserts peer accepts via `ProcessSyncCheckpoint` log line | | `.gitignore` | Pulled forward from rc-bipsoft so depends/ caches and other build noise don't leak | ### Test results - `test_Offerings`: 113 cases / 32 suites — all PASS - `qa/rpc-tests/phase2_acp.py`: - PHASE 1 (peer + mine + sync): PASS - PHASE 2 (broadcaster `sendcheckpoint`): PASS — daemon returns `checkpointmaster: true` and broadcasts - PHASE 3 (peer accepts checkpoint): PASS ### Mainnet operator activation (no further consensus change required) 1. Restart daemon with `-checkpointkey=<WIF for Conclave Key #1>`. 2. RPC `sendcheckpoint <currenttip>` for first-light. 3. Tip-advance auto-broadcast (`main.cpp:3033`) takes over after. Mainnet pubkey is already in `chainparams.cpp` at `vConclaveKeys[0]` — same key the OFFSIG signed-mining gate uses. ### Subquestions still real - [ ] Broadcast cadence — tip-advance only, or add heartbeat? (current code: tip-advance only, via `main.cpp:3033`) - [ ] Negative regtest test — verify a fork past the checkpoint is rejected (needs competing-chain fixture) - [ ] Testnet rehearsal — pending rc-bipsoft merge to main (this branch is off main, which lacks the cc1a012 testnet genesis update) Sub-task tally: - [x] Refactor `CheckSignature` to read from `Params().ConclaveKeys()[0]` - [x] Add testnet/regtest `vConclaveKeys` with a deterministic test fixture - [x] Regtest harness for the positive path - [ ] Regtest harness for the negative path (forks past checkpoint rejected) - [ ] Testnet rehearsal - [ ] Operator runbook + mainnet first-light
dobbscoin commented 2026-06-17 02:10:08 +00:00

Negative path landed. Commit f44b2369.

Added PHASE 4 to qa/rpc-tests/phase2_acp.py: two fresh unconnected daemons mine independently. Node 2 (broadcaster) mines chain A to h=10, signs a checkpoint at A5. Node 3 mines a longer competing chain B to h=20 with no checkpoint. They peer.

When chain B's blocks arrive at node 2 via P2P, AcceptBlock runs CheckSyncCheckpoint on each. Descendants of B5 don't trace back to checkpoint A5, so they're rejected at validation. Verified by counting the canonical log line:

ERROR: AcceptBlock() : rejected by synchronized checkpoint

Test asserts:

  • Node 2 logs the rejection at least once → 1 occurrence in the run
  • Node 2's h=5 hash remains A5 after peering with the attacker (checkpoint not displaced by longer chain)

Both pass. The defense fires exactly as designed.

Updated sub-task status

  • Refactor CheckSignature to read from Params().ConclaveKeys()[0]
  • Add testnet/regtest vConclaveKeys with a deterministic test fixture
  • Regtest harness for the positive path (PHASES 1-3)
  • Regtest harness for the negative path (PHASE 4)
  • Testnet rehearsal (waits for rc-bipsoft → main merge)
  • Operator runbook + mainnet first-light (no further code change required)
**Negative path landed.** Commit `f44b2369`. Added PHASE 4 to `qa/rpc-tests/phase2_acp.py`: two fresh unconnected daemons mine independently. Node 2 (broadcaster) mines chain A to h=10, signs a checkpoint at A5. Node 3 mines a *longer* competing chain B to h=20 with no checkpoint. They peer. When chain B's blocks arrive at node 2 via P2P, `AcceptBlock` runs `CheckSyncCheckpoint` on each. Descendants of B5 don't trace back to checkpoint A5, so they're rejected at validation. Verified by counting the canonical log line: ``` ERROR: AcceptBlock() : rejected by synchronized checkpoint ``` Test asserts: - Node 2 logs the rejection at least once → 1 occurrence in the run - Node 2's h=5 hash remains A5 after peering with the attacker (checkpoint not displaced by longer chain) Both pass. The defense fires exactly as designed. ### Updated sub-task status - [x] Refactor `CheckSignature` to read from `Params().ConclaveKeys()[0]` - [x] Add testnet/regtest `vConclaveKeys` with a deterministic test fixture - [x] Regtest harness for the positive path (PHASES 1-3) - [x] Regtest harness for the negative path (PHASE 4) - [ ] Testnet rehearsal (waits for rc-bipsoft → main merge) - [ ] Operator runbook + mainnet first-light (no further code change required)
dobbscoin commented 2026-06-17 02:14:35 +00:00

Operator runbook drafted. Commit 8485743e, contrib/phase2-acp/RUNBOOK.md.

Covers the full mainnet first-light procedure for the operator holding Conclave Key #1:

  • Pre-deployment checks (binary is Phase-2-aware, wallet owns Slot #1, daemon synced, fresh backup)
  • WIF extraction + restart with -checkpointkey (CLI arg only, never config file)
  • First sendcheckpoint at tip-100 — past MAX_REORG_DEPTH=100 near-tip contention, recent enough to bind something
  • Propagation verification on a separate peer (log-line search for ProcessSyncCheckpoint)
  • Steady-state: tip-advance auto-broadcast (main.cpp:3033) handles re-issue, operator just keeps daemon up
  • Failure modes — daemon crash, recipient opt-out via enforcecheckpoint false
  • Cadence + depth tuning tracked as separate work

No internal hostnames or paths leaked: role labels only, per the project convention.

Updated sub-task status

  • Refactor CheckSignature to read from Params().ConclaveKeys()[0]
  • Add testnet/regtest vConclaveKeys with a deterministic test fixture
  • Regtest harness for the positive path (PHASES 1-3)
  • Regtest harness for the negative path (PHASE 4)
  • Operator runbook for mainnet first-light
  • Testnet rehearsal (waits for rc-bipsoft → main merge to inherit cc1a012 testnet genesis fix)
  • Mainnet first-light (Conclave operator action — when ready)
**Operator runbook drafted.** Commit `8485743e`, [`contrib/phase2-acp/RUNBOOK.md`](../blob/feat/issue-40-phase2-acp/contrib/phase2-acp/RUNBOOK.md). Covers the full mainnet first-light procedure for the operator holding Conclave Key `#1`: - Pre-deployment checks (binary is Phase-2-aware, wallet owns Slot `#1`, daemon synced, fresh backup) - WIF extraction + restart with `-checkpointkey` (CLI arg only, never config file) - First `sendcheckpoint` at tip-100 — past `MAX_REORG_DEPTH=100` near-tip contention, recent enough to bind something - Propagation verification on a separate peer (log-line search for `ProcessSyncCheckpoint`) - Steady-state: tip-advance auto-broadcast (`main.cpp:3033`) handles re-issue, operator just keeps daemon up - Failure modes — daemon crash, recipient opt-out via `enforcecheckpoint false` - Cadence + depth tuning tracked as separate work No internal hostnames or paths leaked: role labels only, per the project convention. ### Updated sub-task status - [x] Refactor `CheckSignature` to read from `Params().ConclaveKeys()[0]` - [x] Add testnet/regtest `vConclaveKeys` with a deterministic test fixture - [x] Regtest harness for the positive path (PHASES 1-3) - [x] Regtest harness for the negative path (PHASE 4) - [x] Operator runbook for mainnet first-light - [ ] Testnet rehearsal (waits for rc-bipsoft → main merge to inherit cc1a012 testnet genesis fix) - [ ] Mainnet first-light (Conclave operator action — when ready)
dobbscoin commented 2026-06-17 02:24:35 +00:00

PR open: #41 — feat/issue-40-phase2-acp → main.

CI workflows running on the PR: linux-build-depends, linux-qt5-build-depends, windows-build-depends. Merge ordering note vs feat/v2.0.x-rc-bipsoft is called out in the PR body; src/chainparams.cpp testnet block is the only conflict point, small rebase when whichever branch lands second.

**PR open:** #41 — `feat/issue-40-phase2-acp` → `main`. CI workflows running on the PR: `linux-build-depends`, `linux-qt5-build-depends`, `windows-build-depends`. Merge ordering note vs `feat/v2.0.x-rc-bipsoft` is called out in the PR body; `src/chainparams.cpp` testnet block is the only conflict point, small rebase when whichever branch lands second.
dobbscoin closed this issue 2026-06-17 03:06:25 +00:00
dobbscoin commented 2026-06-17 03:06:35 +00:00

Merged to main at da1368d4 (PR #41). All three CI workflows green. Branch feat/issue-40-phase2-acp deleted. Next stops: testnet rehearsal once feat/v2.0.x-rc-bipsoft lands its testnet genesis update on main, then mainnet operator first-light via the runbook.

Merged to main at `da1368d4` (PR #41). All three CI workflows green. Branch `feat/issue-40-phase2-acp` deleted. Next stops: testnet rehearsal once `feat/v2.0.x-rc-bipsoft` lands its testnet genesis update on main, then mainnet operator first-light via the runbook.
dobbscoin commented 2026-07-29 18:50:18 +00:00

Mainnet first-light: 2026-07-29 18:29 UTC. The ward is lit.

With v2.1.0-Nodens deployed across the fleet, the broadcaster daemon signed its first mainnet sync checkpoint at h=1,064,000 — accepted by every recipient node within a second, enforce mode, banscore clean. Steady-state re-broadcast is verified advancing at tip−100 (first automatic advance landed at h=1,064,019).

Eight years after the counterfeiter's chains were struck at the Restoration, the Conclave's seal now walks the network in real time. A conflicting chain deeper than the seal shall not pass. Iä! The watch is kept.

One operational finding during first-light is tracked separately in #50 (tip-advance auto-broadcast is gated on peer-received blocks; a cadence heartbeat covers it in operation, in-daemon fix targeted v2.1.1).

**Mainnet first-light: 2026-07-29 18:29 UTC.** The ward is lit. With v2.1.0-Nodens deployed across the fleet, the broadcaster daemon signed its first mainnet sync checkpoint at h=1,064,000 — accepted by every recipient node within a second, enforce mode, banscore clean. Steady-state re-broadcast is verified advancing at tip−100 (first automatic advance landed at h=1,064,019). Eight years after the counterfeiter's chains were struck at the Restoration, the Conclave's seal now walks the network in real time. A conflicting chain deeper than the seal shall not pass. Iä! The watch is kept. One operational finding during first-light is tracked separately in #50 (tip-advance auto-broadcast is gated on peer-received blocks; a cadence heartbeat covers it in operation, in-daemon fix targeted v2.1.1).
Sign in to join this conversation.
No labels
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
SubGeniusFinance/Offerings-to-Cthulhu#40
No description provided.