Skip to content

refactor: unordered transactions ante handling #24573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

technicallyty
Copy link
Contributor

@technicallyty technicallyty commented Apr 24, 2025

Description

changes how unordered transactions ante handling works


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues. Your PR will not be merged unless you satisfy
all of these items.

I have...

  • included the correct type prefix in the PR title, you can find examples of the prefixes below:
  • confirmed ! in the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • updated the relevant documentation or specification, including comments for documenting Go code
  • confirmed all CI checks have passed

Summary by CodeRabbit

  • New Features

    • Added support for enabling unordered transactions via a new configuration option.
    • Introduced customizable gas costs and timeout durations for unordered transactions.
    • Enhanced signature verification to handle unordered transactions, including TTL enforcement and nonce uniqueness.
  • Bug Fixes

    • Improved validation to reject unordered transactions when the feature is disabled.
  • Documentation

    • Updated upgrade guides and documentation to reflect the new configuration and usage patterns for unordered transactions.
  • Tests

    • Expanded and refactored test coverage for unordered transaction scenarios, including multi-signer and duplicate handling.
  • Refactor

    • Consolidated configuration and management of unordered transactions into core modules for easier setup and maintenance.

Copy link

ironbird-prod bot commented Apr 24, 2025

Ironbird - launch a network To use Ironbird, you can use the following commands:
  • /ironbird start OR /ironbird start --load-test-config= - Launch a testnet with the specified chain and load test configuration.
  • /ironbird chains - List of chain images that ironbird can use to spin-up testnet
  • /ironbird loadtests - List of load test modes that ironbird can run against testnet
Custom Load Test Configuration You can provide a custom load test configuration using the `--load-test-config=` flag:
/ironbird start cosmos --load-test-config={
  "block_gas_limit_target": 0.75,
  "num_of_blocks": 50,
  "msgs": [
    {"weight": 0.3, "type": "MsgSend"},
    {"weight": 0.3, "type": "MsgMultiSend"},
	{"weight": 0.4, "type": "MsgArr", "ContainedType": "MsgSend", "NumMsgs": 3300}
  ]
}

Use /ironbird loadtests to see more examples.

