Skip to main content
Version: v0.53

Upgrading Cosmos SDK

This guide provides instructions for upgrading to specific versions of Cosmos SDK. Note, always read the SimApp section for more information on application wiring updates.

v0.53.x

Unordered Transactions

The Cosmos SDK now supports unordered transactions. This means that transactions can be executed in any order and doesn't require the client to deal with or manage nonces. This also means the order of execution is not guaranteed.

Unordered transactions are automatically enabled when using depinject / app di, simply supply the servertypes.AppOptions in app.go:

    depinject.Supply(
+ // supply the application options
+ appOpts,
// supply the logger
logger,
)
Step-by-step Wiring
If you are still using the legacy wiring, you must enable unordered transactions manually:
  • Update the App constructor to create, load, and save the unordered transaction manager.

    func NewApp(...) *App {
    // ...

    // create, start, and load the unordered tx manager
    utxDataDir := filepath.Join(cast.ToString(appOpts.Get(flags.FlagHome)), "data")
    app.UnorderedTxManager = unorderedtx.NewManager(utxDataDir)
    app.UnorderedTxManager.Start()

    if err := app.UnorderedTxManager.OnInit(); err != nil {
    panic(fmt.Errorf("failed to initialize unordered tx manager: %w", err))
    }
    }
  • Add the decorator to the existing AnteHandler chain, which should be as early as possible.

    anteDecorators := []sdk.AnteDecorator{
    ante.NewSetUpContextDecorator(),
    // ...
    ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, options.TxManager, options.Environment),
    // ...
    }

    return sdk.ChainAnteDecorators(anteDecorators...), nil
  • If the App has a SnapshotManager defined, you must also register the extension for the TxManager.

    if manager := app.SnapshotManager(); manager != nil {
    err := manager.RegisterExtensions(unorderedtx.NewSnapshotter(app.UnorderedTxManager))
    if err != nil {
    panic(fmt.Errorf("failed to register snapshot extension: %w", err))
    }
    }
  • Create or update the App's Preblocker() method to call the unordered tx manager's OnNewBlock() method.

    ...
    app.SetPreblocker(app.PreBlocker)
    ...

    func (app *SimApp) PreBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) {
    app.UnorderedTxManager.OnNewBlock(ctx.BlockTime())
    return app.ModuleManager.PreBlock(ctx, req)
    }
  • Create or update the App's Close() method to close the unordered tx manager. Note, this is critical as it ensures the manager's state is written to file such that when the node restarts, it can recover the state to provide replay protection.

    func (app *App) Close() error {
    // ...

    // close the unordered tx manager
    if e := app.UnorderedTxManager.Close(); e != nil {
    err = errors.Join(err, e)
    }

    return err
    }

To submit an unordered transaction, the client must set the unordered flag to true and ensure a reasonable timeout_height is set. The timeout_height is used as a TTL for the transaction and is used to provide replay protection. See ADR-070 for more details.