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

BE-594/domain/cosmos | cosmos/auth, cosmos/tx packages #526

Merged
merged 3 commits into from
Oct 22, 2024

Conversation

deividaspetraitis
Copy link
Collaborator

@deividaspetraitis deividaspetraitis commented Oct 14, 2024

This PR was opened as part of bigger claimbot feature to keep PRs small, focused and more manageable and adds cosmos/auth, cosmos/tx packages containing various high level helper functions and wrappers abstracting lower level details interacting with the chain.

Note, this PR will be merged after #525 is merged since it depends on delivery/http package.

Summary by CodeRabbit

  • New Features

    • Introduced a new package for querying account information in the Cosmos Auth module.
    • Added functionality for building, simulating, and sending transactions within the Cosmos SDK framework, including gas and fee calculations.
    • Implemented mock clients for testing account queries and transaction functionalities.
  • Bug Fixes

    • Enhanced error handling in mock implementations to prevent unimplemented function calls.
  • Documentation

    • Updated documentation to reflect new structures and methods for better clarity on usage.

Adds cosmos/auth, cosmos/tx packages containing various high level helper functions
and wrappers abstracting lower level details interacting with the chain.
@deividaspetraitis deividaspetraitis self-assigned this Oct 14, 2024
Copy link
Contributor

coderabbitai bot commented Oct 14, 2024

Walkthrough

This pull request introduces a types package for interacting with the Cosmos Auth module, implementing a QueryClient interface that retrieves account information. Additionally, a tx package is added for managing transactions, including building, signing, and sending them. A mock implementation for the QueryClient interface is also provided to facilitate testing, along with other mock structures for transaction service interactions.

Changes

File Path Change Summary
domain/cosmos/auth/types/types.go Added types package with QueryClient interface, queryClient struct, and GetAccount method for account retrieval.
domain/cosmos/tx/tx.go Introduced tx package with transaction management functionalities including BuildTx, SendTx, gas simulations, and fee calculations.
domain/mocks/auth.go Added mock implementation of QueryClient with AuthQueryClientMock struct and GetAccount method.

Possibly related PRs

Suggested reviewers

  • PaddyMc

🐰 In the cosmos where we play,
New types and mocks have come to stay.
Transactions built with care and ease,
Account queries flow like a breeze.
Hopping through code, we cheer and sing,
For every change, a joyful spring! 🌼


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.

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 (10)
domain/mocks/auth.go (2)

11-13: Well-structured mock with room for improved documentation.

The AuthQueryClientMock struct is well-designed for flexible mocking. The GetAccountFunc field allows for easy customization of the mock's behavior in tests.

Consider adding a comment to the struct and its field to improve documentation:

+// AuthQueryClientMock mocks the QueryClient interface for testing purposes.
 type AuthQueryClientMock struct {
+	// GetAccountFunc mocks the GetAccount method. If set, it will be called instead of the default implementation.
 	GetAccountFunc func(ctx context.Context, address string) (*authtypes.QueryAccountResponse, error)
 }

15-20: Solid mock implementation with room for enhancement.

The GetAccount method implementation is correct and follows good mocking practices. It delegates to the mock function when set and panics with a clear message when not set.

Consider enhancing the mock to return a default error instead of panicking when GetAccountFunc is not set. This can make tests more robust and easier to debug:

 func (m *AuthQueryClientMock) GetAccount(ctx context.Context, address string) (*authtypes.QueryAccountResponse, error) {
 	if m.GetAccountFunc != nil {
 		return m.GetAccountFunc(ctx, address)
 	}
-	panic("GetAccountFunc has not been mocked")
+	return nil, fmt.Errorf("GetAccountFunc has not been mocked")
 }

Don't forget to add the fmt import if you make this change.

domain/mocks/keyring.go (1)

15-19: LGTM: Well-designed mock struct with a minor suggestion.

The Keyring struct is well-designed for flexible mocking of the keyring.Keyring interface. Each function field corresponds to a method in the interface, allowing easy customization of mock behavior in tests.

Consider adding comments to each field explaining their purpose and expected return types. This would improve the readability and maintainability of the code. For example:

type Keyring struct {
    // GetKeyFunc returns a mock secp256k1 private key
    GetKeyFunc     func() secp256k1.PrivKey
    // GetAddressFunc returns a mock account address
    GetAddressFunc func() sdk.AccAddress
    // GetPubKeyFunc returns a mock public key
    GetPubKeyFunc  func() cryptotypes.PubKey
}
domain/mocks/txfees_client.go (3)

13-20: LGTM: TxFeesQueryClient struct is well-designed for mocking.

The TxFeesQueryClient struct is well-designed with function fields corresponding to each method in the txfeestypes.QueryClient interface. This approach allows for flexible mocking of individual methods.

Consider adding a comment above the struct to briefly explain its purpose and usage in tests. For example:

// TxFeesQueryClient is a mock implementation of txfeestypes.QueryClient.
// It allows for custom implementations of each method to be provided for testing.
type TxFeesQueryClient struct {
    // ... existing fields ...
}

22-34: LGTM: FeeTokens and DenomSpotPrice methods are correctly implemented.

Both methods follow a consistent and appropriate pattern for mock implementations. They correctly use the function fields and pass through all parameters.

Consider using a helper function to reduce code duplication across all methods. For example:

func callOrPanic(f interface{}, args ...interface{}) []interface{} {
    if f == nil {
        panic("unimplemented")
    }
    return reflect.ValueOf(f).Call(reflectArgs(args))
}

func (m *TxFeesQueryClient) FeeTokens(ctx context.Context, in *txfeestypes.QueryFeeTokensRequest, opts ...grpc.CallOption) (*txfeestypes.QueryFeeTokensResponse, error) {
    res := callOrPanic(m.FeeTokensFunc, ctx, in, opts)
    return res[0].(*txfeestypes.QueryFeeTokensResponse), res[1].(error)
}

This would make the code more DRY and easier to maintain.


50-55: LGTM: GetEipBaseFee method is correctly implemented.

The GetEipBaseFee method maintains the consistent implementation pattern seen in the other methods. It correctly uses the function field and passes through all parameters.

To improve the overall quality and maintainability of the mock, consider the following suggestions:

  1. Implement the helper function as suggested in previous comments to reduce code duplication.
  2. Add error handling to prevent panics in production code. For example:
func (m *TxFeesQueryClient) GetEipBaseFee(ctx context.Context, in *txfeestypes.QueryEipBaseFeeRequest, opts ...grpc.CallOption) (*txfeestypes.QueryEipBaseFeeResponse, error) {
    if m.GetEipBaseFeeFunc == nil {
        return nil, errors.New("GetEipBaseFee: unimplemented")
    }
    return m.GetEipBaseFeeFunc(ctx, in, opts...)
}
  1. Consider adding a NewTxFeesQueryClient() function that returns a TxFeesQueryClient with default (no-op) implementations for all methods. This would make it easier to use the mock in tests where only specific methods need to be overridden.

These changes would make the mock more robust and easier to use in various testing scenarios.

domain/mocks/txservice_client.go (1)

13-23: Well-structured mock client with room for minor improvement.

The ServiceClient struct is well-designed, with function fields corresponding to each method in the txtypes.ServiceClient interface. This approach allows for flexible mocking of individual methods, which is excellent for testing various scenarios.

To further enhance the code:

Consider adding a comment above the struct definition to briefly explain its purpose and usage. For example:

// ServiceClient is a mock implementation of txtypes.ServiceClient.
// It allows for custom implementations of each method to be set for testing purposes.
type ServiceClient struct {
    // ... (existing fields)
}

This addition would provide quick context for developers using this mock in their tests.

domain/cosmos/auth/types/types.go (1)

1-77: Add unit tests for the GetAccount method

To ensure the correctness and reliability of the GetAccount method, consider adding unit tests that cover both successful responses and error scenarios.

🧰 Tools
🪛 GitHub Check: test_prices

[failure] 43-43:
undefined: http.Get

🪛 GitHub Check: test_routes

