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

feat: add GetStatus to tmclient #247

Merged
merged 1 commit into from
Sep 30, 2024
Merged

feat: add GetStatus to tmclient #247

merged 1 commit into from
Sep 30, 2024

Conversation

proofofze
Copy link
Contributor

@proofofze proofofze commented Sep 30, 2024

This PR adds a method to tmClient that lets callers get the status of the Tendermint node

Copy link

coderabbitai bot commented Sep 30, 2024

Walkthrough

The pull request introduces significant enhancements to the Cosmos SDK keyring management, including the addition of a new keyring helper, error handling improvements, and updates to the testing framework. The workflow for running tests has been modified to include GPG key setup and password management. Additionally, various files have been created or updated to support the new functionalities, including error definitions and configuration options for the keyring.

Changes

Files Change Summary
.github/workflows/run-tests.yml Added steps for GPG key setup and password manager installation.
.pre-commit-config.yaml Updated exclude patterns to broaden scope of excluded files.
auth_vote/authz_vote.go Removed redundant error check after tmClient initialization.
client/keyring/README.md Introduced a new keyring helper for the Cosmos SDK with flexible configuration options.
client/keyring/errors.go Added error variables for keyring operation failures.
client/keyring/key_config.go Introduced a struct for keyring configuration with functional options.
client/keyring/keyring.go Implemented keyring management functions and validation logic.
client/keyring/keyring_config.go Defined configuration structure and options for the keyring.
client/keyring/keyring_errors_test.go Added unit tests for keyring error handling scenarios.
client/keyring/keyring_test.go Established a test suite for keyring functionalities.
client/keyring/testdata/... Introduced new test data files related to JWT tokens and hashes.
client/tm/tmclient.go Added GetStatus method to the TendermintClient interface.
go.mod Updated dependencies and added a new direct dependency on github.com/cosmos/go-bip39.

Possibly related PRs

Suggested reviewers

  • aarmoa
  • kakysha
  • albertchon

🐰 In the meadow, where the bunnies play,
A keyring helper hops in, brightening the day!
With GPG keys and passwords, oh what a sight,
Managing secrets, making it right!
Errors caught, tests run with glee,
In the land of code, it's a jubilee! 🎉


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 92ece76 and 1ef066b.

📒 Files selected for processing (17)
  • .github/workflows/run-tests.yml (1 hunks)
  • .pre-commit-config.yaml (1 hunks)
  • auth_vote/authz_vote.go (0 hunks)
  • client/keyring/README.md (1 hunks)
  • client/keyring/errors.go (1 hunks)
  • client/keyring/key_config.go (1 hunks)
  • client/keyring/keyring.go (1 hunks)
  • client/keyring/keyring_config.go (1 hunks)
  • client/keyring/keyring_errors_test.go (1 hunks)
  • client/keyring/keyring_test.go (1 hunks)
  • client/keyring/testdata/keyring-file/263117aad9ebf5759a8272ad2ae4968dd12d4602.address (1 hunks)
  • client/keyring/testdata/keyring-file/310322fcb0937ade77a9ba0d128f9e7f17312796.address (1 hunks)
  • client/keyring/testdata/keyring-file/keyhash (1 hunks)
  • client/keyring/testdata/keyring-file/test.info (1 hunks)
  • client/keyring/testdata/keyring-file/test2.info (1 hunks)
  • client/tm/tmclient.go (2 hunks)
  • go.mod (1 hunks)
💤 Files with no reviewable changes (1)
  • auth_vote/authz_vote.go
✅ Files skipped from review due to trivial changes (1)
  • client/keyring/testdata/keyring-file/test.info
🧰 Additional context used
🪛 LanguageTool
client/keyring/README.md

[style] ~3-~3: The phrase “a variety of” may be wordy. To make your writing clearer, consider replacing it.
Context: ...ring Helper Creates a new keyring from a variety of options. See ConfigOpt and related op...

(A_VARIETY_OF)


[grammar] ~24-~24: Did you mean “having to alias” or “having aliased”?
Context: ...ds a single key to the keyring, without having alias name. * WithNamedKey addes a single k...

(WITHOUT_VBG_VB)


