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

fix: circuit relay v2 follow up items #1619

Merged
merged 3 commits into from
Mar 14, 2023

Conversation

achingbrain
Copy link
Member

@achingbrain achingbrain commented Mar 8, 2023

Code sanitation:

  • splits code and config into transport and server
  • updates docs
  • consolidates relay and circuit tests
  • updates relay discovery to use topology
  • increases test coverage
  • reuses connection gater for acl instead of introducing a new acl mechanism
  • adds migration guide

Bug fixes:

  • if multiple relays are discovered simultaneously, try to reserve a slot in them in series, otherwise we can end up listening on multiple relays by accident
  • relay server tags the reserving peer instead of tagging itself
  • incoming remote address was missing p2p-circuit tuple so we were allowing relay to relay forwarding
  • relay client tags outgoing relay connections
  • limit data transfer as total in both directions instead of apply limit to both sides of the relayed stream separately
  • allow client to refuse incoming relayed connections

fixes: #1608
refs: #1610

Code sanitation:

- splits code and config into transport and server
- updates docs
- consolidates relay and circuit tests
- updates relay discovery to use topology
- increases test coverage

Bug fixes:

- if multiple relays are discovered simultaneously, try to reserve a slot in them in series, otherwise we can end up listening on multiple relays by accident
- relay server tags the reserving peer instead of tagging itself
- incoming remote address was missing `p2p-circuit` tuple so we were allowing relay to relay forwarding
- relay client tags outgoing relay connections

fixes: #1608
refs: #1610
@achingbrain achingbrain force-pushed the fix/refactor-circuit-relay-v2 branch from 68a9456 to 5d36dec Compare March 9, 2023 01:21
@maschad maschad mentioned this pull request Mar 9, 2023

## Circuit Relay v2

[email protected] ships with support for [Circuit Relay v2](https://github.com/libp2p/specs/blob/master/relay/circuit-v2.md). This update to the spec changes the relay from being an open relay by default, and as such quite dangerous to enable, to being a limited relay with a slot reservation mechanism that is much safer.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does the JS impl use ASNs to limit the peers?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not out of the box, but the connection gater interface can be used to do this.

Copy link
Collaborator

@MarcoPolo MarcoPolo left a comment

Choose a reason for hiding this comment

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

Quick review. This looks good. I think it would be better if we had some metrics here and can see how this behaves after some time on the real network. Can other nodes use it? Can it use other nodes?

* example, the DHT needs some peers to be able to publish) this
* value should be high enough that they will have warmed up
*/
bootDelay?: number
Copy link
Collaborator

Choose a reason for hiding this comment

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

seems like a hack, no? Should the content routers know to hold off on publishing until they are warm enough? This component would have less context on that than the content router itself.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. The bootDelay option is carried over from the previous implementation, but it would be an improvement for, say, the dht to buffer up network queries until it's first self-query has run.

// result.expire is non-null if `ReservationStore.reserve` returns with status == OK
if (result.expire != null) {
const ttl = new Date().getTime() - result.expire
await this.peerStore.tagPeer(connection.remotePeer, RELAY_SOURCE_TAG, { value: 1, ttl })
Copy link
Collaborator

Choose a reason for hiding this comment

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

what does value: 1 mean?

Copy link
Member Author

Choose a reason for hiding this comment

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

The connection manager has a max connections setting - when a node breaches this setting the connection manager chooses connections to prune.

It does this by sorting the connections by peer value and peer values are derived from their tags.

Random incoming dials will have a value of 0 so will be pruned first - setting the tag value to 1 here makes the peer ever so slightly more valuable than a random incoming dial but not as valuable as a peer that is kad-close, a bootstrap node during startup or a in a gossipsub topic mesh, for example.

return
}

if (isRelayAddr(connection.remoteAddr)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

why twice? We already did this check above

}

const destinationConnection = connections[0]
log('hop connect request from %s to %s is valid', connection.remotePeer, dstPeer)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a debug log level so that we don't log this all the time under normal operation?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, there's log.trace. Can probably remove this line though.

Copy link
Member Author

Choose a reason for hiding this comment

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

FWIW under normal operation these log lines are all no-ops, stuff is only logged if the DEBUG env var is set.

type: StopMessage.Type.CONNECT,
peer: {
id: connection.remotePeer.toBytes(),
addrs: [multiaddr(`/p2p/${connection.remotePeer.toString()}`).bytes]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need the addrs field? It doesn't say so in the spec: https://github.com/libp2p/specs/blob/master/relay/circuit-v2.md#stop-protocol

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think so, no. There's no information there that isn't elsewhere in the message anyway.

@achingbrain
Copy link
Member Author

I'm going to merge this to unblock the other PRs. We should hold off release until the multiaddr/webrtc naming thing is resolved.

Adding metrics is a good idea, this can be done as a follow up.

@achingbrain achingbrain merged commit b085562 into master Mar 14, 2023
@achingbrain achingbrain deleted the fix/refactor-circuit-relay-v2 branch March 14, 2023 07:02
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.

Circuit Relay v2 follow up work items
2 participants