Skip to main content
Version: Next

Upgrading a network

A CenterChain release that changes consensus behaviour is applied at a block height through a software-upgrade plan, not by restarting nodes at a moment of the operator's choosing. Every validator must be running the new binary at the same height, or the network splits.

This page describes the mechanism. The release-specific changes are in the v1.2 notes and the v1.1 notes.

Why the height matters​

If half the validators accept a message the other half rejects, the two halves compute different state and the chain forks. v1.1 was such a change: an old binary accepts MsgForceTransfer, a new one rejects it. A block that contains one is valid to one node set and invalid to the other.

The chain therefore does not rely on operators swapping binaries in time. It reads the plan on chain and switches every node at the height the plan names.

Registered plans​

A node can only apply a plan its binary knows. The registered plan names are compiled in:

Plan namePurpose
v0.55The first Cosmos SDK v0.55 state upgrade.
v1.1Holder asset protection and single-leg authorizations.

There is no v1.2 plan. v1.2 changes the authorization state schema and the message surface, and it ships without a migration: a v1.2 network starts from a new genesis. See Applying v1.2.

A node whose binary does not carry the handler for a plan that reaches its height cannot apply the upgrade and will stop. Building the binary from the release commit is what puts the handler there.

What the handler does​

The handler is the same for every plan: it runs the module manager's migrations with the version map the chain carried in. For v1.1 that means tokenfactory migrates from consensus version 2 to 3, binding every pre-existing authorization to SWAP. The store loader installs an empty store upgrade — no store is added, renamed, or deleted.

v1.2 has no handler because it has no migration. Its state changes are installed by the genesis file instead. A live v1.1 chain cannot be converted in place by this release.

Before the height​

  1. Get the artifact. A release is a v* tag whose workflow produces Linux amd64/arm64 archives and a SHA-256 checksum manifest, then signs the manifest with Cosign. Verify it before deploying: cosign verify-blob against the manifest, and compare the archive's SHA-256 to the manifest.
  2. Back up the node home. State and the consensus key. An upgrade that goes wrong is recovered from a backup; there is no rewind.
  3. Stage, do not run. Put the new binary where the supervisor will find it at the height and leave the old one running: cosmovisor/upgrades/<plan>/bin/centerchaind. Cosmovisor is required in production so the switch happens at the height rather than when an operator is awake.
  4. Submit the plan. A governance proposal carrying MsgSoftwareUpgrade{Name: "<plan>", Height: H, Info: "<release-url> sha256=<hash>"}. The plan name must match a handler compiled into the binary. The voting period and deposit are the network's governance parameters.

At the height​

The node stops producing and applying blocks, the supervisor starts the staged binary, the store loader runs, the module migrations run, and the chain continues.

A chain that runs the binary inside its container image, with no supervisor, depends on operator action to restart at the height. That is a testnet convenience, not a production design: the halt lasts as long as the operator takes. When the plan is applied, stopping the containers before the height prevents the plan from ever being reached.

Releases applied by genesis reset​

Not every release can use a plan. When the state schema changes and no migration is shipped, the network starts again from a new genesis with a new chain ID. That is how v1.2 was applied:

  1. Stop the old network and keep its data for reference. Do not point a v1.2 binary at a v1.1 home.
  2. Build the new genesis with the v1.2 binary and a new chain ID.
  3. Start every validator from the same genesis hash.
  4. Treat every authorization and claim permit signed for the old chain as void. The new chain_id is what makes the old signatures unusable.

A reset is not an upgrade and has no rollback: the old chain is a separate network, not a previous state of the new one. A network that must preserve state across a schema change needs a migration release instead.

Rollback​

A plan can be cancelled by governance only before its height. After the height there is no safe rollback: reverting the binary would re-interpret state the new code already wrote, and the chain cannot rewind. The only correct recovery is forward, to another release.

Verifying​

Check the release notes' verification list after the height. For v1.2 the concrete checks are in v1.2 § Verifying the result. For v1.1 they are in v1.1 § Verifying the result.

Where this fits​