[uncategorized] ~62-~62: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... WithKeyFrom("sender"), ), ) ``` Real world use case of keyring initialization from...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

🪛 Gitleaks
client/keyring/keyring_test.go

285-285: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


286-286: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (19)
client/keyring/testdata/keyring-file/keyhash (1)

1-1: LGTM. Consider adding context for the hash.

The addition of this bcrypt hash for test purposes is appropriate. The hash uses a secure format with a cost factor of 10, which is suitable for testing scenarios.

Consider adding a comment at the top of the file to provide context about what this hash represents and how it's used in tests. This will improve maintainability and make it easier for other developers to understand its purpose.

Let's verify if this hash is used in corresponding test cases:

This will help ensure that the hash is properly utilized in the test suite.

client/keyring/testdata/keyring-file/263117aad9ebf5759a8272ad2ae4968dd12d4602.address (1)

1-1: LGTM. Consider documenting the test data and verifying the creation date.

The JWT structure looks correct and uses strong encryption methods, which is good. However, I have a few suggestions:

  1. The creation date in the JWT is set to September 7, 2024, which is in the future. While this might be intentional for testing purposes, it's worth verifying to ensure it aligns with the test requirements.

  2. Consider adding a comment or separate documentation file explaining the purpose of this test data, including what it represents and how it should be used in tests. This will help other developers understand its significance and how to maintain it.

To check if there's any existing documentation for this test data, you can run:

If no documentation is found, consider adding some to explain the purpose and usage of this test data.

client/keyring/testdata/keyring-file/310322fcb0937ade77a9ba0d128f9e7f17312796.address (1)

1-1: LGTM with some considerations

The JWT structure looks correct and uses strong encryption algorithms (PBES2-HS256+A128KW for key wrapping and A256GCM for encryption). However, please consider the following points:

  1. The creation date in the JWT is set to 2024, which is in the future. While this might be intentional for testing purposes, ensure that your code handles future dates correctly to avoid any potential issues.

  2. As this file is in a testdata directory, please confirm that it doesn't contain any real, sensitive information. It's crucial to use mock data for testing to prevent accidental exposure of sensitive data.

  3. The filename (310322fcb0937ade77a9ba0d128f9e7f17312796.address) appears to be a hexadecimal string. Could you verify its purpose and ensure it aligns with the intended use in your tests?

To ensure this file is only used for testing purposes, you can run the following command:

If this command returns any results, please review those occurrences to ensure the test data isn't being used in production code.

.pre-commit-config.yaml (1)

5-6: LGTM: Exclusion of test data files is appropriate.

The addition of client/keyring/testdata/.* to the exclude section is a good practice. This prevents pre-commit hooks from running on test data files, which often don't need to adhere to the same formatting or linting rules as production code.

client/keyring/testdata/keyring-file/test2.info (1)

1-1: Verify the "created" date in the JWT header

The JWT header contains a creation date set in the future: "2024-09-07". This might cause issues with date-sensitive operations in your tests or actual implementation. Consider updating it to a more recent or static date for consistency in test results.

To confirm this observation, you can run the following command:

.github/workflows/run-tests.yml (1)

18-24: Clarify the purpose of GPG and password management additions.

The workflow now includes steps for setting up GPG keys and a password manager before running tests. While these additions enhance the workflow's cryptographic capabilities, it's not clear why they are necessary or how they relate to the tests.

Could you please provide some context on:

  1. Why GPG keys and a password manager are needed for running tests?
  2. How these new steps relate to the changes in the application being tested?
  3. Are there any new environment variables or secrets that need to be set up for these steps to work correctly?

This information will help ensure that the workflow changes align with the project's needs and that all necessary configurations are in place.

client/keyring/errors.go (1)

1-3: LGTM: Package declaration and import statement are correct.

The package name "keyring" is appropriate for the functionality it provides, and the import of "github.com/pkg/errors" is correct and commonly used for error handling in Go.

client/keyring/key_config.go (2)

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

The package name keyring is suitable for the functionality provided. The imports for bip39 and errors are relevant and correctly specified.


1-69: Overall assessment: Good design with some security improvements needed.

The key_config.go file introduces a well-designed keyring configuration system using the functional options pattern, which provides good flexibility. The code is generally well-structured and follows Go conventions.

Key points:

  1. The use of functional options is a good practice for configuration.
  2. Mnemonic validation is a positive security measure.
  3. Security warnings for insecure options are present but could be more prominent.
  4. There's room for improvement in handling sensitive data and preventing insecure options in production.

Please address the suggestions in the previous comments to enhance the overall security and robustness of this module.

client/tm/tmclient.go (3)

21-21: LGTM: New method added to the interface

The GetStatus method is a good addition to the TendermintClient interface. It follows the existing naming conventions and method signatures, and it provides a way to query the node's status, which can be useful for monitoring and diagnostics.


21-21: Summary of changes

The addition of the GetStatus method to both the TendermintClient interface and its implementation in tmClient is a valuable enhancement. It provides a clean way to query the node's status, which can be useful for monitoring and diagnostics. The implementation is consistent with existing patterns in the codebase.

Key points:

  1. The interface addition is well-designed and follows existing conventions.
  2. The implementation is straightforward and correct.
  3. A minor suggestion was made to improve the method's documentation.
  4. It's recommended to verify the usage of this new method in the broader codebase.

Overall, these changes improve the functionality of the Tendermint client without introducing any breaking changes.

Also applies to: 94-97


21-21: Verify usage of the new GetStatus method

The addition of the GetStatus method enhances the TendermintClient interface and its implementation. To ensure it's being utilized effectively:

Let's check if the new method is being used in other parts of the codebase:

If there are no results, consider adding a TODO to utilize this new functionality where appropriate in the codebase.

Also applies to: 94-97

client/keyring/keyring_config.go (5)

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

The package name keyring accurately reflects the functionality, and the import of github.com/pkg/errors is a good choice for error handling.


7-8: Well-designed configuration option pattern.

The ConfigOpt type definition enables a flexible and extensible configuration system. This functional options pattern allows for easy addition of new configuration options in the future without breaking existing code.


20-30: LGTM: Well-defined backend types with clear documentation.

The Backend type and its associated constants are well-defined and documented. This approach enhances type safety and provides clear options for backend selection.


1-120: Overall: Well-designed and implemented keyring configuration system.

This file introduces a comprehensive and flexible keyring configuration system using the functional options pattern. The code is well-structured, follows Go best practices, and includes appropriate error handling.

Key strengths:

  1. Flexible configuration options
  2. Clear separation of concerns
  3. Type-safe backend selection
  4. Robust error handling

Minor suggestions for improvement have been made throughout the review, including:

  1. Adding field comments to the cosmosKeyringConfig struct
  2. Enhancing input validation for WithKeyringBackend
  3. Refactoring key addition functions to reduce duplication
  4. Adding validation for the default key's existence

Overall, this is a solid implementation that provides a strong foundation for keyring management in the application.


110-120: LGTM with suggestion: Default key setter function.

The WithDefaultKey function is implemented correctly, following the established pattern for configuration options.

However, there's no validation to ensure that the specified default key exists in the Keys slice. Consider adding a validation step to check for the key's existence. This could be done during the configuration application phase.

To verify this, we can search for any existing validation logic:

If no validation is found, consider adding a validation step in the configuration application function (which is not visible in the current file).

client/keyring/README.md (1)

37-82: LGTM for Examples section

The Examples section effectively demonstrates various use cases for keyring initialization. The provided code snippets are clear, well-formatted, and cover different scenarios, including:

  1. In-memory keyring with a private key hex
  2. In-memory keyring with a mnemonic phrase
  3. Real-world use case with CLI flags

These examples provide valuable guidance for users implementing the keyring helper in different contexts.

🧰 Tools
🪛 LanguageTool

[uncategorized] ~62-~62: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ... WithKeyFrom("sender"), ), ) ``` Real world use case of keyring initialization from...

