docs: unordered txs (#24419)

Co-authored-by: Alex | Interchain Labs <alex@interchainlabs.io>
This commit is contained in:
Tyler 2025-04-08 12:19:17 -07:00 committed by GitHub
parent 2f2fff2e9e
commit 29083cb75f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 59 additions and 10 deletions

View File

@ -25,19 +25,14 @@ When users want to interact with an application and make state changes (e.g. sen
Transaction objects are Cosmos SDK types that implement the `Tx` interface
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/tx_msg.go#L51-L56
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/types/tx_msg.go#L53-L58
```
It contains the following methods:
* **GetMsgs:** unwraps the transaction and returns a list of contained `sdk.Msg`s - one transaction may have one or multiple messages, which are defined by module developers.
* **ValidateBasic:** lightweight, [_stateless_](../beginner/01-tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./00-baseapp.md#checktx) and [`DeliverTx`](./00-baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth) module's `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. When [`runTx`](./00-baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself.
:::note
This function is different from the deprecated `sdk.Msg` [`ValidateBasic`](../beginner/01-tx-lifecycle.md#ValidateBasic) methods, which was performing basic validity checks on messages only.
:::
As a developer, you should rarely manipulate `Tx` directly, as `Tx` is really an intermediate type used for transaction generation. Instead, developers should prefer the `TxBuilder` interface, which you can learn more about [below](#transaction-generation).
As a developer, you should rarely manipulate `Tx` directly, as `Tx` is an intermediate type used for transaction generation. Instead, developers should prefer the `TxBuilder` interface, which you can learn more about [below](#transaction-generation).
### Signing Transactions
@ -133,10 +128,10 @@ While messages contain the information for state transition logic, a transaction
### Transaction Generation
The `TxBuilder` interface contains data closely related with the generation of transactions, which an end-user can freely set to generate the desired transaction:
The `TxBuilder` interface contains data closely related with the generation of transactions, which an end-user can set to generate the desired transaction:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/tx_config.go#L40-L53
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/client/tx_config.go#L39-L57
```
* `Msg`s, the array of [messages](#messages) included in the transaction.
@ -144,6 +139,8 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/tx_config.go#L4
* `Memo`, a note or comment to send with the transaction.
* `FeeAmount`, the maximum amount the user is willing to pay in fees.
* `TimeoutHeight`, block height until which the transaction is valid.
* `Unordered`, an option indicating this transaction may be executed in any order (requires TimeoutTimestamp to be set)
* `TimeoutTimestamp`, the timeout timestamp (unordered nonce) of the transaction (required to be used with Unordered).
* `Signatures`, the array of signatures from all signers of the transaction.
As there are currently two sign modes for signing transactions, there are also two implementations of `TxBuilder`:
@ -154,7 +151,7 @@ As there are currently two sign modes for signing transactions, there are also t
However, the two implementations of `TxBuilder` should be hidden away from end-users, as they should prefer using the overarching `TxConfig` interface:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/tx_config.go#L24-L34
https://github.com/cosmos/cosmos-sdk/blob/v0.53.0-rc.2/client/tx_config.go#L27-L37
```
`TxConfig` is an app-wide configuration for managing transactions. Most importantly, it holds the information about whether to sign each transaction with `SIGN_MODE_DIRECT` or `SIGN_MODE_LEGACY_AMINO_JSON`. By calling `txBuilder := txConfig.NewTxBuilder()`, a new `TxBuilder` will be created with the appropriate sign mode.
@ -204,3 +201,21 @@ An example can be seen [here](../../user/run-node/03-txs.md#using-rest)
#### CometBFT RPC
The three methods presented above are actually higher abstractions over the CometBFT RPC `/broadcast_tx_{async,sync,commit}` endpoints, documented [here](https://docs.cometbft.com/v0.37/core/rpc). This means that you can use the CometBFT RPC endpoints directly to broadcast the transaction, if you wish so.
### Unordered Transactions
:::tip
Looking to enable unordered transactions on your chain?
Check out the [v0.53.0 Upgrade Guide](https://docs.cosmos.network/v0.53/build/migrations/upgrade-guide#enable-unordered-transactions-optional)
:::
Beginning with Cosmos SDK v0.53.0, chains may enable unordered transaction support.
Unordered transactions work by using a timestamp as the transaction's nonce value.
The timestamp must be greater than the current block time and not exceed the chain's configured max unordered timeout timestamp duration.
Senders must use a unique timestamp for each distinct transaction. The difference may be as small as a nanosecond, however.
These unique timestamps serve as a one-shot nonce, and their lifespan in state is short-lived.
Upon transaction inclusion, an entry consisting of timeout timestamp and account address will be recorded to state.
Once the block time is passed the timeout timestamp value, the entry will be removed. This ensures that unordered nonces do not indefinitely fill up the chain's storage.

View File

@ -179,6 +179,40 @@ func sendTx() error {
At this point, `TxBuilder`'s underlying transaction is ready to be signed.
#### Generating an Unordered Transaction
Starting with Cosmos SDK v0.53.0, users may send unordered transactions to chains that have the feature enabled.
Using the example above, we can set the required fields to mark a transaction as unordered.
By default, unordered transactions charge an extra 2240 units of gas to offset the additional storage overhead that supports their functionality.
The extra units of gas are customizable and therefore vary by chain, so be sure to check the chain's ante handler for the gas value set, if any.
```go
func sendTx() error {
// --snip--
expiration := 5 * time.Minute
txBuilder.SetUnordered(true)
txBuilder.SetTimeoutTimestamp(time.Now().Add(expiration + (1 * time.Nanosecond)))
}
```
Unordered transactions from the same account must use a unique timeout timestamp value. The difference between each timeout timestamp value may be as small as a nanosecond, however.
```go
import (
"github.com/cosmos/cosmos-sdk/client"
)
func sendMessages(txBuilders []client.TxBuilder) error {
// --snip--
expiration := 5 * time.Minute
for _, txb := range txBuilders {
txb.SetUnordered(true)
txb.SetTimeoutTimestamp(time.Now().Add(expiration + (1 * time.Nanosecond)))
}
}
```
### Signing a Transaction
We set encoding config to use Protobuf, which will use `SIGN_MODE_DIRECT` by default. As per [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-020-protobuf-transaction-encoding.md), each signer needs to sign the `SignerInfo`s of all other signers. This means that we need to perform two steps sequentially: