Skip to content
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

refactor(client/v2)!: remove client.Context #22493

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

Conversation

JulianToledano
Copy link
Contributor

@JulianToledano JulianToledano commented Nov 8, 2024

Description

Closes:
#22397


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.

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

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

Please see Pull Request Reviewer section in the contributing guide for more information on how to review a pull request.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic, API design and naming, documentation is accurate, tests and test coverage

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced transaction handling with new command-line flags for better configurability.
    • Introduced a new context structure for improved command execution.
    • Added functions for user confirmation before broadcasting transactions.
    • New configuration management for client applications, supporting TOML and environment variables.
    • Support for off-chain signing and verification of files.
    • Extended keyring interface with KeyType and KeyInfo.
    • Custom broadcast logic added.
  • Bug Fixes

    • Improved error handling in various command methods and transaction broadcasting.
    • Resolved issues with *big.Int unmarshalling in transactions.
  • Documentation

    • Updated command usage documentation to reflect new flags and functionalities.
  • Refactor

    • Restructured code for better modularity and clarity, particularly in transaction and context management.
    • Refactored to eliminate dependencies on the v1 context.
  • Tests

    • Updated tests to accommodate new features and ensure robust error handling.

Copy link
Contributor

coderabbitai bot commented Nov 8, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes in this pull request involve significant modifications to the client/v2/autocli package, particularly focusing on the AppOptions structure and associated methods. Key alterations include the removal of the ClientCtx field and the introduction of new fields for better codec management. Additionally, various methods across multiple files have been updated to utilize these new fields. The changes extend to transaction handling, command flag management, and error handling improvements, reflecting a comprehensive refactoring aimed at enhancing modularity and clarity in the CLI's functionality.

Changes

File Path Change Summary
client/v2/autocli/app.go Removed ClientCtx, added fields: AddressCodec, ValidatorAddressCodec, ConsensusAddressCodec, Cdc, TxConfigOpts. Updated EnhanceRootCommand and NewAppOptionsFromConfig methods.
client/v2/autocli/builder.go Added fields: Cdc, EnabledSignModes to Builder struct. Updated import statements.
client/v2/autocli/common.go Refactored outOrStdoutFormat, added preRunE, setFlagsFromConfig, getContext, getQueryClientConn, and signModesToApiSignModes methods.
client/v2/autocli/common_test.go Added home, chainID, kBackend to fixture struct. Updated AddTxConnFlags to use addTxAndGlobalFlagsToCmd.
client/v2/autocli/config/config.go Introduced Config and GRPCConfig structs. Added functions: DefaultConfig, CreateClientConfig, CreateClientConfigFromFlags, writeConfigFile, and readConfig.
client/v2/autocli/flag/address.go Updated method signatures in addressValue and consensusAddressValue to use pointer receivers. Enhanced getKeyringFromCtx.
client/v2/autocli/keyring/keyring.go Added NewKeyringFromFlags function. Removed NewKeyringInContext.
client/v2/autocli/msg.go Added generateOrBroadcastTxWithV2 and userConfirmation methods. Updated BuildMsgMethodCommand.
client/v2/autocli/msg_test.go Added --chain-id and --keyring-backend flags to tests.
client/v2/autocli/query.go Added queryContext method. Updated BuildQueryMethodCommand to simplify client connection retrieval.
client/v2/autocli/testdata/help-echo-msg.golden Added --home string flag to command documentation.
client/v2/broadcast/comet/comet.go Updated cdc field type in CometBFTBroadcaster. Modified NewCometBFTBroadcaster constructor.
client/v2/broadcast/comet/comet_test.go Updated test struct to use codec.Codec.
client/v2/offchain/cli.go Updated SignFile and VerifyFile functions to use new context structure. Added persistent flag for Bech32 prefix.
client/v2/offchain/common_test.go Removed several import statements and testConfig type. Introduced mockClientConn struct.
client/v2/offchain/sign.go Updated Sign function signature to include conn.
client/v2/offchain/sign_test.go Updated TestSign to use mockClientConn.
client/v2/offchain/verify.go Updated Verify and verify functions to use new parameters.
client/v2/offchain/verify_test.go Updated Test_Verify and Test_SignVerify to use new context.
client/v2/tx/encoder.go Updated jsonMarshalOptions to include EmitUnpopulated: true.
client/v2/tx/factory.go Updated validateFlagSet logic to prevent offline mode with dryRun. Changed tx field to pointer type.
client/v2/tx/tx.go Refactored transaction handling functions to improve parameter management. Added GenerateAndBroadcastTxCLIWithPrompt.
client/v2/tx/types.go Added generateOnly flag to txParamsFromFlagSet. Renamed several flag constants to uppercase.
simapp/simd/cmd/root.go Modified NewRootCmd to initialize autoCliOpts with individual assignments instead of ClientCtx.
tests/systemtests/mint_test.go Added build constraint for system tests. Defined TestMintQueries for mint-related gRPC queries.
client/v2/broadcast/comet/client_conn.go Introduced CometBFTBroadcaster struct with methods for gRPC communication.
client/v2/internal/print/printer.go Defined Printer struct with methods for formatted output management.
client/v2/internal/flags/flags.go Added several new constant declarations for application flags.
client/v2/context/context.go Introduced new Context struct for managing command execution context. Added functions for context management.
client/v2/tx/flags.go Updated visibility of several flag constants from unexported to exported.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant Context
    participant Keyring
    participant Codec
    participant Broadcaster

    User->>CLI: Execute command
    CLI->>Context: Set up context
    Context->>Keyring: Retrieve keyring
    Context->>Codec: Retrieve codec
    CLI->>Broadcaster: Broadcast transaction
    Broadcaster->>User: Return response
Loading

Possibly related PRs

  • feat(client/v2): factory #20623: This PR modifies the getKeyringFromCtx function to accept an address.Codec parameter, which is relevant to the changes made in the AppOptions structure in the main PR, where codec fields were introduced.
  • feat(client/v2): add keyring flags in query commands #22443: This PR enhances the EnhanceRootCommand method in app.go to integrate keyring flags into query commands, which aligns with the changes in the main PR that involve restructuring application options and context management.

Suggested labels

C:server/v2, backport/v0.52.x

Suggested reviewers

  • akhilkumarpilli
  • testinginprod

Warning

Rate limit exceeded

@JulianToledano has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 15 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 84891ce and f67151d.


📜 Recent review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 84891ce and f67151d.

📒 Files selected for processing (1)
  • client/v2/CHANGELOG.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
client/v2/CHANGELOG.md (1)

Pattern **/*.md: "Assess the documentation for misspellings, grammatical errors, missing documentation and correctness"

🔇 Additional comments (1)
client/v2/CHANGELOG.md (1)

57-57: LGTM! The changelog entry is well-structured and informative.

The entry correctly documents this breaking change, following the changelog format guidelines. It clearly communicates both the changes made (removal of v1 context) and the improvements introduced (new packages and enhanced functionality).


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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.
    • Generate unit testing code for this file.
    • 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 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 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.

}

if err := clientCtx.PrintRaw(txBytes); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "error: %v\n%s\n", err, txBytes)
clientCtx, err := clientcontext.ClientContextFromGoContext(ctx)
Copy link
Member

Choose a reason for hiding this comment

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

Yeah so broadcast tx shouldn't print anything as it returns the output. We should let the caller (which is autocli or any other caller) to handle the printing.

Copy link
Member

@julienrbrt julienrbrt Nov 22, 2024

Choose a reason for hiding this comment

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

I know this command is somewhat interactive, as it can take an user input, but that should be handled by something else (autocli or client) imho not here.

Copy link
Member

Choose a reason for hiding this comment

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

We could have an helper for generate, and one for sign and broadcast and kill all that input logic. In autocli we can easily handle the printing + sign+broadcast in two seperate call.

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: 4

🧹 Outside diff range and nitpick comments (11)
client/v2/internal/flags/flags.go (3)

22-23: Enhance documentation for keyring backend options

Consider listing all supported keyring backend types in the documentation comment (e.g., "os", "file", "test", etc.) to provide better guidance for users.

-	// FlagKeyringBackend is the flag to specify which backend to use for the keyring (e.g. os, file, test).
+	// FlagKeyringBackend is the flag to specify which backend to use for the keyring.
+	// Supported backends: os (default), file, test, memory, kwallet, pass, secret-service

31-32: Enhance documentation for broadcast mode options

Consider listing all supported broadcast modes in the documentation comment to provide better guidance for users.

-	// FlagBroadcastMode is the flag to specify the broadcast mode for transactions.
+	// FlagBroadcastMode is the flag to specify the broadcast mode for transactions.
+	// Supported modes: sync (default), async, block

36-37: Add security warning for insecure gRPC connections

Consider adding a security warning in the documentation for the grpc-insecure flag.

-	// FlagGrpcInsecure is the flag to allow insecure gRPC connections.
+	// FlagGrpcInsecure is the flag to allow insecure gRPC connections.
+	// WARNING: This flag disables transport security. Use only in trusted networks.
client/v2/internal/print/printer.go (2)

15-18: Add documentation for constants.

Consider adding documentation comments for the constants to explain their purpose and valid values.

 const (
+	// jsonOutput represents JSON output format
 	jsonOutput = flags.OutputFormatJSON
+	// textOutput represents text/YAML output format
 	textOutput = flags.OutputFormatText
 )

20-24: Add documentation for struct fields.

Consider adding documentation for the struct fields to improve code clarity.

 // Printer handles formatted output of different types of data
 type Printer struct {
+	// Output is the writer where formatted data will be written
 	Output       io.Writer
+	// OutputFormat specifies the format (json or text) for the output
 	OutputFormat string
 }
client/v2/tx/tx.go (4)

29-32: Enhance error context in ClientContextFromGoContext error handling

Consider wrapping the error with additional context to help with debugging.

 clientCtx, err := clientcontext.ClientContextFromGoContext(ctx)
 if err != nil {
-    return nil, err
+    return nil, fmt.Errorf("failed to get client context: %w", err)
 }

63-71: Improve error context in error handling chain

Consider wrapping errors with additional context for better debugging.

 c, err := clientcontext.ClientContextFromGoContext(ctx)
 if err != nil {
-    return nil, err
+    return nil, fmt.Errorf("failed to get client context: %w", err)
 }

 cometBroadcaster, err := getCometBroadcaster(c.Cdc, c.Flags)
 if err != nil {
-    return nil, err
+    return nil, fmt.Errorf("failed to create comet broadcaster: %w", err)
 }

Line range hint 86-103: Add validation for gRPC connection

The function should validate that the gRPC connection is not nil before using it.

 func newFactory(ctx clientcontext.Context, conn grpc.ClientConn) (Factory, error) {
+    if conn == nil {
+        return Factory{}, fmt.Errorf("gRPC connection cannot be nil")
+    }

129-146: Enhance error context in generateOnly and dryRun functions

Add more context to errors for better debugging experience.

 func generateOnly(txf Factory, msgs ...transaction.Msg) ([]byte, error) {
     uTx, err := txf.UnsignedTxString(msgs...)
     if err != nil {
-        return nil, err
+        return nil, fmt.Errorf("failed to generate unsigned transaction: %w", err)
     }
     return []byte(uTx), nil
 }

 func dryRun(txf Factory, msgs ...transaction.Msg) ([]byte, error) {
     _, gas, err := txf.Simulate(msgs...)
     if err != nil {
-        return nil, err
+        return nil, fmt.Errorf("failed to simulate transaction: %w", err)
     }
     return []byte(fmt.Sprintf("%s\n", GasEstimateResponse{GasEstimate: gas})), nil
 }
client/v2/autocli/common.go (2)

295-308: Simplify error handling in preRunE

The current implementation returns nil after checking for an error, which can be simplified for clarity.

Apply this diff to simplify the function:

 func (b *Builder) preRunE() func(cmd *cobra.Command, args []string) error {
 	return func(cmd *cobra.Command, args []string) error {
-		err := b.setFlagsFromConfig(cmd)
-		if err != nil {
-			return err
-		}
-
-		return nil
+		return b.setFlagsFromConfig(cmd)
 	}
 }

This refactor removes unnecessary lines and makes the code more concise.


289-289: Correct field name EnabledSignmodes to EnabledSignModes

The struct field EnabledSignmodes should be renamed to EnabledSignModes to maintain consistent naming conventions and improve code readability.

Apply the following diff:

 clientCtx := clientcontext.Context{
     Flags:                 cmd.Flags(),
     AddressCodec:          b.AddressCodec,
     ValidatorAddressCodec: b.ValidatorAddressCodec,
     ConsensusAddressCodec: b.ConsensusAddressCodec,
     Cdc:                   b.Cdc,
     Keyring:               k,
-    EnabledSignmodes:      signModesToApiSignModes(b.EnabledSignModes),
+    EnabledSignModes:      signModesToApiSignModes(b.EnabledSignModes),
 }

Ensure that all references to this field are updated accordingly.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 7421b85 and 11ebebf.

📒 Files selected for processing (6)
  • client/v2/autocli/common.go (3 hunks)
  • client/v2/autocli/context/context.go (1 hunks)
  • client/v2/internal/flags/flags.go (2 hunks)
  • client/v2/internal/print/printer.go (1 hunks)
  • client/v2/offchain/cli.go (5 hunks)
  • client/v2/tx/tx.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • client/v2/autocli/context/context.go
  • client/v2/offchain/cli.go
🧰 Additional context used
📓 Path-based instructions (4)
client/v2/autocli/common.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/internal/flags/flags.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/internal/print/printer.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/tx/tx.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

🔇 Additional comments (12)
client/v2/internal/flags/flags.go (2)

5-6: LGTM: Clear documentation and consistent naming

The FlagChainID constant follows the established naming pattern and includes clear documentation.


Line range hint 5-37: Verify complete coverage of client.Context functionality

Let's ensure these flags cover all the necessary functionality previously provided by client.Context.

✅ Verification successful

Let me gather more information about the flags and their usage to ensure complete coverage.


Let me do one final check to understand how the new v2 client handles these configurations.


Based on the gathered information, I can now provide the final response:

Flags adequately cover client.Context functionality with improved organization

The defined flags in flags.go appropriately cover the essential functionality from the original client.Context, with improvements:

  • Core connectivity flags: chain-id, node, grpc-addr, grpc-insecure, broadcast-mode
  • Keyring configuration: keyring-dir, keyring-backend
  • Output control: output, no-indent, no-prompt
  • Transaction signing: from
  • Special operations: no-proposal

The new implementation shows a cleaner separation of concerns, with dedicated initialization functions for specific components (e.g., NewFactoryFromFlagSet, NewKeyringFromFlags) that properly utilize these flags.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if all client.Context fields have corresponding flags

# Search for client.Context fields in the codebase
echo "Searching for client.Context fields..."
rg -A 10 "type Context struct" "client/"

# Search for any remaining references to client.Context
echo "Checking for remaining client.Context references..."
rg "client\.Context" "client/v2/"

Length of output: 2267


Script:

#!/bin/bash
# Check how these flags are used and if they cover all client.Context fields

# Search for flag usage in v2
echo "Searching for flag usage in v2..."
rg "AddFlag|MarkFlagRequired" "client/v2/"

# Search for any new configuration or context setup
echo "Searching for context/config setup..."
rg "NewContext|WithContext|Config" "client/v2/internal/"

# Check for any potential missing functionality
echo "Checking client.Context fields usage in v2..."
rg "Client|GRPCClient|ChainID|Codec|InterfaceRegistry|Input|Keyring|KeyringOptions" "client/v2/internal/"

Length of output: 8659


Script:

#!/bin/bash
# Check for client configuration and initialization

# Look for client initialization and configuration
echo "Checking client initialization..."
rg -A 5 "func New|func Init" "client/v2/"

# Look for how flags are bound to configuration
echo "Checking flag binding..."
rg -A 5 "BindFlags|AddFlags" "client/v2/"

# Check for any configuration structs
echo "Checking configuration structures..."
ast-grep --pattern 'type $_ struct {
  $$$
}'  --lang go client/v2/internal/config/

Length of output: 6307

client/v2/internal/print/printer.go (5)

1-13: LGTM! Well-organized imports and package structure.

The imports are properly grouped and the package name follows Go conventions.


26-41: LGTM! Constructor implementation is sound.

The constructor properly validates the output format and handles errors appropriately.


43-46: LGTM! Clean and concise implementation.

The method provides a convenient way to print strings while reusing PrintBytes logic.


48-51: LGTM! Appropriate handling of raw JSON messages.

The method correctly handles raw JSON messages by delegating to PrintBytes.


53-84: Skip comment as covered by previous review.

A comprehensive refactoring suggestion for this method was provided in a previous review and is still valid.

client/v2/autocli/common.go (5)

258-263: Function outOrStdoutFormat is correctly refactored

The function properly initializes a new printer and uses it to print the output bytes. The error handling is appropriate.


265-294: Function getContext is well-implemented

The getContext function effectively creates a new context with the necessary client information. It initializes the keyring correctly based on the command flags and constructs a clientcontext.Context with all required fields.


309-338: Efficient flag setting in setFlagsFromConfig

The setFlagsFromConfig function effectively sets command flags from the configuration while checking if they have been changed by the user. Error handling is appropriately managed.


380-386: Function signModesToApiSignModes is correctly implemented

The function properly converts a slice of signing.SignMode to a slice of apitxsigning.SignMode. The implementation is efficient and follows best practices.


345-346: ⚠️ Potential issue

Set explicit server name in TLS configuration

When creating TLS credentials with credentials.NewTLS, the ServerName field in tls.Config is not set. This might cause hostname verification to be skipped, potentially reducing the security of the TLS connection.

Modify the TLS configuration to include the server name derived from the address:

 if !insecure {
-    creds = credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12})
+    tlsConfig := &tls.Config{
+        MinVersion: tls.VersionTLS12,
+        ServerName: extractHostname(addr),
+    }
+    creds = credentials.NewTLS(tlsConfig)
 }

Implement a helper function extractHostname to parse and return the hostname from the addr variable.

Likely invalid or redundant comment.

client/v2/tx/tx.go Show resolved Hide resolved
client/v2/tx/tx.go Outdated Show resolved Hide resolved
client/v2/autocli/common.go Show resolved Hide resolved
client/v2/autocli/common.go Show resolved Hide resolved
return err
}

bz, err := v2tx.GenerateOrBroadcastTxCLI(ctx, cConn, msgs...)
Copy link
Member

Choose a reason for hiding this comment

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

Here we need to call them seperately and ask the user Y/N then sign/broadcast

Copy link
Member

Choose a reason for hiding this comment

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

Doing this allowed us to have the tx package not care about any priting

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: 10

🧹 Outside diff range and nitpick comments (4)
client/v2/autocli/context/context.go (1)

1-14: Consider relocating package to client/v2/context

As suggested in the previous review, consider moving this package to client/v2/context for better organization, as it would make more sense at the root level since it's a core component.

client/v2/tx/tx.go (2)

30-33: Improve error handling with context

The error from ClientContextFromGoContext should be wrapped with additional context to help with debugging.

 clientCtx, err := clientcontext.ClientContextFromGoContext(ctx)
 if err != nil {
-    return nil, err
+    return nil, fmt.Errorf("failed to get client context: %w", err)
 }

189-204: Improve error handling in BroadcastTx

The function should wrap errors with context to provide better debugging information.

 func BroadcastTx(ctx context.Context, txf Factory, broadcaster broadcast.Broadcaster) ([]byte, error) {
+    if broadcaster == nil {
+        return nil, fmt.Errorf("broadcaster cannot be nil")
+    }
     if len(txf.tx.msgs) == 0 {
         return nil, errors.New("no messages to broadcast")
     }

     signedTx, err := txf.sign(ctx, true)
     if err != nil {
-        return nil, err
+        return nil, fmt.Errorf("failed to sign transaction: %w", err)
     }

     txBytes, err := txf.txConfig.TxEncoder()(signedTx)
     if err != nil {
-        return nil, err
+        return nil, fmt.Errorf("failed to encode transaction: %w", err)
     }

     return broadcaster.Broadcast(ctx, txBytes)
 }
client/v2/autocli/msg.go (1)

236-236: Add test coverage for the new method

The new generateOrBroadcastTxWithV2 method requires test coverage to ensure it handles various scenarios correctly, including error cases.

Would you like me to help create test cases for this new method?

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 11ebebf and 9c7eb26.

📒 Files selected for processing (6)
  • client/v2/autocli/common.go (3 hunks)
  • client/v2/autocli/context/context.go (1 hunks)
  • client/v2/autocli/msg.go (2 hunks)
  • client/v2/broadcast/comet/client_conn.go (1 hunks)
  • client/v2/tx/factory.go (2 hunks)
  • client/v2/tx/tx.go (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/v2/tx/factory.go
🧰 Additional context used
📓 Path-based instructions (5)
client/v2/autocli/common.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/autocli/context/context.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/autocli/msg.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/broadcast/comet/client_conn.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/tx/tx.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

🪛 golangci-lint (1.61.0)
client/v2/autocli/common.go

9-9: File is not gci-ed with --skip-generated -s standard -s default -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) --custom-order

(gci)


26-26: File is not gci-ed with --skip-generated -s standard -s default -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) --custom-order

(gci)

client/v2/tx/tx.go

15-15: File is not gci-ed with --skip-generated -s standard -s default -s prefix(cosmossdk.io) -s prefix(github.com/cosmos/cosmos-sdk) --custom-order

(gci)

🔇 Additional comments (8)
client/v2/autocli/context/context.go (2)

16-20: LGTM! Well-documented and follows best practices

The implementation uses an empty struct for the context key, which is the recommended approach in Go for context keys.


22-36: LGTM! Verify completeness of context fields

The Context struct is well-designed with clear documentation. Let's verify that all necessary fields are present for command execution.

✅ Verification successful

Let me gather more information about the Context struct usage to ensure completeness.


Let me search for the actual command implementations to verify if all required fields are being used properly.


Based on the comprehensive analysis of the code, I can now provide the final response:

Context struct contains all necessary fields for autocli commands

The Context struct is complete and well-designed with all required fields for command execution:

  • All fields are actively used in the codebase
  • Required codecs (Address, Validator, Consensus) are properly validated in the flag builder
  • The struct matches the actual usage patterns in command implementations
  • No error messages or TODOs indicating missing fields
  • Previous concern about the printer field has been correctly addressed by its removal
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any potential missing fields by analyzing usage patterns

# Search for field access patterns in the codebase
echo "Searching for Context field usage patterns..."
rg -A 2 "Context\." --type go

# Search for any TODO comments related to Context
echo "Checking for TODO comments related to Context..."
rg -i "todo.*context" --type go

Length of output: 11018


Script:

#!/bin/bash
# Search for actual usage of Context fields in autocli
echo "Searching for Context field usage in autocli..."
rg -A 3 "ctx\.(Flags|AddressCodec|ValidatorAddressCodec|ConsensusAddressCodec|Cdc|Keyring|EnabledSignmodes)" --type go client/v2/autocli/

# Search for any potential missing fields by looking at similar context structs
echo "Searching for other context structs for comparison..."
ast-grep --pattern 'type $_ struct {
  $$$
  Flags $_
  $$$
}'

Length of output: 1221


Script:

#!/bin/bash
# Search for command implementations in autocli
echo "Searching for command implementations..."
rg -A 5 "func.*Command" --type go client/v2/autocli/

# Search for any error messages or panics that might indicate missing fields
echo "Searching for error messages related to missing context fields..."
rg "missing|required" --type go client/v2/autocli/

Length of output: 20839

client/v2/autocli/msg.go (2)

16-20: LGTM: New imports align with v2 transaction handling

The added imports support the transition to v2 transaction handling and follow Go conventions.


234-260: Implementation looks good, verify integration points

The new method is well-structured with proper error handling and follows the v2 transaction handling pattern. However, since it's marked as unused, we should verify the integration points.

client/v2/autocli/common.go (4)

258-263: LGTM! Clean refactor of output formatting.

The change simplifies the output formatting logic by leveraging the new print.NewPrinter method, improving code maintainability.


265-293: LGTM! Well-structured context initialization.

The function properly handles keyring initialization based on flags and provides a clean way to create and configure the client context.


309-338: LGTM! Robust flag management implementation.

The function provides a clean way to initialize flags from configuration while respecting user-specified values. The error handling is comprehensive.


379-386: LGTM! Clean sign mode conversion implementation.

The function provides a type-safe way to convert between signing mode types.

client/v2/autocli/context/context.go Outdated Show resolved Hide resolved
client/v2/tx/tx.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
client/v2/broadcast/comet/client_conn.go Show resolved Hide resolved
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/input"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/codec"
)

// GenerateOrBroadcastTxCLIWithBroadcaster will either generate and print an unsigned transaction
Copy link
Member

Choose a reason for hiding this comment

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

I guess it should be GenerateAndBroadcast... now, as we've killed the signing confirmation.
If a the caller wants to ask the user to ask he should: call genetate, ask for confirmation, call broadcast.

return nil, err
}

return BroadcastTx(ctx, txf, broadcaster)
}

// GenerateOrBroadcastTxCLI will either generate and print an unsigned transaction
Copy link
Member

Choose a reason for hiding this comment

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

Same comment to add here

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: 8

🧹 Outside diff range and nitpick comments (10)
client/v2/tx/flags.go (1)

Line range hint 1-52: Consider consistent visibility for all constants

While the transaction-related flags are now exported, defaultGasLimit and gasFlagAuto remain unexported. Consider if these should also be exported for consistency, or document why they should remain package-private.

client/v2/internal/flags/flags.go (2)

23-27: Consider enhancing keyring backend documentation.

While the documentation is good, it would be helpful to list all supported backend types and their security implications in the comment for FlagKeyringBackend.

Consider updating the comment like this:

-// FlagKeyringBackend is the flag to specify which backend to use for the keyring (e.g. os, file, test).
+// FlagKeyringBackend is the flag to specify which backend to use for the keyring.
+// Supported backends:
+// - os: use the operating system's default credentials store
+// - file: encrypted file-based keyring
+// - test: insecure, for testing purposes only
+// - kwallet: KDE Wallet Manager
+// - pass: Unix password manager

32-36: Enhance documentation for node and broadcast mode flags.

The documentation could be more specific about:

  • Expected node URL format
  • Available broadcast modes and their implications

Consider updating the comments like this:

-// FlagNode is the flag to specify the node address to connect to.
+// FlagNode is the flag to specify the node address to connect to (e.g., tcp://localhost:26657).

-// FlagBroadcastMode is the flag to specify the broadcast mode for transactions.
+// FlagBroadcastMode is the flag to specify the broadcast mode for transactions.
+// Available modes:
+// - sync: wait for the tx to be broadcast to the network
+// - async: return immediately after the tx is broadcast
+// - block: wait for the tx to be committed in a block
client/v2/context/context.go (2)

16-20: Consider a more specific name for the context key variable.

While the implementation is correct, consider renaming ContextKey to something more specific like ClientContextKey or AutoCliContextKey to avoid potential naming conflicts in the broader codebase.

-var ContextKey contextKey
+var ClientContextKey contextKey

22-36: Consider adding validation and constructor method.

The Context struct is well-designed, but it would benefit from having:

  1. A constructor method to ensure all required fields are properly initialized
  2. A validation method to check for nil fields before use

This would help prevent runtime errors from uninitialized fields.

Here's a suggested addition:

// NewContext creates a new Context with validation
func NewContext(flags *pflag.FlagSet, addressCodec address.Codec, validatorCodec address.ValidatorAddressCodec, 
    consensusCodec address.ConsensusAddressCodec, cdc codec.Codec, keyring keyring.Keyring, 
    signModes []apisigning.SignMode) (*Context, error) {
    if addressCodec == nil || validatorCodec == nil || consensusCodec == nil || cdc == nil {
        return nil, errors.New("required codecs cannot be nil")
    }
    return &Context{
        Flags: flags,
        AddressCodec: addressCodec,
        ValidatorAddressCodec: validatorCodec,
        ConsensusAddressCodec: consensusCodec,
        Cdc: cdc,
        Keyring: keyring,
        EnabledSignmodes: signModes,
    }, nil
}
client/v2/tx/tx.go (1)

31-39: Improve error handling with context

The error handling could be more descriptive by wrapping errors with additional context.

 	txf, err := initFactory(ctx, conn, msgs...)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to initialize transaction factory: %w", err)
 	}
 
 	err = generateTx(txf, msgs...)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to generate transaction: %w", err)
 	}
client/v2/autocli/common.go (3)

315-324: Consider using map literal initialization

The map initialization could be more concise using a map literal, improving readability.

-	flagsToSet := map[string]string{
-		flags.FlagChainID:        conf.ChainID,
-		flags.FlagKeyringBackend: conf.KeyringBackend,
-		flags.FlagFrom:           conf.KeyringDefaultKeyName,
-		flags.FlagOutput:         conf.Output,
-		flags.FlagNode:           conf.Node,
-		flags.FlagBroadcastMode:  conf.BroadcastMode,
-		flags.FlagGrpcAddress:    conf.GRPC.Address,
-		flags.FlagGrpcInsecure:   strconv.FormatBool(conf.GRPC.Insecure),
-	}
+	flagsToSet := map[string]string{flags.FlagChainID: conf.ChainID, flags.FlagKeyringBackend: conf.KeyringBackend,
+		flags.FlagFrom: conf.KeyringDefaultKeyName, flags.FlagOutput: conf.Output, flags.FlagNode: conf.Node,
+		flags.FlagBroadcastMode: conf.BroadcastMode, flags.FlagGrpcAddress: conf.GRPC.Address,
+		flags.FlagGrpcInsecure: strconv.FormatBool(conf.GRPC.Insecure)}

365-365: Consider documenting the default CometBFT behavior

The TODO comment could be more descriptive about why CometBFT is the default and what implications this has.

-			// TODO: default is comet
+			// TODO: Using CometBFT as default for backward compatibility with legacy implementations

377-384: Consider using make with length and capacity

For better performance, pre-allocate the slice with both length and capacity.

-	r := make([]apitxsigning.SignMode, len(modes))
+	r := make([]apitxsigning.SignMode, len(modes), len(modes))
client/v2/autocli/msg.go (1)

257-268: Simplify conditional logic for better readability

The nested if-else statements handling genOnly, isDryRun, and skipConfirm can be refactored to improve code readability and maintainability.

Consider refactoring the conditionals as follows:

if genOnly {
	bz, err = v2tx.GenerateOnly(ctx, cConn, msgs...)
} else if isDryRun {
	bz, err = v2tx.DryRun(ctx, cConn, msgs...)
} else {
	skipConfirm, _ := cmd.Flags().GetBool("yes")
	if skipConfirm {
		bz, err = v2tx.GenerateAndBroadcastTxCLI(ctx, cConn, msgs...)
	} else {
		bz, err = v2tx.GenerateAndBroadcastTxCLIWithPrompt(ctx, cConn, b.userConfirmation(cmd), msgs...)
	}
}

This refactoring flattens the conditional structure, making it easier to follow the logic.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between e63aa2b and 6cafaa8.

📒 Files selected for processing (15)
  • client/v2/autocli/common.go (3 hunks)
  • client/v2/autocli/config/config.go (1 hunks)
  • client/v2/autocli/flag/address.go (5 hunks)
  • client/v2/autocli/msg.go (5 hunks)
  • client/v2/context/context.go (1 hunks)
  • client/v2/go.mod (4 hunks)
  • client/v2/internal/flags/flags.go (2 hunks)
  • client/v2/offchain/cli.go (5 hunks)
  • client/v2/offchain/sign.go (3 hunks)
  • client/v2/offchain/sign_test.go (2 hunks)
  • client/v2/offchain/verify.go (3 hunks)
  • client/v2/offchain/verify_test.go (2 hunks)
  • client/v2/tx/flags.go (1 hunks)
  • client/v2/tx/tx.go (4 hunks)
  • client/v2/tx/types.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • client/v2/autocli/config/config.go
  • client/v2/go.mod
  • client/v2/offchain/cli.go
  • client/v2/offchain/sign_test.go
  • client/v2/offchain/verify_test.go
  • client/v2/tx/types.go
🧰 Additional context used
📓 Path-based instructions (9)
client/v2/autocli/common.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/autocli/flag/address.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/autocli/msg.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/context/context.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/internal/flags/flags.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/offchain/sign.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/offchain/verify.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/tx/flags.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/tx/tx.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

🪛 golangci-lint (1.62.2)
client/v2/autocli/msg.go

242-242: directive //nolint:unused // It'll be used once BuildMsgMethodCommand is updated to use factory v2. is unused for linter "unused"

(nolintlint)

🔇 Additional comments (20)
client/v2/tx/flags.go (1)

13-29: LGTM! Note: This is a breaking change.

The conversion of flag constants from unexported to exported is well-structured and follows Go naming conventions. This change improves reusability by allowing external packages to access these flags directly.

Let's verify the impact of this breaking change:

✅ Verification successful

Let me analyze the search results. The flags in client/v2/tx/flags.go are being used extensively throughout the codebase, but primarily in test files and in the v2 client implementation itself. The key observations are:

  1. Most usages are in test files (_test.go)
  2. The flags are used in the v2 client implementation (client/v2/tx/types.go, client/v2/tx/factory.go)
  3. The flags are referenced from other packages using the flags package name, suggesting proper import usage

Let me verify if there are any direct string literal usages that might break:


Breaking change is safe to proceed with

The change to export flag constants in client/v2/tx/flags.go is well-structured and safe. The analysis shows:

  1. Most direct flag usages are in test files
  2. Production code references are properly importing and using the flag constants through the package
  3. String literals found in other files are primarily in:
    • Generated files (.pulsar.go)
    • Internal implementation files that define the constants
    • Configuration files that consume these values

The change aligns with the v2 client refactoring goals and follows Go's idioms for exported constants. No compatibility issues were found that would prevent this change.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any direct usage of these flags in their previous lowercase form
# This helps identify any code that needs to be updated
rg -i "flag(timeoutTimestamp|chainID|note|signMode|accountNumber|sequence|from|dryRun|gas|gasAdjustment|gasPrices|fees|feePayer|feeGranter|unordered|offline|generateOnly)[^A-Z]"

Length of output: 42640


Script:

#!/bin/bash
# Search for direct string literals matching the flag names
rg -l '"timeout-timestamp"|"chain-id"|"note"|"sign-mode"|"account-number"|"sequence"|"from"|"dry-run"|"gas"|"gas-adjustment"|"gas-prices"|"fees"|"fee-payer"|"fee-granter"|"unordered"|"offline"|"generate-only"' --type go | grep -v "_test.go"

Length of output: 1305

client/v2/internal/flags/flags.go (1)

5-10: LGTM! Well-documented home and chain ID flags.

The flag constants follow Go naming conventions and include clear documentation.

client/v2/context/context.go (2)

1-14: LGTM! Clean package structure and imports.

The package structure follows Go conventions, and imports are well-organized with clear aliases where needed.


1-55: Verify migration from old client.Context.

Since this is part of removing client.Context, we should verify that all callers are properly migrated to the new context package.

client/v2/offchain/sign.go (5)

7-10: LGTM: Import changes are well-organized and necessary.

The new imports support the transition from client.Context to clientcontext.Context and the addition of gRPC client functionality.


Line range hint 91-91: Use the parent context instead of context.Background().

Skipping detailed explanation as this issue was already raised in a previous review.


54-54: LGTM: Explicit dependency initialization.

The account retriever initialization is now more explicit about its dependencies, which improves code clarity.


70-70: LGTM: Clear dependency injection in factory creation.

The transaction factory initialization clearly shows its dependencies through the new context structure.


75-78: LGTM: Clean keyring access with proper error handling.

The keyring access is straightforward and includes appropriate error handling.

client/v2/offchain/verify.go (2)

Line range hint 21-37: LGTM! Clean refactor of the Verify function.

The changes properly migrate from client.Context to clientcontext.Context while maintaining the necessary functionality. The new TxConfig creation correctly utilizes the context fields.


Line range hint 41-91: LGTM! Good improvement in dependency management.

The refactored verify function now explicitly accepts its dependencies (addressCodec and txConfig) instead of extracting them from a context. This change:

  • Improves testability
  • Makes dependencies explicit
  • Reduces coupling with the context structure
client/v2/autocli/flag/address.go (5)

10-10: LGTM: Import aligns with refactoring goals

The new import supports the transition away from client.Context as per PR objectives.


46-52: LGTM: Appropriate use of pointer receivers

The conversion to pointer receivers is a good practice for consistency and efficiency.


57-58: LGTM: Keyring initialization timing issue resolved

The implementation correctly addresses the keyring initialization timing concerns raised in previous reviews while maintaining the desired functionality.


112-113: LGTM: Consistent implementation with addressValue

The changes maintain consistency with the addressValue implementation while preserving the required keyring functionality.


149-162: Consider fallback to client.Context v1

The implementation handles nil checks and invalid contexts gracefully. However, as suggested in the previous review, consider adding a fallback to check client.Context v1 for better backward compatibility.

Let's check if there are any direct uses of client.Context v1 in the codebase:

client/v2/tx/tx.go (1)

140-144: ⚠️ Potential issue

Handle flag retrieval errors

The function ignores potential errors from flag retrieval which could lead to silent failures.

 func getCometBroadcaster(cdc codec.Codec, flagSet *pflag.FlagSet) (broadcast.Broadcaster, error) {
-	url, _ := flagSet.GetString(flags.FlagNode)
-	mode, _ := flagSet.GetString(flags.FlagBroadcastMode)
+	if cdc == nil {
+		return nil, fmt.Errorf("codec cannot be nil")
+	}
+	if flagSet == nil {
+		return nil, fmt.Errorf("flag set cannot be nil")
+	}
+
+	url, err := flagSet.GetString(flags.FlagNode)
+	if err != nil {
+		return nil, fmt.Errorf("failed to get node URL: %w", err)
+	}
+	if url == "" {
+		return nil, fmt.Errorf("node URL is required")
+	}
+
+	mode, err := flagSet.GetString(flags.FlagBroadcastMode)
+	if err != nil {
+		return nil, fmt.Errorf("failed to get broadcast mode: %w", err)
+	}
+	if mode == "" {
+		return nil, fmt.Errorf("broadcast mode is required")
+	}
+
 	return comet.NewCometBFTBroadcaster(url, mode, cdc)
 }

Likely invalid or redundant comment.

client/v2/autocli/common.go (3)

256-261: LGTM: Clean printer implementation

The refactored implementation properly handles errors and uses the new printer abstraction.


263-291: LGTM: Well-structured context initialization

The function properly handles keyring initialization based on flags and creates a comprehensive client context with all necessary codecs.


293-305: LGTM: Clean PreRunE implementation

The function follows the single responsibility principle and properly handles error propagation.

client/v2/internal/flags/flags.go Show resolved Hide resolved
client/v2/context/context.go Show resolved Hide resolved
client/v2/offchain/sign.go Show resolved Hide resolved
client/v2/tx/tx.go Show resolved Hide resolved
client/v2/tx/tx.go Show resolved Hide resolved
client/v2/autocli/msg.go Outdated Show resolved Hide resolved
client/v2/autocli/msg.go Show resolved Hide resolved
client/v2/autocli/msg.go Outdated Show resolved Hide resolved
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: 0

🧹 Outside diff range and nitpick comments (2)
client/v2/autocli/msg.go (2)

240-240: Remove unnecessary nolint directive

The //nolint:unused directive is no longer needed as this function will be used in the updated BuildMsgMethodCommand.

-//nolint:unused // It'll be used once BuildMsgMethodCommand is updated to use factory v2.

241-278: Consider enhancing error handling with specific error types

The error handling could be more specific to help users better understand and debug issues. Consider wrapping errors with context.

 func (b *Builder) generateOrBroadcastTxWithV2(cmd *cobra.Command, msgs ...transaction.Msg) error {
 	ctx, err := b.getContext(cmd)
 	if err != nil {
-		return err
+		return fmt.Errorf("failed to get context: %w", err)
 	}

 	cConn, err := b.GetClientConn(cmd)
 	if err != nil {
-		return err
+		return fmt.Errorf("failed to get client connection: %w", err)
 	}
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6cafaa8 and 6e1f112.

📒 Files selected for processing (1)
  • client/v2/autocli/msg.go (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
client/v2/autocli/msg.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

🪛 golangci-lint (1.62.2)
client/v2/autocli/msg.go

282-282: func (*Builder).userConfirmation is unused

(unused)

🔇 Additional comments (1)
client/v2/autocli/msg.go (1)

282-307: 🛠️ Refactor suggestion

Use command I/O streams for better testability

Using os.Stdin and os.Stderr directly makes testing difficult. Instead, use the command's input and error output streams.

 func (b *Builder) userConfirmation(cmd *cobra.Command) func([]byte) (bool, error) {
     format, _ := cmd.Flags().GetString(flags.FlagOutput)
     printer := print.Printer{
         Output:       cmd.OutOrStdout(),
         OutputFormat: format,
     }

     return func(bz []byte) (bool, error) {
         err := printer.PrintBytes(bz)
         if err != nil {
             return false, err
         }
-        buf := bufio.NewReader(os.Stdin)
+        buf := bufio.NewReader(cmd.InOrStdin())
         ok, err := input.GetConfirmation(
             "confirm transaction before signing and broadcasting",
-            buf, os.Stderr
+            buf, cmd.ErrOrStderr(),
         )
         if err != nil {
-            _, _ = fmt.Fprintf(os.Stderr, "error: %v\ncanceled transaction\n", err)
+            _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "error: %v\ncanceled transaction\n", err)
             return false, err
         }
         if !ok {
-            _, _ = fmt.Fprintln(os.Stderr, "canceled transaction")
+            _, _ = fmt.Fprintln(cmd.ErrOrStderr(), "canceled transaction")
             return false, nil
         }

         return true, nil
     }
 }

Likely invalid or redundant comment.

🧰 Tools
🪛 golangci-lint (1.62.2)

282-282: func (*Builder).userConfirmation is unused

(unused)

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: 0

🧹 Outside diff range and nitpick comments (2)
client/v2/autocli/msg.go (2)

239-239: Remove unnecessary nolint directive

The nolint:unused directive is no longer needed as this function will be used when BuildMsgMethodCommand is updated to use factory v2.

Apply this diff to remove the directive:

-//nolint:unused // It'll be used once BuildMsgMethodCommand is updated to use factory v2.

240-277: LGTM! Consider enhancing error handling

The implementation is well-structured and handles different transaction scenarios appropriately. Consider wrapping errors with more context for better debugging.

Example enhancement:

 if err != nil {
-    return err
+    return fmt.Errorf("failed to get context: %w", err)
 }
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6e1f112 and ae00cea.

📒 Files selected for processing (2)
  • client/v2/autocli/msg.go (4 hunks)
  • client/v2/autocli/query.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/v2/autocli/query.go
🧰 Additional context used
📓 Path-based instructions (1)
client/v2/autocli/msg.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

🪛 golangci-lint (1.62.2)
client/v2/autocli/msg.go

281-281: func (*Builder).userConfirmation is unused

(unused)

🔇 Additional comments (1)
client/v2/autocli/msg.go (1)

281-306: LGTM! Well-implemented user confirmation flow

The implementation follows best practices:

  • Uses command's I/O streams for better testability
  • Provides clear user feedback
  • Properly handles errors with user-friendly messages
🧰 Tools
🪛 golangci-lint (1.62.2)

281-281: func (*Builder).userConfirmation is unused

(unused)

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: 0

🧹 Outside diff range and nitpick comments (1)
client/v2/autocli/msg.go (1)

282-282: Remove unnecessary nolint:unused directive

The nolint:unused directive is no longer needed as the function is being used in generateOrBroadcastTxWithV2.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ae00cea and d4b36f9.

📒 Files selected for processing (1)
  • client/v2/autocli/msg.go (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
client/v2/autocli/msg.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

🔇 Additional comments (3)
client/v2/autocli/msg.go (3)

239-239: Remove unnecessary nolint:unused directive

The nolint:unused directive is no longer needed as the function is being used.


283-308: Well-implemented user confirmation flow with proper I/O handling

The implementation follows best practices:

  • Uses command's I/O streams for better testability
  • Properly handles user input and error cases
  • Clear error messages and user feedback

240-277: Implementation looks good with comprehensive transaction handling

The method properly handles different transaction modes (generate-only, dry-run, broadcast) with appropriate error handling and user confirmation flow.

Let's verify the error handling paths:

✅ Verification successful

Based on the extensive error handling patterns shown in the codebase, particularly in the transaction-related code, I can now generate the final response:

Error handling implementation is robust and comprehensive

The transaction handling in generateOrBroadcastTxWithV2 follows established error handling patterns seen throughout the codebase:

  • Immediate error checking after context and client connection initialization
  • Proper error propagation from all transaction modes (generate-only, dry-run, broadcast)
  • Consistent error handling pattern with early returns
  • No swallowed errors or unhandled edge cases
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify error handling in transaction-related code
# Look for error handling patterns in transaction-related code

# Check for error handling in transaction operations
rg -A 2 'if err [!:=]' --type go

# Check for potential error paths that might be missed
ast-grep --pattern 'if $cond {
  $$$
  return $err
}'

Length of output: 113963

Copy link
Member

@julienrbrt julienrbrt left a comment

Choose a reason for hiding this comment

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

utACK. Let's add a changelog and could you check this: https://github.com/cosmos/cosmos-sdk/pull/22493/files#r1848398289

@JulianToledano
Copy link
Contributor Author

utACK. Let's add a changelog and could you check this: https://github.com/cosmos/cosmos-sdk/pull/22493/files#r1848398289

I don’t think it makes much sense to pass the context to create the keyring, as it is the context creation function that actually uses this function to create its keyring.

@julienrbrt
Copy link
Member

utACK. Let's add a changelog and could you check this: https://github.com/cosmos/cosmos-sdk/pull/22493/files#r1848398289

I don’t think it makes much sense to pass the context to create the keyring, as it is the context creation function that actually uses this function to create its keyring.

Ok! Makes sense

@julienrbrt
Copy link
Member

Can we still get a changelog?

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: 0

🧹 Outside diff range and nitpick comments (2)
client/v2/tx/tx.go (2)

59-89: Consider splitting the prompt logic into a separate package

The prompt functionality should be moved to a dedicated UI/interaction package to maintain better separation of concerns. This transaction package should focus solely on transaction handling.

Consider creating a new package like client/v2/interaction to handle user prompts and confirmations.


293-310: Add timeout to confirmation prompt

The confirmation prompt should have a timeout to prevent indefinite waiting.

Consider adding a timeout context to the prompter function:

-func askConfirmation(txf Factory, prompter func([]byte) (bool, error)) (bool, error) {
+func askConfirmation(ctx context.Context, txf Factory, prompter func(context.Context, []byte) (bool, error)) (bool, error) {
 	encoder := txf.txConfig.TxJSONEncoder()
 	if encoder == nil {
 		return false, errors.New("failed to encode transaction: tx json encoder is nil")
 	}

 	tx, err := txf.getTx()
 	if err != nil {
 		return false, err
 	}

 	txBytes, err := encoder(tx)
 	if err != nil {
 		return false, fmt.Errorf("failed to encode transaction: %w", err)
 	}

-	return prompter(txBytes)
+	return prompter(ctx, txBytes)
 }
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between d4b36f9 and 84891ce.

📒 Files selected for processing (5)
  • client/v2/autocli/common.go (3 hunks)
  • client/v2/broadcast/comet/comet.go (1 hunks)
  • client/v2/context/context.go (1 hunks)
  • client/v2/tx/tx.go (4 hunks)
  • tests/systemtests/mint_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • client/v2/broadcast/comet/comet.go
  • client/v2/context/context.go
  • tests/systemtests/mint_test.go
🧰 Additional context used
📓 Path-based instructions (2)
client/v2/autocli/common.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

client/v2/tx/tx.go (1)

Pattern **/*.go: Review the Golang code for conformity with the Uber Golang style guide, highlighting any deviations.

