Skip to content

Commit

Permalink
feat: auto relay network query for new relays
Browse files Browse the repository at this point in the history
  • Loading branch information
vasco-santos committed Sep 23, 2020
1 parent 2b6c231 commit 8060470
Show file tree
Hide file tree
Showing 11 changed files with 471 additions and 196 deletions.
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"aggregate-error": "^3.0.1",
"any-signal": "^1.1.0",
"bignumber.js": "^9.0.0",
"cids": "^1.0.0",
"class-is": "^1.1.0",
"debug": "^4.1.1",
"err-code": "^2.0.0",
Expand All @@ -66,6 +67,7 @@
"moving-average": "^1.0.0",
"multiaddr": "^8.0.0",
"multicodec": "^2.0.0",
"multihashing-async": "^2.0.1",
"multistream-select": "^1.0.0",
"mutable-proxy": "^1.0.0",
"node-forge": "^0.9.1",
Expand All @@ -89,18 +91,17 @@
"chai-as-promised": "^7.1.1",
"chai-bytes": "^0.1.2",
"chai-string": "^1.5.0",
"cids": "^1.0.0",
"delay": "^4.3.0",
"dirty-chai": "^2.0.1",
"interop-libp2p": "^0.3.0",
"ipfs-http-client": "^46.0.0",
"ipfs-http-client": "^47.0.1",
"it-concat": "^1.0.0",
"it-pair": "^1.0.0",
"it-pushable": "^1.4.0",
"libp2p": ".",
"libp2p-bootstrap": "^0.12.0",
"libp2p-delegated-content-routing": "^0.6.0",
"libp2p-delegated-peer-routing": "^0.6.0",
"libp2p-delegated-content-routing": "^0.7.0",
"libp2p-delegated-peer-routing": "^0.7.0",
"libp2p-floodsub": "^0.23.0",
"libp2p-gossipsub": "^0.6.0",
"libp2p-kad-dht": "^0.20.0",
Expand Down
58 changes: 46 additions & 12 deletions src/circuit/auto-relay.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ const PeerId = require('peer-id')

const { relay: multicodec } = require('./multicodec')
const { canHop } = require('./circuit/hop')

const circuitProtoCode = 290
const hopMetadataKey = 'hop_relay'
const hopMetadataValue = 'true'
const { namespaceToCid } = require('./utils')
const {
CIRCUIT_PROTO_CODE,
HOP_METADATA_KEY,
HOP_METADATA_VALUE,
RELAY_RENDEZVOUS_NS
} = require('./constants')

class AutoRelay {
/**
Expand Down Expand Up @@ -74,15 +77,15 @@ class AutoRelay {
const connection = this._connectionManager.get(peerId)

// Do not hop on a relayed connection
if (connection.remoteAddr.protoCodes().includes(circuitProtoCode)) {
if (connection.remoteAddr.protoCodes().includes(CIRCUIT_PROTO_CODE)) {
log(`relayed connection to ${id} will not be used to hop on`)
return
}

const supportsHop = await canHop({ connection })

if (supportsHop) {
this._peerStore.metadataBook.set(peerId, hopMetadataKey, uint8ArrayFromString(hopMetadataValue))
this._peerStore.metadataBook.set(peerId, HOP_METADATA_KEY, uint8ArrayFromString(HOP_METADATA_VALUE))
await this._addListenRelay(connection, id)
}
} catch (err) {
Expand Down Expand Up @@ -121,15 +124,21 @@ class AutoRelay {
}

// Create relay listen addr
let listenAddr, remoteMultiaddr
let listenAddr, remoteMultiaddr, remoteAddrs

try {
const remoteAddrs = this._peerStore.addressBook.get(connection.remotePeer)
remoteAddrs = this._peerStore.addressBook.get(connection.remotePeer)
// TODO: HOP Relays should avoid advertising private addresses!
remoteMultiaddr = remoteAddrs.find(a => a.isCertified).multiaddr // Get first announced address certified
} catch (_) {
log.error(`${id} does not have announced certified multiaddrs`)
return

// Attempt first if existing
if (!remoteAddrs || !remoteAddrs.length) {
return
}

remoteMultiaddr = remoteAddrs[0].multiaddr
}

if (!remoteMultiaddr.protoNames().includes('p2p')) {
Expand Down Expand Up @@ -188,10 +197,10 @@ class AutoRelay {
continue
}

const supportsHop = metadataMap.get(hopMetadataKey)
const supportsHop = metadataMap.get(HOP_METADATA_KEY)

// Continue to next if it does not support Hop
if (!supportsHop || uint8ArrayToString(supportsHop) !== hopMetadataValue) {
if (!supportsHop || uint8ArrayToString(supportsHop) !== HOP_METADATA_VALUE) {
continue
}

Expand Down Expand Up @@ -223,7 +232,32 @@ class AutoRelay {
}
}

// TODO: Try to find relays to hop on the network
// Try to find relays to hop on the network
try {
const cid = await namespaceToCid(RELAY_RENDEZVOUS_NS)
for await (const provider of this._libp2p.contentRouting.findProviders(cid)) {
if (!provider || !provider.id || !provider.multiaddrs || !provider.multiaddrs.length) {
continue
}
const peerId = provider.id

this._peerStore.addressBook.add(peerId, provider.multiaddrs)
const connection = await this._libp2p.dial(peerId)

await this._addListenRelay(connection, peerId.toB58String())

// Check if already listening on enough relays
if (this._listenRelays.size >= this.maxListeners) {
return
}
}
} catch (err) {
if (err.code !== 'NO_ROUTERS_AVAILABLE') {
throw err
} else {
log('there are no routers configured to find hop relay services')
}
}
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/circuit/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'

const minute = 60 * 1000

module.exports = {
ADVERTISE_BOOT_DELAY: 15 * minute,
ADVERTISE_TTL: 30 * minute,
CIRCUIT_PROTO_CODE: 290,
HOP_METADATA_KEY: 'hop_relay',
HOP_METADATA_VALUE: 'true',
RELAY_RENDEZVOUS_NS: '/libp2p/relay'
}
Loading

0 comments on commit 8060470

Please sign in to comment.