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
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...), nilIf 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'sOnNewBlock()
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.