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

Help js browser peers discover each other out of the box #95

Open
2color opened this issue Sep 27, 2023 · 19 comments
Open

Help js browser peers discover each other out of the box #95

2color opened this issue Sep 27, 2023 · 19 comments
Assignees

Comments

@2color
Copy link
Collaborator

2color commented Sep 27, 2023

Background

When I initially created this project, I aimed to have it simply work when loaded in the browser for demo purposes. I wanted to show how easy libp2p makes it for different runtimes and languages to connect to each other — even when behind NAT.

I wanted to be able to just share the URL as part of a talk/demo, and for browsers to just establish connectivity with each other.

Moreover, it expands the scope of this demo app to include a critical part of any libp2p app, namely peer discovery/routing.

Current challenges

  • There's no existing protocol or suggestions regarding how browsers should discover each other's webrtc multiaddrs.

  • The example relies on hardcoded ephemeral multiaddrs — this is actually an antipattern because the multiaddrs are invalid after a the certificates are rotated (~ 2 weeks).

Ideal case

  • We have both Rust and Go peers deployed. feat(rust): automated deployment to fly.io #91 should solve the Rust node
  • The js peer has the PeerIds of the Rust and Go peers, hardcoded
  • The js peer can do peer routing to discover the latest multiaddrs of the Rust/Go peers

Open questions

  • Which peer routing/discovery approach should be used for this? DHT with the public bootstrap nodes or Rendezvous?
@2color
Copy link
Collaborator Author

2color commented Sep 27, 2023

Based on https://libp2p.io/implementations/, js-libp2p doesn't support Rendezvous in the browser
Screenshot 2023-09-27 at 12 27 04 PM

@thomaseizinger
Copy link
Contributor

What does bootstrap refer to? And I am pretty sure rust-libp2p can do random walks :)

Seems to be outdated! I'll put it on my list for tomorrow to update!

@2color
Copy link
Collaborator Author

2color commented Sep 27, 2023

What does bootstrap refer to?

Not sure what you mean with this question

@thomaseizinger
Copy link
Contributor

What does bootstrap refer to?

Not sure what you mean with this question

The first row in the screenshot you posted.

@2color
Copy link
Collaborator Author

2color commented Sep 27, 2023

I don't actually know what is referred to there. It links to the kad-DHT spec https://github.com/libp2p/specs/blob/master/kad-dht/README.md#bootstrap-process but it doesn't go into the actual details and it isn't clear what is referred to.

@p-shahi Any thoughts?

@thomaseizinger
Copy link
Contributor

I don't actually know what is referred to there. It links to the kad-DHT spec libp2p/specs@master/kad-dht/README.md#bootstrap-process but it doesn't go into the actual details and it isn't clear what is referred to.

@p-shahi Any thoughts?

Yep, just realised that too. rust-libp2p definitely supports that so I'll update that!

@2color 2color changed the title Make the browser app work out of the box Help js browser peers discover each other out of the box Sep 28, 2023
@maceip
Copy link
Contributor

maceip commented Sep 28, 2023

To keep the magic alive I'd be interested in trying to come up with a way to get users (who can't or won't run local server clients) to collaborate in support of browser-browser connectivity. Harken back to the old folding@home or seti@home days?

I would personally donate a node with a public IP running relayV2, thus enabling users to drive-by connect using the js-peer in this demo -- but what's the fun in that and what are we showing them anyways?

Given how many conferences we all go to, I think a better use case would be to demo WebRTC data channel establishment & signaling via QRcode in person. This has an interesting property as it requires you to actually talk to people, and gives you a cool reason to do so. Each time you connect you get one non-financial/non-redeemable libp2p point to be proudly showcased in your git profile, via IPLD 💚

@2color
Copy link
Collaborator Author

2color commented Sep 28, 2023

Thanks for your input @maceip — I appreciate your willingness to help and donate.

Given how many conferences we all go to, I think a better use case would be to demo WebRTC data channel establishment & signaling via QRcode in person.

That's pretty neat, but it's worth pointing out that this approach would only work on a local network due to NAT hole punching. Here's some prior work on this:

@maceip
Copy link
Contributor

maceip commented Sep 28, 2023

precisely! what better way to demo the power of libp2p than at a conference hall with 10-10k people all on the same (v)LAN!

If you want an online demo that shows how a users browser window can connect to a hosted relay / hosted peer, we can definitely do that but if you are going to hardcode the multiaddr -- what is the user journey here?

Nevertheless, watching the the js helia / ipfs debug output (like in the repo's listed below ::hattip:: @achingbrain ) makes it worthwhile to just get something up that works:

https://github.com/ipfs-shipyard/www-helia-identify/tree/main/src
https://github.com/ipfs-shipyard/www-libp2p-webtransport-sessions

I'm not sure the best way to donate here -- it's likely that i'll spin up some server, give it dns, and then in ~5 years i'll be on an island and forget about it and rm -rf it :(

@thomaseizinger
Copy link
Contributor

Given how many conferences we all go to, I think a better use case would be to demo WebRTC data channel establishment & signaling via QRcode in person.

If both parties have a connection to the relay, all the QR code needs to contain is the nodes peer ID and you are good to connect!

@maceip
Copy link
Contributor

maceip commented Sep 29, 2023

I spun up a node on AWS in milan (closest region to istanbul), running latest helia / ubuntu / caddy. the username.rs domain was purchased by me a few days ago to try to take over the world but that never happened, so it is unused. I can donate this to y'all if needed. The AWS account has startup accelerator credits so at a minimum it will fund this relay for 12 months. at the moment it's not doing ci/cd, but can do later. ->

relay info:

https://relay.username.rs/info/

and the hosted js-peer, bootstrapping off the relay:

https://relay.username.rs/u/

and the stable multiaddr browsers can use as a bootstrap:

/dns4/relay.username.rs/tcp/443/wss/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3

will upload the repo and share -- y'all can decide what you want to do with it or how to manage it.

@polus-arcticus
Copy link

polus-arcticus commented Oct 3, 2023

Thanks for opening this @2color this type of functionality was provided out of the box with js-libp2p-webrtc-star where i could simply https://github.com/libp2p/js-libp2p-webrtc-star/blob/master/packages/webrtc-star-signalling-server/DEPLOYMENT.md and have two browser windows doing pubsub and automatically discovering each other, for ui/ux that feels just like doing pubsub over a centralized server. But recreating this after the depreciation of the star protocols has proven a major challenge for me

@thomaseizinger
Copy link
Contributor

Wrote up a proposal for ambient peer discovery here: libp2p/specs#587

@2color
Copy link
Collaborator Author

2color commented Oct 4, 2023

Thanks @maceip for your efforts. I was able to connect from the browser app to /dns4/relay.username.rs/tcp/443/wss/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3 get the browser node's listen address then connect to another browser tab.

Not exactly sure why, but even once the connection between two browser nodes is established, exchanging chat messages doesn't work. Not sure exactly why.

If you want an online demo that shows how a users browser window can connect to a hosted relay / hosted peer, we can definitely do that but if you are going to hardcode the multiaddr -- what is the user journey here?

We were thinking of prefilling the multiaddr input field with the deployed rust peer multiaddr, and allowing the user to optionally connect to it or alternatively, passing in your own relay multiaddr.

At this point, messages in the chat should get relayed between browser nodes, since the rust peer is also subscribed to the pubsub topic.

There may be some limits to how many concurrent browser peers can exchange messages by only being connected to the rust peer. This is where directly connecting to other browser peers may be useful and where ambient peer discovery may be useful.

@thomaseizinger How does that align with your vision and understanding of the protocol constraints?

@maceip
Copy link
Contributor

maceip commented Oct 4, 2023

Thanks @maceip for your efforts. I was able to connect from the browser app to /dns4/relay.username.rs/tcp/443/wss/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3 get the browser node's listen address then connect to another browser tab.

Not exactly sure why, but even once the connection between two browser nodes is established, exchanging chat messages doesn't work. Not sure exactly why.

Just tested it by: On one tab I went to /u/, it connected to bootstrap relay, then I copied it's WebRTC multiaddr:

ip4/127.0.0.1/tcp/8001/ws/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3/p2p-circuit/webrtc/p2p/12D3KooWGW3nqSaQAfqWvwCotAySUyJRtXktMXRcTMB7frkU6krR

I then opened another tab and browsed to /u/, and after it connected to the relay I pasted in the above WebRTC multiaddr and hit connect. It connected and then chat worked:

Screenshot_20231004-084825
Screenshot_20231004-084729

@2color
Copy link
Collaborator Author

2color commented Oct 4, 2023

Thanks @maceip — I tried again and it works.

It didn't work the first time because I mistakenly used the /p2p-circuit/p2p/ relay address rather than the webrtc one. It results in a connection, but I presume all traffic is relayed as it is a circuit relay v2 connection rather than a direct WebRTC one that is constrained and therefore doesn't work for gossipsub messages:
Screenshot 2023-10-04 at 5 03 17 PM

Anyway, with the webrtc multiaddr, the chat works too! Now we have to figure out ambient peer discovery

@thomaseizinger
Copy link
Contributor

There may be some limits to how many concurrent browser peers can exchange messages by only being connected to the rust peer. This is where directly connecting to other browser peers may be useful and where ambient peer discovery may be useful.

@thomaseizinger How does that align with your vision and understanding of the protocol constraints?

There are for sure limits! We don't have any numbers on gossipsub messages but the IPFS bootstrap nodes handled 40k connections pretty easily with ~ 300kb RAM per connection. Based on the available RAM on the smallest fly.io instance that we are running on, that is about 500 connections :)

@thomaseizinger
Copy link
Contributor

There may be some limits to how many concurrent browser peers can exchange messages by only being connected to the rust peer. This is where directly connecting to other browser peers may be useful and where ambient peer discovery may be useful.
@thomaseizinger How does that align with your vision and understanding of the protocol constraints?

There are for sure limits! We don't have any numbers on gossipsub messages but the IPFS bootstrap nodes handled 40k connections pretty easily with ~ 300kb RAM per connection. Based on the available RAM on the smallest fly.io instance that we are running on, that is about 500 connections :)

This made me think that we probably want to add some connection limits :)

#102

@2color
Copy link
Collaborator Author

2color commented Feb 21, 2024

A couple of thoughts on how we could we could improve browser-to-browser connectivity out of the box this without necessarily introducing a new protocol:

  • Create a dedicated topic for exchanging webrtc multiaddrs (not webrtc direct) and publish from the Go/Rust peer a selected subset of the multiaddrs of webrtc peers already connected to you when a new browser peer connects to you.
    • Browsers would subscribe to this topic and try connecting to multiaddrs they receive.
  • To solve the problem of the ephemeral webtransport and webrtc multiaddrs of the bootstrappers expiring (due to the ephemeral self-signed certificate), we could instead just hardcode the PeerID which remains stable into the frontend, and use the delegated routing PUTs in order to publish their multiaddrs to the delegated routing endpoint.

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

No branches or pull requests

4 participants