Skip to content

Commit 97e3633

Browse files
committed
chore: store self protocols in protobook (#760)
1 parent e36b67a commit 97e3633

File tree

6 files changed

+258
-100
lines changed

6 files changed

+258
-100
lines changed

doc/API.md

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
* [`peerStore.protoBook.add`](#peerstoreprotobookadd)
3838
* [`peerStore.protoBook.delete`](#peerstoreprotobookdelete)
3939
* [`peerStore.protoBook.get`](#peerstoreprotobookget)
40+
* [`peerStore.protoBook.remove`](#peerstoreprotobookremove)
4041
* [`peerStore.protoBook.set`](#peerstoreprotobookset)
4142
* [`peerStore.delete`](#peerstoredelete)
4243
* [`peerStore.get`](#peerstoreget)
@@ -875,32 +876,6 @@ Consider using `addressBook.add()` if you're not sure this is what you want to d
875876
peerStore.addressBook.add(peerId, multiaddr)
876877
```
877878

878-
### peerStore.protoBook.add
879-
880-
Add known `protocols` of a given peer.
881-
882-
`peerStore.protoBook.add(peerId, protocols)`
883-
884-
#### Parameters
885-
886-
| Name | Type | Description |
887-
|------|------|-------------|
888-
| peerId | [`PeerId`][peer-id] | peerId to set |
889-
| protocols | `Array<string>` | protocols to add |
890-
891-
#### Returns
892-
893-
| Type | Description |
894-
|------|-------------|
895-
| `ProtoBook` | Returns the Proto Book component |
896-
897-
#### Example
898-
899-
```js
900-
peerStore.protoBook.add(peerId, protocols)
901-
```
902-
903-
904879
### peerStore.keyBook.delete
905880

906881
Delete the provided peer from the book.
@@ -1123,6 +1098,31 @@ Set known metadata of a given `peerId`.
11231098
peerStore.metadataBook.set(peerId, 'location', uint8ArrayFromString('Berlin'))
11241099
```
11251100

1101+
### peerStore.protoBook.add
1102+
1103+
Add known `protocols` of a given peer.
1104+
1105+
`peerStore.protoBook.add(peerId, protocols)`
1106+
1107+
#### Parameters
1108+
1109+
| Name | Type | Description |
1110+
|------|------|-------------|
1111+
| peerId | [`PeerId`][peer-id] | peerId to set |
1112+
| protocols | `Array<string>` | protocols to add |
1113+
1114+
#### Returns
1115+
1116+
| Type | Description |
1117+
|------|-------------|
1118+
| `ProtoBook` | Returns the Proto Book component |
1119+
1120+
#### Example
1121+
1122+
```js
1123+
peerStore.protoBook.add(peerId, protocols)
1124+
```
1125+
11261126
### peerStore.protoBook.delete
11271127

11281128
Delete the provided peer from the book.
@@ -1179,6 +1179,31 @@ peerStore.protoBook.get(peerId)
11791179
// [ '/proto/1.0.0', '/proto/1.1.0' ]
11801180
```
11811181

1182+
### peerStore.protoBook.remove
1183+
1184+
Remove given `protocols` of a given peer.
1185+
1186+
`peerStore.protoBook.remove(peerId, protocols)`
1187+
1188+
#### Parameters
1189+
1190+
| Name | Type | Description |
1191+
|------|------|-------------|
1192+
| peerId | [`PeerId`][peer-id] | peerId to set |
1193+
| protocols | `Array<string>` | protocols to remove |
1194+
1195+
#### Returns
1196+
1197+
| Type | Description |
1198+
|------|-------------|
1199+
| `ProtoBook` | Returns the Proto Book component |
1200+
1201+
#### Example
1202+
1203+
```js
1204+
peerStore.protoBook.remove(peerId, protocols)
1205+
```
1206+
11821207
### peerStore.protoBook.set
11831208

11841209
Set known `protocols` of a given peer.

src/identify/index.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,8 @@ class IdentifyService {
5151
* @class
5252
* @param {object} options
5353
* @param {Libp2p} options.libp2p
54-
* @param {Map<string, handler>} options.protocols - A reference to the protocols we support
5554
*/
56-
constructor ({ libp2p, protocols }) {
55+
constructor ({ libp2p }) {
5756
/**
5857
* @property {PeerStore}
5958
*/
@@ -74,8 +73,6 @@ class IdentifyService {
7473
*/
7574
this._libp2p = libp2p
7675

77-
this._protocols = protocols
78-
7976
this.handleMessage = this.handleMessage.bind(this)
8077

8178
// Store self host metadata
@@ -97,6 +94,13 @@ class IdentifyService {
9794
this.pushToPeerStore()
9895
}
9996
})
97+
98+
// When self protocols change, trigger identify-push
99+
this.peerStore.on('change:protocols', ({ peerId }) => {
100+
if (peerId.toString() === this.peerId.toString()) {
101+
this.pushToPeerStore()
102+
}
103+
})
100104
}
101105

102106
/**
@@ -108,7 +112,7 @@ class IdentifyService {
108112
async push (connections) {
109113
const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId)
110114
const listenAddrs = this._libp2p.multiaddrs.map((ma) => ma.bytes)
111-
const protocols = Array.from(this._protocols.keys())
115+
const protocols = this.peerStore.protoBook.get(this.peerId) || []
112116

113117
const pushes = connections.map(async connection => {
114118
try {
@@ -139,6 +143,11 @@ class IdentifyService {
139143
* @returns {void}
140144
*/
141145
pushToPeerStore () {
146+
// Do not try to push if libp2p node is not running
147+
if (!this._libp2p.isStarted()) {
148+
return
149+
}
150+
142151
const connections = []
143152
let connection
144153
for (const peer of this.peerStore.peers.values()) {
@@ -258,6 +267,7 @@ class IdentifyService {
258267
}
259268

260269
const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId)
270+
const protocols = this.peerStore.protoBook.get(this.peerId) || []
261271

262272
const message = Message.encode({
263273
protocolVersion: this._host.protocolVersion,
@@ -266,7 +276,7 @@ class IdentifyService {
266276
listenAddrs: this._libp2p.multiaddrs.map((ma) => ma.bytes),
267277
signedPeerRecord,
268278
observedAddr: connection.remoteAddr.bytes,
269-
protocols: Array.from(this._protocols.keys())
279+
protocols
270280
})
271281

272282
try {

src/index.js

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,7 @@ class Libp2p extends EventEmitter {
158158
})
159159

160160
// Add the identify service since we can multiplex
161-
this.identifyService = new IdentifyService({
162-
libp2p: this,
163-
protocols: this.upgrader.protocols
164-
})
161+
this.identifyService = new IdentifyService({ libp2p: this })
165162
this.handle(Object.values(IDENTIFY_PROTOCOLS), this.identifyService.handleMessage)
166163
}
167164

@@ -442,10 +439,8 @@ class Libp2p extends EventEmitter {
442439
this.upgrader.protocols.set(protocol, handler)
443440
})
444441

445-
// Only push if libp2p is running
446-
if (this.isStarted() && this.identifyService) {
447-
this.identifyService.pushToPeerStore()
448-
}
442+
// Add new protocols to self protocols in the Protobook
443+
this.peerStore.protoBook.add(this.peerId, protocols)
449444
}
450445

451446
/**
@@ -460,10 +455,8 @@ class Libp2p extends EventEmitter {
460455
this.upgrader.protocols.delete(protocol)
461456
})
462457

463-
// Only push if libp2p is running
464-
if (this.isStarted() && this.identifyService) {
465-
this.identifyService.pushToPeerStore()
466-
}
458+
// Remove protocols from self protocols in the Protobook
459+
this.peerStore.protoBook.remove(this.peerId, protocols)
467460
}
468461

469462
async _onStarting () {

src/peer-store/proto-book.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,50 @@ class ProtoBook extends Book {
112112
return this
113113
}
114114

115-
protocols = [...newSet]
116-
117115
this._setData(peerId, newSet)
118116
log(`added provided protocols for ${id}`)
119117

120118
return this
121119
}
120+
121+
/**
122+
* Removes known protocols of a provided peer.
123+
* If the protocols did not exist before, nothing will be done.
124+
*
125+
* @param {PeerId} peerId
126+
* @param {Array<string>} protocols
127+
* @returns {ProtoBook}
128+
*/
129+
remove (peerId, protocols) {
130+
if (!PeerId.isPeerId(peerId)) {
131+
log.error('peerId must be an instance of peer-id to store data')
132+
throw errcode(new Error('peerId must be an instance of peer-id'), ERR_INVALID_PARAMETERS)
133+
}
134+
135+
if (!protocols) {
136+
log.error('protocols must be provided to store data')
137+
throw errcode(new Error('protocols must be provided'), ERR_INVALID_PARAMETERS)
138+
}
139+
140+
const id = peerId.toB58String()
141+
const recSet = this.data.get(id)
142+
143+
if (recSet) {
144+
const newSet = new Set([
145+
...recSet
146+
].filter((p) => !protocols.includes(p)))
147+
148+
// Any protocol removed?
149+
if (recSet.size === newSet.size) {
150+
return this
151+
}
152+
153+
this._setData(peerId, newSet)
154+
log(`removed provided protocols for ${id}`)
155+
}
156+
157+
return this
158+
}
122159
}
123160

124161
module.exports = ProtoBook

0 commit comments

Comments
 (0)