🔇 Additional comments (9)
client/v2/tx/tx.go (3)

140-144: 🛠️ Refactor suggestion

Add validation for required flag values

The function should validate that required flag values are present and valid.

Apply this diff:

 func getCometBroadcaster(cdc codec.Codec, flagSet *pflag.FlagSet) (broadcast.Broadcaster, error) {
+	if cdc == nil {
+		return nil, fmt.Errorf("codec cannot be nil")
+	}
+	if flagSet == nil {
+		return nil, fmt.Errorf("flag set cannot be nil")
+	}
 	url, _ := flagSet.GetString(flags.FlagNode)
+	if url == "" {
+		return nil, fmt.Errorf("node URL is required")
+	}
 	mode, _ := flagSet.GetString(flags.FlagBroadcastMode)
+	if mode == "" {
+		return nil, fmt.Errorf("broadcast mode is required")
+	}
 	return comet.NewCometBFTBroadcaster(url, mode, cdc)
 }

Likely invalid or redundant comment.


241-256: 🛠️ Refactor suggestion

Improve error handling and context cancellation checks

The function should handle context cancellation and provide better error context.

Apply this diff:

 func BroadcastTx(ctx context.Context, txf Factory, broadcaster broadcast.Broadcaster) ([]byte, error) {
+	if ctx == nil {
+		return nil, fmt.Errorf("context cannot be nil")
+	}
+	if broadcaster == nil {
+		return nil, fmt.Errorf("broadcaster cannot be nil")
+	}
+
+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	default:
+	}
+
 	if len(txf.tx.msgs) == 0 {
 		return nil, errors.New("no messages to broadcast")
 	}

 	signedTx, err := txf.sign(ctx, true)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to sign transaction: %w", err)
 	}

 	txBytes, err := txf.txConfig.TxEncoder()(signedTx)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to encode transaction: %w", err)
 	}