(EN_COMPOUND_ADJECTIVE_INTERNAL)

go.mod (1)

21-21: Approve the addition of go-bip39 dependency.

The addition of github.com/cosmos/go-bip39 v1.0.0 is appropriate for implementing BIP39-related functionality, which is commonly used for mnemonic-based key generation in the Cosmos ecosystem.

Please ensure that this new dependency is properly utilized in the codebase. You can run the following command to check its usage:

#!/bin/bash
# Check usage of the new go-bip39 dependency
rg --type go 'github.com/cosmos/go-bip39'

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.

@proofofze proofofze changed the base branch from master to dev September 30, 2024 16:23
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post

Actionable comments posted: 12

🧹 Outside diff range and nitpick comments (30)
.pre-commit-config.yaml (2)

Line range hint 18-18: Consider using a specific version for pre-commit-golang.

Currently, the pre-commit-golang repository is set to use the master branch. This can lead to unexpected changes in behavior if the repository is updated. It's generally a good practice to pin to a specific version or commit hash for better reproducibility and stability.

Consider changing the rev field to a specific version or commit hash. For example:

  -   repo: https://github.com/dnephin/pre-commit-golang
      rev: v0.5.1  # Replace with the latest stable version
      hooks:
        - id: go-fmt
        - id: go-imports
        - id: golangci-lint
          args: [--timeout=15m]

Line range hint 13-14: Remove duplicate end-of-file-fixer hook.

The end-of-file-fixer hook is listed twice under the pre-commit-hooks repository. This is likely an oversight and may cause the hook to run unnecessarily twice.

Remove one of the duplicate entries:

      hooks:
        -   id: trailing-whitespace
        -   id: end-of-file-fixer
-       -   id: end-of-file-fixer
        -   id: check-yaml
client/keyring/testdata/keyring-file/test2.info (1)

1-1: Add a newline at the end of the file

The file currently lacks a newline character at the end. While this doesn't affect the JWT itself, it's a good practice to end text files with a newline. This can prevent issues with certain text processing tools and improves compatibility across different systems.

Consider adding a newline character at the end of the file.

.github/workflows/run-tests.yml (2)

18-19: Remove sudo from the apt-get commands.

GitHub Actions runners already have root privileges, so using sudo is unnecessary and can be removed.

Apply this change:

- run: sudo apt-get update && sudo apt-get install -y pass
+ run: apt-get update && apt-get install -y pass

23-24: Consider using a more appropriate name for the keyring.

The current setup uses keyring_test as the name for both the GPG key and the password store. While this is consistent, it suggests a test environment, which may not be appropriate for a production workflow.

Consider using a more descriptive and production-appropriate name, such as github_actions_keyring or ci_cd_keyring. For example:

- run: pass init keyring_test
+ run: pass init github_actions_keyring

Remember to update the Name-Comment in the GPG key generation step as well to maintain consistency.

client/keyring/errors.go (2)

5-20: LGTM with suggestions: Error variables are well-structured, but some messages could be more specific.

The error variables are correctly defined using errors.New() and are appropriately exported. The messages are generally clear and follow a consistent style. However, some error messages could be more specific or provide more context:

  1. For ErrCosmosKeyringCreationFailed and ErrCosmosKeyringImportFailed, consider adding more context about what might cause these failures.
  2. ErrFilepathIncorrect could be more specific, e.g., "invalid filepath format" or "filepath not found".
  3. ErrHexFormatError could specify what aspect of the hex format is incorrect.
  4. ErrIncompatibleOptionsProvided could benefit from mentioning which options are incompatible.

