8000 feat: multi ledger support by beer-1 · Pull Request #375 · initia-labs/initia · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: multi ledger support #375

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

Merged
merged 4 commits into from
Mar 21, 2025
Merged

feat: multi ledger support #375

merged 4 commits into from
Mar 21, 2025

Conversation

beer-1
Copy link
Member
@beer-1 beer-1 commented Mar 21, 2025

Description

Closes: #XXXX


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
  • provided a link to the relevant issue or specification
  • reviewed "Files changed" and left comments if necessary
  • included the necessary unit and integration tests
  • 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.

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

@beer-1 beer-1 self-assigned this Mar 21, 2025
@beer-1 beer-1 requested a review from a team as a code owner March 21, 2025 04:08
Copy link
github-actions bot commented Mar 21, 2025

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

OpenSSF Scorecard

PackageVersionScoreDetails

Scanned Files

Copy link
coderabbitai bot commented Mar 21, 2025
📝 Walkthrough

Walkthrough

The pull request refines ledger device handling by enhancing functions in the keyring and ledger packages. In the keyring package, the EthSecp256k1Option function is updated to differentiate between Ethereum and Cosmos ledger devices, incorporating a new flag validation function and constant. The ledger packages replace the nested LedgerDerivationFn with a more straightforward FindLedgerEthereumApp function, which initializes a package-level ledger instance and improves error reporting for the Ethereum app's status. Similar adjustments are made across the main, mock, and not-available ledger files.

Changes

File(s) Change Summary
crypto/keyring/options.go Updated EthSecp256k1Option to detect and validate Ethereum and Cosmos ledger devices; introduced new constant flagCoinType and added validateFlags to encapsulate flag checking and improve modularity.
crypto/ledger/ledger.go Replaced LedgerDerivationFn with FindLedgerEthereumApp; introduced a package-level initiaLedger variable and added error handling in connect() to verify Ethereum app availability and provide detailed feedback on ledger connection issues.
crypto/ledger/ledger_mock.go, crypto/ledger/ledger_notavail.go Removed the nested LedgerDerivationFn and added FindLedgerEthereumApp, which now directly returns a nil ledger instance with an error message, simplifying the control flow for unsupported ledger devices.

Sequence Diagram(s)

sequenceDiagram
    participant UA as User Application
    participant KO as Keyring Options
    participant LD as Ledger Device

    UA->>KO: Call EthSecp256k1Option
    KO->>KO: Call validateFlags (using viper config)
    KO->>LD: Attempt to detect Ethereum ledger
    alt Ethereum ledger found
        LD-->>KO: Return Ethereum ledger details
        KO->>KO: Process Ethereum ledger (validate coin & key type)
    else Ethereum ledger not found
        KO->>LD: Attempt to detect Cosmos ledger
        LD-->>KO: Return Cosmos ledger details
        KO->>KO: Set LedgerAppName to "Cosmos"
    end
    KO->>UA: Return appropriate public key message
Loading
sequenceDiagram
    participant App as Application
    participant FLE as FindLedgerEthereumApp
    participant IL as InitiaLedger

    App->>FLE: Invoke FindLedgerEthereumApp
    FLE->>FLE: Check if initiaLedger is nil
    alt Uninitialized
        FLE->>IL: Create new InitiaLedger instance
    end
    FLE->>IL: Call connect()
    alt Ethereum app offline
        IL-->>FLE: Close wallet and return error
    else Ethereum app online
        IL-->>FLE: Return ledger.SECP256K1 instance
    end
    FLE->>App: Return ledger instance or error
Loading

Possibly related PRs

  • release: prepare v1.0.0-beta.0 #362: Involves modifications to crypto/keyring/options.go, focusing on keyring option changes similar to the enhancements in the EthSecp256k1Option function.
  • feat: ethereum ledger integration #365: Addresses changes to ledger handling functions, with a direct connection to updates around the ledger derivation flow as seen in the new FindLedgerEthereumApp function.

Poem

I'm a rabbit in the code,
Hopping through ledger lanes,
Ethereum or Cosmos, I cheer,
With flags validated, there's no fear.
New functions make my heart sing,
Code so fresh—let the changes spring! 🐇


🪧 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.

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
crypto/ledger/ledger.go (1)

58-66: Extract "Ethereum app offline" into a constant.
Instead of checking against a hard-coded string, define a constant to reduce the risk of typos and improve maintainability.

crypto/keyring/options.go (2)

41-62: Switch to a structured logging approach.
Multiple multi-line messages use fmt.Printf and fmt.Println. Using a logger (or more structured output) may improve readability and maintainability, especially for debugging in production.


110-124: Clarify function parameter naming.
Parameters eCoinType and eKeyType are used for both Ethereum and Cosmos ledgers. Consider using more neutral names to avoid confusion, such as requiredCoinType or expectedKeyType.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b8eb64e and 8fec807.

⛔ Files ignored due to path filters (1)
  • go.mod is excluded by !**/*.mod
📒 Files selected for processing (4)
  • crypto/keyring/options.go (2 hunks)
  • crypto/ledger/ledger.go (2 hunks)
  • crypto/ledger/ledger_mock.go (1 hunks)
  • crypto/ledger/ledger_notavail.go (1 hunks)
🧰 Additional context used
🧬 Code Definitions (3)
crypto/ledger/ledger_notavail.go (2)
crypto/ledger/ledger_mock.go (1) (1)
  • FindLedgerEthereumApp (11-13)
crypto/ledger/ledger.go (1) (1)
  • FindLedgerEthereumApp (24-30)
crypto/ledger/ledger_mock.go (2)
crypto/ledger/ledger_notavail.go (1) (1)
  • FindLedgerEthereumApp (11-13)
crypto/ledger/ledger.go (1) (1)
  • FindLedgerEthereumApp (24-30)
crypto/keyring/options.go (4)
crypto/ledger/ledger_mock.go (1) (1)
  • FindLedgerEthereumApp (11-13)
crypto/ledger/ledger_notavail.go (1) (1)
  • FindLedgerEthereumApp (11-13)
crypto/ledger/ledger.go (1) (1)
  • FindLedgerEthereumApp (24-30)
crypto/hd/algorithm.go (1) (1)
  • EthSecp256k1Type (16-16)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: golangci-lint
  • GitHub Check: Run test and upload codecov
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
crypto/ledger/ledger_mock.go (1)

11-13: Mock ledger device approach looks good.
No issues found with returning nil and an error for unavailable ledger scenarios in a mock context.

crypto/ledger/ledger_notavail.go (1)

11-13: Consistent message for unavailable ledger.
Returning nil and a not-available error cleanly conveys that ledger support is not compiled into this build.

crypto/keyring/options.go (1)

37-105: Review the handling of isCosmosLedger.
Once Ethereum ledger detection fails, this variable is flipped to true, causing all subsequent derivations to skip Ethereum checks. Consider re-initializing or scoping isCosmosLedger inside the returned closure to support repeated attempts or device reconnection scenarios.

@beer-1 beer-1 requested a review from Vritra4 March 21, 2025 04:15
Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
crypto/ledger/ledger.go (1)

22-22: Global variable concurrency caution
Declaring initiaLedger as a global pointer could lead to race conditions if multiple goroutines invoke initialization concurrently. Consider guarding it with sync.Once or a similar pattern for thread safety.

crypto/keyring/options.go (2)

38-95: Consolidated ledger derivation logic
Combining both Ethereum and Cosmos ledger flows here improves discoverability. However, there is a fair amount of duplicated structure and console output. Consider abstracting the shared checks and prints—potentially using a helper function to cut repetition and centralize error messaging.


97-105: Conditionally printing ledger type
Showing "Using Ethereum Pubkey" vs. "Using Cosmos Pubkey" can be helpful in development. In a production setting, you might want to move these statements to a debug log level.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b8eb64e and 4918576.

⛔ Files ignored due to path filters (1)
  • go.mod is excluded by !**/*.mod
📒 Files selected for processing (4)
  • crypto/keyring/options.go (1 hunks)
  • crypto/ledger/ledger.go (2 hunks)
  • crypto/ledger/ledger_mock.go (1 hunks)
  • crypto/ledger/ledger_notavail.go (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
crypto/ledger/ledger_mock.go (2)
crypto/ledger/ledger_notavail.go (1) (1)
  • FindLedgerEthereumApp (11-13)
crypto/ledger/ledger.go (1) (1)
  • FindLedgerEthereumApp (24-30)
crypto/ledger/ledger_notavail.go (2)
crypto/ledger/ledger_mock.go (1) (1)
  • FindLedgerEthereumApp (11-13)
crypto/ledger/ledger.go (1) (1)
  • FindLedgerEthereumApp (24-30)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: golangci-lint
  • GitHub Check: Run test and upload codecov
  • GitHub Check: Analyze (go)
🔇 Additional comments (9)
crypto/ledger/ledger_mock.go (1)

11-12: Consistent mock return for ledger unavailability
This function serves as a direct placeholder for ledger device usage, returning a fixed error to indicate that such support is unavailable. Maintaining the same error message across different mock or "not available" files keeps the behavior consistent.

crypto/ledger/ledger_notavail.go (1)

11-12: Uniform "not available" approach
Returning a nil interface and a uniform error as in the mock ensures consistent handling across builds without ledger support.

crypto/ledger/ledger.go (2)

24-30: Simplified approach to finding the Ledger
By assigning and returning initiaLedger.connect(), the logic is streamlined. However, confirm that re-initialization or re-connection flows are handled properly if the device is disconnected or reconnected at runtime.

Could you verify if repeated calls to FindLedgerEthereumApp() handle a plugged/unplugged sequence gracefully?


58-66: Robust error handling for offline Ethereum app
Closing the wallet before returning an error prevents resource leaks. Consider adding structured logging or counters, so any offline occurrences can be easily found in monitoring.

crypto/keyring/options.go (5)

4-5: Addition of the fmt import
This import is used for console output. It’s acceptable given the new print statements below, but consider switching to a logging library for more consistent user messages.


9-10: Expanded imports for multi-ledger support
These imports facilitate both Ethereum- and Cosmos-specific ledger functions. Verify that you align versions across modules to avoid potential dependency conflicts.

Would you like me to confirm version consistency in your go.mod?

Also applies to: 12-12, 13-13, 15-15, 19-20


27-27: Refined supported algorithms
By including EthSecp256k1 alongside Cosmos Secp256k1, you’ve properly enabled multi-ledger signing. This aligns with the expanded ledger functionalities.

Also applies to: 31-31


106-106: Default ledger app setting
Defaulting to "Cosmos" is valid but might risk confusion if Ethereum is the more common scenario. Double-check that the user understands which ledger application is being used.


111-111: Centralized flag validation
Encapsulating validation of coin type and key type in validateFlags improves maintainability. Ensure all relevant commands consistently call this function.

Also applies to: 113-125

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
crypto/ledger/ledger.go (1)

22-30: ⚠️ Potential issue

Address the Concurrency Issue in Ledger Initialization

The function FindLedgerEthereumApp() checks and initializes initiaLedger without any synchronization. This could lead to race conditions if multiple goroutines invoke the function concurrently.

Use a synchronization mechanism such as sync.Once to ensure that the ledger is initialized only once:

var initiaLedger *InitiaLedger
+var ledgerOnce sync.Once

func FindLedgerEthereumApp() (ledger.SECP256K1, error) {
-	if initiaLedger == nil {
-		initiaLedger = new(InitiaLedger)
-	}
+	ledgerOnce.Do(func() {
+		initiaLedger = new(InitiaLedger)
+	})

	return initiaLedger.connect()
}

Don't forget to add "sync" to your imports.

🧹 Nitpick comments (2)
crypto/ledger/ledger.go (1)

58-66: Consider using a constant for the Ethereum app status message

Good enhancement to error handling, but the string "Ethereum app offline" is used both for checking in the condition and for returning the error. This could cause issues if the message changes in the future.

Consider defining a constant:

+const EthereumAppOfflineStatus = "Ethereum app offline"

// In the connect() method:
	// check if ethereum app is offline or not
	status, err := wallet.Status()
	if err != nil {
		wallet.Close()
		return nil, errors.Wrap(err, "failed to get wallet status")
-	} else if status == "Ethereum app offline" {
+	} else if status == EthereumAppOfflineStatus {
		wallet.Close()
		return nil, errors.New(status)
	}
crypto/keyring/options.go (1)

38-96: Good implementation for multi-ledger support, consider extracting error messages

The implementation correctly handles both Ethereum and Cosmos ledger devices with proper validation and fallback strategy. However, the error messages contain a lot of formatting and newlines which reduce code readability.

Consider extracting these error message templates to constants or helper functions:

+// Error message templates
+const (
+    ledgerValidationErrorTemplate = `
+Failed to validate flags for %s ledger:
+%s
+
+Please make sure you have the correct coin type and key type set for the %s ledger.
+
+You can use the following command to set the correct flags:
+--coin-type %d --key-type %s
+
+`
+)

+// formatLedgerValidationError creates a formatted error message for ledger validation failures
+func formatLedgerValidationError(ledgerType string, err error, coinType uint32, keyType string) string {
+    return fmt.Sprintf(ledgerValidationErrorTemplate, ledgerType, err.Error(), ledgerType, coinType, keyType)
+}

Then use these in your validation checks:

// For Ethereum ledger validation
if err := validateFlags(60, string(ethhd.EthSecp256k1Type)); err != nil {
-    fmt.Printf(`
-Failed to validate flags for Ethereum ledger:
-%s
-
-Please make sure you have the correct coin type and key type set for the Ethereum ledger.
-
-You can use the following command to set the correct flags:
---coin-type 60 --key-type %s
-
-`, err.Error(), ethhd.EthSecp256k1Type)
+    fmt.Printf(formatLedgerValidationError("Ethereum", err, 60, string(ethhd.EthSecp256k1Type)))
    return nil, err
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8fec807 and a809ecc.

📒 Files selected for processing (2)
  • crypto/keyring/options.go (1 hunks)
  • crypto/ledger/ledger.go (2 hunks)
🔇 Additional comments (2)
crypto/keyring/options.go (2)

97-108: Good public key selection logic with clear user feedback

The implementation correctly selects between Ethereum and Cosmos public keys based on the detected ledger type and provides helpful console output to indicate which one is being used.


111-125: Good flag validation implementation

The validateFlags function properly encapsulates the validation logic for coin and key types, improving code modularity and readability. The function correctly handles cases where flags are not set (empty string for keyType or 0 for coinType).

Copy link
codecov bot commented Mar 21, 2025

Codecov Report

Attention: Patch coverage is 0% with 69 lines in your changes missing coverage. Please review.

Project coverage is 39.83%. Comparing base (4e3e933) to head (a809ecc).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
crypto/keyring/options.go 0.00% 67 Missing ⚠️
crypto/ledger/ledger_mock.go 0.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #375      +/-   ##
==========================================
- Coverage   39.93%   39.83%   -0.10%     
==========================================
  Files         277      277              
  Lines       26862    26923      +61     
==========================================
  Hits        10726    10726              
- Misses      14478    14539      +61     
  Partials     1658     1658              
Files with missing lines Coverage Δ
crypto/ledger/ledger_mock.go 0.00% <0.00%> (ø)
crypto/keyring/options.go 0.00% <0.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Contributor
@Vritra4 Vritra4 left a comment

Choose a reason for hiding this comment

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

LGTM

@beer-1 beer-1 merged commit ccc35ba into main Mar 21, 2025
9 of 10 checks passed
@beer-1 beer-1 deleted the feat/multi-ledger branch March 21, 2025 09:18
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
0