Repository navigation
feat(chain): revert by release machinery, empty table — §5.6 rules, ASERT re-anchor, upgrade-required, --revert drill (P9b, D19) - #13
Conversation
The release carries a revert table beside ACTIVATIONS, shipped empty. An entry makes `keep` a compiled checkpoint, vetoes the old block(s) at H+1 and their descendants, requires time >= anchor_time at H+1 and the entry's rule set from H+1, and re-anchors ASERT above H on the anchor time and the target of block H+1 (daa::next_bits_reverted). The table is checked statically and against the store at open; an inconsistent one refuses to start. At open the stored main chain is cut below its lowest invalid block (state is rebuilt by the existing replay, so no undo is needed), the retracted transactions are kept for the mempool and an Event::Reverted is queued ahead of any block event and logged. A PoW-valid header of an unknown rule set sets upgrade_required and is not stored. With an empty table every path reduces to the previous code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…her releases `--revert H:keep:vetoed[,..]:anchor_time[:rule_set]` adds rehearsal entries (rule set defaults to the last known + 1); the engine refuses them on pussy and bostrom. /status gains reverts, reverted, rehearsal and upgrade-required (activations now lists the revert rule sets). Peers offering vetoed headers or headers of an unknown rule set are no longer scored (chain-wire §5); the node re-admits retracted transactions to the mempool at start, and the wire adapter keeps Reverted events queued. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…SERT, timing Covers the empty table, two nodes reaching one tip above H by rule, an old-release node reporting upgrade-required and keeping its tip, the inconsistent-table and production-chain refusals, the ASERT re-anchor (function and engine), and a p9b-timing receipt line for undo and replay cost per block. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Rehearsal 41411831611 does not measure this PR — void, re-dispatched as 41414017957. Receipt ( 41414017957 ( |
|
Receipt, rehearsal 41414017957: leg 1 of 5 (Linux x86_64)
macOS aarch64, macOS x86_64, Linux aarch64 and the stack leg are still running. This PR does not merge until all five are read. |
|
Rehearsal 41414017957: legs 2 and 3 of 5 read (director, session 548, 09:1x UTC).
Both legs build from overrides The design, after the owner's answers of 2026-11-02 (plan P9): the trigger is now a revert statement signed by an owner-held key in the genesis params, not a table compiled into a release. This PR stays the core, for these reasons:
P9c adds the statement as a third source of entries, and nothing here is reworked. The merge waits on the last two legs: no red beyond the baseline, and the new tests passing. |
|
Rehearsal 41414017957, legs 4 and 5 of 5 read (director, session 549). This PR adds one red and does not merge yet.
The new red,
Fix on the consumer, not here. |
|
Correction (director, session 550 — the earlier comment said 549): rehearsal 41423712587 is void, cancelled at its snapshot. It built |
|
Gate read — rehearsal 41423930605 (
Review (director, second pass): base Merging into |
What
P9b of the director's plan (
soft3/release/director/plan.md, D19). This PR adds the machinery of revert by release,specs/chain.md§5.6 as drafted in #12, with an empty compiled table (params::REVERTS = &[]). The spec text stays in #12 and is the owner's decision (D6). This PR has no spec text.params.rs:RevertandREVERTSsit besideACTIVATIONS.revert.rsholds the effective table: the compiled entries plus--revertrehearsal entries. Its static checks are sort order, a non-emptyvetoed, rule sets that strictly increase, and nokeepthat an earlier entry vetoes. Its store checks are the ancestry ofkeepand that eachvetoedid lies above H. An inconsistent table refuses to open.engine.rscheck_header,engine_api.rsaccept_header):keepacts as a compiled checkpoint at H.H+1must havetime ≥ anchor_time.H+1on is the entry's.daa.rsnext_bits_reverted): for h > H+1, Δt = parent.time − anchor_time, ideal = (h−H−2)·T, and the anchor target is target(bits_{H+1}). With no entry below the parent it isnext_bits, unchanged.upgrade-required(§7.1): a header with valid PoW whose rule set is above the last known one sets the flag and is neither stored nor relayed.UnknownRuleSetnow scores 0, because a peer of another release is not an attacker (chain-wire §5).Chain::apply_reverts, run beforereplay()): it marks the vetoed blocks, their descendants and any non-keepblock at H as invalid, then cuts the main chain below the first invalid block. The state is rebuilt by the existing replay from genesis with its root checks, which is the spec's wipe-and-replay path. Retracted transactions, coinbases skipped, are re-admitted throughMempool::admitat node start, so only those still valid stay.Event::Reverted { to_height, keep, vetoed, rehearsal }is queued before any block event and kept by the kernel'smoved(). It is also persisted in<home>/reverted.log.--revert H:keep:vetoed[,…]:anchor_time[:rule_set]is a repeatable rehearsal flag. It is refused on pussy and bostrom (by name, and by a pinnedCHAINSid).pussy-rcis allowed, which the alpha-network drill needs./statusgainsreverts,reverted,rehearsalandupgrade-required(plusupgrade-heightandupgrade-rule-set).activationsis now computed and reads1@0when the table is empty.Verified
Not yet. Nothing was compiled on the director's host, by rule. The gate is a soft3
Release trainrehearsal withoverride=cybernode=pull/<this>/head, and its receipts will be posted here. Review notes from the director:rule_set_for=RULE_SET,bits_after=next_bits,apply_revertsreturns early, and the template hasversion1.ChainNode::opennow callsKernelChain::open_with({checkpoints: true, clock: from_env, ..Default}), which is exactly whatChain::openbuilt.OpenOptionsfromsoft3::chain::engine, not from cybernode, so the new field cannot break it.Tests (
chain::tests::revert::*):an_empty_table_changes_nothingtwo_nodes_revert_by_rule_and_end_on_one_tip_above_han_old_release_node_reports_upgrade_required_and_keeps_its_tipan_inconsistent_table_refuses_to_opena_rehearsal_refuses_to_start_on_a_production_chainasert_reanchors_above_an_entry_in_the_functionasert_reanchors_in_the_engine_and_is_unchanged_without_an_entryp9b_timing_undo_and_replay_per_block, which printsp9b-timing undo_per_block_us=… replay_per_block_us=…as the cost receipt §5.6 asks forThere are also five unit tests in
chain::revert::testsandcli::tests::node_args_revert_is_repeatable_and_validated.Remains
pussy-rc, two nodes), which is P9c.Risk
upgrade-required, where it used to score 10. At the launch PoW limit,upgrade-requiredcosts little to trigger. It only raises a flag, and the node keeps its tip.OpenOptions.revertsfield reachestests/mod.rsonly in commit 3.🤖 Generated with Claude Code