[failure] 43-43:
undefined: http.Get

🪛 GitHub Check: Run linter

[failure] 1-1:
: # github.com/osmosis-labs/sqs/domain/cosmos/auth/types


[failure] 43-43:
undefined: http.Get (typecheck)


[failure] 43-43:
undefined: http.Get) (typecheck)

🪛 GitHub Check: test_coingecko_prices

[failure] 43-43:
undefined: http.Get

🪛 GitHub Check: test

[failure] 43-43:
undefined: http.Get

domain/cosmos/tx/tx.go (2)

121-121: Remove unnecessary // nolint directive

At line 121:

// nolint

This nolint comment is not suppressing any specific linter warnings and may be unnecessary.

Consider removing it or specifying the linter directive if it serves a particular purpose.


144-145: Reevaluate the gas adjustment factor

In SimulateMsgs, you set the gas adjustment factor to 1.05:

txFactory = txFactory.WithGasAdjustment(1.05)

A 5% adjustment might be insufficient for fluctuating gas consumption. Consider increasing the adjustment factor to provide a more robust buffer.

For example:

-txFactory = txFactory.WithGasAdjustment(1.05)
+txFactory = txFactory.WithGasAdjustment(1.2)

This sets a 20% gas adjustment to accommodate variations.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e9a5865 and 3e1d5a2.

