Skip to content

Conversation

@aarmoa
Copy link
Collaborator

@aarmoa aarmoa commented Jul 17, 2025

  • added a context parameter to broadcast functions in ChainClientV2 to allow cancelation and timeouts
  • added new broadcast functions in ChainClient (v1) to include the context as a parameter, but without changing the existing functions (keeping backwards compatibility)

Fixes CP-517

Summary by CodeRabbit

  • New Features

    • Added context-aware support with timeout and cancellation for all chain client operations, including gas price retrieval and transaction broadcasting.
    • Enhanced transaction broadcasting with configurable polling intervals and retry logic for synchronous operations.
  • Refactor

    • Simplified message struct initialization and removed simulation steps from example code.
    • Unified and streamlined example code to use context-based synchronous broadcasting and improved error handling.
  • Style

    • Improved and corrected comments in select files for better clarity.
  • Documentation

    • Updated comments to accurately reflect functionality.

aarmoa added 2 commits July 17, 2025 18:35
…entV2 to allow cancelation and timeouts. Added new broadcast functions in ChainClient (v1) to include the context as a parameter, but without changing the existing functions (keeping backwards compatibility)
@aarmoa aarmoa requested a review from Copilot July 17, 2025 21:43
@coderabbitai
Copy link

coderabbitai bot commented Jul 17, 2025

Walkthrough

This update introduces context-aware operations throughout the chain client, examples, and test support code. All chain client transaction simulation, broadcasting, and gas price retrieval methods now accept a context.Context parameter, enabling cancellation and timeout control. Example usages are refactored to create and pass context objects, and mock/test clients are updated to match the new method signatures. Some comments are corrected for clarity.

Changes