@@ -258,6 +293,11 @@ func (svd SigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul

utx, ok := tx.(sdk.TxWithUnordered)
isUnordered := ok && utx.GetUnordered()
unorderedEnabled := svd.ak.IsUnorderedTransactionsEnabled()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we just use ak and not have the unorderedTxManagerfield at all?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah i can do that instead

Comment on lines 224 to 226
maxTxTimeoutDuration time.Duration
unorderedTxGasCost uint64
unorderedTxManager UnorderedNonceManager
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only wonky thing is that we have these options that are not really signing related on the signing decorator

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i feel like an option controlling how far ahead a tx's nonce value is before its considered invalid is related enough to make sense here.

the gas cost does feel odd, but one could also consider its related to the cost of verifying a more complex tx type (unordered)

x/auth/module.go Outdated
Comment on lines 104 to 105
start := telemetry.Now()
defer telemetry.ModuleMeasureSince(types.ModuleName, start, telemetry.MetricKeyPreBlocker)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should have this outside of the if

@technicallyty technicallyty requested a review from aaronc April 24, 2025 23:07
@technicallyty technicallyty marked this pull request as ready for review April 25, 2025 01:21
Copy link
Contributor

coderabbitai bot commented Apr 25, 2025

📝 Walkthrough

Walkthrough

The changes introduce a new mechanism for enabling and configuring unordered transactions in the Cosmos SDK's authentication module. The AccountKeeper now accepts a WithUnorderedTransactions option during initialization to enable unordered transactions, replacing the previous approach that relied on ante handler options and a dedicated UnorderedNonceManager. Configuration for unordered transaction gas cost and timeout duration is now passed through a new SigVerifyOptions field in the ante handler options, which are consumed by the SigVerificationDecorator. The dedicated UnorderedTxDecorator and related manager interfaces are removed, with all unordered transaction logic consolidated into the signature verification decorator and account keeper. Documentation and tests are updated to reflect these structural changes.

Changes

File(s) Change Summary
UPGRADE_GUIDE.md, UPGRADING.md Updated upgrade instructions to reflect new approach for enabling and configuring unordered transactions via WithUnorderedTransactions and SigVerifyOptions. Removed references to old fields and decorators.
simapp/app.go, simapp/ante.go, simapp/app_di.go Updated app and ante handler setup to use new unordered transaction configuration: removed UnorderedNonceManager, added WithUnorderedTransactions to keeper, and passed SigVerifyOptions to signature verification decorator.
x/auth/ante/ante.go, x/auth/ante/expected_keepers.go Removed UnorderedNonceManager and related fields; merged nonce management methods into AccountKeeper interface; updated ante handler to use new signature verification options.
x/auth/ante/sigverify.go Extended SigVerificationDecorator to handle unordered transactions, added configuration options for gas cost and timeout, and consolidated nonce verification logic.
x/auth/ante/unordered.go Deleted file; removed UnorderedTxDecorator and all related types, constants, and functions.
x/auth/keeper/keeper.go Added enableUnorderedTxs flag and initialization option to AccountKeeper; exposed IsUnorderedTransactionsEnabled method.
x/auth/module.go Added EnableUnorderedTransactions field to module inputs; updated module provisioning and pre-block logic to respect unordered transactions flag.
x/auth/ante/sigverify_test.go, x/auth/ante/testutil_test.go, x/auth/ante/ante_test.go, x/auth/ante/unordered_test.go, x/auth/keeper/unordered_tx_test.go Refactored and expanded tests to use new setup and transaction creation logic supporting unordered transactions; removed tests for deleted decorator; updated test suite initialization and assertions.

Sequence Diagram(s)

sequenceDiagram
    participant App as SimApp
    participant Keeper as AccountKeeper
    participant Ante as AnteHandler
    participant SigVer as SigVerificationDecorator

    App->>Keeper: NewAccountKeeper(..., WithUnorderedTransactions(true))
    App->>Ante: NewAnteHandler(HandlerOptions{SigVerifyOptions: [...]})
    Ante->>SigVer: NewSigVerificationDecorator(AccountKeeper, SignModeHandler, ...SigVerifyOptions)
    Note over SigVer: SigVerificationDecorator configured for unordered txs

    User->>App: BroadcastTx (unordered, with timeout)
    App->>Ante: AnteHandler(ctx, tx, ...)
    Ante->>SigVer: AnteHandle(ctx, tx, ...)
    SigVer->>Keeper: IsUnorderedTransactionsEnabled()
    alt Unordered tx enabled
        SigVer->>SigVer: verifyUnorderedNonce(ctx, tx)
        SigVer->>Keeper: TryAddUnorderedNonce(ctx, sender, timestamp)
        SigVer->>Ante: Continue to next decorator
    else Unordered tx disabled
        SigVer-->>Ante: Return error (unordered txs not enabled)
    end
    Ante-->>App: AnteHandler result
Loading
sequenceDiagram
    participant Module as AppModule
    participant Keeper as AccountKeeper

    Module->>Keeper: NewAccountKeeper(..., WithUnorderedTransactions(flag))
    Module->>Module: PreBlock(ctx)
    Module->>Keeper: IsUnorderedTransactionsEnabled()
    alt Unordered tx enabled
        Module->>Keeper: RemoveExpiredUnorderedNonces(ctx)
    end
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
x/auth/ante/sigverify.go (1)

460-465: extractSignersBytes duplicates logic already available above

sigTx.GetSigners() is executed earlier in AnteHandle; we could pass that slice down rather than re-reading from the tx, avoiding another type-assert and keeping signer ordering consistent.

Minor, but keeps the call graph tight.

🧹 Nitpick comments (10)
UPGRADE_GUIDE.md (2)

409-422: Clear upgrade instructions for enabling unordered transactions.

The instructions now clearly explain how to enable unordered transactions through the AccountKeeper configuration with the new WithUnorderedTransactions option.

Consider using spaces instead of tabs in the code block for consistent formatting across Markdown files.

-	app.AccountKeeper = authkeeper.NewAccountKeeper(
-		appCodec,
-		runtime.NewKVStoreService(keys[authtypes.StoreKey]),
-		authtypes.ProtoBaseAccount,
-		maccPerms,
-		authcodec.NewBech32Codec(sdk.Bech32MainPrefix),
-		sdk.Bech32MainPrefix,
-		authtypes.NewModuleAddress(govtypes.ModuleName).String(),
-		authkeeper.WithUnorderedTransactions(true), // new option!
-	)
+    app.AccountKeeper = authkeeper.NewAccountKeeper(
+        appCodec,
+        runtime.NewKVStoreService(keys[authtypes.StoreKey]),
+        authtypes.ProtoBaseAccount,
+        maccPerms,
+        authcodec.NewBech32Codec(sdk.Bech32MainPrefix),
+        sdk.Bech32MainPrefix,
+        authtypes.NewModuleAddress(govtypes.ModuleName).String(),
+        authkeeper.WithUnorderedTransactions(true), // new option!
+    )
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

412-412: Hard tabs
Column: 1

(MD010, no-hard-tabs)


413-413: Hard tabs
Column: 1

(MD010, no-hard-tabs)


414-414: Hard tabs
Column: 1

(MD010, no-hard-tabs)


415-415: Hard tabs
Column: 1

(MD010, no-hard-tabs)


416-416: Hard tabs
Column: 1

(MD010, no-hard-tabs)


417-417: Hard tabs
Column: 1

(MD010, no-hard-tabs)


418-418: Hard tabs
Column: 1

(MD010, no-hard-tabs)


419-419: Hard tabs
Column: 1

(MD010, no-hard-tabs)


420-420: Hard tabs
Column: 1

(MD010, no-hard-tabs)


421-421: Hard tabs
Column: 1

(MD010, no-hard-tabs)


437-441: Updated ante handler setup example.

This example clearly shows how to pass the SigVerifyOptions to the NewSigVerificationDecorator.

Replace tabs with spaces for consistent formatting in the code block.

-	// ... snip
-    ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler, options.SigVerifyOptions...), // supply new options
+    // ... snip
+    ante.NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler, options.SigVerifyOptions...), // supply new options
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

