Skip to content

Commit c9e6757

Browse files
authored
chore: store self protocols in protobook (#760)
1 parent 5246cf8 commit c9e6757

File tree

6 files changed

+264
-96
lines changed

6 files changed

+264
-96
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)
@@ -843,32 +844,6 @@ Consider using `addressBook.add()` if you're not sure this is what you want to d
843844
peerStore.addressBook.add(peerId, multiaddr)
844845
```
845846

846-
### peerStore.protoBook.add
847-
848-
Add known `protocols` of a given peer.
849-
850-
`peerStore.protoBook.add(peerId, protocols)`
851-
852-
#### Parameters
853-
854-
| Name | Type | Description |
855-
|------|------|-------------|
856-
| peerId | [`PeerId`][peer-id] | peerId to set |
857-
| protocols | `Array<string>` | protocols to add |
858-
859-
#### Returns
860-
861-
| Type | Description |
862-
|------|-------------|
863-
| `ProtoBook` | Returns the Proto Book component |
864-
865-
#### Example
866-
867-
```js
868-
peerStore.protoBook.add(peerId, protocols)
869-
```
870-
871-
872847
### peerStore.keyBook.delete
873848

874849
Delete the provided peer from the book.
@@ -1091,6 +1066,31 @@ Set known metadata of a given `peerId`.
10911066
peerStore.metadataBook.set(peerId, 'location', uint8ArrayFromString('Berlin'))
10921067
```
10931068

1069+
### peerStore.protoBook.add
1070+
1071+
Add known `protocols` of a given peer.
1072+
1073+
`peerStore.protoBook.add(peerId, protocols)`
1074+
1075+
#### Parameters
1076+
1077+
| Name | Type | Description |
1078+
|------|------|-------------|
1079+
| peerId | [`PeerId`][peer-id] | peerId to set |
1080+
| protocols | `Array<string>` | protocols to add |
1081+
1082+
#### Returns
1083+
1084+
| Type | Description |
1085+
|------|-------------|
1086+
| `ProtoBook` | Returns the Proto Book component |
1087+
1088+
#### Example
1089+
1090+
```js
1091+
peerStore.protoBook.add(peerId, protocols)
1092+
```
1093+
10941094
### peerStore.protoBook.delete
10951095

10961096
Delete the provided peer from the book.
@@ -1147,6 +1147,31 @@ peerStore.protoBook.get(peerId)
11471147
// [ '/proto/1.0.0', '/proto/1.1.0' ]
11481148
```
11491149

1150+
### peerStore.protoBook.remove
1151+
1152+
Remove given `protocols` of a given peer.
1153+
1154+
`peerStore.protoBook.remove(peerId, protocols)`
1155+
1156+
#### Parameters
1157+
1158+
| Name | Type | Description |
1159+
|------|------|-------------|
1160+
| peerId | [`PeerId`][peer-id] | peerId to set |
1161+
| protocols | `Array<string>` | protocols to remove |
1162+
1163+
#### Returns
1164+
1165+
| Type | Description |
1166+
|------|-------------|
1167+
| `ProtoBook` | Returns the Proto Book component |
1168+
1169+
#### Example
1170+
1171+
```js
1172+
peerStore.protoBook.remove(peerId, protocols)
1173+
```
1174+
11501175
### peerStore.protoBook.set
11511176

11521177
Set known `protocols` of a given peer.

src/identify/index.js

Lines changed: 17 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,10 +73,9 @@ class IdentifyService {
7473
*/
7574
this._libp2p = libp2p
7675

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

78+
// When a new connection happens, trigger identify
8179
this.connectionManager.on('peer:connect', (connection) => {
8280
const peerId = connection.remotePeer
8381

@@ -90,6 +88,13 @@ class IdentifyService {
9088
this.pushToPeerStore()
9189
}
9290
})
91+
92+
// When self protocols change, trigger identify-push
93+
this.peerStore.on('change:protocols', ({ peerId }) => {
94+
if (peerId.toString() === this.peerId.toString()) {
95+
this.pushToPeerStore()
96+
}
97+
})
9398
}
9499

95100
/**
@@ -101,7 +106,7 @@ class IdentifyService {
101106
async push (connections) {
102107
const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId)
103108
const listenAddrs = this._libp2p.multiaddrs.map((ma) => ma.bytes)
104-
const protocols = Array.from(this._protocols.keys())
109+
const protocols = this.peerStore.protoBook.get(this.peerId) || []
105110

106111
const pushes = connections.map(async connection => {
107112
try {
@@ -132,6 +137,11 @@ class IdentifyService {
132137
* @returns {void}
133138
*/
134139
pushToPeerStore () {
140+
// Do not try to push if libp2p node is not running
141+
if (!this._libp2p.isStarted()) {
142+
return
143+
}
144+
135145
const connections = []
136146
let connection
137147
for (const peer of this.peerStore.peers.values()) {
@@ -251,6 +261,7 @@ class IdentifyService {
251261
}
252262

253263
const signedPeerRecord = await this.peerStore.addressBook.getRawEnvelope(this.peerId)
264+
const protocols = this.peerStore.protoBook.get(this.peerId) || []
254265

255266
const message = Message.encode({
256267
protocolVersion: PROTOCOL_VERSION,
@@ -259,7 +270,7 @@ class IdentifyService {
259270
listenAddrs: this._libp2p.multiaddrs.map((ma) => ma.bytes),
260271
signedPeerRecord,
261272
observedAddr: connection.remoteAddr.bytes,
262-
protocols: Array.from(this._protocols.keys())
273+
protocols
263274
})
264275

265276
try {

src/index.js

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

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

@@ -436,10 +433,8 @@ class Libp2p extends EventEmitter {
436433
this.upgrader.protocols.set(protocol, handler)
437434
})
438435

439-
// Only push if libp2p is running
440-
if (this.isStarted() && this.identifyService) {
441-
this.identifyService.pushToPeerStore()
442-
}
436+
// Add new protocols to self protocols in the Protobook
437+
this.peerStore.protoBook.add(this.peerId, protocols)
443438
}
444439

445440
/**
@@ -454,10 +449,8 @@ class Libp2p extends EventEmitter {
454449
this.upgrader.protocols.delete(protocol)
455450
})
456451

457-
// Only push if libp2p is running
458-
if (this.isStarted() && this.identifyService) {
459-
this.identifyService.pushToPeerStore()
460-
}
452+
// Remove protocols from self protocols in the Protobook
453+
this.peerStore.protoBook.remove(this.peerId, protocols)
461454
}
462455

463456
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)