From 29083cb75fbdc00d884cdb745a024562b8775f11 Mon Sep 17 00:00:00 2001 From: Tyler <48813565+technicallyty@users.noreply.github.com> Date: Tue, 8 Apr 2025 12:19:17 -0700 Subject: [PATCH] docs: unordered txs (#24419) Co-authored-by: Alex | Interchain Labs --- docs/docs/learn/advanced/01-transactions.md | 35 +++++++++++++++------ docs/docs/user/run-node/03-txs.md | 34 ++++++++++++++++++++ 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/docs/docs/learn/advanced/01-transactions.md b/docs/docs/learn/advanced/01-transactions.md index 900d8b3fe1..9d9147f31b 100644 --- a/docs/docs/learn/advanced/01-transactions.md +++ b/docs/docs/learn/advanced/01-transactions.md @@ -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. diff --git a/docs/docs/user/run-node/03-txs.md b/docs/docs/user/run-node/03-txs.md index f459acb880..022cdcc192 100644 --- a/docs/docs/user/run-node/03-txs.md +++ b/docs/docs/user/run-node/03-txs.md @@ -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: