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/upgrade to bridge #16780

Merged
merged 3 commits into from
Feb 5, 2025
Merged

Feat/upgrade to bridge #16780

merged 3 commits into from
Feb 5, 2025

Conversation

marekrjpolak
Copy link
Contributor

@marekrjpolak marekrjpolak commented Feb 3, 2025

Description

When any transport is active, DeviceList is periodically pinging to all transports with higher priority (currently only Bridge ping is implemented) and initiate reconnection as soon as any of them becomes accessible.

Copy link

coderabbitai bot commented Feb 3, 2025

Walkthrough

The pull request introduces updates across multiple packages to improve transport management and debugging functionality. In the connection component, the DeviceList class is enhanced by adding a private property for scheduled upgrade checks and introducing a new method to periodically verify the availability of newer transports. Corresponding adjustments ensure that scheduled checks are cleaned up when a transport is stopped. In the suite’s settings for debugging, the transport selection logic is restructured by defining explicit arrays for different platforms, introducing a new type alias, and a helper function to generate transport menu items with detailed properties. Additionally, in the transport layer, a ping method is added to both the abstract transport class and its BridgeTransport implementation to facilitate endpoint testing.

Suggested reviewers

  • komret

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.
✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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.

@marekrjpolak marekrjpolak force-pushed the feat/upgrade-to-bridge branch 2 times, most recently from 26c0a1a to e4bfffd Compare February 4, 2025 16:27
Copy link
Contributor

@mroz22 mroz22 left a comment

Choose a reason for hiding this comment

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

top 🔝

just don't forget to sort transports in that way that bridge always comes first

@marekrjpolak marekrjpolak force-pushed the feat/upgrade-to-bridge branch from e4bfffd to 95eb1d7 Compare February 5, 2025 13:30
@marekrjpolak marekrjpolak marked this pull request as ready for review February 5, 2025 13:47
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 (4)
packages/suite/src/views/settings/SettingsDebug/Transport.tsx (2)

22-31: Verify completeness of transport lists and descriptions.

The newly added TRANSPORTS_WEB, TRANSPORTS_DESKTOP, and TRANSPORT_DESCRIPTIONS seem accurate. Double-check that no internal or third-party transport type is missing, particularly if additional environments might require specialized transport entries.


63-80: Double-check XOR logic when filtering nextTransports.

The statement (t.name === transport.name) !== t.checked can be confusing at first glance. It effectively toggles the item. Consider extracting a helper to enhance readability. Otherwise, the dispatch calls (setDebugMode, TrezorConnect.setTransports) are consistent with the suite’s approach.

packages/transport/src/transports/abstract.ts (1)

146-148: Document or implement the ping method’s intended behavior.

Currently, ping always resolves to false. If this is just a placeholder, adding a brief comment highlighting that it’s a no-op would clarify its purpose for future maintainers.

packages/connect/src/device/DeviceList.ts (1)

405-423: Consider adding documentation for the upgrade check mechanism.

The scheduleUpgradeCheck method implements an important feature but lacks documentation explaining its purpose and behavior.

Add JSDoc comments to explain:

  1. The purpose of the upgrade check
  2. The checking interval
  3. The upgrade process
  4. The cleanup mechanism
+/**
+ * Schedules periodic checks for newer transports of the same API type.
+ * If a newer transport is found and successfully pinged, it triggers
+ * a transport upgrade process.
+ *
+ * @param apiType - The transport API type to check
+ * @param initParams - Transport initialization parameters
+ * @private
+ */
 private scheduleUpgradeCheck(apiType: TransportApiType, initParams: InitParams) {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c89c834 and 95eb1d7.

📒 Files selected for processing (4)
  • packages/connect/src/device/DeviceList.ts (4 hunks)
  • packages/suite/src/views/settings/SettingsDebug/Transport.tsx (2 hunks)
  • packages/transport/src/transports/abstract.ts (1 hunks)
  • packages/transport/src/transports/bridge.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: methods / web
  • GitHub Check: methods / core_in_popup
  • GitHub Check: run_android_e2e_tests
  • GitHub Check: e2e-test-suite-web (@group=metadata2, trezor-user-env-unix)
  • GitHub Check: run-desktop-tests (@group=suite, trezor-user-env-unix)
🔇 Additional comments (7)
packages/suite/src/views/settings/SettingsDebug/Transport.tsx (3)

13-19: Ensure consistency for newly introduced types.

Defining a dedicated alias (Transport) and extending it within TransportMenuItem is a neat approach. Just make sure all future references, comments, and imports internally echo these names for clarity. The definition of name and checked fields appears coherent.


33-47: Memoize usage looks fine; watch out for repeated updates.

useMemo over [transports, activeTransports, debugTransports] is appropriate. If the data changes very frequently (e.g., each render), the memo might be recalculated often. Otherwise, this approach is optimal for performance.


49-52: Conditional desktop vs. web transport selection is well-structured.

Dynamic assignment based on the environment is clear and maintainable.

packages/transport/src/transports/bridge.ts (1)

90-94: Ensure error handling covers connection edge cases.

ping attempts a POST to '/', returning a boolean based on success. This is concise, but if an unexpected network error arises (e.g., partial or slow connectivity), confirm that returning false is the desired fallback behavior. Otherwise, the method aligns with the abstraction from AbstractTransport.

packages/connect/src/device/DeviceList.ts (3)

206-206: LGTM! Property declaration is well-typed.

The scheduledUpgradeChecks property is correctly typed using ApiTypeMap to store timeout identifiers for each transport type.


383-386: LGTM! Transport upgrade check scheduling is properly guarded.

The upgrade check is only scheduled when a transport is successfully started or retained, which is the correct behavior.


571-572: LGTM! Proper cleanup of scheduled upgrade checks.

The stopTransport method correctly cleans up the scheduled upgrade check for the transport being stopped.

Comment on lines +405 to +423
private scheduleUpgradeCheck(apiType: TransportApiType, initParams: InitParams) {
clearTimeout(this.scheduledUpgradeChecks[apiType]);
this.scheduledUpgradeChecks[apiType] = setTimeout(async () => {
const transport = this.transport[apiType];
if (!transport) return;
const transports = this.transports.filter(t => t.apiType === apiType);
for (const t of transports) {
if (t === transport) break;
if (await t.ping()) {
this.transportLock(apiType, 'Upgrading', signal =>
this.createInitPromise(apiType, initParams, signal),
).catch(() => {});

return;
}
}
this.scheduleUpgradeCheck(apiType, initParams);
}, 1000);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding error handling and cleanup in the upgrade check.

The upgrade check implementation could be improved in a few areas:

  1. The timeout callback should handle potential errors during transport ping
  2. The recursive scheduling could lead to memory leaks if the transport is stopped during the ping operation

Consider this implementation:

 private scheduleUpgradeCheck(apiType: TransportApiType, initParams: InitParams) {
     clearTimeout(this.scheduledUpgradeChecks[apiType]);
     this.scheduledUpgradeChecks[apiType] = setTimeout(async () => {
         const transport = this.transport[apiType];
-        if (!transport) return;
+        if (!transport || !this.scheduledUpgradeChecks[apiType]) return;
         const transports = this.transports.filter(t => t.apiType === apiType);
         for (const t of transports) {
             if (t === transport) break;
-            if (await t.ping()) {
-                this.transportLock(apiType, 'Upgrading', signal =>
-                    this.createInitPromise(apiType, initParams, signal),
-                ).catch(() => {});
-
-                return;
+            try {
+                if (await t.ping()) {
+                    this.transportLock(apiType, 'Upgrading', signal =>
+                        this.createInitPromise(apiType, initParams, signal),
+                    ).catch(() => {});
+                    return;
+                }
+            } catch (error) {
+                // Log error but continue checking other transports
+                console.error(`Error pinging transport: ${error}`);
             }
         }
         this.scheduleUpgradeCheck(apiType, initParams);
     }, 1000);
 }
📝 Committable suggestion

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

Suggested change
private scheduleUpgradeCheck(apiType: TransportApiType, initParams: InitParams) {
clearTimeout(this.scheduledUpgradeChecks[apiType]);
this.scheduledUpgradeChecks[apiType] = setTimeout(async () => {
const transport = this.transport[apiType];
if (!transport) return;
const transports = this.transports.filter(t => t.apiType === apiType);
for (const t of transports) {
if (t === transport) break;
if (await t.ping()) {
this.transportLock(apiType, 'Upgrading', signal =>
this.createInitPromise(apiType, initParams, signal),
).catch(() => {});
return;
}
}
this.scheduleUpgradeCheck(apiType, initParams);
}, 1000);
}
private scheduleUpgradeCheck(apiType: TransportApiType, initParams: InitParams) {
clearTimeout(this.scheduledUpgradeChecks[apiType]);
this.scheduledUpgradeChecks[apiType] = setTimeout(async () => {
const transport = this.transport[apiType];
if (!transport || !this.scheduledUpgradeChecks[apiType]) return;
const transports = this.transports.filter(t => t.apiType === apiType);
for (const t of transports) {
if (t === transport) break;
try {
if (await t.ping()) {
this.transportLock(apiType, 'Upgrading', signal =>
this.createInitPromise(apiType, initParams, signal),
).catch(() => {});
return;
}
} catch (error) {
// Log error but continue checking other transports
console.error(`Error pinging transport: ${error}`);
}
}
this.scheduleUpgradeCheck(apiType, initParams);
}, 1000);
}

@marekrjpolak marekrjpolak merged commit 8d03473 into develop Feb 5, 2025
75 of 77 checks passed
@marekrjpolak marekrjpolak deleted the feat/upgrade-to-bridge branch February 5, 2025 15:03
@coderabbitai coderabbitai bot mentioned this pull request Feb 6, 2025
@bosomt
Copy link
Contributor

bosomt commented Feb 10, 2025

QA OK

tested auto upgrade

  • webUSB > bridge 2.0
  • webUSB > bridge 3.0
  • downgrade to webUSB after bridge became unavailable

Info:

  • Suite version: web 25.3.0 (b8dc85b)
  • Browser: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36
  • OS: MacIntel
  • Screen: 1470x956
  • Device: Trezor T2T1 2.8.7 regular (revision 8a254aa8eae82f99630df63f40e4d290066a3efc)
  • Transport: BridgeTransport 3.0.0-bundled.25.2.1

@bosomt
Copy link
Contributor

bosomt commented Feb 10, 2025

@marekrjpolak @mroz22

from now on we will see these error in console when we use only webUSB ?

image

@mroz22
Copy link
Contributor

mroz22 commented Feb 10, 2025

I would like to see only unexpected errors in console and this one is in fact expected. But I am afraid we can't do anything about it. :(

@marekrjpolak
Copy link
Contributor Author

@bosomt If you really want to use only webusb and never upgrade (unlike production web suite), it should be enough to turn Bridge transport off in debug menu.

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

Successfully merging this pull request may close these issues.

3 participants