439-439: Hard tabs
Column: 1

(MD010, no-hard-tabs)

UPGRADING.md (2)

30-43: Clear upgrade instructions for enabling unordered transactions.

The instructions explain how to enable unordered transactions using the new WithUnorderedTransactions option.

Consider using spaces instead of tabs in the code block for consistent formatting across Markdown files.

-	app.AccountKeeper = authkeeper.NewAccountKeeper(
-		appCodec,
-		runtime.NewKVStoreService(keys[authtypes.StoreKey]),
-		authtypes.ProtoBaseAccount,
-		maccPerms,
-		authcodec.NewBech32Codec(sdk.Bech32MainPrefix),
-		sdk.Bech32MainPrefix,
-		authtypes.NewModuleAddress(govtypes.ModuleName).String(),
-		authkeeper.WithUnorderedTransactions(true), // new option!
-	)
+    app.AccountKeeper = authkeeper.NewAccountKeeper(
+        appCodec,
+        runtime.NewKVStoreService(keys[authtypes.StoreKey]),
+        authtypes.ProtoBaseAccount,
+        maccPerms,
+        authcodec.NewBech32Codec(sdk.Bech32MainPrefix),
+        sdk.Bech32MainPrefix,
+        authtypes.NewModuleAddress(govtypes.ModuleName).String(),
+        authkeeper.WithUnorderedTransactions(true), // new option!
+    )
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

33-33: Hard tabs
Column: 1

(MD010, no-hard-tabs)


34-34: Hard tabs
Column: 1

(MD010, no-hard-tabs)


35-35: Hard tabs
Column: 1

(MD010, no-hard-tabs)


36-36: Hard tabs
Column: 1

(MD010, no-hard-tabs)


37-37: Hard tabs
Column: 1

(MD010, no-hard-tabs)


38-38: Hard tabs
Column: 1

