@libp2p/gossipsub 16.0.5 → 16.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +3 -3
- package/dist/src/gossipsub.d.ts +15 -0
- package/dist/src/gossipsub.d.ts.map +1 -1
- package/dist/src/gossipsub.js +53 -15
- package/dist/src/gossipsub.js.map +1 -1
- package/package.json +9 -9
- package/src/gossipsub.ts +61 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/gossipsub",
|
|
3
|
-
"version": "16.0
|
|
3
|
+
"version": "16.1.0",
|
|
4
4
|
"description": "A typescript implementation of gossipsub",
|
|
5
5
|
"files": [
|
|
6
6
|
"src",
|
|
@@ -81,9 +81,9 @@
|
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@libp2p/crypto": "^5.1.21",
|
|
83
83
|
"@libp2p/interface": "^3.2.5",
|
|
84
|
-
"@libp2p/interface-internal": "^3.1.
|
|
85
|
-
"@libp2p/peer-id": "^6.0.
|
|
86
|
-
"@libp2p/utils": "^7.3.
|
|
84
|
+
"@libp2p/interface-internal": "^3.1.10",
|
|
85
|
+
"@libp2p/peer-id": "^6.0.13",
|
|
86
|
+
"@libp2p/utils": "^7.3.1",
|
|
87
87
|
"@multiformats/multiaddr": "^13.0.3",
|
|
88
88
|
"denque": "^2.1.0",
|
|
89
89
|
"it-length-prefixed": "^11.0.1",
|
|
@@ -96,11 +96,11 @@
|
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"@chainsafe/as-sha256": "^1.2.0",
|
|
99
|
-
"@libp2p/floodsub": "^11.0.
|
|
100
|
-
"@libp2p/logger": "^6.2.
|
|
101
|
-
"@libp2p/peer-store": "^12.0.
|
|
99
|
+
"@libp2p/floodsub": "^11.0.27",
|
|
100
|
+
"@libp2p/logger": "^6.2.11",
|
|
101
|
+
"@libp2p/peer-store": "^12.0.25",
|
|
102
102
|
"@types/benchmark": "^2.1.5",
|
|
103
|
-
"@types/sinon": "^
|
|
103
|
+
"@types/sinon": "^22.0.0",
|
|
104
104
|
"abortable-iterator": "^5.1.0",
|
|
105
105
|
"aegir": "^48.1.1",
|
|
106
106
|
"benchmark": "^2.1.4",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
"p-retry": "^8.0.0",
|
|
114
114
|
"p-wait-for": "^6.0.0",
|
|
115
115
|
"protons": "^9.0.1",
|
|
116
|
-
"sinon": "^
|
|
116
|
+
"sinon": "^22.0.0",
|
|
117
117
|
"sinon-ts": "^2.0.0",
|
|
118
118
|
"time-cache": "^0.3.0"
|
|
119
119
|
},
|
package/src/gossipsub.ts
CHANGED
|
@@ -972,6 +972,8 @@ export class GossipSub extends TypedEventEmitter<GossipSubEvents> implements Typ
|
|
|
972
972
|
// update peer subscriptions
|
|
973
973
|
|
|
974
974
|
const subscriptions: Array<{ topic: TopicStr, subscribe: boolean }> = []
|
|
975
|
+
const fromStr = from.toString()
|
|
976
|
+
const graftTopics: TopicStr[] = []
|
|
975
977
|
|
|
976
978
|
rpc.subscriptions.forEach((subOpt) => {
|
|
977
979
|
const topic = subOpt.topic
|
|
@@ -986,10 +988,21 @@ export class GossipSub extends TypedEventEmitter<GossipSubEvents> implements Typ
|
|
|
986
988
|
|
|
987
989
|
this.handleReceivedSubscription(from, topic, subscribe)
|
|
988
990
|
|
|
991
|
+
// graft the peer into the mesh now rather than waiting for the next
|
|
992
|
+
// heartbeat, so a message published right after subscribing is not dropped
|
|
993
|
+
if (subscribe && this.graftOnSubscribe(fromStr, topic)) {
|
|
994
|
+
graftTopics.push(topic)
|
|
995
|
+
}
|
|
996
|
+
|
|
989
997
|
subscriptions.push({ topic, subscribe })
|
|
990
998
|
}
|
|
991
999
|
})
|
|
992
1000
|
|
|
1001
|
+
// send one batched GRAFT covering every topic grafted while handling this RPC
|
|
1002
|
+
if (graftTopics.length > 0) {
|
|
1003
|
+
this.sendGraft(fromStr, graftTopics)
|
|
1004
|
+
}
|
|
1005
|
+
|
|
993
1006
|
this.safeDispatchEvent<SubscriptionChangeData>('subscription-change', {
|
|
994
1007
|
detail: { peerId: from, subscriptions }
|
|
995
1008
|
})
|
|
@@ -1539,10 +1552,7 @@ export class GossipSub extends TypedEventEmitter<GossipSubEvents> implements Typ
|
|
|
1539
1552
|
// valid graft
|
|
1540
1553
|
} else {
|
|
1541
1554
|
this.log('GRAFT: Add mesh link from %s in %s', id, topicID)
|
|
1542
|
-
this.
|
|
1543
|
-
peersInMesh.add(id)
|
|
1544
|
-
|
|
1545
|
-
this.metrics?.onAddToMesh(topicID, InclusionReason.Subscribed, 1)
|
|
1555
|
+
this.addToMesh(id, topicID, InclusionReason.Subscribed)
|
|
1546
1556
|
}
|
|
1547
1557
|
|
|
1548
1558
|
this.safeDispatchEvent<MeshPeer>('gossipsub:graft', { detail: { peerId: id, topic: topicID, direction: 'inbound' } })
|
|
@@ -1877,7 +1887,7 @@ export class GossipSub extends TypedEventEmitter<GossipSubEvents> implements Typ
|
|
|
1877
1887
|
|
|
1878
1888
|
toAdd.forEach((id) => {
|
|
1879
1889
|
this.log('JOIN: Add mesh link to %s in %s', id, topic)
|
|
1880
|
-
this.sendGraft(id, topic)
|
|
1890
|
+
this.sendGraft(id, [topic])
|
|
1881
1891
|
|
|
1882
1892
|
// rust-libp2p
|
|
1883
1893
|
// - peer_score.graft()
|
|
@@ -2276,16 +2286,55 @@ export class GossipSub extends TypedEventEmitter<GossipSubEvents> implements Typ
|
|
|
2276
2286
|
/**
|
|
2277
2287
|
* Sends a GRAFT message to a peer
|
|
2278
2288
|
*/
|
|
2279
|
-
private sendGraft (id: PeerIdStr,
|
|
2280
|
-
const graft =
|
|
2281
|
-
{
|
|
2282
|
-
topicID: topic
|
|
2283
|
-
}
|
|
2284
|
-
]
|
|
2289
|
+
private sendGraft (id: PeerIdStr, topics: string[]): void {
|
|
2290
|
+
const graft = topics.map((topicID) => ({ topicID }))
|
|
2285
2291
|
const out = createGossipRpc([], { graft })
|
|
2286
2292
|
this.sendRpc(id, out)
|
|
2287
2293
|
}
|
|
2288
2294
|
|
|
2295
|
+
/**
|
|
2296
|
+
* Add a peer to a topic mesh, updating peer score, mesh membership and metrics.
|
|
2297
|
+
* Sending the GRAFT is left to the caller: the heartbeat and graft-on-subscribe
|
|
2298
|
+
* send one, which dispatches the outbound gossipsub:graft event via sendRpc,
|
|
2299
|
+
* while the inbound GRAFT handler sends none and dispatches its own event.
|
|
2300
|
+
*/
|
|
2301
|
+
private addToMesh (id: PeerIdStr, topic: TopicStr, reason: InclusionReason): void {
|
|
2302
|
+
this.score.graft(id, topic)
|
|
2303
|
+
this.mesh.get(topic)?.add(id)
|
|
2304
|
+
this.metrics?.onAddToMesh(topic, reason, 1)
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
/**
|
|
2308
|
+
* When a peer subscribes to a topic we are meshed on, graft it into the mesh
|
|
2309
|
+
* immediately if there is room, instead of waiting for the next heartbeat.
|
|
2310
|
+
* Without this, a message published before the mesh has formed is forwarded to
|
|
2311
|
+
* nobody and silently dropped. Returns true if the peer was grafted, so the
|
|
2312
|
+
* caller can send one batched GRAFT for every topic grafted from an RPC.
|
|
2313
|
+
*/
|
|
2314
|
+
private graftOnSubscribe (id: PeerIdStr, topic: TopicStr): boolean {
|
|
2315
|
+
const mesh = this.mesh.get(topic)
|
|
2316
|
+
|
|
2317
|
+
// only fill a mesh we belong to, and only while it is below the low-water mark
|
|
2318
|
+
if (mesh == null || mesh.has(id) || mesh.size >= this.opts.Dlo) {
|
|
2319
|
+
return false
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
// require an outbound stream on one of our protocols, the same check the
|
|
2323
|
+
// heartbeat applies when selecting mesh peers
|
|
2324
|
+
const peerStreams = this.streamsOutbound.get(id)
|
|
2325
|
+
if (peerStreams == null || !this.protocols.includes(peerStreams.protocol)) {
|
|
2326
|
+
return false
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2329
|
+
// do not graft direct peers, negatively scored peers or backed off peers
|
|
2330
|
+
if (this.direct.has(id) || this.score.score(id) < 0 || (this.backoff.get(topic)?.has(id) ?? false)) {
|
|
2331
|
+
return false
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
this.addToMesh(id, topic, InclusionReason.Subscribed)
|
|
2335
|
+
return true
|
|
2336
|
+
}
|
|
2337
|
+
|
|
2289
2338
|
/**
|
|
2290
2339
|
* Sends a PRUNE message to a peer
|
|
2291
2340
|
*/
|
|
@@ -2752,13 +2801,9 @@ export class GossipSub extends TypedEventEmitter<GossipSubEvents> implements Typ
|
|
|
2752
2801
|
|
|
2753
2802
|
const graftPeer = (id: PeerIdStr, reason: InclusionReason): void => {
|
|
2754
2803
|
this.log('HEARTBEAT: Add mesh link to %s in %s', id, topic)
|
|
2755
|
-
|
|
2756
|
-
this.score.graft(id, topic)
|
|
2757
|
-
// add peer to mesh
|
|
2758
|
-
peers.add(id)
|
|
2804
|
+
this.addToMesh(id, topic, reason)
|
|
2759
2805
|
// when we add a new mesh peer, we don't want to gossip messages to it
|
|
2760
2806
|
peersToGossip.delete(id)
|
|
2761
|
-
this.metrics?.onAddToMesh(topic, reason, 1)
|
|
2762
2807
|
// add to tograft
|
|
2763
2808
|
const topics = tograft.get(id)
|
|
2764
2809
|
if (topics == null) {
|