Consider revising these error messages to provide more specific information, which could aid in debugging and error handling.


1-20: Suggestion: Add comments and documentation to improve code readability.

While the file structure is clean and focused, it would benefit from additional documentation:

  1. Consider adding a package-level comment at the top of the file explaining the purpose of these error definitions.
  2. Add comments for each exported error variable, describing when and why these errors might occur. This is especially important for exported variables in Go.

Example:

// Package keyring provides error definitions for keyring operations.

// ErrCosmosKeyringCreationFailed is returned when the creation of a Cosmos keyring fails.
var ErrCosmosKeyringCreationFailed = errors.New("cosmos keyring creation failed")

// ErrCosmosKeyringImportFailed is returned when importing a key into the Cosmos keyring fails.
var ErrCosmosKeyringImportFailed = errors.New("cosmos keyring unable to import key")

// ... (continue for other error variables)

Adding these comments will improve code readability and make it easier for other developers to understand and use these error definitions correctly.

client/keyring/key_config.go (2)

16-28: LGTM: Good use of functional options pattern.

The KeyConfigOpt type and WithKeyFrom function are well-implemented, using the functional options pattern for flexible configuration. The function correctly handles empty input.

Consider adding more robust input validation for the KeyFrom value. For example, you might want to check for invalid characters or enforce a specific format for key names.


54-69: Good mnemonic validation, but enhance security measures.

The WithMnemonic function includes good practice by validating the mnemonic using bip39.IsMnemonicValid. However, similar to the previous functions, consider the following enhancements:

  1. Make the warning about insecurity more prominent.
  2. Implement a mechanism to prevent this option from being used in production environments.

Here's a suggested improvement:

// WithMnemonic allows to specify a mnemonic phrase as plaintext.
// WARNING: This is an insecure option, use for testing only.
// The package will create a virtual keyring to derive the keys and meet all the interfaces.
func WithMnemonic(v string) KeyConfigOpt {
    return func(c *cosmosKeyConfig) error {
        if runtime.GOOS != "test" {
            return errors.New("WithMnemonic is only allowed in test environments")
        }
        if v != "" {
            if !bip39.IsMnemonicValid(v) {
                return errors.New("provided mnemonic is not a valid BIP39 mnemonic")
            }
            c.Mnemonic = []byte(v)
        }
        return nil
    }
}

This maintains the good practice of mnemonic validation while adding the production usage safeguard and updating to use []byte for the sensitive Mnemonic field.

client/tm/tmclient.go (1)

94-97: LGTM: Implementation looks good with a minor suggestion

The implementation of GetStatus is correct and consistent with other methods in the struct. It properly uses the provided context and directly returns the result from the underlying RPC client.

Consider expanding the comment slightly to provide more context:

-// GetStatus returns the node status.
+// GetStatus returns the status of the Tendermint node, including sync info, validator info, and node info.

This gives users a better idea of what information they can expect from the status call.

client/keyring/keyring_config.go (3)

10-18: LGTM: Comprehensive keyring configuration structure.

The cosmosKeyringConfig struct covers all necessary aspects of keyring configuration, including multiple key management and a default key specification.

Consider adding comments to each field to improve code documentation. For example:

type cosmosKeyringConfig struct {
    // KeyringDir is the directory where the keyring is stored
    KeyringDir     string
    // KeyringAppName is the name of the application using the keyring
    KeyringAppName string
    // KeyringBackend specifies the type of keyring backend to use
    KeyringBackend Backend
    // UseLedger indicates whether to use a hardware wallet
    UseLedger      bool

    // Keys is a slice of key configurations
    Keys       []*cosmosKeyConfig
    // DefaultKey is the name or address of the default key to use
    DefaultKey string
}

32-72: LGTM: Well-implemented configuration options.

The WithKeyringDir, WithKeyringAppName, WithKeyringBackend, and WithUseLedger functions are well-implemented, following the functional options pattern consistently. The empty string checks in relevant functions prevent setting empty values.

Consider adding error returns for invalid inputs, especially for WithKeyringBackend. For example:

func WithKeyringBackend(v Backend) ConfigOpt {
    return func(c *cosmosKeyringConfig) error {
        switch v {
        case BackendTest, BackendFile, BackendOS:
            c.KeyringBackend = v
            return nil
        default:
            return errors.New("invalid keyring backend")
        }
    }
}

This change would provide better input validation and error handling.


74-108: LGTM: Flexible and robust key addition functions.

The WithKey and WithNamedKey functions provide a flexible way to add keys to the configuration, with robust error handling for each key option.

Consider extracting the common logic of these functions to reduce code duplication:

func addKey(c *cosmosKeyringConfig, name string, opts ...KeyConfigOpt) error {
    config := &cosmosKeyConfig{Name: name}

    for optIdx, optFn := range opts {
        if err := optFn(config); err != nil {
            return errors.Wrapf(ErrFailedToApplyKeyConfigOption, "key option #%d: %s", optIdx+1, err.Error())
        }
    }

    c.Keys = append(c.Keys, config)
    return nil
}

func WithKey(opts ...KeyConfigOpt) ConfigOpt {
    return func(c *cosmosKeyringConfig) error {
        return addKey(c, "", opts...)
    }
}

func WithNamedKey(name string, opts ...KeyConfigOpt) ConfigOpt {
    return func(c *cosmosKeyringConfig) error {
        return addKey(c, name, opts...)
    }
}

This refactoring would reduce duplication and make the code more maintainable.

client/keyring/README.md (3)

1-5: Minor style improvement suggestion

The introduction provides a clear and concise overview of the Injective Chain Keyring Helper. To enhance clarity, consider revising the phrase "a variety of options" on line 3.

You could replace it with "multiple options" or "various options" for a more concise expression:

-Creates a new keyring from a variety of options. See `ConfigOpt` and related options. This keyring helper allows initializing the Cosmos SDK keyring used for signing transactions.
+Creates a new keyring from various options. See `ConfigOpt` and related options. This keyring helper allows initializing the Cosmos SDK keyring used for signing transactions.
🧰 Tools
🪛 LanguageTool

[style] ~3-~3: The phrase “a variety of” may be wordy. To make your writing clearer, consider replacing it.
Context: ...ring Helper Creates a new keyring from a variety of options. See ConfigOpt and related op...

(A_VARIETY_OF)


84-91: LGTM for Testing section with a suggestion

The Testing section provides clear instructions on how to run the tests and displays the test results. The current coverage of 83.1% is good, but there might be room for improvement.

Consider aiming for higher test coverage, if possible. Identify areas of the code that are not currently covered by tests and add additional test cases to increase the coverage percentage. This will help ensure the reliability and robustness of the keyring helper.


93-101: LGTM for Test Fixture section with a security suggestion

The Generating a Test Fixture section provides clear instructions on how to create a test fixture, including the necessary command and passphrase information. This is helpful for reproducibility in testing environments.

However, for security best practices, consider revising the approach to handling the passphrase:

  1. Instead of hardcoding the passphrase in the documentation, you could prompt the user to enter a passphrase of their choice when generating the test fixture.
  2. Alternatively, you could use environment variables to set the passphrase, which would keep it out of the documentation and allow for easier management in different environments.

Example using an environment variable:

export TEST_PASSPHRASE="test12345678"
injectived keys --keyring-dir `pwd` --keyring-backend file add test

This approach maintains the ease of use while improving security practices.

go.mod (2)

Line range hint 282-299: Review custom dependency forks and consider upstream alignment.

The replace directives point to custom forks of several core dependencies, including:

  • cosmos-sdk
  • wasmd
  • cometbft
  • ibc-go

While these custom forks allow for necessary modifications, they also introduce potential risks:

  1. Divergence from upstream versions may make future upgrades more challenging.
  2. Custom forks may not receive the same level of community scrutiny as upstream versions.

Consider the following recommendations:

  1. Regularly review and sync your custom forks with upstream changes to minimize divergence.
  2. Document the reasons for each custom fork to facilitate future maintenance.
  3. Implement a process to monitor upstream changes and evaluate their impact on your custom forks.
  4. Where possible, contribute your changes back to the upstream projects to reduce the need for custom forks.

To help with this process, you can use the following command to list all the replace directives:

#!/bin/bash
# List all replace directives
grep -n '^replace' go.mod

This will help in regularly reviewing and updating these custom dependencies.


Deprecated usages detected in the codebase.

Several deprecated APIs and functions were found across multiple files. These may impact functionality and should be addressed promptly.

Key Locations:

  • exchange/accounts_rpc/pb/goadesign_goagen_injective_accounts_rpc.pb.go
  • client/exchange/exchange.go
  • client/chain/markets_assistant.go
  • client/chain/chain.go

Please review and update these deprecated usages to ensure compatibility and maintain code quality.

🔗 Analysis chain

Line range hint 1-280: Approve dependency updates and recommend thorough testing.

The following key dependencies have been updated:

  • github.com/cosmos/cosmos-sdk from v0.50.7 to v0.50.8
  • github.com/cometbft/cometbft from v0.38.9 to v0.38.10
  • github.com/CosmWasm/wasmd from v0.40.2 to v0.51.0-inj-0

These updates are generally beneficial for security and feature improvements. However, the significant version jump for wasmd may introduce breaking changes.

Please ensure that comprehensive testing is performed, especially focusing on functionality related to these updated dependencies. Pay extra attention to any CosmWasm-related features due to the major version update of wasmd.

Run the following commands to check for any breaking changes or deprecations:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for potential breaking changes or deprecations
rg --type go -i 'deprecated|breaking.?change' $(fd -e go)

Length of output: 200


Script:

#!/bin/bash
# Check for potential breaking changes or deprecations
rg --type go -i 'deprecated|breaking.?change' $(fd -e go)

Length of output: 84064

client/keyring/keyring_errors_test.go (10)

10-22: Add documentation comment to test function for clarity

Consider adding a descriptive comment to the TestErrCosmosKeyringCreationFailed function to explain its purpose. This will enhance readability and help future maintainers understand the intent of the test.


24-35: Add documentation comment to test function for clarity

Adding a brief comment to the TestErrFailedToApplyConfigOption function will improve code readability and provide context for the test case.


37-58: Add documentation comment to test function for clarity

Including a descriptive comment for the TestErrHexFormatError function will help others understand what specific error scenarios are being tested.


60-82: Add documentation comment to test function for clarity

Consider describing the purpose of the TestErrIncompatibleOptionsProvided function with a comment to enhance maintainability.


84-90: Add documentation comment to test function for clarity

Adding a comment to the TestErrInsufficientKeyDetails function will provide clarity on the test's objective.


92-139: Add documentation comment to test function for clarity

Including a descriptive comment for the TestErrKeyIncompatible function will help clarify the intent and improve code readability.


138-138: Address the TODO: Implement test for unsupported multisig keys

The TODO comment indicates that a test for unsupported multisig keys is pending. Implementing this test will enhance error handling coverage and ensure multisig keys are properly tested.

Do you want assistance in implementing this test or opening a GitHub issue to track it?


141-155: Add documentation comment to test function for clarity

Consider adding a comment to the TestErrKeyRecordNotFound function to explain its purpose and the scenario it covers.


157-169: Add documentation comment to test function for clarity

Providing a descriptive comment for the TestErrPrivkeyConflict function will improve understanding of the test case.


171-193: Add documentation comment to test function for clarity

Including a comment for the TestErrUnexpectedAddress function will enhance code clarity and assist future maintainers.

client/keyring/keyring.go (2)

399-431: Handle unsupported key types in checkKeyRecord more gracefully.

The function currently returns errors for unsupported key types like TypeOffline and TypeMulti. Consider if these key types could be supported or if more descriptive error messages could aid in debugging.

Provide clearer guidance or support for additional key types if appropriate.


1-497: Add comments and documentation for exported functions and types.

The code lacks GoDoc comments for exported functions and types, which is important for maintaining clear and understandable code, especially in shared libraries.

Add GoDoc comments to all exported functions, methods, and types to improve code readability and maintainability.

🛑 Comments failed to post (12)
.github/workflows/run-tests.yml (1)

20-22: ⚠️ Potential issue

Review GPG key generation for security concerns.

The current GPG key generation has some potential security issues:

  1. The key is generated without passphrase protection (%no-protection), which could be a security risk if the key is compromised.
  2. The key is set to never expire (Expire-Date: 0), which is not a best practice for key management.

Consider the following improvements:

  1. Remove the %no-protection line to enable passphrase protection. You'll need to securely manage this passphrase, possibly using GitHub Secrets.
  2. Set a reasonable expiration date for the key, e.g., Expire-Date: 1y for one year.
  3. Use GitHub Secrets to store sensitive information like the key configuration.

Here's an example of how you could modify the step:

- name: Generate GPG key
  env:
    GPG_KEY_CONFIG: ${{ secrets.GPG_KEY_CONFIG }}
  run: |
    echo "$GPG_KEY_CONFIG" > genkey
    gpg --gen-key --batch genkey

Then, store the key configuration in a GitHub Secret named GPG_KEY_CONFIG, excluding the %no-protection line and including a reasonable Expire-Date.

client/keyring/key_config.go (2)

8-14: 🛠️ Refactor suggestion

Enhance struct documentation and security.

While the cosmosKeyConfig struct effectively encapsulates the necessary information, consider the following improvements:

  1. Add comments for each field to explain their purpose and usage.
  2. For sensitive fields (KeyPassphrase, PrivKeyHex, Mnemonic), consider using a more secure type that can be zeroed out after use, such as []byte, to minimize the risk of exposing sensitive data in memory.

Here's a suggested improvement:

type cosmosKeyConfig struct {
    Name          string  // Name of the key configuration
    KeyFrom       string  // Source of the key
    KeyPassphrase []byte  // Passphrase for keyring files (sensitive)
    PrivKeyHex    []byte  // Private key in hex format (sensitive)
    Mnemonic      []byte  // Mnemonic phrase (sensitive)
}

Remember to update the related functions to handle []byte instead of string for the sensitive fields.


30-52: ⚠️ Potential issue

Enhance security measures for sensitive options.

The WithKeyPassphrase and WithPrivKeyHex functions are correctly implemented, but given their sensitive nature, consider the following security enhancements:

  1. Make the warning about insecurity more prominent, perhaps using a dedicated WARNING: prefix.
  2. Implement a mechanism to prevent these options from being used in production environments. This could be done through build tags or environment checks.
  3. For WithPrivKeyHex, add validation to ensure the input is a valid hex string.

Here's an example of how you might implement these suggestions:

// WithKeyPassphrase sets the passphrase for keyring files.
// WARNING: This is an insecure option, use for testing only.
// The package will fallback to os.Stdin if this option was not provided, but pass is required.
func WithKeyPassphrase(v string) KeyConfigOpt {
    return func(c *cosmosKeyConfig) error {
        if runtime.GOOS != "test" {
            return errors.New("WithKeyPassphrase is only allowed in test environments")
        }
        if v != "" {
            c.KeyPassphrase = []byte(v)
        }
        return nil
    }
}

// WithPrivKeyHex allows to specify a private key as plaintext hex.
// WARNING: This is an insecure option, use for testing only.
// The package will create a virtual keyring holding that key, to meet all the interfaces.
func WithPrivKeyHex(v string) KeyConfigOpt {
    return func(c *cosmosKeyConfig) error {
        if runtime.GOOS != "test" {
            return errors.New("WithPrivKeyHex is only allowed in test environments")
        }
        if v != "" {
            if _, err := hex.DecodeString(v); err != nil {
                return errors.New("invalid hex string for private key")
            }
            c.PrivKeyHex = []byte(v)
        }
        return nil
    }
}

Note: This example assumes you've updated the cosmosKeyConfig struct to use []byte for sensitive fields as suggested earlier.

client/keyring/README.md (1)

7-36: ⚠️ Potential issue

Fix typo and LGTM for Usage section

The Usage section provides comprehensive and well-structured information about the NewCosmosKeyring function and its configuration options. There's a minor typo to address:

Please apply the following fix:

-* `WithNamedKey` addes a single key to the keyring, with a name.
+* `WithNamedKey` adds a single key to the keyring, with a name.

Overall, the explanation of options is clear and informative, providing users with a good understanding of how to use the keyring helper.

📝 Committable suggestion

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

## Usage

```go
NewCosmosKeyring(cdc codec.Codec, opts ...ConfigOpt) (sdk.AccAddress, cosmkeyring.Keyring, error)
```

**ConfigOpts:**

These options are global on the keyring level.

* `WithKeyringDir` option sets keyring path in the filesystem, useful when keyring backend is `file`.
* `WithKeyringAppName` option sets keyring application name (defaults to `injectived`)
* `WithKeyringBackend` sets the keyring backend. Expected values: `test`, `file`, `os`.
* `WithUseLedger` sets the option to use hardware wallet, if available on the system.

These options allow adding keys to the keyring during initialization.

* `WithKey` adds a single key to the keyring, without having alias name.
* `WithNamedKey` adds a single key to the keyring, with a name.
* `WithDefaultKey` sets a default key reference to use for signing (by name).

**KeyConfigOpts:**

These options are set per key.

* `WithKeyFrom` sets the key name to use for signing. Must exist in the provided keyring.
* `WithKeyPassphrase` sets the passphrase for keyring files. The package will fallback to `os.Stdin` if this option was not provided, but passphrase is required.
* `WithPrivKeyHex` allows specifying a private key as plain-text hex. Insecure option, use for testing only. The package will create a virtual keyring holding that key, to meet all the interfaces.
* `WithMnemonic` allows specifying a mnemonic phrase as plain-text hex. Insecure option, use for testing only. The package will create a virtual keyring to derive the keys and meet all the interfaces.

🧰 Tools
🪛 LanguageTool

[grammar] ~24-~24: Did you mean “having to alias” or “having aliased”?
Context: ...ds a single key to the keyring, without having alias name. * WithNamedKey addes a single k...

(WITHOUT_VBG_VB)

client/keyring/keyring_test.go (3)

283-286: ⚠️ Potential issue

Avoid hardcoding private keys and mnemonics in code

Including hardcoded private keys (testPrivKeyHex, testOtherPrivKeyHex) and mnemonics (testMnemonic) in the codebase poses a security risk. Even in test code, these sensitive values can be accidentally exposed or misused. Consider generating these values securely at runtime or using environment variables to manage them.

🧰 Tools
🪛 Gitleaks

285-285: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


286-286: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


67-67: ⚠️ Potential issue

Remove calls to logPrivKey to prevent logging private keys

The calls to logPrivKey in the test functions log sensitive private key information. Please remove these calls to enhance security.

Apply this diff to remove the calls:

 // In TestKeyFromPrivkey function
-	logPrivKey(s.T(), kb, accAddr)

 // In TestKeyFromMnemonic function
-	logPrivKey(s.T(), kb, accAddr)

 // In TestKeyringFile function
-	logPrivKey(s.T(), kb, accAddr)

 // In TestNamedKeys function
-	logPrivKey(s.T(), kb, accAddr)

Also applies to: 96-96, 139-139, 270-270


300-304: ⚠️ Potential issue

Remove logging of private keys in tests

Logging private keys can lead to unintended exposure of sensitive information if logs are accessible. It's recommended to avoid printing private keys to logs. Please remove the t.Log statement to prevent logging the private key.

Apply this diff to remove the logging:

 func logPrivKey(t *testing.T, kb cosmkeyring.Keyring, accAddr sdk.AccAddress) {
 	armor, _ := kb.ExportPrivKeyArmorByAddress(accAddr, "")
 	privKey, _, _ := cosmcrypto.UnarmorDecryptPrivKey(armor, "")
-	t.Log("[PRIV]", hex.EncodeToString(privKey.Bytes()))
 }
📝 Committable suggestion

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

func logPrivKey(t *testing.T, kb cosmkeyring.Keyring, accAddr sdk.AccAddress) {
	armor, _ := kb.ExportPrivKeyArmorByAddress(accAddr, "")
	privKey, _, _ := cosmcrypto.UnarmorDecryptPrivKey(armor, "")
}
client/keyring/keyring.go (5)

294-297: ⚠️ Potential issue

Reconsider using os.Stdin as the default passphrase reader.

Using os.Stdin may not be appropriate in all environments, especially where interactive input is not possible or secure.

Consider implementing a more flexible passphrase handling mechanism that can accommodate different environments, such as accepting a passphrase from a secure source or providing prompts when appropriate.


144-200: 🛠️ Refactor suggestion

Refactor duplicate logic in fromPrivkeyHex and fromMnemonic.

The functions fromPrivkeyHex and fromMnemonic share similar logic for key name handling, address verification, and error handling.

Extract the common code into helper functions to reduce duplication and improve maintainability. This will make future updates easier and minimize the risk of inconsistencies.

For example:

func verifyKeyNameAndAddress(keyName string, keyConfig *cosmosKeyConfig, addressFromKey sdk.AccAddress) (string, error) {
    // Common logic for verifying key name and address
}

Then update both fromPrivkeyHex and fromMnemonic to use this helper function.

Also applies to: 202-267


490-497: ⚠️ Potential issue

Avoid using panic() and ensure passphrase is suitable for encryption.

In the randPhrase function, using panic() to handle errors is not recommended in production code. Additionally, converting random bytes directly to a string may result in non-printable characters, which may not be suitable for use as a passphrase.

Consider handling the error by returning it and generating a passphrase using a base64 or hex encoding to ensure it contains printable characters.

Apply this diff to improve error handling and passphrase generation:

 func randPhrase(size int) (string, error) {
     buf := make([]byte, size)
     if _, err := rand.Read(buf); err != nil {
-        panic(err)
+        return "", err
     }
-    return string(buf)
+    return hex.EncodeToString(buf), nil
 }
📝 Committable suggestion

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

func randPhrase(size int) (string, error) {
	buf := make([]byte, size)
	if _, err := rand.Read(buf); err != nil {
		return "", err
	}

	return hex.EncodeToString(buf), nil
}

469-479: ⚠️ Potential issue

Handle the passphrase and errors appropriately in addFromPrivKey.

The function uses a random passphrase to encrypt the private key, but the passphrase is not stored or returned. This means the encrypted key cannot be retrieved later, which might lead to issues if the keyring is used beyond the in-memory session.

Consider returning the passphrase or using a consistent passphrase if the keyring needs to persist beyond the current session. Also, update the function to handle errors from the modified randPhrase function.

Apply this diff to address the concerns:

-func addFromPrivKey(kb cosmkeyring.Keyring, name string, privKey cryptotypes.PrivKey) error {
-    tmpPhrase := randPhrase(64)
+func addFromPrivKey(kb cosmkeyring.Keyring, name string, privKey cryptotypes.PrivKey) (string, error) {
+    tmpPhrase, err := randPhrase(64)
+    if err != nil {
+        return "", err
+    }
     armored := cosmcrypto.EncryptArmorPrivKey(privKey, tmpPhrase, privKey.Type())
     err := kb.ImportPrivKey(name, armored, tmpPhrase)
     if err != nil {
         err = errors.Wrapf(ErrCosmosKeyringImportFailed, "failed to import privkey: %s", err.Error())
-        return err
+        return "", err
     }

-    return nil
+    return tmpPhrase, nil
 }

Ensure that any calling functions are updated to handle the returned passphrase and error accordingly.

📝 Committable suggestion

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

func addFromPrivKey(kb cosmkeyring.Keyring, name string, privKey cryptotypes.PrivKey) (string, error) {
    tmpPhrase, err := randPhrase(64)
    if err != nil {
        return "", err
    }
    armored := cosmcrypto.EncryptArmorPrivKey(privKey, tmpPhrase, privKey.Type())
    err = kb.ImportPrivKey(name, armored, tmpPhrase)
    if err != nil {
        err = errors.Wrapf(ErrCosmosKeyringImportFailed, "failed to import privkey: %s", err.Error())
        return "", err
    }

    return tmpPhrase, nil
}

492-494: ⚠️ Potential issue

Handle errors from rand.Read instead of panicking.

Panicking on error is discouraged as it can crash the program and doesn't provide a way to recover or handle the error gracefully.

Modify the function to return an error, allowing the caller to decide how to handle it.

Apply this diff:

 func randPhrase(size int) (string, error) {
     buf := make([]byte, size)
     if _, err := rand.Read(buf); err != nil {
-        panic(err)
+        return "", err
     }
-    return string(buf)
+    return hex.EncodeToString(buf), nil
 }

Committable suggestion was skipped due to low confidence.

@proofofze proofofze changed the title feat: add status to tmclient feat: add GetStatus to tmclient Sep 30, 2024
Copy link
Collaborator

@aarmoa aarmoa left a comment

Choose a reason for hiding this comment

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

The change looks good to me

@aarmoa aarmoa merged commit bb9ef54 into dev Sep 30, 2024
4 checks passed
@aarmoa aarmoa deleted the feat/add-status-to-tmclient branch September 30, 2024 16:34
@coderabbitai coderabbitai bot mentioned this pull request Nov 14, 2024
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