github.com/Finschia/finschia-sdk@v0.49.1/docs/core/upgrade.md (about)

     1  <!--
     2  order: 15
     3  -->
     4  
     5  # In-Place Store Migrations
     6  
     7  ::: warning
     8  Read and understand all of the in-place store migration documentation before you run a migration on a live chain.
     9  :::
    10  
    11  Upgrade your app modules smoothly with custom in-place store migration logic. {synopsis}
    12  
    13  The Cosmos SDK uses two methods to perform upgrades.
    14  
    15  - Exporting the entire application state to a JSON file using the `export` CLI command, making changes, and then starting a new binary with the changed JSON file as the genesis file. See [Chain Upgrade Guide to v0.42](/v0.42/migrations/chain-upgrade-guide-040.html).
    16  
    17  - Version v0.44 and later can perform upgrades in place to significantly decrease the upgrade time for chains with a larger state. Use the [Module Upgrade Guide](../building-modules/upgrade.md) to set up your application modules to take advantage of in-place upgrades.
    18  
    19  This document provides steps to use the In-Place Store Migrations upgrade method.
    20  
    21  ## Tracking Module Versions
    22  
    23  Each module gets assigned a consensus version by the module developer. The consensus version serves as the breaking change version of the module. The Cosmos SDK keeps track of all module consensus versions in the x/upgrade `VersionMap` store. During an upgrade, the difference between the old `VersionMap` stored in state and the new `VersionMap` is calculated by the Cosmos SDK. For each identified difference, the module-specific migrations are run and the respective consensus version of each upgraded module is incremented.
    24  
    25  ### Consensus Version
    26  
    27  The consensus version is defined on each app module by the module developer and serves as the breaking change version of the module. The consensus version informs the SDK on which modules need to be upgraded. For example, if the bank module was version 2 and an upgrade introduces bank module 3, the SDK upgrades the bank module and runs the "version 2 to 3" migration script.
    28  
    29  ### Version Map
    30  
    31  The version map is a mapping of module names to consensus versions. The map is persisted to x/upgrade's state for use during in-place migrations. When migrations finish, the updated version map is persisted in the state.
    32  
    33  ## Upgrade Handlers
    34  
    35  Upgrades use an `UpgradeHandler` to facilitate migrations. The `UpgradeHandler` functions implemented by the app developer must conform to the following function signature. These functions retrieve the `VersionMap` from x/upgrade's state and return the new `VersionMap` to be stored in x/upgrade after the upgrade. The diff between the two `VersionMap`s determines which modules need upgrading.
    36  
    37  ```go
    38  type UpgradeHandler func(ctx sdk.Context, plan Plan, fromVM VersionMap) (VersionMap, error)
    39  ```
    40  
    41  Inside these functions, you must perform any upgrade logic to include in the provided `plan`. All upgrade handler functions must end with the following line of code:
    42  
    43  ```go
    44    return app.mm.RunMigrations(ctx, cfg, fromVM)
    45  ```
    46  
    47  ## Running Migrations
    48  
    49  Migrations are run inside of an `UpgradeHandler` using `app.mm.RunMigrations(ctx, cfg, vm)`. The `UpgradeHandler` functions describe the functionality to occur during an upgrade. The `RunMigration` function loops through the `VersionMap` argument and runs the migration scripts for all versions that are less than the versions of the new binary app module. After the migrations are finished, a new `VersionMap` is returned to persist the upgraded module versions to state.
    50  
    51  ```go
    52  cfg := module.NewConfigurator(...)
    53  app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
    54  
    55      // ...
    56      // additional upgrade logic
    57      // ...
    58  
    59      // returns a VersionMap with the updated module ConsensusVersions
    60      return app.mm.RunMigrations(ctx, fromVM)
    61  })
    62  ```
    63  
    64  To learn more about configuring migration scripts for your modules, see the [Module Upgrade Guide](../building-modules/upgrade.md).
    65  
    66  ### Order Of Migrations
    67  
    68  By default, all migrations are run in module name alphabetical ascending order, except `x/auth` which is run last. The reason is state dependencies between x/auth and other modules (you can read more in [issue #10606](https://github.com/cosmos/cosmos-sdk/issues/10606)).
    69  
    70  If you want to change the order of migration then you should call `app.mm.SetOrderMigrations(module1, module2, ...)` in your app.go file. The function will panic if you forget to include a module in the argument list.
    71  
    72  ## Adding New Modules During Upgrades
    73  
    74  You can introduce entirely new modules to the application during an upgrade. New modules are recognized because they have not yet been registered in `x/upgrade`'s `VersionMap` store. In this case, `RunMigrations` calls the `InitGenesis` function from the corresponding module to set up its initial state.
    75  
    76  ### Add StoreUpgrades for New Modules
    77  
    78  All chains preparing to run in-place store migrations will need to manually add store upgrades for new modules and then configure the store loader to apply those upgrades. This ensures that the new module's stores are added to the multistore before the migrations begin.
    79  
    80  ```go
    81  upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
    82  if err != nil {
    83  	panic(err)
    84  }
    85  
    86  if upgradeInfo.Name == "my-plan" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
    87  	storeUpgrades := storetypes.StoreUpgrades{
    88  		// add store upgrades for new modules
    89  		// Example:
    90  		//    Added: []string{"foo", "bar"},
    91  		// ...
    92  	}
    93  
    94  	// configure store loader that checks if version == upgradeHeight and applies store upgrades
    95  	app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
    96  }
    97  ```
    98  
    99  ## Genesis State
   100  
   101  When starting a new chain, the consensus version of each module MUST be saved to state during the application's genesis. To save the consensus version, add the following line to the `InitChainer` method in `app.go`:
   102  
   103  ```diff
   104  func (app *MyApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
   105    ...
   106  + app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap())
   107    ...
   108  }
   109  ```
   110  
   111  This information is used by the Cosmos SDK to detect when modules with newer versions are introduced to the app.
   112  
   113  For a new module `foo`, `InitGenesis` is called by `RunMigration` only when `foo` is registered in the module manager but it's not set in the `fromVM`. Therefore, if you want to skip `InitGenesis` when a new module is added to the app, then you should set its module version in `fromVM` to the module consensus version:
   114  
   115  ```go
   116  app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
   117      // ...
   118  
   119      // Set foo's version to the latest ConsensusVersion in the VersionMap.
   120      // This will skip running InitGenesis on Foo
   121      fromVM[foo.ModuleName] = foo.AppModule{}.ConsensusVersion()
   122  
   123      return app.mm.RunMigrations(ctx, fromVM)
   124  })
   125  ```
   126  
   127  ### Overwriting Genesis Functions
   128  
   129  The Cosmos SDK offers modules that the application developer can import in their app. These modules often have an `InitGenesis` function already defined.
   130  
   131  You can write your own `InitGenesis` function for an imported module. To do this, manually trigger your custom genesis function in the upgrade handler.
   132  
   133  ::: warning
   134  You MUST manually set the consensus version in the version map passed to the `UpgradeHandler` function. Without this, the SDK will run the Module's existing `InitGenesis` code even if you triggered your custom function in the `UpgradeHandler`.
   135  :::
   136  
   137  ```go
   138  import foo "github.com/my/module/foo"
   139  
   140  app.UpgradeKeeper.SetUpgradeHandler("my-plan", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap)  (module.VersionMap, error) {
   141  
   142      // Register the consensus version in the version map
   143      // to avoid the SDK from triggering the default
   144      // InitGenesis function.
   145      fromVM["foo"] = foo.AppModule{}.ConsensusVersion()
   146  
   147      // Run custom InitGenesis for foo
   148      app.mm["foo"].InitGenesis(ctx, app.appCodec, myCustomGenesisState)
   149  
   150      return app.mm.RunMigrations(ctx, cfg, fromVM)
   151  })
   152  ```
   153  
   154  ## Syncing a Full Node to an Upgraded Blockchain
   155  
   156  You can sync a full node to an existing blockchain which has been upgraded using Cosmovisor
   157  
   158  In order to successfully sync, you must start with the initial binary that the blockchain started with at genesis. Cosmovisor will handle downloading and switching to the binaries associated with each sequential upgrade.
   159  
   160  To learn more about Cosmovisor, see the [Cosmovisor Quick Start](../run-node/cosmovisor.md).