From a65d2dc26a557117910956dc69694e55ea2a5ab4 Mon Sep 17 00:00:00 2001 From: nol4lej Date: Sat, 8 Aug 2026 01:21:50 -0400 Subject: [PATCH] chore(runtime): bump spec_version to 8 --- frame/validator-set/CHANGELOG.md | 3 ++ template/runtime/RUNTIME_VERSIONS.md | 60 +++++++++++++++++++++++++++- template/runtime/src/lib.rs | 2 +- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/frame/validator-set/CHANGELOG.md b/frame/validator-set/CHANGELOG.md index 45ec1a2e..b726b045 100644 --- a/frame/validator-set/CHANGELOG.md +++ b/frame/validator-set/CHANGELOG.md @@ -32,6 +32,9 @@ with `InsufficientBond`. Callers that pre-funded 1 001 ORB to register can stop. - No migration ships with this change: `ValidatorBondOf` was verified empty on testnet (0 entries, empty pending queue) before removing it, so there are no reserves left stranded. A chain that *had* live bonds would need one. +- `spec_version` moves 7 → 8 at release, since the removed Config constant and + storage item change the metadata. `transaction_version` stays at 2: + `register_validator` keeps its call index and its empty signature. ### Verification 50 pallet tests; runtime, `try-runtime` and `runtime-benchmarks` all compile. A diff --git a/template/runtime/RUNTIME_VERSIONS.md b/template/runtime/RUNTIME_VERSIONS.md index acc78e9e..67fd77cf 100644 --- a/template/runtime/RUNTIME_VERSIONS.md +++ b/template/runtime/RUNTIME_VERSIONS.md @@ -20,9 +20,67 @@ to `spec_version` / `transaction_version` must add a row here in the same PR. The genesis reset (`69d1b837`) set `spec_version` back to 1 and `transaction_version` to 1 for the public testnet launch. +### spec 8 — tx 2 — 2026-08-08 + +Bundles the whole audit-remediation batch plus the config/feature work that +preceded it. `transaction_version` stays at 2 — no call index or dispatch +signature changed; the metadata moves, so `spec_version` does. + +**Features / config** + +- **validator-set 0.2.0 — registration bond removed** (#121). The 1 000 ORB + `register_validator` bond is gone: `ValidatorBond` and `Currency` Config + items, the `ValidatorBondOf` map, both bond events and `InsufficientBond`. + Governance approval already gated the active set, so the bond only added a + funding step for hand-onboarded operators. No migration — `ValidatorBondOf` + was queried on testnet first and found empty (0 entries, empty queue, 3 + validators all sudo-added), so nothing stays reserved. +- **shielded-pool — minimum shield amount removed** (#121). `MinShieldAmount` + and `AmountTooSmall` are gone; any non-zero amount is shieldable, zero still + refused via `InvalidAmount`. This shifts the numeric index of every `Error` + variant declared after `AmountTooSmall` — clients matching on error *names* + are unaffected; anything decoding by index needs fresh metadata. +- **shielded-pool — sealed-tree pruning** (#122). New Config + `SealedTreePrunedBelowLevel` (production 10) and an `on_idle` sweep that + reclaims ~99.8% of a sealed tree's `MerkleNodes` (1,048,574 → 2,046 per + tree); `get_merkle_path` recomputes pruned siblings from `MerkleLeaves` on + demand. Benchmarked at 12.68 µs/node, so the 512-node per-block ceiling + costs ~6.5 ms. No migration — nothing prunes until a tree seals at 2^20 + leaves, and the sweep reaches already-sealed trees on its own. +- **runtime config split into modules** (#121). `template/runtime/src/configs/`. + No consensus effect on its own. +- **legacy `shieldedPool_*` RPC server retired** (#119). Node-side only. + +**Security (audit remediation)** + +- **zk-verifier — deserialization bounds + circuit-id de-aliasing** (#123). + `MAX_VK_BYTES` / `MAX_PROOF_BYTES` cap the length prefix before + `Vec::with_capacity`; circuit ids no longer alias to the same `u8`, and + genesis asserts VK arity. +- **shielded-pool — zero-hash ladder and tree-depth shift bounded** (#124). + `zero_hash_at_level` is iterative (a recursive call could exhaust the 1 MB + Wasm stack and abort the process); a const assertion pins tree `DEPTH < 32` + so `capacity()` cannot shift into a `u32`. +- **shielded-pool 0.16.0 — non-canonical and zero commitments/nullifiers + refused** (#125). Both are raw-byte storage keys while byte→field reduces + mod the BN254 `p`, so `n` and `n + p` were two keys for one element — a + double-spend vector. `is_canonical` is now checked on every write path + (`shield`, `private_transfer`, `unshield`); zero commitments refused + separately since zero is canonical but indistinguishable from an empty tree + slot. Shifts `Error` indices (breaking for index-decoders, not name-matchers). +- **precompile 0.5.0 — ABI decoder truncation/overflow fixed** (#126). + Offsets/lengths were narrowed with `low_u32()`; a wrapping length built an + inverted slice range and panicked the runtime (`wasm unreachable`, reachable + from an unsigned gas-free `eth_call`). Words are now rejected when they don't + fit their type, and all offset/length arithmetic is checked. No ABI change. +- **shielded-pool 0.17.0 — duplicate nullifier in `private_transfer` refused** + (#127). Two equal non-dummy nullifiers spent one input twice (both cleared + the used-set check, the second `mark_as_used` was idempotent). `execute` now + rejects a duplicate with `NullifierAlreadyUsed`. Defense in depth. + | spec | tx | Date | Commit | Change | |------|----|------|--------|--------| -| 7 | 2 | 2026-08-06 | — | Several pallet changes shipping in one upgrade (7 was never deployed, so they collapse into a single bump). **validator-set:** the 1 000 ORB `register_validator` bond is removed — `ValidatorBond` and `Currency` Config items, the `ValidatorBondOf` map, both bond events and `InsufficientBond` are gone. Governance approval already gated the active set; the bond only added a funding step for hand-onboarded testnet operators. No migration: `ValidatorBondOf` was verified empty on testnet before removal. **shielded-pool 0.15.0:** `MinShieldAmount` and `AmountTooSmall` removed — any non-zero amount is shieldable, zero still rejected via `InvalidAmount`. This shifts the numeric index of every `Error` variant after `AmountTooSmall`; clients matching on error *names* are unaffected. Also adds `SealedTreePrunedBelowLevel` and an `on_idle` sweep that reclaims ~99.8% of a sealed tree's `MerkleNodes`, with `get_merkle_path` recomputing pruned siblings on demand. **shielded-pool 0.14.0:** historic-root window re-anchored from insert counts to block numbers. New Config `RootRetentionBlocks` (300 blocks); `MaxHistoricRoots` (raised to 16384) becomes a queue-length cap rather than the window. `HistoricPoseidonRoots` now stores an expiry block instead of a bool; `HistoricRootsOrder` replaced by the slot-indexed `HistoricRootsQueue` + `Head`/`Tail`. `STORAGE_VERSION` 2 → 3 with `MigrateToV3` in the tuple. Weights re-benchmarked against the v3 layout. The amount-overflow pool rejection moves from `Custom(2)` to `Custom(4)`, which had two meanings. **Applied migrations removed (`72ff7b88`):** the v1/v2 modules are gone from shielded-pool and zk-verifier 0.11.0 — testnet was already past both, so they were no-ops, and `MigrateToV1` rebuilt the whole Merkle tree in one block. `spec_version` moves because storage layout and `on_runtime_upgrade` both change; `transaction_version` stays — no call signature changed. | +| 7 | 2 | 2026-08-05 | — | Two pallet changes shipping in one upgrade. **shielded-pool 0.14.0:** historic-root window re-anchored from insert counts to block numbers. New Config `RootRetentionBlocks` (300 blocks); `MaxHistoricRoots` (raised to 16384) becomes a queue-length cap rather than the window. `HistoricPoseidonRoots` now stores an expiry block instead of a bool; `HistoricRootsOrder` replaced by the slot-indexed `HistoricRootsQueue` + `Head`/`Tail`. `STORAGE_VERSION` 2 → 3 with `MigrateToV3` in the tuple. Weights re-benchmarked against the v3 layout. The amount-overflow pool rejection moves from `Custom(2)` to `Custom(4)`, which had two meanings. **Applied migrations removed (`72ff7b88`):** the v1/v2 modules are gone from shielded-pool and zk-verifier 0.11.0 — testnet was already past both, so they were no-ops, and `MigrateToV1` rebuilt the whole Merkle tree in one block. `spec_version` moves because storage layout and `on_runtime_upgrade` both change; `transaction_version` stays — no call signature changed. | | 6 | 2 | 2026-08-03 | — | `pallet-account-mapping` and its precompile (index 14, address 0x0800) removed, along with the `private_link` circuit (id 5) and its verification key. Index 14 is retired and must not be reassigned. zk-verifier 0.10.0 gains `purge_circuit` (call index 7, Root) plus `STORAGE_VERSION` 1 and `MigrateToV1`, which drops the stranded circuit-5 key that no extrinsic could reach. `transaction_version` moves because the new call index changes extrinsic encoding. | | 5 | 1 | 2026-07-30 | — | shielded-pool 0.12.0: multi-tree forest. Full trees seal (`TreeSealed`, permanent `SealedTreeRoots` anchors) and inserts roll over to a fresh tree — the 2^20-note network ceiling is gone. New Config `MaxLeavesPerTree` (2^20), `STORAGE_VERSION` 2 (`MigrateToV2`, version-only), runtime API v2 (`get_forest_info`, `get_root_for_leaf`). No circuit/extrinsic/ABI changes. | | 4 | 1 | 2026-07-30 | `63caafca` | shielded-pool 0.11.0: `MerkleNodes` storage (internal nodes written on every insert) + `MigrateToV1` migration (backfill, `STORAGE_VERSION` 1). O(depth) Merkle proofs. Weights re-benchmarked. The upgrade block runs the one-shot migration (~3s at ~90k leaves). | diff --git a/template/runtime/src/lib.rs b/template/runtime/src/lib.rs index e10f7e58..e18ff9f5 100644 --- a/template/runtime/src/lib.rs +++ b/template/runtime/src/lib.rs @@ -201,7 +201,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: Cow::Borrowed("orbinum"), impl_name: Cow::Borrowed("orbinum"), authoring_version: 1, - spec_version: 7, + spec_version: 8, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 2,