⛔ Files ignored due to path filters (3)
  • domain/cosmos/auth/types/types_test.go is excluded by !**/*_test.go
  • domain/cosmos/tx/export_test.go is excluded by !**/*_test.go
  • domain/cosmos/tx/tx_test.go is excluded by !**/*_test.go
📒 Files selected for processing (6)
  • domain/cosmos/auth/types/types.go (1 hunks)
  • domain/cosmos/tx/tx.go (1 hunks)
  • domain/mocks/auth.go (1 hunks)
  • domain/mocks/keyring.go (1 hunks)
  • domain/mocks/txfees_client.go (1 hunks)
  • domain/mocks/txservice_client.go (1 hunks)
🧰 Additional context used
🪛 GitHub Check: test_prices
domain/cosmos/auth/types/types.go

[failure] 43-43:
undefined: http.Get

🪛 GitHub Check: test_routes
domain/cosmos/auth/types/types.go

[failure] 43-43:
undefined: http.Get

🪛 GitHub Check: Run linter
domain/cosmos/auth/types/types.go

[failure] 1-1:
: # github.com/osmosis-labs/sqs/domain/cosmos/auth/types


[failure] 43-43:
undefined: http.Get (typecheck)


[failure] 43-43:
undefined: http.Get) (typecheck)

domain/mocks/auth.go

[failure] 6-6:
could not import github.com/osmosis-labs/sqs/domain/cosmos/auth/types (-: # github.com/osmosis-labs/sqs/domain/cosmos/auth/types

🪛 GitHub Check: test_coingecko_prices
domain/cosmos/auth/types/types.go

[failure] 43-43:
undefined: http.Get

🪛 GitHub Check: test
domain/cosmos/auth/types/types.go

[failure] 43-43:
undefined: http.Get

🪛 GitHub Check: build
domain/cosmos/tx/tx.go

[failure] 7-7:
no required module provides package github.com/osmosis-labs/sqs/delivery/grpc; to add it:

🔇 Additional comments (13)
domain/mocks/auth.go (2)

9-9: Excellent use of compile-time interface check.

The use of a blank identifier to verify that AuthQueryClientMock satisfies the authtypes.QueryClient interface is a good practice. It ensures type compatibility at compile-time without incurring any runtime cost.


1-7: ⚠️ Potential issue

Verify the import path for the custom authtypes package.

The linter is unable to resolve the import for github.com/osmosis-labs/sqs/domain/cosmos/auth/types. This could be due to the package not being in the expected location or a misconfiguration in the project structure.

To verify the package location and structure, run the following script:

If the package is not found or the QueryClient interface is not defined, you may need to create the package or adjust the import path.

✅ Verification successful

Import path for authtypes is correct and resolvable.

The github.com/osmosis-labs/sqs/domain/cosmos/auth/types package exists and contains the necessary QueryClient interface. No issues found with the import.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and structure of the authtypes package

# Test 1: Check if the package directory exists
echo "Checking for package directory:"
fd -t d -p "domain/cosmos/auth/types$"

# Test 2: List Go files in the package directory
echo "Listing Go files in the package directory:"
fd -e go -p "domain/cosmos/auth/types"

# Test 3: Check for QueryClient interface definition
echo "Searching for QueryClient interface definition:"
rg --type go "type QueryClient interface" -A 5

Length of output: 989

🧰 Tools
🪛 GitHub Check: Run linter

[failure] 6-6:
could not import github.com/osmosis-labs/sqs/domain/cosmos/auth/types (-: # github.com/osmosis-labs/sqs/domain/cosmos/auth/types

domain/mocks/keyring.go (3)

1-11: LGTM: Package declaration and imports are appropriate.

The package name 'mocks' is suitable for a mock implementation. All imports are relevant to the functionality being implemented, and there are no unused imports.


13-13: LGTM: Proper interface assertion.

The interface assertion var _ keyring.Keyring = &Keyring{} is a good practice. It ensures at compile-time that the Keyring struct implements the keyring.Keyring interface.


1-45: Summary of review for domain/mocks/keyring.go

Overall, this file provides a good foundation for a mock Keyring implementation. The use of function fields for flexible mocking is a strong point. However, there are several areas for improvement:

  1. Add comments to struct fields for better documentation.
  2. Enhance error handling in mock methods, possibly returning errors instead of panicking.
  3. Improve the GenPrivKey method by handling errors, validating input, and aligning it with the mock pattern used in other methods.
  4. Consider adding unit tests for this mock implementation to ensure its correctness and catch any regressions in future changes.

Addressing these points will significantly improve the robustness and maintainability of this mock implementation.

domain/mocks/txfees_client.go (3)

1-9: LGTM: Package declaration and imports are appropriate.

The package name mocks is suitable for a mock implementation, and the imports are relevant to the functionality being implemented.


11-11: Excellent: Interface implementation check is in place.

The line var _ txfeestypes.QueryClient = &TxFeesQueryClient{} ensures at compile-time that TxFeesQueryClient implements the txfeestypes.QueryClient interface. This is a crucial check that prevents potential runtime errors due to incomplete interface implementation.


36-48: LGTM: DenomPoolId and BaseDenom methods are correctly implemented.

These methods maintain the consistent implementation pattern seen in the previous methods. They correctly use the function fields and pass through all parameters.

As mentioned in the previous comment, consider using a helper function to reduce code duplication across all methods. This suggestion applies to these methods as well.

domain/mocks/txservice_client.go (3)

1-9: LGTM: Package declaration and imports are appropriate.

The package name mocks is suitable for this mock implementation. The imports are relevant and correctly include the necessary packages for the mock's functionality. The use of an alias for txtypes is a good practice for clarity.


11-11: Excellent use of compile-time interface check.

The line var _ txtypes.ServiceClient = &ServiceClient{} is a valuable compile-time check. It ensures that the ServiceClient struct implements all methods required by the txtypes.ServiceClient interface. This practice helps catch any discrepancies early in the development process.


1-86: Overall, well-implemented mock with room for enhancements.

This mock implementation of txtypes.ServiceClient is well-structured, consistent, and serves its purpose effectively. The use of function fields for each method allows for flexible mocking, and the compile-time interface check ensures completeness.

To recap the main suggestions for improvement:

  1. Add a descriptive comment for the ServiceClient struct to explain its purpose and usage.
  2. Enhance the mock's flexibility by returning errors instead of panicking for unimplemented methods.
  3. Implement a call tracking mechanism to allow for more comprehensive testing scenarios.

These enhancements would make the mock more robust, safer to use, and provide additional capabilities for thorough testing.

Great job on implementing this mock! With these suggested improvements, it will become an even more valuable tool for testing the system's interaction with the Cosmos SDK transaction service.

domain/cosmos/tx/tx.go (2)

81-87: Verify signing parameters and avoid redundancy

When signing the transaction:

signed, err := txclient.SignWithPrivKey(
	ctx,
	signingtypes.SignMode_SIGN_MODE_DIRECT, signerData,
	txBuilder, privKey, encodingConfig.TxConfig, account.Sequence)

Ensure that the account.Sequence used here matches the one used in building the transaction. Also, since SignWithPrivKey sets the signature, there's no need to set it again unless modifications are made afterward.


208-209: Ensure accurate fee calculation

In CalculateFeeAmount:

return baseFee.MulInt64(int64(gas)).Ceil().TruncateInt()

Using both Ceil() and TruncateInt() might introduce rounding issues. Verify that this calculation accurately reflects the intended fee without precision loss.

You might simplify the calculation:

-return baseFee.MulInt64(int64(gas)).Ceil().TruncateInt()
+return baseFee.MulInt64(int64(gas)).Ceil().RoundInt()

Using RoundInt() ensures proper rounding.

domain/mocks/keyring.go Outdated Show resolved Hide resolved
domain/mocks/txservice_client.go Outdated Show resolved Hide resolved
domain/cosmos/auth/types/types.go Outdated Show resolved Hide resolved
domain/cosmos/auth/types/types.go Outdated Show resolved Hide resolved
domain/cosmos/auth/types/types.go Outdated Show resolved Hide resolved
domain/cosmos/tx/tx.go Outdated Show resolved Hide resolved
domain/cosmos/tx/tx.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: 12

🧹 Outside diff range and nitpick comments (7)
domain/mocks/auth.go (2)

22-26: Excellent helper method for mock setup.

The WithGetAccount method is a great addition for easy mock setup in tests. It follows a fluent interface pattern, which enhances readability in test code.

Consider returning the mock instance to allow method chaining:

-func (m *AuthQueryClientMock) WithGetAccount(response *authtypes.QueryAccountResponse, err error) {
+func (m *AuthQueryClientMock) WithGetAccount(response *authtypes.QueryAccountResponse, err error) *AuthQueryClientMock {
 	m.GetAccountFunc = func(ctx context.Context, address string) (*authtypes.QueryAccountResponse, error) {
 		return response, err
 	}
+	return m
 }

This change would allow for more concise test setup when multiple mock methods are added in the future.


1-26: Overall, well-implemented mock for QueryClient.

The AuthQueryClientMock provides a solid foundation for mocking the QueryClient interface. It follows good practices for Go mocks and offers flexibility in test setups. The suggested improvements (handling unmocked cases without panicking and enabling method chaining) would further enhance its usability.

As this is part of a new feature (BE-594/domain/cosmos), ensure that comprehensive tests are written to validate the behavior of systems using this mock.

Would you like assistance in writing test cases that demonstrate the usage of this mock?

🧰 Tools
🪛 GitHub Check: Run linter

[failure] 6-6:
could not import github.com/osmosis-labs/sqs/domain/cosmos/auth/types (-: # github.com/osmosis-labs/sqs/domain/cosmos/auth/types

domain/mocks/gas_calculator.go (2)

9-11: LGTM: GasCalculator struct is well-defined.

The GasCalculator struct is clear and flexible. The CalculateGasFunc field allows for easy customization of the mock's behavior.

Consider adding a comment to explain the purpose of the GasCalculator struct and its CalculateGasFunc field. This would improve the code's documentation and make it easier for other developers to understand and use this mock.


21-25: LGTM: WithCalculateGas method is well-implemented.

The WithCalculateGas method provides a clean way to configure the mock's behavior. Its implementation is correct and follows common patterns for mock objects.

Consider adding a comment to explain that this method is used for setting up the mock's behavior in tests. For example:

// WithCalculateGas configures the mock to return the specified response, gas amount, and error
// when CalculateGas is called. This method is typically used in test setup.
func (m *GasCalculator) WithCalculateGas(response *txtypes.SimulateResponse, n uint64, err error) {
    // ... (existing implementation)
}
domain/cosmos/tx/gas.go (1)

17-21: Consider renaming clientCtx to conn for clarity

The parameter and struct field clientCtx could be misleading, as it's of type gogogrpc.ClientConn, not a client context. Renaming it to conn or grpcConn can improve readability.

Apply the following changes:

  • In NewGasCalculator function (Lines 17-21):

    -func NewGasCalculator(clientCtx gogogrpc.ClientConn) GasCalculator {
    -	return &TxGasCalculator{
    -		clientCtx: clientCtx,
    +func NewGasCalculator(conn gogogrpc.ClientConn) GasCalculator {
    +	return &TxGasCalculator{
    +		conn: conn,
    	}
    }
  • In TxGasCalculator struct (Line 25):

    -	clientCtx gogogrpc.ClientConn
    +	conn gogogrpc.ClientConn
  • In CalculateGas method (Line 34):

    -		c.clientCtx,
    +		c.conn,

Also applies to: 25-25, 34-34

domain/mocks/txservice_client.go (1)

13-23: Add documentation comments to the struct and its fields for better clarity.

Including GoDoc comments for the TxServiceClient struct and its function fields will enhance readability and maintainability. This helps other developers understand the purpose and usage of each method in the mock client.

Example:

// TxServiceClient is a mock implementation of txtypes.ServiceClient for testing purposes.
// Customize behaviors by setting the function fields accordingly.
type TxServiceClient struct {
    // SimulateFunc simulates a transaction without broadcasting.
    SimulateFunc func(ctx context.Context, in *txtypes.SimulateRequest, opts ...grpc.CallOption) (*txtypes.SimulateResponse, error)
    // GetTxFunc retrieves a transaction by hash.
    GetTxFunc func(ctx context.Context, in *txtypes.GetTxRequest, opts ...grpc.CallOption) (*txtypes.GetTxResponse, error)
    // BroadcastTxFunc broadcasts a transaction to the network.
    BroadcastTxFunc func(ctx context.Context, in *txtypes.BroadcastTxRequest, opts ...grpc.CallOption) (*txtypes.BroadcastTxResponse, error)
    // Add comments for other function fields...
}
domain/cosmos/tx/tx.go (1)

143-152: Consider handling multiple signatures

The BuildSignatures function is designed for single signatures:

func BuildSignatures(publicKey cryptotypes.PubKey, signature []byte, sequence uint64) signingtypes.SignatureV2 {
    return signingtypes.SignatureV2{
        PubKey: publicKey,
        Data: &signingtypes.SingleSignatureData{
            SignMode:  signingtypes.SignMode_SIGN_MODE_DIRECT,
            Signature: signature,
        },
        Sequence: sequence,
    }
}

If you plan to support multi-signature accounts in the future, consider implementing support for MultiSignatureData to make your code more extensible.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3e1d5a2 and 6cf8649.

⛔ Files ignored due to path filters (1)
  • domain/cosmos/tx/tx_test.go is excluded by !**/*_test.go
