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(torii-libp2p): inter torii messaging for offchain messages #3082

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

Conversation

Larkooo
Copy link
Collaborator

@Larkooo Larkooo commented Mar 5, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced connectivity by adding support for additional transport protocols, including WebRTC and WebSocket connections.
    • Introduced a new command-line option for specifying other Torii relays to synchronize with.
    • Added a new messaging topic for peer communication.
  • Refactor

    • Updated the Relay struct to initialize a list of peers for connection establishment.
    • Modified the Relay server instantiation to accept a list of peers for improved network behavior.
    • Refined handling of identity determination to allow more flexible processing of varied network scenarios.

Copy link

coderabbitai bot commented Mar 5, 2025

Ohayo, sensei! Below is the detailed breakdown of the changes in this pull request.

Walkthrough

This pull request updates two parts of the torii libp2p crate. In the client module, the RelayClient::new method now sets up WebRTC and WebSocket transports for non-WASM targets by generating a certificate for WebRTC and configuring the SwarmBuilder with additional transports. In the server module, the new method of the Relay struct is enhanced to accept a list of peers, allowing the server to establish connections with these peers after setup.

Changes

File(s) Change Summary
crates/torii/libp2p/src/client/mod.rs Added WebRTC and WebSocket transport configurations in RelayClient::new (WebRTC uses a generated certificate; WebSocket is configured with DNS, Noise, and yamux).
crates/torii/libp2p/src/server/mod.rs Updated Relay::new method to accept a Vec<String> of peers and modified control flow for handling entity_identity with a wildcard match.
crates/torii/cli/src/options.rs Introduced new field peers: Vec<String> in RelayOptions for holding relay addresses, with command-line argument parsing options and updated Default implementation.
crates/torii/libp2p/src/constants.rs Added new constant PEERS_MESSAGING_TOPIC for messaging related to peers.

Possibly related PRs


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 5fc639e and 528487e.

📒 Files selected for processing (2)
  • crates/torii/libp2p/src/client/mod.rs (2 hunks)
  • crates/torii/libp2p/src/server/mod.rs (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/torii/libp2p/src/client/mod.rs
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: fmt
🔇 Additional comments (4)
crates/torii/libp2p/src/server/mod.rs (4)

72-83: Nicely refactored function structure!

Ohayo sensei! I like how you've maintained backward compatibility by having new call new_with_peers with an empty vector. This is a clean implementation that preserves the API for existing users while adding new functionality.


85-94: Good enhancement with peer support!

The new new_with_peers method provides a clean way to initialize the relay with a list of peers. This supports the inter-torii messaging feature nicely.


208-213: LGTM - Topic subscription properly added!

Appropriately subscribing to the peers messaging topic. This is necessary for the server to receive messages from other Torii instances.


322-322: Broadened pattern matching is better

Switching from None to a wildcard match _ makes the code more resilient by handling any pattern that isn't a Some(identity) value. Good defensive programming, sensei!


🪧 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

@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 (2)
crates/torii/libp2p/src/client/mod.rs (2)

64-64: Ohayo sensei, consider gracefully handling errors instead of unwrapping.

Using unwrap() might panic. A more robust approach:

- let cert = Certificate::generate(&mut thread_rng()).unwrap();
+ let cert = Certificate::generate(&mut thread_rng())
+     .map_err(Error::CertificateGeneration)?;

74-87: Ohayo sensei, WebSocket transport creation is solid.

Your combination of Noise + Yamux is a common, reliable pattern. Watch for expect() usage if you prefer recovery over panic.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d008071 and a17ca33.

📒 Files selected for processing (2)
  • crates/torii/libp2p/src/client/mod.rs (2 hunks)
  • crates/torii/libp2p/src/server/mod.rs (1 hunks)
🔇 Additional comments (4)
crates/torii/libp2p/src/server/mod.rs (1)

288-288: Ohayo sensei, be mindful of overshadowing other pattern matches.

Changing None => ... to _ => ... risks swallowing other potential branches. If you only intended to handle None, revert to a more explicit match. Otherwise, confirm no other variants need separate handling.

crates/torii/libp2p/src/client/mod.rs (3)

15-15: Ohayo sensei, nice new import.

Bringing in libp2p_webrtc is essential for the new transport. Looks good!


54-58: Ohayo sensei, these imports look well-organized.

They’re properly used below and align with your new transport setup.


70-73: Ohayo sensei, good job integrating the WebRTC transport.

Be sure the ephemeral certificate usage meets security requirements. Otherwise, everything here looks correct.

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 (1)
crates/torii/cli/src/options.rs (1)

79-87: Looks good! The new peer sync option is well-structured.

Ohayo sensei! The addition of this feature looks well-implemented with proper documentation and CLI argument configuration. This will enable inter-torii relay communication for offchain messages as intended.

You might consider clarifying the expected format of peer addresses in the help message, such as specifying if these should be LibP2P multiaddresses (e.g., "/ip4/127.0.0.1/tcp/9090/p2p/QmHash...").

-        help = "A list of other torii relays to connect to and sync with."
+        help = "A list of other torii relays to connect to and sync with. Format: multiaddr (e.g., \"/ip4/127.0.0.1/tcp/9090/p2p/QmHash...\")."
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a17ca33 and 7d54e8f.

📒 Files selected for processing (1)
  • crates/torii/cli/src/options.rs (2 hunks)
🔇 Additional comments (1)
crates/torii/cli/src/options.rs (1)

98-98: Default implementation updated correctly!

The default implementation properly initializes the new peers field with an empty vector, maintaining consistency with how other collection fields are handled in this codebase.

@Larkooo Larkooo marked this pull request as draft March 5, 2025 09:15
@Larkooo Larkooo marked this pull request as ready for review March 5, 2025 09:33
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 (2)
crates/torii/libp2p/src/server/mod.rs (2)

295-295: Maintain explicit matching on None
Ohayo sensei, replacing None => with _ => can obscure future changes or unexpected variants. Retaining explicit matching on None helps catch potential edge cases more clearly.


365-382: Remove the unwrap() on serialization
Ohayo sensei, relying on unwrap() here can panic if serialization fails unexpectedly. It might be safer to handle the error in a consistent manner:

-if let Err(e) = self
-    .swarm
-    .behaviour_mut()
-    .gossipsub
-    .publish(
-        IdentTopic::new(constants::MESSAGING_TOPIC),
-        serde_json::to_string(&data).unwrap(),
-    )
-    .map_err(Error::PublishError)
-{
+if let Err(e) = serde_json::to_string(&data)
+    .map_err(Error::from)
+    .and_then(|serialized| {
+        self.swarm
+            .behaviour_mut()
+            .gossipsub
+            .publish(IdentTopic::new(constants::MESSAGING_TOPIC), serialized)
+            .map_err(Error::PublishError)
+    })
+{
     info!(
         target: LOG_TARGET,
         error = %e,
         "Publishing message to peers."
     );
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d54e8f and f0d5a44.

📒 Files selected for processing (1)
  • crates/torii/libp2p/src/server/mod.rs (4 hunks)
🔇 Additional comments (1)
crates/torii/libp2p/src/server/mod.rs (1)

72-72: Nice addition of the peers parameter
Ohayo sensei, this provides a straightforward way to initialize peer connections for offchain message broadcasting.

Comment on lines +171 to +175
// We dial all of our peers. Our server will then broadcast
// all incoming offchain messages to all of our peers.
for peer in peers {
swarm.dial(peer.parse::<Multiaddr>().unwrap())?;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential parse failures
Ohayo sensei, using unwrap() when parsing Multiaddr may crash the server if the input is invalid. Consider gracefully handling parse errors:

-for peer in peers {
-    swarm.dial(peer.parse::<Multiaddr>().unwrap())?;
-}
+for peer in peers {
+    if let Ok(addr) = peer.parse::<Multiaddr>() {
+        if let Err(e) = swarm.dial(addr) {
+            warn!(target: LOG_TARGET, error = ?e, "Dialing peer.");
+        }
+    } else {
+        warn!(target: LOG_TARGET, peer = %peer, "Invalid Multiaddr, skipping dial.");
+    }
+}
📝 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
// We dial all of our peers. Our server will then broadcast
// all incoming offchain messages to all of our peers.
for peer in peers {
swarm.dial(peer.parse::<Multiaddr>().unwrap())?;
}
// We dial all of our peers. Our server will then broadcast
// all incoming offchain messages to all of our peers.
for peer in peers {
if let Ok(addr) = peer.parse::<Multiaddr>() {
if let Err(e) = swarm.dial(addr) {
warn!(target: LOG_TARGET, error = ?e, "Dialing peer.");
}
} else {
warn!(target: LOG_TARGET, peer = %peer, "Invalid Multiaddr, skipping dial.");
}
}

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

♻️ Duplicate comments (1)
crates/torii/libp2p/src/server/mod.rs (1)

171-175: ⚠️ Potential issue

Handle potential parse failures

Ohayo sensei, using unwrap() when parsing Multiaddr may crash the server if the input is invalid. Consider gracefully handling parse errors:

-for peer in peers {
-    swarm.dial(peer.parse::<Multiaddr>().unwrap())?;
-}
+for peer in peers {
+    if let Ok(addr) = peer.parse::<Multiaddr>() {
+        if let Err(e) = swarm.dial(addr) {
+            warn!(target: LOG_TARGET, error = ?e, "Dialing peer.");
+        }
+    } else {
+        warn!(target: LOG_TARGET, peer = %peer, "Invalid Multiaddr, skipping dial.");
+    }
+}
🧹 Nitpick comments (1)
crates/torii/libp2p/src/server/mod.rs (1)

301-301: More robust pattern matching with wildcard.

Ohayo sensei! Good improvement changing from specifically matching None to using a wildcard pattern. This makes the code more flexible to handle any case where entity_identity isn't a Some value.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f0d5a44 and 4b5306d.

📒 Files selected for processing (2)
  • crates/torii/libp2p/src/constants.rs (1 hunks)
  • crates/torii/libp2p/src/server/mod.rs (5 hunks)
🔇 Additional comments (3)
crates/torii/libp2p/src/constants.rs (1)

3-3: LGTM! New messaging topic for peer communication.

Ohayo sensei! The new constant for peer-to-peer communication is well-named and follows the same pattern as the existing message topic.

crates/torii/libp2p/src/server/mod.rs (2)

72-72: Well-designed parameter addition for peer connections.

Ohayo sensei! Nice work adding support for connecting to other Torii relays.


187-191: LGTM! Subscription to peer messaging topic.

Ohayo sensei! Excellent work setting up the subscription to the peer messaging topic, consistent with how other topics are handled.

Comment on lines +372 to +394
// We only want to publish messages from our clients. Not from our peers
// otherwise recursion hell :<
if message.topic != IdentTopic::new(constants::MESSAGING_TOPIC).hash() {
continue;
}

// Publish message to all peers
if let Err(e) = self
.swarm
.behaviour_mut()
.gossipsub
.publish(
IdentTopic::new(constants::PEERS_MESSAGING_TOPIC),
serde_json::to_string(&data).unwrap(),
)
.map_err(Error::PublishError)
{
info!(
target: LOG_TARGET,
error = %e,
"Publishing message to peers."
);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential serialization failure

Ohayo sensei! The code has a robust check to prevent recursion when forwarding messages, but there's an unwrap() call that could cause the server to crash if serialization fails.

if let Err(e) = self
    .swarm
    .behaviour_mut()
    .gossipsub
    .publish(
        IdentTopic::new(constants::PEERS_MESSAGING_TOPIC),
-        serde_json::to_string(&data).unwrap(),
+        match serde_json::to_string(&data) {
+            Ok(serialized) => serialized,
+            Err(e) => {
+                info!(
+                    target: LOG_TARGET,
+                    error = %e,
+                    "Serializing message for peers."
+                );
+                continue;
+            }
+        },
    )
    .map_err(Error::PublishError)
📝 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
// We only want to publish messages from our clients. Not from our peers
// otherwise recursion hell :<
if message.topic != IdentTopic::new(constants::MESSAGING_TOPIC).hash() {
continue;
}
// Publish message to all peers
if let Err(e) = self
.swarm
.behaviour_mut()
.gossipsub
.publish(
IdentTopic::new(constants::PEERS_MESSAGING_TOPIC),
serde_json::to_string(&data).unwrap(),
)
.map_err(Error::PublishError)
{
info!(
target: LOG_TARGET,
error = %e,
"Publishing message to peers."
);
}
// We only want to publish messages from our clients. Not from our peers
// otherwise recursion hell :<
if message.topic != IdentTopic::new(constants::MESSAGING_TOPIC).hash() {
continue;
}
// Publish message to all peers
if let Err(e) = self
.swarm
.behaviour_mut()
.gossipsub
.publish(
IdentTopic::new(constants::PEERS_MESSAGING_TOPIC),
match serde_json::to_string(&data) {
Ok(serialized) => serialized,
Err(e) => {
info!(
target: LOG_TARGET,
error = %e,
"Serializing message for peers."
);
continue;
}
},
)
.map_err(Error::PublishError)
{
info!(
target: LOG_TARGET,
error = %e,
"Publishing message to peers."
);
}

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 (2)
crates/torii/libp2p/src/server/mod.rs (2)

183-187: ⚠️ Potential issue

Handle potential parse failures

Ohayo sensei, using unwrap() when parsing Multiaddr may crash the server if the input is invalid. Consider gracefully handling parse errors:

-for peer in peers {
-    swarm.dial(peer.parse::<Multiaddr>().unwrap())?;
-}
+for peer in peers {
+    if let Ok(addr) = peer.parse::<Multiaddr>() {
+        if let Err(e) = swarm.dial(addr) {
+            warn!(target: LOG_TARGET, error = ?e, "Dialing peer.");
+        }
+    } else {
+        warn!(target: LOG_TARGET, peer = %peer, "Invalid Multiaddr, skipping dial.");
+    }
+}

384-406: ⚠️ Potential issue

Handle potential serialization failure

Ohayo sensei! The code has a robust check to prevent recursion when forwarding messages, but there's an unwrap() call that could cause the server to crash if serialization fails.

if let Err(e) = self
    .swarm
    .behaviour_mut()
    .gossipsub
    .publish(
        IdentTopic::new(constants::PEERS_MESSAGING_TOPIC),
-        serde_json::to_string(&data).unwrap(),
+        match serde_json::to_string(&data) {
+            Ok(serialized) => serialized,
+            Err(e) => {
+                info!(
+                    target: LOG_TARGET,
+                    error = %e,
+                    "Serializing message for peers."
+                );
+                continue;
+            }
+        },
    )
    .map_err(Error::PublishError)
🧹 Nitpick comments (1)
crates/torii/libp2p/src/server/mod.rs (1)

76-85: Keep an eye on the code formatting issue on line 70.

Ohayo sensei! The pipeline is reporting a code formatting issue on line 70 related to "inconsistent use of function call formatting." This might be related to how the parameters are aligned between the two function declarations.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b5306d and 5fc639e.

📒 Files selected for processing (2)
  • crates/torii/libp2p/src/server/mod.rs (5 hunks)
  • crates/torii/runner/src/lib.rs (1 hunks)
🧰 Additional context used
🪛 GitHub Actions: ci
crates/torii/libp2p/src/server/mod.rs

[error] 70-70: Code formatting issues detected: inconsistent use of function call formatting.

🔇 Additional comments (5)
crates/torii/runner/src/lib.rs (1)

225-234: LGTM! Relay server now connects to specified peers.

Ohayo sensei! You've successfully updated the run method to use the new new_with_peers function, allowing the relay server to connect to a specified list of peers. This change enables inter-torii messaging for offchain messages as mentioned in the PR objectives.

crates/torii/libp2p/src/server/mod.rs (4)

63-74: Good refactoring of the Relay constructor!

Ohayo sensei! You've nicely refactored the original new method to delegate to the new new_with_peers method with an empty peer list. This maintains backward compatibility while adding new functionality.

🧰 Tools
🪛 GitHub Actions: ci

[error] 70-70: Code formatting issues detected: inconsistent use of function call formatting.


199-204: Good subscription to the peer messaging topic!

Ohayo sensei! You've properly subscribed to the new peer messaging topic, which is necessary for inter-torii communication.


313-324: Pattern matching improvement with wildcard.

The change from None to wildcard match (_) improves the code by catching any case where entity_identity isn't present or can't be parsed from the database. This is more robust and will handle unexpected states better.


384-389: Great recursion prevention logic!

Ohayo sensei! The check to ensure messages don't recursively propagate between peers is essential for preventing potential infinite loops or message storms in the network. This is a very important safety measure.

Copy link

codecov bot commented Mar 6, 2025

Codecov Report

Attention: Patch coverage is 89.85507% with 7 lines in your changes missing coverage. Please review.

Project coverage is 57.26%. Comparing base (d008071) to head (528487e).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
crates/torii/libp2p/src/server/mod.rs 91.11% 4 Missing ⚠️
crates/torii/runner/src/lib.rs 0.00% 2 Missing ⚠️
crates/torii/cli/src/options.rs 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3082      +/-   ##
==========================================
+ Coverage   57.22%   57.26%   +0.04%     
==========================================
  Files         441      441              
  Lines       60098    60182      +84     
==========================================
+ Hits        34390    34464      +74     
- Misses      25708    25718      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

1 participant