diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8ee997a4d..0dfa3a589 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,6 +80,8 @@ jobs: echo echo "Commit: \`${{ github.sha }}\` · srtool image: \`paritytech/srtool:1.81.0\` · reproduce with the same commit and image." echo + echo "For \`parachainSystem.authorizeUpgrade\` use **\`blake2_256\`** below (the code hash the chain recomputes from the wasm at enactment); \`proposal_hash\` is the preimage hash of a \`system.setCode\` call and \`parachain_authorize_upgrade_hash\` is derived from the authorize call — neither is the value to authorize." + echo echo '```json' jq '.runtimes.compressed.subwasm // .' srtool-${{ steps.meta.outputs.chain }}.json echo '```' diff --git a/docs/pen-migration-internal-review.md b/docs/pen-migration-internal-review.md index 8d5e2b15d..ba18d429a 100644 --- a/docs/pen-migration-internal-review.md +++ b/docs/pen-migration-internal-review.md @@ -848,6 +848,29 @@ ships-paused with no storage written. **RB-5 passed 5/5**: the wasm written to attestor decoded post-upgrade blocks without a restart and rode a node restart. Dev-machine benchmark weights were accepted as production weights. +### Published spec-26 artifact (2026-09-08) + +Built reproducibly by the new `Release Runtime` workflow (srtool v0.17.0, +rustc 1.81.0) from the tagged commit `14eb720` and published as +[pendulum-release-26](https://github.com/pendulum-chain/pendulum/releases/tag/pendulum-release-26) +together with the srtool report. Verified locally: the downloaded wasm's +sha256 equals the report's, and the embedded version is spec 26 / +transaction_version 11. + +| | | +|---|---| +| `pendulum_runtime.compact.compressed.wasm` | 2,177,219 bytes | +| sha256 | `370ac425e69125ac3d23971a1d2eba7966b15c7026621dd6a778c099432eb66d` | +| blake2_256 (code hash) | `0x6a19a408826fb4d2ab04886c864714dda188df2a1bfa11f27b1b2d0c0192e896` | +| democracy proposal hash | `0x830dd2349bf421f430b068e1361010b33dfaf8d38e8c9465cd95ee7cd378a0bf` | +| `parachainSystem.authorizeUpgrade` hash | `0xf6cd1f4a600906a31f305ea0a8401ca31f84afa52b9fa31d31d35cde406b6ebf` | + +Against **this** binary — the thing to be shipped, not a local build — the +fork reports spec 26, **phase 2 passed 14/14** and **RB-5 passed 5/5**. +Anyone can reproduce the hashes from the same commit with +`paritytech/srtool:1.81.0`. The referendum text should carry the code hash +and the proposal hash above. + ## Residual risks and standing practices (no external audit — risk accepted) - Every change to the fund-release path (vault release/approve/sweep logic, pallet burn path) gets a fresh independent adversarial review round before diff --git a/docs/pen-migration-runbooks.md b/docs/pen-migration-runbooks.md index 34ffec5e4..a7dfab676 100644 --- a/docs/pen-migration-runbooks.md +++ b/docs/pen-migration-runbooks.md @@ -154,12 +154,32 @@ Before the upgrade is enacted: migration touching `NextNonce` storage must preserve it; reject one that doesn't. -After enactment: -4. Watch the fleet: all four daemons progressing past the upgrade block, test - migration of a small amount end-to-end, monitor `ok` lines resuming. -5. If daemons exit on the upgrade block: they hold position (checkpoint stays +When the referendum enacts (`parachainSystem.authorizeUpgrade(code_hash, +check_version = true)` executes — this only *authorizes* the hash): +4. **Enact it.** Anyone submits `parachainSystem.enactAuthorizedUpgrade(code)` + with the full published wasm (`pendulum_runtime.compact.compressed.wasm` + from the GitHub release, ~2.2 MB; the length fee is well under 1 PEN). The + call verifies `blake2_256(code)` against the authorized hash and, with + `check_version`, that the new `spec_version` is higher; it then signals the + upgrade to the relay chain, which applies it after its validation delay. + Nothing happens until this call is sent. Verify afterwards: + `system.lastRuntimeUpgrade` reports the new spec, `tokenMigration.paused()` + is `true`, and `parachainSystem.authorizedUpgrade` is cleared. +5. Reclaim the preimage deposit: `preimage.unnotePreimage(hash)` from the + account that noted it (the deposit is returned once the preimage is unused). +6. Watch the fleet: all four daemons progressing past the upgrade block, test + migration of a small amount end-to-end (only after the governance unpause), + monitor `ok` lines resuming. +7. If daemons exit on the upgrade block: they hold position (checkpoint stays put) — fix decoding, redeploy, they resume without loss. +**Which hash goes where.** The release's srtool report lists several hashes. +`parachainSystem.authorizeUpgrade` takes the **code hash** — `blake2_256` of +the wasm file (the value `enactAuthorizedUpgrade` recomputes from the bytes). +The report's `proposal_hash` is the preimage hash of a `system.setCode` call +and its `parachain_authorize_upgrade_hash` is derived from the authorize +*call*; neither is what the pallet checks at enactment. + ## RB-7: Window close and remainder sweep **Trigger:** the migration window is closing (per decision D5) and governance