(MD010, no-hard-tabs)


39-39: Hard tabs
Column: 1

(MD010, no-hard-tabs)


40-40: Hard tabs
Column: 1

(MD010, no-hard-tabs)


41-41: Hard tabs
Column: 1

(MD010, no-hard-tabs)


42-42: Hard tabs
Column: 1

(MD010, no-hard-tabs)


59-62: Updated ante handler setup example.

This example clearly shows how to pass the SigVerifyOptions to the NewSigVerificationDecorator.

Replace tab with spaces for consistent formatting in the "snip" line.

-  // ... snip ...
+    // ... snip ...
x/auth/ante/sigverify_test.go (2)

258-289: Comprehensive test helper for generating transactions.

The genTestTx function is well-implemented with good error handling and flexibility for creating different types of test transactions. It will help ensure robust test coverage for the new unordered transaction functionality.

Remove the redundant error check at line 286, as the same error is already checked at line 284:

-	require.NoError(t, err)

291-319: Useful helper for multi-signed unordered transactions.

The genMultiSignedUnorderedTx function provides a clean way to generate test transactions with multiple signers, which is important for comprehensive test coverage of complex scenarios.

Remove the redundant error check at line 316, as the same error is already checked at line 314:

-	require.NoError(t, err)
x/auth/ante/unordered_test.go (1)

72-83: Duplicate TxConfig creation – extract a helper

txConfigOpts and the authtx.NewTxConfigWithOptions call are repeated twice inside reset. This is only test code, but the duplication makes the function longer and harder to tweak (e.g. when adding a new sign-mode).

Consider extracting a small helper:

func buildTxConfig(ir codectypes.InterfaceRegistry, queryFn banktypes.MetadataQueryFn, modes []signing.SignMode) client.TxConfig { … }

Call it once for suite.clientCtx and once for the ante-specific config.

x/auth/ante/testutil_test.go (2)

82-85: Option order makes the call brittle – move the new flag to a struct option

keeper.NewAccountKeeper now receives keeper.WithUnorderedTransactions(enableUnorderedTxs) as the last positional argument. Any future change in the constructor’s signature will silently break this line.

Prefer functional-options consistently:

- sdk.Bech32MainPrefix, types.NewModuleAddress("gov").String(), keeper.WithUnorderedTransactions(enableUnorderedTxs),
+ sdk.Bech32MainPrefix,
+ types.NewModuleAddress("gov").String(),
+ keeper.WithUnorderedTransactions(enableUnorderedTxs),

Even better, switch the boolean enableUnorderedTxs coming into setupSuite to an explicit []keeper.AccountKeeperOption so callers cannot swap booleans by accident.


230-237: Setting TimeoutTimestamp on ordered txs may mask bugs

createTx unconditionally calls SetTimeoutTimestamp(unorderedTimeout).
When unordered == false, the SDK currently ignores the field, but future validation might reject non-zero timestamps on ordered txs.

- suite.txBuilder.SetTimeoutTimestamp(unorderedTimeout)
+ if unordered {
+     suite.txBuilder.SetTimeoutTimestamp(unorderedTimeout)
+ }

A tiny guard keeps the builder’s behaviour crystal-clear.

x/auth/ante/sigverify.go (1)

447-454: Partial state write before duplicate-nonce failure – tighten the flow

TryAddUnorderedNonce is called inside a loop.
On the first signer that duplicates a nonce, an error is returned; earlier successful insertions for previous signers are discarded only because the entire ante-handler wraps a cached store.

While this is safe today, making the operation explicitly atomic is clearer and future-proof:

  1. Run a read-only pass to detect duplicates for all signers.
  2. If no duplicates, run a second pass that records the nonce and charges gas.

This avoids relying on implicit cache semantics and makes reasoning about state changes easier.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4846e80 and 39e0768.