File(s) Change Summary
client/chain/chain.go, client/chain/chain_v2.go Refactored all transaction and simulation methods to accept context.Context, added context-aware variants, unified error handling, removed batching logic, and updated gas price retrieval to use context.
client/chain/chain_test_support.go, client/chain/chain_test_support_v1.go Updated mock chain client methods to accept context parameters and match the new signatures; added context-aware mock methods.
auth_vote/authz_vote.go, chain/exchange/types/key.go, typeddata/typed_data.go Corrected and clarified function comments; no logic changes.
examples/chain/*/example.go Refactored all example usages to create a context.Context with timeout and pass it to chain client methods; switched from pointer to value message initialization where possible; replaced QueueBroadcastMsg with context-aware broadcasting; removed unnecessary sleeps and gas fee retrieval after broadcasting; improved error handling and output formatting.
examples/chain/permissions/1_MsgCreateNamespace/example.go, examples/chain/permissions/2_MsgUpdateNamespace/example.go Updated SyncBroadcastMsg usage to accept context, polling interval, and retry count parameters.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ExampleApp
    participant ChainClient
    participant Blockchain

    User->>ExampleApp: Run example
    ExampleApp->>ExampleApp: Create context with timeout
    ExampleApp->>ChainClient: CurrentChainGasPrice(ctx)
    ChainClient->>Blockchain: Query gas price (with ctx)
    Blockchain-->>ChainClient: Return gas price
    ChainClient-->>ExampleApp: Return gas price
    ExampleApp->>ChainClient: BroadcastMsg(ctx, msg, mode)
    ChainClient->>Blockchain: Submit transaction (with ctx)
    Blockchain-->>ChainClient: Broadcast result
    ChainClient-->>ExampleApp: Return broadcast response
    ExampleApp->>User: Print response
Loading

Poem

A context now hops with every call,
To gas price, broadcast—one and all!
No more waiting, sleeping, stuck,
With timeouts, rabbits trust their luck.
Refactored code, much less mess,
Chain clients now context-obsess!
🐇⏳✨

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a8b8b8b and 9acaa50.

📒 Files selected for processing (4)
  • client/chain/chain.go (5 hunks)
  • client/chain/chain_test_support.go (2 hunks)
  • client/chain/chain_test_support_v1.go (3 hunks)
  • client/chain/chain_v2.go (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • client/chain/chain_test_support_v1.go
  • client/chain/chain_test_support.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
client/chain/chain.go (4)
exchange/exchange_rpc/pb/goadesign_goagen_injective_exchange_rpc.pb.go (6)
  • BroadcastTxResponse (854-876)
  • BroadcastTxResponse (891-891)
  • BroadcastTxResponse (906-908)
  • BroadcastTxRequest (686-707)
  • BroadcastTxRequest (722-722)
  • BroadcastTxRequest (737-739)
client/common/api_request_assistant.go (1)
  • ExecuteCall (13-37)
client/chain/tx_factory.go (1)
  • NewTxFactory (9-19)
client/constants.go (1)
  • InjDenom (5-5)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: lint
  • GitHub Check: run-tests
🔇 Additional comments (17)
client/chain/chain_v2.go (8)

62-72: LGTM! Interface methods correctly updated for context-aware operations.

The interface methods have been properly updated to accept context parameters as the first argument, following Go conventions. The addition of pollInterval and maxRetries parameters to synchronous broadcast methods provides better control over polling behavior.


691-694: LGTM! Method signature correctly updated for context support.

The SimulateMsg method has been properly updated to accept a context parameter, maintaining consistency with other context-aware methods in the interface.


727-768: LGTM! Context parameter properly used throughout the method.

The buildSignedTx method correctly accepts and uses the context parameter throughout all its operations, including simulation, factory preparation, signing, and encoding. This is a good example of proper context propagation.


770-822: LGTM! Well-implemented polling mechanism with proper context handling.

The SyncBroadcastSignedTx method correctly implements:

  • Context-aware cancellation via ctx.Done()
  • Configurable polling interval and maximum retries
  • Proper error handling distinguishing between fatal and retryable errors
  • Resource cleanup with timer management

The retry logic properly checks for fatal errors using CheckCometError and respects the maximum retry limit.


824-840: LGTM! Context parameter properly integrated into broadcast methods.

Both AsyncBroadcastSignedTx and BroadcastSignedTx methods correctly accept and use the context parameter. The delegation pattern in AsyncBroadcastSignedTx is appropriate, and the context is properly passed to ExecuteCall.


842-862: LGTM! Context parameter properly used in broadcastTx method.

The broadcastTx method correctly accepts and uses the context parameter in both the buildSignedTx call and the ExecuteCall operation. Context propagation is handled appropriately.


2607-2660: LGTM! Consistent polling implementation with proper context handling.

The SyncBroadcastMsg method follows the same robust pattern as SyncBroadcastSignedTx:

  • Proper context-aware cancellation
  • Configurable polling interval and retry limits
  • Appropriate error handling for fatal vs retryable errors
  • Clean resource management

The consistency between these two methods is beneficial for maintainability.


2665-2836: LGTM! Context parameters properly integrated across broadcast and gas price methods.

All three methods correctly implement context handling:

  • AsyncBroadcastMsg and BroadcastMsg properly accept and use context parameters
  • CurrentChainGasPrice correctly uses the context parameter in the FetchEipBaseFee call
  • Context propagation is handled consistently throughout the method implementations

The context-aware refactoring is well-executed across these methods.

client/chain/chain.go (9)

87-92: Well-structured interface additions for context-aware broadcast methods.

The new context-aware broadcast methods follow Go conventions with proper context parameter placement and consistent naming patterns. The addition of configurable pollInterval and maxRetries parameters provides enhanced control over broadcast operations.


100-104: Consistent interface design for signed transaction methods.

The context-aware signed transaction methods maintain consistency with the broadcast methods and follow proper Go conventions for context handling.


327-327: Good addition for context-aware gas price querying.

The CurrentChainGasPriceWithContext method provides context support while maintaining backward compatibility with the existing CurrentChainGasPrice method.


781-805: Correct implementation of context-aware transaction simulation.

The SimulateMsgWithContext method properly integrates context support while maintaining the same logical flow as the original SimulateMsg method. The context is correctly passed to the ExecuteCall function.


861-912: Proper implementation of context-aware transaction building.

The BuildSignedTxWithContext and buildSignedTxWithContext methods correctly integrate context support throughout the transaction building process, including simulation and signing operations. The implementation maintains consistency with the original methods while adding context propagation.


3016-3071: Well-structured context-aware synchronous broadcast implementation.

The SyncBroadcastMsgWithContext method properly implements context cancellation, configurable polling intervals, and appropriate error handling. The polling loop structure follows good practices for waiting on transaction inclusion.


3073-3079: Simple and correct async broadcast implementation.

The AsyncBroadcastMsgWithContext method correctly delegates to BroadcastMsgWithContext with the appropriate broadcast mode. The implementation is clean and follows the expected pattern.


3081-3108: Correct context-aware broadcast implementation with proper error handling.

The BroadcastMsgWithContext method correctly integrates context support while maintaining the existing sequence mismatch retry logic and error handling patterns. The implementation follows the established patterns in the codebase.


3207-3222: Correct context-aware gas price querying implementation.

The CurrentChainGasPriceWithContext method properly integrates context support while maintaining the same logic and error handling as the original CurrentChainGasPrice method. The context is correctly passed to the FetchEipBaseFee call.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.

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

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves broadcast functions in the SDK by adding context parameter support to allow for proper cancellation and timeout handling. The changes ensure that blockchain operations can be cancelled or timed out gracefully, providing better control over long-running operations.

  • Added context parameter to all broadcast functions in ChainClientV2 to enable cancellation and timeout support
  • Added new broadcast functions in ChainClient (v1) with context support while maintaining backward compatibility
  • Updated all example files to use the new context-aware broadcast functions with proper timeout handling

Reviewed Changes

Copilot reviewed 66 out of 66 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
client/chain/chain_v2.go Added context parameter to all broadcast functions and enhanced SyncBroadcast methods with retry logic
client/chain/chain.go Added new context-aware broadcast functions for v1 client maintaining backward compatibility
client/chain/chain_test_support.go Updated mock methods to match new signatures for v2 client
client/chain/chain_test_support_v1.go Added new mock methods for context-aware functions in v1 client
examples/chain/*/example.go Updated all example files to use new context-aware broadcast functions
typeddata/typed_data.go Fixed function name comment from "SignTextWithValidator" to "SignTextValidator"
chain/exchange/types/key.go Fixed function name comment from "orderIndexByMarketDirectionSubaccountPrefix" to "ordersByMarketDirectionPricePrefix"
auth_vote/authz_vote.go Updated to use context-aware broadcast functions

