Skip to content

Commit

Permalink
feat: [ADR-070] Unordered Transactions (1/2) (#18641)
Browse files Browse the repository at this point in the history
Co-authored-by: yihuang <[email protected]>
Co-authored-by: Facundo <[email protected]>
  • Loading branch information
3 people authored Jan 4, 2024
1 parent d520fcf commit 6ec53aa
Show file tree
Hide file tree
Showing 26 changed files with 1,517 additions and 310 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (x/auth) Support the ability to broadcast unordered transactions per ADR-070. See UPGRADING.md for more details on integration.
* (client) [#18557](https://github.com/cosmos/cosmos-sdk/pull/18557) Add `--qrcode` flag to `keys show` command to support displaying keys address QR code.
* (x/staking) [#18142](https://github.com/cosmos/cosmos-sdk/pull/18142) Introduce `key_rotation_fee` param to calculate fees while rotating the keys
* (client) [#18101](https://github.com/cosmos/cosmos-sdk/pull/18101) Add a `keyring-default-keyname` in `client.toml` for specifying a default key name, and skip the need to use the `--from` flag when signing transactions.
Expand Down Expand Up @@ -189,7 +190,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (x/auth) [#18351](https://github.com/cosmos/cosmos-sdk/pull/18351) Auth module was moved to its own go.mod `cosmossdk.io/x/auth`
* (types) [#18372](https://github.com/cosmos/cosmos-sdk/pull/18372) Removed global configuration for coin type and purpose. Setters and getters should be removed and access directly to defined types.
* (types) [#18695](https://github.com/cosmos/cosmos-sdk/pull/18695) Removed global configuration for txEncoder.
* (server) [#18909](https://github.com/cosmos/cosmos-sdk/pull/18909) Remove configuration endpoint on grpc reflection endpoint in favour of auth module bech32prefix endpoint already exposed.
* (server) [#18909](https://github.com/cosmos/cosmos-sdk/pull/18909) Remove configuration endpoint on grpc reflection endpoint in favour of auth module bech32prefix endpoint already exposed.

### CLI Breaking Changes

Expand Down
75 changes: 75 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,81 @@ Note, always read the **SimApp** section for more information on application wir

## [Unreleased]

### 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. To enable unordered
transactions in your application:

* Update the `App` constructor to create, load, and save the unordered transaction
manager.

```go
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.

```go
anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(),
// ...
ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, app.UnorderedTxManager),
// ...
}

return sdk.ChainAnteDecorators(anteDecorators...), nil
```

* If the App has a SnapshotManager defined, you must also register the extension
for the TxManager.

```go
if manager := app.SnapshotManager(); manager != nil {
err := manager.RegisterExtensions(unorderedtx.NewSnapshotter(app.UnorderedTxManager))
if err != nil {
panic(fmt.Errorf("failed to register snapshot extension: %s", err))
}
}
```

* 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.

```go
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](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-070-unordered-account.md)
for more details.

### Params

* Params Migrations were removed. It is required to migrate to 0.50 prior to upgrading to .51.
Expand Down
308 changes: 194 additions & 114 deletions api/cosmos/tx/v1beta1/tx.pulsar.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions client/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const (
FlagOffset = "offset"
FlagCountTotal = "count-total"
FlagTimeoutHeight = "timeout-height"
FlagUnordered = "unordered"
FlagKeyAlgorithm = "algo"
FlagKeyType = "key-type"
FlagFeePayer = "fee-payer"
Expand Down Expand Up @@ -136,6 +137,7 @@ func AddTxFlagsToCmd(cmd *cobra.Command) {
f.BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation")
f.String(FlagSignMode, "", "Choose sign mode (direct|amino-json|direct-aux|textual), this is an advanced feature")
f.Uint64(FlagTimeoutHeight, 0, "Set a block timeout height to prevent the tx from being committed past a certain height")
f.Bool(FlagUnordered, false, "Enable unordered transaction delivery; must be used in conjunction with --timeout-height")
f.String(FlagFeePayer, "", "Fee payer pays fees for the transaction instead of deducting from the signer")
f.String(FlagFeeGranter, "", "Fee granter grants fees for the transaction")
f.String(FlagTip, "", "Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator")
Expand Down
10 changes: 10 additions & 0 deletions client/tx/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Factory struct {
gasAdjustment float64
chainID string
fromName string
unordered bool
offline bool
generateOnly bool
memo string
Expand Down Expand Up @@ -86,6 +87,7 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e
gasAdj := clientCtx.Viper.GetFloat64(flags.FlagGasAdjustment)
memo := clientCtx.Viper.GetString(flags.FlagNote)
timeoutHeight := clientCtx.Viper.GetUint64(flags.FlagTimeoutHeight)
unordered := clientCtx.Viper.GetBool(flags.FlagUnordered)

gasStr := clientCtx.Viper.GetString(flags.FlagGas)
gasSetting, _ := flags.ParseGasSetting(gasStr)
Expand All @@ -103,6 +105,7 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e
accountNumber: accNum,
sequence: accSeq,
timeoutHeight: timeoutHeight,
unordered: unordered,
gasAdjustment: gasAdj,
memo: memo,
signMode: signMode,
Expand Down Expand Up @@ -132,6 +135,7 @@ func (f Factory) Fees() sdk.Coins { return f.fees }
func (f Factory) GasPrices() sdk.DecCoins { return f.gasPrices }
func (f Factory) AccountRetriever() client.AccountRetriever { return f.accountRetriever }
func (f Factory) TimeoutHeight() uint64 { return f.timeoutHeight }
func (f Factory) Unordered() bool { return f.unordered }
func (f Factory) FromName() string { return f.fromName }

// SimulateAndExecute returns the option to simulate and then execute the transaction
Expand Down Expand Up @@ -245,6 +249,12 @@ func (f Factory) WithTimeoutHeight(height uint64) Factory {
return f
}

// WithUnordered returns a copy of the Factory with an updated unordered field.
func (f Factory) WithUnordered(v bool) Factory {
f.unordered = v
return f
}

// WithFeeGranter returns a copy of the Factory with an updated fee granter.
func (f Factory) WithFeeGranter(fg sdk.AccAddress) Factory {
f.feeGranter = fg
Expand Down
1 change: 1 addition & 0 deletions client/tx_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type (
SetFeePayer(feePayer sdk.AccAddress)
SetGasLimit(limit uint64)
SetTimeoutHeight(height uint64)
SetUnordered(v bool)
SetFeeGranter(feeGranter sdk.AccAddress)
AddAuxSignerData(tx.AuxSignerData) error
}
Expand Down
Loading

0 comments on commit 6ec53aa

Please sign in to comment.