Skip to content

Commit 5931f0e

Browse files
committed
chore: cleanup
1 parent ebb22d1 commit 5931f0e

File tree

7 files changed

+113
-63
lines changed

7 files changed

+113
-63
lines changed

LIBP2P.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Rendezvous Protocol in js-libp2p
22

3-
The rendezvous protocol can be used in different contexts across libp2p. For using it, the libp2p network needs to have well known libp2p nodes acting as rendezvous servers. These nodes will have an extra role in the network. They will collect and maintain a list of registrations per rendezvous namespace. Other peers in the network will act as rendezvous clients and will register themselves on given namespaces by messaging a rendezvous server node. Taking into account these registrations, a rendezvous client is able to discover other peers in a given namespace by querying a server.
3+
The rendezvous protocol can be used in different contexts across libp2p. For using it, the libp2p network needs to have well known libp2p nodes acting as rendezvous servers. These nodes will have an extra role in the network. They will collect and maintain a list of registrations per rendezvous namespace. Other peers in the network will act as rendezvous clients and will register themselves on given namespaces by messaging a rendezvous server node. Taking into account these registrations, a rendezvous client is able to discover other peers in a given namespace by querying a server. A registration should have a `ttl`, in order to avoid having invalid registrations.
44

55
## Usage
66

7-
`js-libp2p` supports the usage of the rendezvous protocol through its configuration. It allows to enable the rendezvous protocol, as well as its server mode, enable automatic peer discover and to specify the topics to register from startup.
7+
`js-libp2p` supports the usage of the rendezvous protocol through its configuration. It allows the rendezvous protocol to be enabled, as well as its server mode. In addition automatic peer discovery can be enabled and namespaces to register can be specified from startup through the config.
88

99
The rendezvous comes with a discovery service that enables libp2p to automatically discover other peers in the provided namespaces and eventually connect to them.
1010

@@ -40,7 +40,3 @@ If the discovery service is disabled, the rendezvous API should allow users to d
4040
When a libp2p node running the rendezvous protocol is going to stop, it should unregister from all the namespaces previously registered.
4141

4242
In the event of a rendezvous client getting connected to a second rendezvous server, it should propagate its registrations to it. The rendezvous server should clean its registrations for a peer when it is not connected with it anymore.
43-
44-
## Other notes:
45-
46-
After a query is made, who is responsible for determining if we need more records? (cookie reuse)

README.md

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,67 @@ See https://github.com/libp2p/specs/tree/master/rendezvous for more details
1919

2020
## API
2121

22+
### constructor
23+
24+
Creating an instance of Rendezvous.
25+
26+
`const rendezvous = new Rendezvous({ libp2p })`
27+
28+
#### Parameters
29+
30+
| Name | Type | Description |
31+
|------|------|-------------|
32+
| params | `object` | rendezvous parameters |
33+
| params.libp2p | `Libp2p` | a libp2p node instance |
34+
| params.namespaces | `Array<string>` | namespaces to keep registering and discovering over time (default: `[]`) |
35+
| params.server | `object` | rendezvous server options |
36+
| params.server.enabled | `boolean` | rendezvous server enabled (default: `true`) |
37+
| params.server.gcInterval | `number` | rendezvous garbage collector interval (default: `3e5`) |
38+
| params.discovery | `object` | rendezvous peer discovery options |
39+
| params.discovery.interval | `number` | automatic rendezvous peer discovery interval (default: `5e3`) |
40+
41+
### rendezvous.start
42+
43+
Register the rendezvous protocol topology into libp2p and starts its internal services. The rendezvous server will be started if enabled, as well as the service to keep self registrations available.
44+
45+
`rendezvous.start()`
46+
47+
When registering to new namespaces from the API, the new namespace will be added to the registrations to keep by default.
48+
49+
### rendezvous.stop
50+
51+
Unregister the rendezvous protocol and the streams with other peers will be closed.
52+
53+
`rendezvous.stop()`
54+
55+
### rendezvous.discovery.start
56+
57+
Starts the rendezvous automatic discovery service.
58+
59+
`rendezvous.discovery.start()`
60+
61+
Like other libp2p discovery protocols, it will emit `peer` events when new peers are discovered.
62+
63+
### rendezvous.discovery.stop
64+
65+
Stops the rendezvous automatic discovery service.
66+
67+
`rendezvous.discovery.stop()`
68+
2269
### rendezvous.register
2370

2471
Registers the peer in a given namespace.
2572

26-
`rendezvous.register(namespace, [ttl])`
73+
`rendezvous.register(namespace, [options])`
2774

2875
#### Parameters
2976

3077
| Name | Type | Description |
3178
|------|------|-------------|
3279
| namespace | `string` | namespace to register |
33-
| ttl | `number` | registration ttl in ms (default: `7200e3` and minimum `120`) |
80+
| options | `object` | rendezvous registrations options |
81+
| options.ttl | `number` | registration ttl in ms (default: `7200e3` and minimum `120`) |
82+
| options.keep | `boolean` | register over time to guarantee availability (default: `true`) |
3483

