topology-foundation / ts-topology

The official TypeScript implementation of Topology Protocol
https://topology-foundation.github.io/ts-topology/
MIT License
25 stars 15 forks source link

Peers won't discover neighbors topics subscriptions when relayed #27

Closed d-roak closed 3 months ago

d-roak commented 3 months ago

We are currently having an issue where peers are not aware of their neighbors topics when they use a relay. Everything works perfectly when both peers are in the same network (either localhost or LAN), we assume it would also work if both peers weren't behind NATs and had a direct connection (we didn't tested this).

Things we tested:

Things to check:

Things to test around:

achingbrain commented 3 months ago

By default the Circuit Relay protocol only allows a small amount of data to be transferred over a relayed connection - if the limit is breached the relay will close the connection - this is to ensure relays can be run to help other nodes create direct connections but not be an open relay which is ripe for abuse.

By default there are only a few protocols that will run over relayed connections - Identify is one of them but Gossipsub is not.

Your peers should use the relay to establish a direct connection, over which Gossipsub should run as expected.

d-roak commented 3 months ago

@achingbrain thanks for helping out! It seems that enabling runOnTransientConnection on both gossipsub configs and stream options fixed the issues of no communication at all. With what u said, I am afraid we will still have limitations regarding the amount of data transmitted on those connections.

achingbrain commented 3 months ago

runOnTransientConnection should be left as the default value of false, otherwise you're likely to have your connection closed unexpectedly by the relay once the data/time limits are reached.

Since it works on a LAN and it works via a relay it sounds like the two nodes are failing to make a direct connection.

Have you configured any STUN servers?

If not can you please try updating the config of the two NATed nodes to something like:

const node = await createLibp2p({
  //... other config
  transports: [
    //... other transports
    webRTC({
      rtcConfiguration: {
        iceServers: [{
          urls: ['stun:stun.l.google.com:19302']
        }, {
          urls: ['stun:global.stun.twilio.com:3478']
        }]
      }
    })
  ]
})

There will be something like this as default config in the next release so it shouldn't be necessary forever.

d-roak commented 3 months ago

Yep. The initial tests we made didn't have the STUN servers configured and the ones that followed had both STUN and relaying enabled, so the results were unclear.

Currently, it's working, we still need to debug some scenarios where there is a connection, the messaging is working, but the handler is failing (high probability is on our side).

We still found some edge cases where STUN is insufficient to make a direct connection (w/ VPNs in the mix). This is out-of-scope for now.

Thank you so much for taking the time to help out fixing our issues!

achingbrain commented 3 months ago

Great stuff, glad you got it sorted out.

There will be something like this as default config in the next release so it shouldn't be necessary forever.

This shipped in @libp2p/webrtc@4.1.1 yesterday so you shouldn't need to specify STUN servers manually any more.

Also if you like, please feel free to PR your logo into the js-libp2p README - https://github.com/libp2p/js-libp2p#used-by