For most of its life the EmpoorioChain testnet was not upgraded — it was restarted. Each new runtime came with a new genesis, a new chain, and an empty history. That changed on 4 September 2026, and this post is the log of what happened next.
The relaunch and the first upgrade
The current chain was launched on 31 August 2026 with genesis 0xe973931e…eae7aa. On 4 September runtime 208 was applied to it in place — the first time the live network had ever changed its rules without a restart. The genesis has been stable since, and every upgrade below was applied to the same chain with its history intact.
Runtime 208 also introduced the two custom signed extensions (CheckPqcPolicy, CheckDormantAccount) that every client must now encode — see the transaction-pipeline post for why that mattered more than anyone expected.
The log
| Runtime | Date | What changed |
|---|---|---|
| 208 | 4 Sep | First in-place upgrade of the live chain. Custom signed extensions wired into SignedExtra. |
| 211 | ~9 Sep | EVM accepts self-contained Ethereum transactions. Until then the runtime's generic extrinsic type rejected every MetaMask and Hardhat transaction; measured on 6 September, fixed here. |
| 213 | ~10 Sep | Storage-market billing moved from whole gigabytes to bytes; prices stay per GB and costs round up so that a tiny file is never free. EVM acceptance of real transactions confirmed live. |
| 215 | ~11 Sep | Bounded-state rule enforced across the runtime; audit for #[pallet::unbounded] escape hatches. |
| 217 | ~11 Sep | The "wire it or retire it" rule applied to empty promises: every dispatchable either has a real circuit with a mutation-tested path, or is removed with a migration. |
| 218 | 12 Sep | K12: public-sale delivery model — DMS delivered natively via Merkle claim, matching DracmaSaleV2 on Sepolia. Plus D18, T26, T8. |
| 219 | 13 Sep | T3 (partial) and T11. |
| 220 | 14 Sep | EVM gas set to 1 gwei. DEX treasury per pool wired — the emp/dext treasury account had never existed, which is why no swap had ever settled; the first real swap and the first DID registration on the network followed. |
transaction_version moved to 6 across these, because the transaction format itself changed.
What the log taught
The metadata changes every time. Clients that cached runtime metadata and refreshed it only "when calls change" broke at every upgrade, because the spec version lives inside the metadata. Refresh after every upgrade, unconditionally.
Explicit indexes are not positions. A tool that enumerated a pallet's calls by their position in the source produced eight false mismatches against runtime 218, because FRAME allows an explicit #[pallet::call_index] — set_manufacturer is call 90 while appearing first in the file. Read indexes from metadata.
post_upgrade checks the migration, not the world. Four post-upgrade hooks asserted things like "this storage is empty" without checking whether their own migration had run. They were rewritten to verify the migration's effect and nothing else.
Nothing is free. A DEX with no treasury account looked complete — pallets wired, tests green — and could not execute a single swap because the account that collects fees had zero existential deposit and therefore did not exist. One DMS from sudo, in runtime 220, unblocked it. The general rule adopted: if a feature has never executed a real transaction on the live chain, it is not done.
Against the upgrade policy
The policy requires the testnet to rehearse four upgrade classes before mainnet: normal, storage-migration, economic, and an emergency drill with rollback. The first two have now happened for real. The economic class and the emergency drill are outstanding.
Based on RED.json, RUNTIME_UPGRADE_POLICY.md and the engineering records for runtimes 208–220.