close(c.msgC)
}

if c.cancelFn != nil {
Copy link

Copilot AI Jul 17, 2025

Choose a reason for hiding this comment

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

[nitpick] Consider adding a nil check for c.cancelFn before calling it. The current check only verifies it's not nil but doesn't handle potential race conditions.

Copilot uses AI. Check for mistakes.
t.Reset(defaultBroadcastStatusPoll)
continue
// If we've reached max retries, return error
if totalAttempts >= maxRetries {
Copy link

Copilot AI Jul 17, 2025

Choose a reason for hiding this comment

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

The retry logic should check if maxRetries is 0 or negative to avoid infinite loops. Consider adding validation for maxRetries parameter.

Copilot uses AI. Check for mistakes.
}

// If we've reached max retries, return error
if totalAttempts >= maxRetries {
Copy link

Copilot AI Jul 17, 2025

Choose a reason for hiding this comment

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

Same issue as in chain_v2.go - the retry logic should validate maxRetries parameter to prevent infinite loops when maxRetries is 0 or negative.

Copilot uses AI. Check for mistakes.
//AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
response, err := chainClient.SyncBroadcastMsg(msg)
pollInterval := 100 * time.Millisecond
response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, 5, msg)
Copy link

Copilot AI Jul 17, 2025

Choose a reason for hiding this comment

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

The magic number '5' for maxRetries should be defined as a constant to improve maintainability and consistency across examples.

Suggested change
response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, 5, msg)
response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, MaxRetries, msg)

Copilot uses AI. Check for mistakes.
//AsyncBroadcastMsg, SyncBroadcastMsg, QueueBroadcastMsg
response, err := chainClient.SyncBroadcastMsg(msg)
pollInterval := 100 * time.Millisecond
response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, 5, msg)
Copy link

Copilot AI Jul 17, 2025

Choose a reason for hiding this comment

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

The magic number '5' for maxRetries should be defined as a constant to improve maintainability and consistency across examples.

Suggested change
response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, 5, msg)
response, err := chainClient.SyncBroadcastMsg(ctx, &pollInterval, MaxRetries, msg)

Copilot uses AI. Check for mistakes.
Copy link

@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: 1

🔭 Outside diff range comments (2)
client/chain/chain_v2.go (2)