3584
#### Returns
3685

@@ -75,15 +124,14 @@ await rendezvous.unregister(namespace)
75124

76125
Discovers peers registered under a given namespace.
77126

78-
`rendezvous.discover(namespace, [limit], [cookie])`
127+
`rendezvous.discover(namespace, [limit])`
79128

80129
#### Parameters
81130

82131
| Name | Type | Description |
83132
|------|------|-------------|
84133
| namespace | `string` | namespace to discover |
85134
| limit | `number` | limit of peers to discover |
86-
| cookie | `Buffer` | |
87135

88136
#### Returns
89137

src/discovery.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ log.error = debug('libp2p:redezvous:discovery:error')
66

77
const { EventEmitter } = require('events')
88

9+
const { codes: errCodes } = require('./errors')
10+
911
const defaultOptions = {
10-
interval: 5000
12+
interval: 5e3
1113
}
1214

1315
/**
@@ -57,12 +59,19 @@ class Discovery extends EventEmitter {
5759
*/
5860
_discover () {
5961
this._rendezvous._namespaces.forEach(async (ns) => {
60-
for await (const reg of this._rendezvous.discover(ns)) {
61-
// TODO: interface-peer-discovery with signedPeerRecord
62-
this.emit('peer', {
63-
id: reg.id,
64-
multiaddrs: reg.multiaddrs
65-
})
62+
try {
63+
for await (const reg of this._rendezvous.discover(ns)) {
64+
// TODO: interface-peer-discovery with signedPeerRecord
65+
this.emit('peer', {
66+
id: reg.id,
67+
multiaddrs: reg.multiaddrs
68+
})
69+
}
70+
} catch (err) {
71+
// It will fail while there are no connected rendezvous servers
72+
if (err.code !== errCodes.NO_CONNECTED_RENDEZVOUS_SERVERS) {
73+
throw err
74+
}
6675
}
6776
})
6877
}

src/index.js

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,24 @@ class Rendezvous {
4343
* @constructor
4444
* @param {object} params
4545
* @param {Libp2p} params.libp2p
46-
* @param {object} params.options
4746
* @param {Array<string>} [params.namespaces = []]
4847
* @param {object} [params.discovery]
49-
* @param {number} [params.discovery.interval = 5000]
48+
* @param {number} [params.discovery.interval = 5e3]
5049
* @param {object} [params.server]
5150
* @param {boolean} [params.server.enabled = true]
5251
* @param {number} [params.server.gcInterval = 3e5]
5352
*/
54-
constructor ({ libp2p, options = {} }) {
53+
constructor ({ libp2p, namespaces = [], discovery = {}, server = {} }) {
5554
this._libp2p = libp2p
5655
this._peerId = libp2p.peerId
5756
this._registrar = libp2p.registrar
5857

59-
this._namespaces = options.namespaces || []
60-
this.discovery = new Discovery(this, options.discovery)
58+
this._namespaces = namespaces
59+
this.discovery = new Discovery(this, discovery)
6160

6261
this._serverOptions = {
6362
...defaultServerOptions,
64-
...options.server || {}
63+
...server
6564
}
6665

6766
/**
@@ -84,9 +83,9 @@ class Rendezvous {
8483

8584
/**
8685
* Register the rendezvous protocol in the libp2p node.
87-
* @returns {Promise<void>}
86+
* @returns {void}
8887
*/
89-
async start () {
88+
start () {
9089
if (this._registrarId) {
9190
return
9291
}
@@ -107,18 +106,17 @@ class Rendezvous {
107106
onDisconnect: this._onPeerDisconnected
108107
}
109108
})
110-
this._registrarId = await this._registrar.register(topology)
111-
112-
log('started')
109+
this._registrarId = this._registrar.register(topology)
113110

114111
this._keepRegistrations()
112+
log('started')
115113
}
116114

117115
/**
118116
* Unregister the rendezvous protocol and the streams with other peers will be closed.
119-
* @returns {Promise<void>}
117+
* @returns {void}
120118
*/
121-
async stop () {
119+
stop () {
122120
if (!this._registrarId) {
123121
return
124122
}
@@ -128,7 +126,7 @@ class Rendezvous {
128126
clearInterval(this._interval)
129127

130128
// unregister protocol and handlers
131-
await this._registrar.unregister(this._registrarId)
129+
this._registrar.unregister(this._registrarId)
132130
if (this._serverOptions.enabled) {
133131
this._server.stop()
134132
}
@@ -153,7 +151,7 @@ class Rendezvous {
153151
const promises = []
154152

155153
this._namespaces.forEach((ns) => {
156-
promises.push(this.register(ns))
154+
promises.push(this.register(ns, { keep: false }))
157155
})
158156

159157
return Promise.all(promises)
@@ -195,10 +193,12 @@ class Rendezvous {
195193
/**
196194
* Register the peer in a given namespace
197195
* @param {string} ns
198-
* @param {number} [ttl = 7200e3] registration ttl in ms (minimum 120)
199-
* @returns {Promise<number>}
196+
* @param {object} [options]
197+
* @param {number} [options.ttl = 7200e3] registration ttl in ms (minimum 120)
198+
* @param {number} [options.keep = true] register over time to guarantee availability.
199+
* @returns {Promise<number>} rendezvous register ttl.
200200
*/
201-
async register (ns, ttl = 7200e3) {
201+
async register (ns, { ttl = 7200e3, keep = true } = {}) {
202202
if (!ns) {
203203
throw errCode(new Error('a namespace must be provided'), errCodes.INVALID_NAMESPACE)
204204
}
@@ -253,7 +253,7 @@ class Rendezvous {
253253
throw new Error('unexpected message received')
254254
}
255255

256-
return recMessage.registerResponse.ttl
256+
return recMessage.registerResponse.ttl // TODO: convert to ms
257257
}
258258

259259
for (const id of this._rendezvousPoints.keys()) {
@@ -262,6 +262,10 @@ class Rendezvous {
262262

263263
// Return first ttl
264264
const [returnTtl] = await Promise.all(registerTasks)
265+
266+
// Keep registering if enabled
267+
keep && this._namespaces.push(ns)
268+
265269
return returnTtl
266270
}
267271

@@ -307,6 +311,7 @@ class Rendezvous {
307311
unregisterTasks.push(taskFn(id))
308312
}
309313

314+
this._namespaces.filter((keeptNampesace) => keeptNampesace !== ns)
310315
await Promise.all(unregisterTasks)
311316
}
312317

test/client-mode.spec.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe('client mode', () => {
1616

1717
afterEach(async () => {
1818
peer && await peer.stop()
19-
rendezvous && await rendezvous.stop()
19+
rendezvous && rendezvous.stop()
2020
})
2121

2222
it('registers a rendezvous handler by default', async () => {
@@ -25,7 +25,7 @@ describe('client mode', () => {
2525

2626
const spyHandle = sinon.spy(peer.registrar, '_handle')
2727

28-
await rendezvous.start()
28+
rendezvous.start()
2929

3030
expect(spyHandle).to.have.property('callCount', 1)
3131
})
@@ -34,16 +34,14 @@ describe('client mode', () => {
3434
[peer] = await createPeer()
3535
rendezvous = new Rendezvous({
3636
libp2p: peer,
37-
options: {
38-
server: {
39-
enabled: false
40-
}
37+
server: {
38+
enabled: false
4139
}
4240
})
4341

4442
const spyHandle = sinon.spy(peer.registrar, '_handle')
4543

46-
await rendezvous.start()
44+
rendezvous.start()
4745
expect(spyHandle).to.have.property('callCount', 0)
4846
})
4947
})

test/discovery.spec.js

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@ describe('rendezvous discovery', () => {
2525
peers.forEach((peer, index) => {
2626
const rendezvous = new Rendezvous({
2727
libp2p: peer,
28-
options: {
29-
discovery: {
30-
interval: 1000
31-
},
32-
server: {
33-
enabled: index === 0
34-
}
28+
discovery: {
29+
interval: 1000
30+
},
31+
server: {
32+
enabled: index === 0
3533
}
3634
})
3735
rendezvous.start()
@@ -107,14 +105,12 @@ describe('interface-discovery', () => {
107105
peers.forEach((peer, index) => {
108106
const rendezvous = new Rendezvous({
109107
libp2p: peer,
110-
options: {
111-
discovery: {
112-
interval: 1000
113-
},
114-
namespaces: ['test-namespace'],
115-
server: {
116-
enabled: index === 0
117-
}
108+
discovery: {
109+
interval: 1000
110+
},
111+
namespaces: ['test-namespace'],
112+
server: {
113+
enabled: index === 0
118114
}
119115
})
120116
rendezvous.start()

test/rendezvous.spec.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ describe('rendezvous', () => {
7070
peers.forEach((peer, index) => {
7171
const rendezvous = new Rendezvous({
7272
libp2p: peer,
73-
options: {
74-
server: {
75-
enabled: index !== 0
76-
}
73+
server: {
74+
enabled: index !== 0
7775
}
7876
})
7977
rendezvous.start()
@@ -95,7 +93,7 @@ describe('rendezvous', () => {
9593
})
9694

9795
it('register throws error if ttl is too small', async () => {
98-
await expect(peers[0].rendezvous.register(namespace, 10))
96+
await expect(peers[0].rendezvous.register(namespace, { ttl: 10 }))
9997
.to.eventually.rejected()
10098
.and.have.property('code', errCodes.INVALID_TTL)
10199
})

0 commit comments

Comments
 (0)