📒 Files selected for processing (7)
  • domain/cosmos/tx/gas.go (1 hunks)
  • domain/cosmos/tx/tx.go (1 hunks)
  • domain/mocks/auth.go (1 hunks)
  • domain/mocks/gas_calculator.go (1 hunks)
  • domain/mocks/keyring.go (1 hunks)
  • domain/mocks/txfees_client.go (1 hunks)
  • domain/mocks/txservice_client.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • domain/mocks/txfees_client.go
🧰 Additional context used
🪛 GitHub Check: Run linter
domain/mocks/auth.go

[failure] 6-6:
could not import github.com/osmosis-labs/sqs/domain/cosmos/auth/types (-: # github.com/osmosis-labs/sqs/domain/cosmos/auth/types

🔇 Additional comments (13)
domain/mocks/auth.go (3)

9-9: Excellent use of interface compliance check.

The use of a blank identifier with type assertion var _ authtypes.QueryClient = &AuthQueryClientMock{} is a great practice. It ensures at compile-time that AuthQueryClientMock implements the authtypes.QueryClient interface.


11-13: Well-designed mock struct.

The AuthQueryClientMock struct is well-designed with a function field GetAccountFunc. This approach allows for flexible mocking of the GetAccount method in tests.


1-7: Verify the import path for the authtypes package.

The static analysis tool reported an issue with importing the authtypes package. This could be due to the package not being present in the expected location or a misconfiguration in the project structure.

Please ensure that the authtypes package exists at the specified path. You can run the following command to verify the package location:

If the package is not found, you may need to create it or adjust the import path.

Would you like assistance in creating the authtypes package or adjusting the import path?

✅ Verification successful

Import Path Verified.

The authtypes package exists at the specified path and contains the necessary Go files.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence of the authtypes package

# Test: Check if the package directory exists
fd -t d "auth/types$" --full-path ./domain/cosmos

# Test: Check for Go files in the package
fd -e go . --full-path ./domain/cosmos/auth/types

Length of output: 208

🧰 Tools
🪛 GitHub Check: Run linter

[failure] 6-6:
could not import github.com/osmosis-labs/sqs/domain/cosmos/auth/types (-: # github.com/osmosis-labs/sqs/domain/cosmos/auth/types

domain/mocks/gas_calculator.go (2)

1-7: LGTM: Package declaration and imports are correct.

The package name mocks is appropriate for this mock implementation, and the imports from the Cosmos SDK are relevant to the file's purpose.


1-25: Overall, the GasCalculator mock is well-implemented.

The GasCalculator mock provides a flexible way to simulate gas calculations in tests. The implementation follows good practices for mock objects and allows for easy configuration of behavior.

Key points:

  1. The struct and method signatures are appropriate for the intended use.
  2. The WithCalculateGas method provides a clean way to set up the mock's behavior.
  3. Error handling in the CalculateGas method could be improved (see previous comment).
  4. Additional comments would enhance the code's documentation.

These suggested improvements are minor and don't affect the core functionality. The implementation is solid and ready for use in tests.

domain/mocks/keyring.go (3)

1-11: LGTM: Package declaration and imports are appropriate.

The package name "mocks" is suitable for a mock implementation, and the imports include necessary packages for the Keyring functionality.


13-19: LGTM: Keyring struct and interface assertion are well-defined.

The interface assertion on line 13 is a good practice to ensure the mock implements the required keyring.Keyring interface. The Keyring struct with function fields allows for flexible mocking of different methods.


1-57: Overall assessment: Good mock implementation with room for improvement.

The Keyring mock implementation provides a good foundation for testing. However, there are several areas where it can be improved:

  1. Consistent error handling across all methods instead of panicking.
  2. Use of a custom error type for unimplemented methods.
  3. Alignment of the GenPrivKey method with the mock pattern used in other methods.
  4. Proper error handling and input validation in the GenPrivKey method.

Implementing these suggestions will result in a more robust and consistent mock implementation, enhancing its usefulness in testing scenarios.

domain/mocks/txservice_client.go (1)

25-92: Avoid panicking in mock methods; return errors instead.

Panicking when a method is unimplemented can cause unexpected test failures. Returning a default error makes the mock safer and more flexible in tests where not all methods are needed.

Refer to the previous review comment by coderabbitai[bot] for a suggested refactoring to return errors and optionally track method calls.

domain/cosmos/tx/tx.go (4)

87-90: Handle potential errors when setting final signatures

After signing the transaction, the signatures are set:

err = txBuilder.SetSignatures(signed)
if err != nil {
    return nil, err
}

Ensure that the error handling here is appropriate. If txBuilder.SetSignatures(signed) fails, consider logging the error or providing more context to aid debugging.


127-127: Review the gas adjustment factor

The gas adjustment factor is set to 1.05:

txFactory = txFactory.WithGasAdjustment(1.05)

Ensure that this factor is sufficient for your application's needs. Depending on network conditions, a higher adjustment may be necessary to prevent transactions from failing due to underestimating gas.


164-180: Check for fee calculation errors and provide fallback options

In CalculateFeeCoin, errors from querying base denomination or base fee result in returning an empty coin and error:

if err != nil {
    return sdk.Coin{}, err
}

Consider providing a fallback fee or defaulting to a standard fee if the query fails. This enhances the robustness of your application by allowing transactions to proceed even if the fee query encounters issues.


185-185: ⚠️ Potential issue

Handle potential overflow in fee amount calculation

In CalculateFeeAmount, the fee amount is calculated:

return baseFee.MulInt64(int64(gas)).Ceil().TruncateInt()

Ensure that the multiplication does not cause an integer overflow, especially if gas values are large.

Run the following script to verify the maximum gas limit used in the codebase:

domain/mocks/auth.go Outdated Show resolved Hide resolved
domain/mocks/gas_calculator.go Show resolved Hide resolved
domain/mocks/keyring.go Show resolved Hide resolved
domain/mocks/keyring.go Show resolved Hide resolved
domain/mocks/keyring.go Show resolved Hide resolved
domain/mocks/txservice_client.go Show resolved Hide resolved
domain/cosmos/tx/tx.go Show resolved Hide resolved
domain/cosmos/tx/tx.go Show resolved Hide resolved
domain/cosmos/tx/tx.go Show resolved Hide resolved
domain/cosmos/tx/tx.go Show resolved Hide resolved
domain/cosmos/tx/tx.go Outdated Show resolved Hide resolved
Comment on lines 36 to 43
// QueryAccountResponse encapsulates the response for an account query.
type QueryAccountResponse struct {
Account Account `json:"account"`
}

// GetAccount retrieves account information for a given address.
func (c *queryClient) GetAccount(ctx context.Context, address string) (*QueryAccountResponse, error) {
resp, err := http.Get(ctx, c.lcd+"/cosmos/auth/v1beta1/accounts/"+address)
Copy link
Member

Choose a reason for hiding this comment

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

I'm also curious if we could rely more on cosmos SDK client helpers, potentially minimizing reimplementation.

Please take a look at this CosmosSender for inspiration:
https://github.com/polaris-portal/polaris/blob/ebafb78bf432380072c9f74a433cf61e7336ed83/app/gasstation/senders/cosmos.go#L46

Copy link
Collaborator Author

@deividaspetraitis deividaspetraitis Oct 17, 2024

Choose a reason for hiding this comment

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

Yes! Great point, thanks! I have also got rid of HTTP, and switched to gRPC, it was a bit unclear how to fill all the fields for BaseAccount, leaving some fields not filled would make this client really confusing.

After the changes our local implementation is a wrapper around QueryClient, that in turn required me to pull in encodingConfig to be able to unpack response.

Let me know if that makes sense!

Copy link

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

🧹 Outside diff range and nitpick comments (1)
domain/cosmos/auth/types/types.go (1)

54-54: Include the actual account type in the error message for better debugging

Enhancing the error message by including the actual type received can help with debugging when the type assertion fails.

Apply this diff:

-return nil, fmt.Errorf("account is not of the type of BaseAccount")
+return nil, fmt.Errorf("account is not of type *BaseAccount, got %T", account)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6cf8649 and 6c45d4c.

⛔ Files ignored due to path filters (1)
  • domain/cosmos/tx/tx_test.go is excluded by !**/*_test.go
📒 Files selected for processing (3)
  • domain/cosmos/auth/types/types.go (1 hunks)
  • domain/cosmos/tx/tx.go (1 hunks)
  • domain/mocks/auth.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • domain/cosmos/tx/tx.go
  • domain/mocks/auth.go
🧰 Additional context used

domain/cosmos/auth/types/types.go Show resolved Hide resolved
domain/cosmos/auth/types/types.go Show resolved Hide resolved
domain/cosmos/auth/types/types.go Show resolved Hide resolved
@deividaspetraitis deividaspetraitis merged commit 29cdce6 into v26.x Oct 22, 2024
9 checks passed
@deividaspetraitis deividaspetraitis deleted the BE-594/domain/cosmos branch October 22, 2024 06:45
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