+	select {
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	default:
+	}
+
 	return broadcaster.Broadcast(ctx, txBytes)

Likely invalid or redundant comment.


25-42: 🛠️ Refactor suggestion

Add parameter validation and improve error handling

The function needs validation for its input parameters and better error wrapping.

Apply this diff:

 func GenerateAndBroadcastTxCLIWithBroadcaster(
 	ctx context.Context,
 	conn grpc.ClientConn,
 	broadcaster broadcast.Broadcaster,
 	msgs ...transaction.Msg,
 ) ([]byte, error) {
+	if ctx == nil {
+		return nil, fmt.Errorf("context cannot be nil")
+	}
+	if conn == nil {
+		return nil, fmt.Errorf("connection cannot be nil")
+	}
+	if broadcaster == nil {
+		return nil, fmt.Errorf("broadcaster cannot be nil")
+	}
+	if len(msgs) == 0 {
+		return nil, fmt.Errorf("at least one message is required")
+	}
+
 	txf, err := initFactory(ctx, conn, msgs...)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to initialize factory: %w", err)
 	}

Likely invalid or redundant comment.

client/v2/autocli/common.go (6)

256-261: LGTM: Clean printer implementation

The refactored implementation using print.NewPrinter is clean and handles errors appropriately.


326-332: LGTM: Proper error handling in flag operations

The implementation correctly handles errors from flag operations in a clean loop structure.


377-384: LGTM: Clean type conversion implementation

The function provides a clean implementation for converting between sign mode types.


79-82: ⚠️ Potential issue

Fix variable shadowing of ctx

The reassignment of ctx shadows the previously declared variable. This can lead to confusion and potential bugs.

Apply this diff to fix the shadowing:

-ctx, err = b.getContext(cmd)
+newCtx, err := b.getContext(cmd)
 if err != nil {
     return err
 }
+ctx = newCtx

343-345: ⚠️ Potential issue

Security: Default to secure gRPC connections

Defaulting to insecure gRPC connections (insecure := true) poses security risks. Consider defaulting to secure connections.

Apply this diff to prioritize security:

-creds := grpcinsecure.NewCredentials()
-
-insecure := true
+insecure := false
+creds := credentials.NewTLS(&tls.Config{MinVersion: tls.VersionTLS12})

373-373: ⚠️ Potential issue

Fix incorrect gRPC client creation

The function grpc.NewClient doesn't exist in the google.golang.org/grpc package. Use grpc.Dial instead.

Apply this diff:

-return grpc.NewClient(addr, []grpc.DialOption{grpc.WithTransportCredentials(creds)}...)
+return grpc.Dial(addr, grpc.WithTransportCredentials(creds))

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

Successfully merging this pull request may close these issues.

3 participants