Upgrade Handlers

Understanding and implementing on-chain upgrade handlers for coordinated chain upgrades

Overview

Upgrade handlers enable coordinated on-chain upgrades across all validators at specific block heights via governance proposals. They provide a mechanism for chains to perform data migrations, parameter updates, and module upgrades in a deterministic way.

Upgrade handlers are critical for maintaining consensus during chain upgrades. All validators must run the same upgrade logic at the same height.

When to Use Upgrade Handlers

Upgrade handlers are required when:

  • Breaking state changes: Modifying storage formats or data structures

  • Module migrations: Updating module versions or parameters

  • Protocol upgrades: Implementing new features that require state transitions

  • Data migrations: Moving data between different storage locations

Basic Structure

Registering Upgrade Handlers

Upgrade handlers are registered in your app's RegisterUpgradeHandlers() method:

```go // app/upgrades.go package app

import ( "context" upgradetypes "Ontomirsdk.io/x/upgrade/types" sdk "github.com/Ontomir/Ontomir-sdk/types" "github.com/Ontomir/Ontomir-sdk/types/module"

)

func (app *App) RegisterUpgradeHandlers() { app.UpgradeKeeper.SetUpgradeHandler( "v1.0.0", // upgrade name (must match governance proposal) func(ctx context.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) sdkCtx.Logger().Info("Starting upgrade", "name", plan.Name) // Run module migrations migrations, err := app.ModuleManager.RunMigrations(ctx, app.configurator, fromVM) if err != nil { return nil, err } // Add custom migration logic here sdkCtx.Logger().Info("Upgrade complete", "name", plan.Name) return migrations, nil }, )

}

Organizing Upgrade Code

For better maintainability, organize upgrades in separate packages:

Directory Structure

constants.go

```go // app/upgrades/v1_0_0/constants.go package v1_0_0

import ( storetypes "Ontomirsdk.io/store/types" "github.com/yourchain/app/upgrades" )

const UpgradeName = "v1.0.0"

var Upgrade = upgrades.Upgrade{ UpgradeName: UpgradeName, CreateUpgradeHandler: CreateUpgradeHandler, StoreUpgrades: storetypes.StoreUpgrades{ Added: []string{}, // New modules Deleted: []string{}, // Removed modules }, }

Migration Patterns

Parameter Migrations

Migrating module parameters to new formats:

State Migrations

Moving data between different storage locations:

Module Addition/Removal

Adding or removing modules during upgrade:

Best Practices

Always test upgrade handlers thoroughly on testnets before mainnet deployment.

Idempotency

Make migrations idempotent when possible:

Error Handling

Use comprehensive error handling and logging:

Testing

Create comprehensive tests for upgrade handlers:

Upgrade Process

Create Upgrade Proposal

Submit a governance proposal with the upgrade details:

Vote on Proposal

Validators and delegators vote on the upgrade:

Prepare Binary

Build and distribute the new binary with the upgrade handler:

Monitor Upgrade

Watch logs during the upgrade height:

Ontomir EVM Specific Migrations

For Ontomir EVM chains, specific migrations include:

  • ERC20 Precompiles Migration: Required for v0.3.x to v0.4.0

  • Fee Market Parameters: Updating EIP-1559 parameters

  • Custom Precompiles: Registering new precompiled contracts

  • EVM State: Migrating account balances or contract storage

Troubleshooting

Consensus Failure

Symptom: Chain halts with consensus failure at upgrade height

Causes:

  • Validators running different binary versions

  • Upgrade handler not registered

  • Non-deterministic migration logic

Solution:

  • Ensure all validators have the same binary

  • Verify upgrade handler is registered

  • Review migration logic for non-determinism

Upgrade Panic

Symptom: Node panics during upgrade

Causes:

  • Unhandled error in migration

  • Missing required state

  • Invalid type assertions

Solution:

  • Add comprehensive error handling

  • Validate state before migration

  • Use safe type conversions

State Corruption

Symptom: Invalid state after upgrade

Causes:

  • Partial migration completion

  • Incorrect data transformation

  • Missing cleanup of old data

Solution:

  • Make migrations atomic

  • Thoroughly test transformations

  • Ensure old data is properly cleaned up

最后更新于