691-715: Use the passed context in PrepareFactory call.

The method accepts a ctx parameter but uses c.ctx when calling PrepareFactory. This prevents proper context propagation for cancellation and timeout handling.

Apply this fix:

-	txf, err := PrepareFactory(c.ctx, c.txFactory)
+	txf, err := PrepareFactory(ctx, c.txFactory)

727-768: Multiple context usage issues in buildSignedTx.

The method has several places where it uses c.ctx instead of the passed ctx parameter:

  1. Line 728: Uses c.ctx.Simulate
  2. Line 749: Uses c.ctx in PrepareFactory
  3. Line 760: Uses c.ctx.GetFeeGranterAddress()
  4. Line 761: Uses c.ctx.GetFromName()
  5. Line 767: Uses c.ctx.TxConfig

This prevents proper context isolation and cancellation propagation.

Consider refactoring to use a context-aware approach or pass these values as parameters instead of relying on the stored context.

🧹 Nitpick comments (1)
examples/chain/exchange/9_MsgBatchUpdateOrders/example.go (1)

47-50: Inconsistent error handling pattern.

While the broadcasting error handling was updated to use panic(err), the client initialization errors still use fmt.Println(err) and return. For consistency with other examples, these should also use panic(err).

Apply this diff to make error handling consistent:

	if err != nil {
-		fmt.Println(err)
-		return
+		panic(err)
	}

And for the second occurrence:

	if err != nil {
-		fmt.Println(err)
-		return
+		panic(err)
	}

Also applies to: 60-62

Comment on lines +717 to 725
func (c *chainClientV2) BuildSignedTx(ctx context.Context, accNum, accSeq, initialGas uint64, gasPrice uint64, msgs ...sdk.Msg) ([]byte, error) {
txf := NewTxFactory(c.ctx).WithSequence(accSeq).WithAccountNumber(accNum)
txf = txf.WithGas(initialGas)

gasPriceWithDenom := fmt.Sprintf("%d%s", gasPrice, client.InjDenom)
txf = txf.WithGasPrices(gasPriceWithDenom)

return c.buildSignedTx(clientCtx, txf, msgs...)
return c.buildSignedTx(ctx, txf, msgs...)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use the passed context in NewTxFactory call.

The method uses c.ctx when calling NewTxFactory instead of the passed ctx parameter.

Apply this fix:

-	txf := NewTxFactory(c.ctx).WithSequence(accSeq).WithAccountNumber(accNum)
+	txf := NewTxFactory(ctx).WithSequence(accSeq).WithAccountNumber(accNum)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (c *chainClientV2) BuildSignedTx(ctx context.Context, accNum, accSeq, initialGas uint64, gasPrice uint64, msgs ...sdk.Msg) ([]byte, error) {
txf := NewTxFactory(c.ctx).WithSequence(accSeq).WithAccountNumber(accNum)
txf = txf.WithGas(initialGas)
gasPriceWithDenom := fmt.Sprintf("%d%s", gasPrice, client.InjDenom)
txf = txf.WithGasPrices(gasPriceWithDenom)
return c.buildSignedTx(clientCtx, txf, msgs...)
return c.buildSignedTx(ctx, txf, msgs...)
}
func (c *chainClientV2) BuildSignedTx(ctx context.Context, accNum, accSeq, initialGas uint64, gasPrice uint64, msgs ...sdk.Msg) ([]byte, error) {
txf := NewTxFactory(ctx).WithSequence(accSeq).WithAccountNumber(accNum)
txf = txf.WithGas(initialGas)
gasPriceWithDenom := fmt.Sprintf("%d%s", gasPrice, client.InjDenom)
txf = txf.WithGasPrices(gasPriceWithDenom)
return c.buildSignedTx(ctx, txf, msgs...)
}
🤖 Prompt for AI Agents
In client/chain/chain_v2.go around lines 717 to 725, the BuildSignedTx method
incorrectly uses c.ctx instead of the passed ctx parameter when calling
NewTxFactory. Replace c.ctx with ctx in the NewTxFactory call to ensure the
passed context is used properly.

@aarmoa aarmoa merged commit 500561a into dev Jul 18, 2025
6 checks passed
@aarmoa aarmoa deleted the cp-517/improve_broadcast_functions branch July 18, 2025 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants