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: Ephemeral peer channels #5346

Merged
merged 87 commits into from
May 17, 2024
Merged

feat: Ephemeral peer channels #5346

merged 87 commits into from
May 17, 2024

Conversation

Septias
Copy link
Contributor

@Septias Septias commented Mar 14, 2024

TLDR: Webxdc API to send ephemeral messages with iroh.

Desktop PR: #3741
Documentation PR: #78
Webxdc Hello PR: #59
Webxdc types PR: #6
Android PR: ?
IOS PR: ?

Gossip Tests: https://github.com/Septias/gossip_tests
Mutliplayer Pong: https://github.com/Septias/multiplayer-pong

Supersedes: #5041

TODO

  • How do we handle chat removals?
  • Expose gossip APIs in cffi
  • polish pong example

WebXDC Realtime API

See Webxdc specs for more info.

Iroh

DeltaChat wants to use the ephemeral-channel provider Iroh, which attempts to establish direct p2p connections between peers (QUIC), using PlumTree as a gossiping protocol for efficient peer sampling. Iroh falls back to relay nodes when a direct connection can not be established. Even a relayed connection is faster than sending single WebXDC messages via mail.

Implementation

Ephemeral channels should be established lazily, to avoid bootstrapping p2p connectivity when it's not required. By asking application developers to explicitly subscribe to ephemeral messages, we know when this should happen.

In any case, we need a way to agree upon a gossip topic ID among all (future) participants, this topic ID should never be guessable or readable to any outsider.

  1. We introduce a new GossipTopic message header with a random 32-byte TopicId, securely generated on the initial webxdc sender’s device. This message header is encrypted and sent in the same message as the webxdc application.
  2. Whenever joinRealtimeChannel().setListener() or joinRealtimeChannel().send() is called by the webxdc application, we start a routine to establish p2p connectivity and join the gossip swarm with Iroh.
  3. The first step of this routine is to introduce yourself with a regular message containing the IrohPublicKey. This message contains the users relay-server and public key. Direct IP address are not included as this information can be persisted by email providers.
  4. After the announcement, the sending peer joins the gossip swarm with an empty list of peer IDs (as they don’t know anyone yet).
  5. Upon receiving an announcement message, other peers store the sender’s NodeAddr in the database (scoped per WebXDC app instance/message-id). The other peers can then join the gossip with joinRealtimeChannel().setListener() and joinRealtimeChannel().send() just like the other peers.

Testing

The application can be tested using the sk/ephemeral_peer_channels branch on the desktop and core. To setup local core on desktop, see here.

You then need two accounts that know each other and a testing xdc. One option is gossip test which can be downloaded from this repository. Another option is the multiplayer pong game located here.

@Septias Septias force-pushed the sk/ephemeral_peer_channels branch from a0429e6 to ddb0eeb Compare April 3, 2024 10:13
src/context.rs Outdated Show resolved Hide resolved
src/peer_channels.rs Outdated Show resolved Hide resolved
deltachat-jsonrpc/src/api.rs Show resolved Hide resolved
deltachat-jsonrpc/src/api.rs Show resolved Hide resolved
src/peer_channels.rs Outdated Show resolved Hide resolved
src/peer_channels.rs Show resolved Hide resolved
src/imap.rs Show resolved Hide resolved
src/peer_channels.rs Outdated Show resolved Hide resolved
src/peer_channels.rs Show resolved Hide resolved
flake.nix Outdated
@@ -525,15 +525,25 @@
};
};

devShells.default = pkgs.mkShell {
devShells.default = let
Copy link
Collaborator

Choose a reason for hiding this comment

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

Unrelated changes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same as #5548.
Should vanish when we merge the PR and the merge main.

@link2xt link2xt changed the base branch from main to sk/update_flake May 17, 2024 16:56
@link2xt link2xt changed the base branch from sk/update_flake to main May 17, 2024 16:57
Copy link
Collaborator

@link2xt link2xt left a comment

Choose a reason for hiding this comment

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

Let's merge it, but it seems we need to move all the tests from Rust to Python. Current Rust tests only work because of hardcoded relay, and we don't actually want any hardcoded relay, only the one which comes from metadata. iroh.testrun.org is not supported to be running forever.

@link2xt
Copy link
Collaborator

link2xt commented May 17, 2024

Also there is still no way to disable it.

@link2xt link2xt merged commit 36f1fc4 into main May 17, 2024
32 of 37 checks passed
@link2xt link2xt deleted the sk/ephemeral_peer_channels branch May 17, 2024 20:13
@dignifiedquire
Copy link
Member

🎉

@Septias Septias restored the sk/ephemeral_peer_channels branch May 18, 2024 08:38
}

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_can_reconnect() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This test is timing out in #5619 in Rust CI / Rust tests (ubuntu-latest, 1.77.0)

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

Successfully merging this pull request may close these issues.

None yet

7 participants