⛔ Files ignored due to path filters (1)
  • x/auth/ante/testutil/expected_keepers_mocks.go is excluded by !**/*_mocks.go
📒 Files selected for processing (16)
  • UPGRADE_GUIDE.md (1 hunks)
  • UPGRADING.md (1 hunks)
  • simapp/ante.go (1 hunks)
  • simapp/app.go (3 hunks)
  • simapp/app_di.go (1 hunks)
  • x/auth/ante/ante.go (2 hunks)
  • x/auth/ante/ante_test.go (1 hunks)
  • x/auth/ante/expected_keepers.go (1 hunks)
  • x/auth/ante/sigverify.go (6 hunks)
  • x/auth/ante/sigverify_test.go (3 hunks)
  • x/auth/ante/testutil_test.go (5 hunks)
  • x/auth/ante/unordered.go (0 hunks)
  • x/auth/ante/unordered_test.go (1 hunks)
  • x/auth/keeper/keeper.go (4 hunks)
  • x/auth/keeper/unordered_tx_test.go (2 hunks)
  • x/auth/module.go (3 hunks)
💤 Files with no reviewable changes (1)
  • x/auth/ante/unordered.go
🧰 Additional context used
🧬 Code Graph Analysis (5)
simapp/ante.go (3)
x/auth/ante/sigverify.go (1)
  • NewSigVerificationDecorator (260-273)
x/auth/ante/expected_keepers.go (1)
  • AccountKeeper (15-24)
x/auth/keeper/keeper.go (1)
  • AccountKeeper (88-111)
x/auth/ante/ante_test.go (1)
x/auth/ante/testutil_test.go (1)
  • SetupTestSuiteWithUnordered (123-126)
x/auth/keeper/keeper.go (1)
x/auth/ante/expected_keepers.go (1)
  • AccountKeeper (15-24)
x/auth/keeper/unordered_tx_test.go (1)
x/auth/keeper/keeper.go (1)
  • WithUnorderedTransactions (115-119)
x/auth/module.go (2)
types/context.go (1)
  • UnwrapSDKContext (392-397)
x/auth/keeper/keeper.go (3)
  • InitOption (113-113)
  • WithUnorderedTransactions (115-119)
  • NewAccountKeeper (129-163)
🪛 markdownlint-cli2 (0.17.2)
UPGRADING.md

33-33: Hard tabs
Column: 1

(MD010, no-hard-tabs)


34-34: Hard tabs
Column: 1

(MD010, no-hard-tabs)


35-35: Hard tabs
Column: 1

(MD010, no-hard-tabs)


36-36: Hard tabs
Column: 1

(MD010, no-hard-tabs)


37-37: Hard tabs
Column: 1

(MD010, no-hard-tabs)


38-38: Hard tabs
Column: 1

(MD010, no-hard-tabs)


39-39: Hard tabs
Column: 1

(MD010, no-hard-tabs)


40-40: Hard tabs
Column: 1

(MD010, no-hard-tabs)


41-41: Hard tabs
Column: 1

(MD010, no-hard-tabs)


42-42: Hard tabs
Column: 1

(MD010, no-hard-tabs)

UPGRADE_GUIDE.md

412-412: Hard tabs
Column: 1

(MD010, no-hard-tabs)


413-413: Hard tabs
Column: 1

(MD010, no-hard-tabs)


414-414: Hard tabs
Column: 1

(MD010, no-hard-tabs)


415-415: Hard tabs
Column: 1

(MD010, no-hard-tabs)


416-416: Hard tabs
Column: 1

(MD010, no-hard-tabs)


417-417: Hard tabs
Column: 1

(MD010, no-hard-tabs)


418-418: Hard tabs
Column: 1

(MD010, no-hard-tabs)


419-419: Hard tabs
Column: 1

(MD010, no-hard-tabs)


420-420: Hard tabs
Column: 1

(MD010, no-hard-tabs)


421-421: Hard tabs
Column: 1

(MD010, no-hard-tabs)


439-439: Hard tabs
Column: 1

(MD010, no-hard-tabs)

⏰ Context from checks skipped due to timeout of 90000ms (15)
  • GitHub Check: test-system-legacy
  • GitHub Check: test-system
  • GitHub Check: tests (03)
  • GitHub Check: tests (02)
  • GitHub Check: tests (01)
  • GitHub Check: tests (00)
  • GitHub Check: test-sim-nondeterminism
  • GitHub Check: test-e2e
  • GitHub Check: test-integration
  • GitHub Check: build (arm64)
  • GitHub Check: build (amd64)
  • GitHub Check: Analyze
  • GitHub Check: golangci-lint
  • GitHub Check: Gosec
  • GitHub Check: Summary
🔇 Additional comments (28)
x/auth/keeper/unordered_tx_test.go (2)

38-38: Enables unordered transactions consistently with the refactored approach.

The addition of keeper.WithUnorderedTransactions(true) during AccountKeeper initialization aligns with the broader refactoring effort where unordered transaction support is now enabled via keeper options rather than through ante handler options.


316-316: Same initialization pattern applied consistently.

This second instance of keeper.WithUnorderedTransactions(true) ensures consistent testing environment setup, properly enabling unordered transactions for the second test case as well.

simapp/app_di.go (1)

277-283: Simplified HandlerOptions structure.

The refactored code removes the UnorderedNonceManager field from HandlerOptions, which aligns with the architectural change where unordered transaction handling is now controlled at the keeper level rather than through dedicated ante handlers.

x/auth/ante/ante_test.go (1)

1453-1453: Updated test setup to use new unordered transactions configuration.

Test now initializes using SetupTestSuiteWithUnordered with an explicit parameter to enable unordered transactions, consistent with the new approach where unordered transaction support is explicitly configured rather than implicitly assumed.

simapp/ante.go (1)

46-46: Updated signature verification decorator with options support.

The NewSigVerificationDecorator now receives configuration options through options.SigVerifyOptions, allowing for fine-grained control of unordered transaction behavior such as gas costs and timeout durations. This is a cleaner approach than having a separate unordered transaction decorator.

x/auth/ante/expected_keepers.go (1)

21-21: Interface expansion aligns with unordered transactions refactoring

The addition of IsUnorderedTransactionsEnabled() to the AccountKeeper interface is part of consolidating unordered transaction functionality directly into the AccountKeeper. This method will be used to check whether unordered transaction support is enabled.

x/auth/keeper/keeper.go (5)

96-96: New field enables unordered transaction support

Adding the enableUnorderedTxs boolean field to the AccountKeeper struct provides a way to track whether unordered transactions are enabled for this keeper instance.


113-119: Good use of functional options pattern

The functional options pattern implementation is clean and provides a flexible way to configure the AccountKeeper during initialization. This approach maintains backward compatibility while allowing new features to be added.


131-131: Updated constructor signature supports initialization options

The NewAccountKeeper function now accepts variadic InitOption parameters, allowing flexible configuration such as enabling unordered transactions.


159-161: Options are applied after keeper construction

The implementation correctly applies all initialization options after the keeper has been constructed, ensuring that the keeper object is fully initialized before customization.


165-167: Feature flag accessor implementation

The IsUnorderedTransactionsEnabled method provides a clean way to check whether unordered transactions are enabled. This method implements the interface method added to AccountKeeper in x/auth/ante/expected_keepers.go.

simapp/app.go (3)

8-10: Import reordering

The imports for "io" and "maps" have been reordered but remain included.


310-310: Enabling unordered transactions in SimApp

The NewSimApp function now enables unordered transactions by default for the AccountKeeper. This aligns with the new initialization pattern introduced in the refactoring.


702-712: Simplified ante handler configuration

The ante handler configuration has been updated to use the new SigVerifyOptions approach for configuring unordered transaction behavior. This replaces the previous approach that used separate decorators and managers. The options include:

  1. WithUnorderedTxGasCost - Sets the additional gas cost for unordered transactions
  2. WithMaxTxTimeoutDuration - Sets the maximum allowed timeout for unordered transactions

This change centralizes unordered transaction configuration and simplifies the ante handler setup.

x/auth/module.go (3)

224-224: Feature flag for unordered transactions

Adding the EnableUnorderedTransactions boolean field to ModuleInputs allows this feature to be toggled at the module level via app configuration.


105-110: Conditionally clean up expired unordered nonces

The PreBlock method now only attempts to remove expired unordered nonces if unordered transactions are enabled. This is an efficient approach that avoids unnecessary processing when the feature is disabled.


254-258: Initialize with unordered transactions option

The ProvideModule function now creates an options slice that includes the unordered transactions setting. This ensures that the AccountKeeper is properly configured based on the module inputs.

x/auth/ante/ante.go (2)

23-26: Good documentation addition for SigVerifyOptions.

The addition of well-documented SigVerifyOptions field in the HandlerOptions struct is a good practice. The comments clearly explain the purpose of the field and how it can be used to modify signature verification behavior.


56-56: Well-structured refactoring of the ante handler configuration.

This change consolidates the unordered transaction handling into the signature verification decorator by passing the SigVerifyOptions, which simplifies the codebase by removing the previous dedicated decorator for unordered transactions.

UPGRADE_GUIDE.md (2)

424-426: Clear explanation of default behavior and configuration options.

This explanation is important for users who want to understand the default behavior and how to customize it.


429-433: Well-structured SigVerifyOptions example.

The example shows how to configure the options with default constants, making it easy for users to understand and modify.

UPGRADING.md (2)

45-46: Good explanation of default values and configuration options.

This section clearly explains the default behavior and how to customize it through SigVerifyOptions.


50-54: Well-formatted configuration example.

The example shows how to configure the options with default constants, making it easy for users to understand and modify.

x/auth/ante/sigverify_test.go (4)

251-256: Well-structured options struct for test transaction generation.

The genTxOptions struct provides a clean way to configure test transactions with various parameters including unordered flags and timestamps, which will be useful for testing the new unordered transaction functionality.


392-403: Important test case for unordered transactions with disabled feature.

This test ensures that unordered transactions are properly rejected when the feature is disabled, which is an important edge case to test.


405-406: Good test suite setup for unordered transactions.

Using a specialized test suite with unordered transactions enabled ensures that the tests reflect the expected behavior in that configuration.


468-468: Updated test case description to reflect actual behavior.

The description now clearly indicates that unordered transactions should not increment the sequence number, which aligns with the expected behavior.

x/auth/ante/sigverify.go (1)

413-421: Method name mismatch – possible compilation error

unorderedTx.GetTimeoutTimeStamp() uses “TimeStamp” (capital S).
Earlier, the builder method is SetTimeoutTimestamp. The SDK interfaces use GetTimeoutTimestamp() (lowercase s) as well.

Please confirm the interface:

timeoutTimestamp := unorderedTx.GetTimeoutTimestamp() // typical SDK spelling

If the current code doesn’t compile, CI will catch it, but fixing it here avoids churn.

Comment on lines 26 to 30
var priv1, priv2, priv3 cryptotypes.PrivKey
var antehandler sdk.AnteHandler
var defaultSignMode signing.SignMode
var accs []sdk.AccountI
var msgs []sdk.Msg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

group?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 35 to 41
enabledSignModes := []signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT, signing.SignMode_SIGN_MODE_TEXTUAL, signing.SignMode_SIGN_MODE_LEGACY_AMINO_JSON}
// Since TEXTUAL is not enabled by default, we create a custom TxConfig
// here which includes it.
txConfigOpts := authtx.ConfigOptions{
TextualCoinMetadataQueryFn: txmodule.NewGRPCCoinMetadataQueryFn(suite.clientCtx),
EnabledSignModes: enabledSignModes,
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed some stuff slim down test copying

x/auth/module.go Outdated
@@ -218,6 +220,8 @@ type ModuleInputs struct {

// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace exported.Subspace `optional:"true"`

EnableUnorderedTransactions bool `optional:"true"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can we verify that this works properly?

Copy link
Contributor Author

@technicallyty technicallyty Apr 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the legacy system test should fail if this doesn't work, since this is opt-in

Copy link
Contributor

@aljo242 aljo242 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approving with some tiny nits

@@ -108,6 +110,14 @@ type AccountKeeper struct {
UnorderedNonces collections.KeySet[collections.Pair[int64, []byte]]
}

type InitOption func(*AccountKeeper)

func WithUnorderedTransactions(enable bool) InitOption {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we godoc this and what the side effects are

@@ -93,6 +93,8 @@ type AccountKeeper struct {
permAddrs map[string]types.PermissionsForAddress
bech32Prefix string

enableUnorderedTxs bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we doc what this does and how it is used

@aljo242
Copy link
Contributor

aljo242 commented Apr 25, 2025

good to merge once @aaronc approves as well

Copy link
Member

@aaronc aaronc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly LGTM. Added a few suggestions including a slightly cleaner way to handle depinject with ManyPerContainerTypes. Going to take little more thorough look at the logic before ACKing

UPGRADE_GUIDE.md Outdated
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
// NEW !! NEW !! NEW !!
ante.NewUnorderedTxDecorator(options.UnorderedNonceManager, options.UnorderedTxOptions...)
// ... snip
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe say "other decorators" instead of snip?

UPGRADING.md Outdated
ante.NewIncrementSequenceDecorator(options.AccountKeeper),
// NEW !! NEW !! NEW !!
ante.NewUnorderedTxDecorator(options.UnorderedNonceManager, options.UnorderedTxOptions...)
// ... snip ...
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

type SigVerificationDecoratorOption func(svd *SigVerificationDecorator)

// WithMaxTxTimeoutDuration sets the maximum TTL a transaction can define for unordered transactions.
func WithMaxTxTimeoutDuration(duration time.Duration) SigVerificationDecoratorOption {
Copy link
Member

@aaronc aaronc Apr 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it's a bit vebose, but I think we should be clearer that this only applies to unordered tx's. We don't enforce this max duration if the tx isn't unordered right?

Suggested change
func WithMaxTxTimeoutDuration(duration time.Duration) SigVerificationDecoratorOption {
func WithMaxUnorderedTimeoutDuration(duration time.Duration) SigVerificationDecoratorOption {

@@ -108,6 +112,17 @@ type AccountKeeper struct {
UnorderedNonces collections.KeySet[collections.Pair[int64, []byte]]
}

type InitOption func(*AccountKeeper)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type InitOption func(*AccountKeeper)
type InitOption interface {
IsManyPerContainerType()
apply(*AccountKeeper)
}
type initOption func(*AccountKeeper)
func (i initOption) apply(ak *AccountKeeper) { i(ak) }
func (initOption) IsManyPerContainerType() {}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does making this change give us given that they way @technicallyty has it works? This seems more confusing to me

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ManyPerContainer allows the options to be supplied from potentially many sources in the dependency graph. They don't have to all be supplied at once as an array. If we don't care about that it doesn't matter, but it follows the same pattern as BaseAppOption, CustomGetSigner, HandlerRoute where options might be collected from multiple sources.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think here we really only want one source (injecting in your app.go) right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

supplying the options in separate places feels like it would be a rare case, and potentially messy for developers to do. i think it is ok as is

x/auth/module.go Outdated
@@ -218,6 +220,8 @@ type ModuleInputs struct {

// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace exported.Subspace `optional:"true"`

KeeperOptions []keeper.InitOption `optional:"true"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
KeeperOptions []keeper.InitOption `optional:"true"`
KeeperOptions []keeper.InitOption

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we not need this tag?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ManyPerContainer dependencies are always optional

Comment on lines +121 to +123
return func(ak *AccountKeeper) {
ak.enableUnorderedTxs = enable
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return func(ak *AccountKeeper) {
ak.enableUnorderedTxs = enable
}
return initOption(func(ak *AccountKeeper) {
ak.enableUnorderedTxs = enable
})

simapp/app_di.go Outdated
@@ -139,7 +139,7 @@ func NewSimApp(
// with the prefix defined in the auth module configuration.
//
// func() address.Codec { return <- custom address codec type -> }

[]authkeeper.InitOption{authkeeper.WithUnorderedTransactions(true)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[]authkeeper.InitOption{authkeeper.WithUnorderedTransactions(true)},
authkeeper.WithUnorderedTransactions(true),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants