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
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions .aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default {
const { MULTIADDRS_WEBSOCKETS } = await import('./dist/test/fixtures/browser.js')
const { plaintext } = await import('./dist/src/insecure/index.js')
const { default: Peers } = await import('./dist/test/fixtures/peers.js')
const { circuitRelayServer, circuitRelayTransport } = await import('./dist/src/circuit/index.js')

// Use the last peer
const peerId = await createFromJSON(Peers[Peers.length - 1])
Expand All @@ -28,6 +29,7 @@ export default {
},
peerId,
transports: [
circuitRelayTransport(),
webSockets()
],
streamMuxers: [
Expand All @@ -37,13 +39,7 @@ export default {
noise(),
plaintext()
],
relay: {
enabled: true,
hop: {
enabled: true,
active: false
}
},
relay: circuitRelayServer(),
nat: {
enabled: false
}
Expand Down
93 changes: 66 additions & 27 deletions doc/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [Setup with Content and Peer Routing](#setup-with-content-and-peer-routing)
- [Setup with Relay](#setup-with-relay)
- [Setup with Automatic Reservations](#setup-with-automatic-reservations)
- [Setup with Preconfigured Reservations](#setup-with-preconfigured-reservations)
- [Setup with Keychain](#setup-with-keychain)
- [Configuring Dialing](#configuring-dialing)
- [Configuring Connection Manager](#configuring-connection-manager)
Expand Down Expand Up @@ -428,54 +429,92 @@ import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'
import { mplex } from '@libp2p/mplex'
import { noise } from '@chainsafe/libp2p-noise'
import { circuitRelayTransport, circuitRelayServer } from 'libp2p/circuit-relay'

const node = await createLibp2p({
transports: [tcp()],
transports: [
tcp(),
circuitRelayTransport({ // allows the current node to make and accept relayed connections
discoverRelays: 0, // how many network relays to find
reservationConcurrency: 1 // how many relays to attempt to reserve slots on at once
})
],
streamMuxers: [mplex()],
connectionEncryption: [noise()],
relay: { // Circuit Relay options
enabled: true, // Allows you to dial and accept relayed connections. Does not make you a relay.
hop: {
enabled: true, // Allows you to be a relay for other peers.
timeout: 30 * 1000, // Incoming hop requests must complete within this timeout
applyConnectionLimits: true // Apply data/duration limits to relayed connections (default: true)
limit: {
duration: 120 * 1000 // the maximum amount of ms a relayed connection can be open for
data: BigInt(1 << 17) // the maximum amount of data that can be transferred over a relayed connection
}
relay: circuitRelayServer({ // makes the node function as a relay server
hopTimeout: 30 * 1000, // incoming relay requests must be resolved within this time limit
advertise: { // if set, use content routing to broadcast availability of this relay
bootDelay: 30 * 1000 // how long to wait after startup before broadcast
},
advertise: {
enabled: true, // Allows you to disable advertising the Hop service
bootDelay: 15 * 60 * 1000, // Delay before HOP relay service is advertised on the network
ttl: 30 * 60 * 1000 // Delay Between HOP relay service advertisements on the network
},
reservationManager: { // the reservation manager creates reservations on discovered relays
enabled: true, // enable the reservation manager, default: false
maxReservations: 1 // the maximum number of relays to create reservations on
reservations: {
maxReservations: 15 // how many peers are allowed to reserve relay slots on this server
reservationClearInterval: 300 * 1000 // how often to reclaim stale reservations
applyDefaultLimit: true // whether to apply default data/duration limits to each relayed connection
defaultDurationLimit: 2 * 60 * 1000 // the default maximum amount of time a relayed connection can be open for
defaultDataLimit: BigInt(2 << 7) // the default maximum number of bytes that can be transferred over a relayed connection
maxInboundHopStreams: 32 // how many inbound HOP streams are allow simultaneously
maxOutboundHopStreams: 64 // how many outbound HOP streams are allow simultaneously
}
}),
connectionGater: {
// used by the server - return true to deny a reservation to the remote peer
denyInboundRelayReservation: (source: PeerId) => Promise<boolean>

// used by the server - return true to deny a relay connection request from the source to the destination peer
denyOutboundRelayedConnection: (source: PeerId, destination: PeerId) => Promise<boolean>

// used by the client - return true to deny a relay connection from the remote relay and peer
denyInboundRelayedConnection: (relay: PeerId, remotePeer: PeerId) => Promise<boolean>
}
})
```

#### Setup with Automatic Reservations

In this configuration the libp2p node will search the network for one relay with a free reservation slot. When it has found one and negotiated a relay reservation, the relayed address will appear in the output of `libp2p.getMultiaddrs()`.

```js
import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'
import { mplex } from '@libp2p/mplex'
import { noise } from '@chainsafe/libp2p-noise'
import { circuitRelayTransport } from 'libp2p/circuit-relay'

const node = await createLibp2p({
transports: [tcp()],
transports: [
tcp(),
circuitRelayTransport({
discoverRelays: 1
})
],
streamMuxers: [mplex()],
connectionEncryption: [noise()]
})
```

#### Setup with Preconfigured Reservations

In this configuration the libp2p node is a circuit relay client which connects to a relay, `/ip4/123.123.123.123/p2p/QmRelay` which has been configured to have slots available.

```js
import { createLibp2p } from 'libp2p'
import { tcp } from '@libp2p/tcp'
import { mplex } from '@libp2p/mplex'
import { noise } from '@chainsafe/libp2p-noise'
import { circuitRelayTransport } from 'libp2p/circuit-relay'

const node = await createLibp2p({
transports: [
tcp(),
circuitRelayTransport()
],
addresses: {
listen: [
'/ip4/123.123.123.123/p2p/QmRelay/p2p-circuit' // a known relay node with reservation slots available
]
},
streamMuxers: [mplex()],
connectionEncryption: [noise()]
relay: { // Circuit Relay options (this config is part of libp2p core configurations)
enabled: true, // Allows you to dial and accept relayed connections. Does not make you a relay.
reservationManager: {
enabled: true, // Allows you to bind to relays with HOP enabled for improving node dialability
maxListeners: 2 // Configure maximum number of HOP relays to use
}
}
})
```

Expand Down
79 changes: 79 additions & 0 deletions doc/migrations/v0.42-v0.43.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Migrating to libp2p@43 <!-- omit in toc -->

A migration guide for refactoring your application code from libp2p v0.42.x to v0.43.0.

## Table of Contents <!-- omit in toc -->

- [Circuit Relay v2](#circuit-relay-v2)

## 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.


With version 2, each relay has a limited number of slots available (default: 15) which network peers can reserve use of to transfer small amounts of data to and from other peers (default 128k) for short amounts of time (default: 2 minutes).

This allows network nodes to act as intermediaries between nodes that may otherwise not be able to communicate due to a lack of compatible transports.

To simplify configuration, the client and server parts of the relay have been split apart to make it easier to configure your node as a client and/or a server.

**Before**

```js
import { createLibp2p } from 'libp2p'

const node = await createLibp2p({
// ... other options
addresses: {
listen: {
'/ip4/123.123.123.123/p2p/QmRelay/p2p-circuit' // optionally configure a static relay
}
},
relay: {
enabled: true, // enable client portion of relay

autoRelay: {
enabled: true, // enable automatically finding network relays
maxListeners: 2 // limit number of network relays to use
}

hop: {
enabled: true, // enable server portion of relay
active: true // dial other nodes on the incoming relay client's behalf
},

advertise: {
enabled: true, // advertise the relay server on this node
bootDelay: 15 * 60 * 1000, // how long to wait after startup before advertising
ttl: 30 * 60 * 1000 // how often to re-advertise
}
}
})
```

**After**

```js
import { createLibp2p } from 'libp2p'
import { circuitRelayClient, circuitRelayServer } from 'libp2p/circuit-relay'

const node = await createLibp2p({
// ... other options
addresses: {
listen: {
'/ip4/123.123.123.123/p2p/QmRelay/p2p-circuit' // optionally configure a static relay
}
},
transports: [
circuitRelayClient({ // enable client portion of relay
discoverRelays: 1 // find this number of network relays (default: 0)
})
],
relay: circuitRelayServer({ // enable server portion of relay
advertise: {
bootDelay: 15 * 60 * 1000 // how long to wait after startup before re-advertising
}
})
})
```

Please see the [Setup with Relay](https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md#setup-with-relay) section of the configuration for a full breakdown of all the options.
4 changes: 3 additions & 1 deletion examples/auto-relay/dialer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { webSockets } from '@libp2p/websockets'
import { noise } from '@chainsafe/libp2p-noise'
import { mplex } from '@libp2p/mplex'
import { multiaddr } from '@multiformats/multiaddr'
import { circuitRelayTransport } from 'libp2p/circuit-relay'

async function main () {
const autoRelayNodeAddr = process.argv[2]
Expand All @@ -12,7 +13,8 @@ async function main () {

const node = await createLibp2p({
transports: [
webSockets()
webSockets(),
circuitRelayTransport()
],
connectionEncryption: [
noise()
Expand Down
15 changes: 6 additions & 9 deletions examples/auto-relay/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { webSockets } from '@libp2p/websockets'
import { noise } from '@chainsafe/libp2p-noise'
import { mplex } from '@libp2p/mplex'
import { multiaddr } from '@multiformats/multiaddr'
import { circuitRelayTransport } from 'libp2p/circuit-relay'

async function main () {
const relayAddr = process.argv[2]
Expand All @@ -12,21 +13,17 @@ async function main () {

const node = await createLibp2p({
transports: [
webSockets()
webSockets(),
circuitRelayTransport({
discoverRelays: 2
})
],
connectionEncryption: [
noise()
],
streamMuxers: [
mplex()
],
relay: {
enabled: true,
autoRelay: {
enabled: true,
maxListeners: 2
}
}
]
})

console.log(`Node started with id ${node.peerId.toString()}`)
Expand Down
11 changes: 2 additions & 9 deletions examples/auto-relay/relay.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createLibp2p } from 'libp2p'
import { webSockets } from '@libp2p/websockets'
import { noise } from '@chainsafe/libp2p-noise'
import { mplex } from '@libp2p/mplex'
import { circuitRelayServer } from 'libp2p/circuit-relay'

async function main () {
const node = await createLibp2p({
Expand All @@ -19,15 +20,7 @@ async function main () {
streamMuxers: [
mplex()
],
relay: {
enabled: true,
hop: {
enabled: true
},
advertise: {
enabled: true,
}
}
relay: circuitRelayServer()
})

console.log(`Node started with id ${node.peerId.toString()}`)
Expand Down
15 changes: 4 additions & 11 deletions examples/delegated-routing/src/libp2p-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { noise } from '@chainsafe/libp2p-noise'
import { delegatedPeerRouting } from '@libp2p/delegated-peer-routing'
import { delegatedContentRouting } from '@libp2p/delegated-content-routing'
import { create as createIpfsHttpClient } from 'ipfs-http-client'
import { circuitRelayTransport } from 'libp2p/circuit-relay'

export default function Libp2pBundle ({peerInfo, peerBook}) {
const wrtcstar = new webRTCStar()
Expand All @@ -34,7 +35,8 @@ export default function Libp2pBundle ({peerInfo, peerBook}) {
],
transports: [
wrtcstar.transport,
webSockets()
webSockets(),
circuitRelayTransport()
],
streamMuxers: [
mplex()
Expand All @@ -44,15 +46,6 @@ export default function Libp2pBundle ({peerInfo, peerBook}) {
],
connectionEncryption: [
noise()
],
connectionManager: {
autoDial: false
},
relay: {
enabled: true,
hop: {
enabled: false
}
}
]
})
}
10 changes: 3 additions & 7 deletions examples/discovery-mechanisms/3.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { noise } from '@chainsafe/libp2p-noise'
import { floodsub } from '@libp2p/floodsub'
import { bootstrap } from '@libp2p/bootstrap'
import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'
import { circuitRelayTransport, circuitRelayServer } from 'libp2p/circuit-relay'

const createNode = async (bootstrappers) => {
const node = await createLibp2p({
Expand Down Expand Up @@ -37,7 +38,7 @@ const createNode = async (bootstrappers) => {
'/ip4/0.0.0.0/tcp/0'
]
},
transports: [tcp()],
transports: [tcp(), circuitRelayTransport()],
streamMuxers: [mplex()],
connectionEncryption: [noise()],
pubsub: floodsub(),
Expand All @@ -46,12 +47,7 @@ const createNode = async (bootstrappers) => {
interval: 1000
})
],
relay: {
enabled: true, // Allows you to dial and accept relayed connections. Does not make you a relay.
hop: {
enabled: true // Allows you to be a relay for other peers
}
}
relay: circuitRelayServer()
})
console.log(`libp2p relay started with id: ${relay.peerId.toString()}`)

Expand Down
Loading