@libp2p/gossipsub 14.1.1-6059227cb

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.
Files changed (160) hide show
  1. package/README.md +85 -0
  2. package/dist/index.min.js +19 -0
  3. package/dist/index.min.js.map +7 -0
  4. package/dist/src/config.d.ts +32 -0
  5. package/dist/src/config.d.ts.map +1 -0
  6. package/dist/src/config.js +2 -0
  7. package/dist/src/config.js.map +1 -0
  8. package/dist/src/constants.d.ts +213 -0
  9. package/dist/src/constants.d.ts.map +1 -0
  10. package/dist/src/constants.js +217 -0
  11. package/dist/src/constants.js.map +1 -0
  12. package/dist/src/errors.d.ts +9 -0
  13. package/dist/src/errors.d.ts.map +1 -0
  14. package/dist/src/errors.js +15 -0
  15. package/dist/src/errors.js.map +1 -0
  16. package/dist/src/gossipsub.d.ts +419 -0
  17. package/dist/src/gossipsub.d.ts.map +1 -0
  18. package/dist/src/gossipsub.js +2520 -0
  19. package/dist/src/gossipsub.js.map +1 -0
  20. package/dist/src/index.d.ts +344 -0
  21. package/dist/src/index.d.ts.map +1 -0
  22. package/dist/src/index.js +43 -0
  23. package/dist/src/index.js.map +1 -0
  24. package/dist/src/message/decodeRpc.d.ts +11 -0
  25. package/dist/src/message/decodeRpc.d.ts.map +1 -0
  26. package/dist/src/message/decodeRpc.js +10 -0
  27. package/dist/src/message/decodeRpc.js.map +1 -0
  28. package/dist/src/message/index.d.ts +2 -0
  29. package/dist/src/message/index.d.ts.map +1 -0
  30. package/dist/src/message/index.js +2 -0
  31. package/dist/src/message/index.js.map +1 -0
  32. package/dist/src/message/rpc.d.ts +99 -0
  33. package/dist/src/message/rpc.d.ts.map +1 -0
  34. package/dist/src/message/rpc.js +663 -0
  35. package/dist/src/message/rpc.js.map +1 -0
  36. package/dist/src/message-cache.d.ts +80 -0
  37. package/dist/src/message-cache.d.ts.map +1 -0
  38. package/dist/src/message-cache.js +144 -0
  39. package/dist/src/message-cache.js.map +1 -0
  40. package/dist/src/metrics.d.ts +467 -0
  41. package/dist/src/metrics.d.ts.map +1 -0
  42. package/dist/src/metrics.js +896 -0
  43. package/dist/src/metrics.js.map +1 -0
  44. package/dist/src/score/compute-score.d.ts +4 -0
  45. package/dist/src/score/compute-score.d.ts.map +1 -0
  46. package/dist/src/score/compute-score.js +75 -0
  47. package/dist/src/score/compute-score.js.map +1 -0
  48. package/dist/src/score/index.d.ts +4 -0
  49. package/dist/src/score/index.d.ts.map +1 -0
  50. package/dist/src/score/index.js +4 -0
  51. package/dist/src/score/index.js.map +1 -0
  52. package/dist/src/score/message-deliveries.d.ts +45 -0
  53. package/dist/src/score/message-deliveries.d.ts.map +1 -0
  54. package/dist/src/score/message-deliveries.js +75 -0
  55. package/dist/src/score/message-deliveries.js.map +1 -0
  56. package/dist/src/score/peer-score-params.d.ts +125 -0
  57. package/dist/src/score/peer-score-params.d.ts.map +1 -0
  58. package/dist/src/score/peer-score-params.js +159 -0
  59. package/dist/src/score/peer-score-params.js.map +1 -0
  60. package/dist/src/score/peer-score-thresholds.d.ts +31 -0
  61. package/dist/src/score/peer-score-thresholds.d.ts.map +1 -0
  62. package/dist/src/score/peer-score-thresholds.js +32 -0
  63. package/dist/src/score/peer-score-thresholds.js.map +1 -0
  64. package/dist/src/score/peer-score.d.ts +119 -0
  65. package/dist/src/score/peer-score.d.ts.map +1 -0
  66. package/dist/src/score/peer-score.js +459 -0
  67. package/dist/src/score/peer-score.js.map +1 -0
  68. package/dist/src/score/peer-stats.d.ts +32 -0
  69. package/dist/src/score/peer-stats.d.ts.map +1 -0
  70. package/dist/src/score/peer-stats.js +2 -0
  71. package/dist/src/score/peer-stats.js.map +1 -0
  72. package/dist/src/score/scoreMetrics.d.ts +23 -0
  73. package/dist/src/score/scoreMetrics.d.ts.map +1 -0
  74. package/dist/src/score/scoreMetrics.js +155 -0
  75. package/dist/src/score/scoreMetrics.js.map +1 -0
  76. package/dist/src/stream.d.ts +30 -0
  77. package/dist/src/stream.d.ts.map +1 -0
  78. package/dist/src/stream.js +55 -0
  79. package/dist/src/stream.js.map +1 -0
  80. package/dist/src/tracer.d.ts +53 -0
  81. package/dist/src/tracer.d.ts.map +1 -0
  82. package/dist/src/tracer.js +155 -0
  83. package/dist/src/tracer.js.map +1 -0
  84. package/dist/src/types.d.ts +148 -0
  85. package/dist/src/types.d.ts.map +1 -0
  86. package/dist/src/types.js +90 -0
  87. package/dist/src/types.js.map +1 -0
  88. package/dist/src/utils/buildRawMessage.d.ts +20 -0
  89. package/dist/src/utils/buildRawMessage.d.ts.map +1 -0
  90. package/dist/src/utils/buildRawMessage.js +151 -0
  91. package/dist/src/utils/buildRawMessage.js.map +1 -0
  92. package/dist/src/utils/create-gossip-rpc.d.ts +7 -0
  93. package/dist/src/utils/create-gossip-rpc.d.ts.map +1 -0
  94. package/dist/src/utils/create-gossip-rpc.js +31 -0
  95. package/dist/src/utils/create-gossip-rpc.js.map +1 -0
  96. package/dist/src/utils/index.d.ts +4 -0
  97. package/dist/src/utils/index.d.ts.map +1 -0
  98. package/dist/src/utils/index.js +4 -0
  99. package/dist/src/utils/index.js.map +1 -0
  100. package/dist/src/utils/messageIdToString.d.ts +5 -0
  101. package/dist/src/utils/messageIdToString.d.ts.map +1 -0
  102. package/dist/src/utils/messageIdToString.js +8 -0
  103. package/dist/src/utils/messageIdToString.js.map +1 -0
  104. package/dist/src/utils/msgIdFn.d.ts +10 -0
  105. package/dist/src/utils/msgIdFn.d.ts.map +1 -0
  106. package/dist/src/utils/msgIdFn.js +23 -0
  107. package/dist/src/utils/msgIdFn.js.map +1 -0
  108. package/dist/src/utils/multiaddr.d.ts +3 -0
  109. package/dist/src/utils/multiaddr.d.ts.map +1 -0
  110. package/dist/src/utils/multiaddr.js +15 -0
  111. package/dist/src/utils/multiaddr.js.map +1 -0
  112. package/dist/src/utils/publishConfig.d.ts +8 -0
  113. package/dist/src/utils/publishConfig.d.ts.map +1 -0
  114. package/dist/src/utils/publishConfig.js +25 -0
  115. package/dist/src/utils/publishConfig.js.map +1 -0
  116. package/dist/src/utils/set.d.ts +14 -0
  117. package/dist/src/utils/set.d.ts.map +1 -0
  118. package/dist/src/utils/set.js +41 -0
  119. package/dist/src/utils/set.js.map +1 -0
  120. package/dist/src/utils/shuffle.d.ts +7 -0
  121. package/dist/src/utils/shuffle.d.ts.map +1 -0
  122. package/dist/src/utils/shuffle.js +21 -0
  123. package/dist/src/utils/shuffle.js.map +1 -0
  124. package/dist/src/utils/time-cache.d.ts +22 -0
  125. package/dist/src/utils/time-cache.d.ts.map +1 -0
  126. package/dist/src/utils/time-cache.js +54 -0
  127. package/dist/src/utils/time-cache.js.map +1 -0
  128. package/package.json +142 -0
  129. package/src/config.ts +31 -0
  130. package/src/constants.ts +261 -0
  131. package/src/errors.ts +17 -0
  132. package/src/gossipsub.ts +3061 -0
  133. package/src/index.ts +404 -0
  134. package/src/message/decodeRpc.ts +19 -0
  135. package/src/message/index.ts +1 -0
  136. package/src/message/rpc.proto +58 -0
  137. package/src/message/rpc.ts +848 -0
  138. package/src/message-cache.ts +196 -0
  139. package/src/metrics.ts +1014 -0
  140. package/src/score/compute-score.ts +98 -0
  141. package/src/score/index.ts +3 -0
  142. package/src/score/message-deliveries.ts +95 -0
  143. package/src/score/peer-score-params.ts +316 -0
  144. package/src/score/peer-score-thresholds.ts +70 -0
  145. package/src/score/peer-score.ts +565 -0
  146. package/src/score/peer-stats.ts +33 -0
  147. package/src/score/scoreMetrics.ts +215 -0
  148. package/src/stream.ts +79 -0
  149. package/src/tracer.ts +177 -0
  150. package/src/types.ts +178 -0
  151. package/src/utils/buildRawMessage.ts +174 -0
  152. package/src/utils/create-gossip-rpc.ts +34 -0
  153. package/src/utils/index.ts +3 -0
  154. package/src/utils/messageIdToString.ts +8 -0
  155. package/src/utils/msgIdFn.ts +24 -0
  156. package/src/utils/multiaddr.ts +19 -0
  157. package/src/utils/publishConfig.ts +33 -0
  158. package/src/utils/set.ts +43 -0
  159. package/src/utils/shuffle.ts +21 -0
  160. package/src/utils/time-cache.ts +71 -0
@@ -0,0 +1,32 @@
1
+ export interface GossipsubOptsSpec {
2
+ /** D sets the optimal degree for a Gossipsub topic mesh. */
3
+ D: number;
4
+ /** Dlo sets the lower bound on the number of peers we keep in a Gossipsub topic mesh. */
5
+ Dlo: number;
6
+ /** Dhi sets the upper bound on the number of peers we keep in a Gossipsub topic mesh. */
7
+ Dhi: number;
8
+ /** Dscore affects how peers are selected when pruning a mesh due to over subscription. */
9
+ Dscore: number;
10
+ /** Dout sets the quota for the number of outbound connections to maintain in a topic mesh. */
11
+ Dout: number;
12
+ /**
13
+ * Dlazy affects the minimum number of peers we will emit gossip to at each
14
+ * heartbeat.
15
+ */
16
+ Dlazy: number;
17
+ /** heartbeatInterval is the time between heartbeats in milliseconds */
18
+ heartbeatInterval: number;
19
+ /**
20
+ * fanoutTTL controls how long we keep track of the fanout state. If it's been
21
+ * fanoutTTL milliseconds since we've published to a topic that we're not subscribed to,
22
+ * we'll delete the fanout map for that topic.
23
+ */
24
+ fanoutTTL: number;
25
+ /** mcacheLength is the number of windows to retain full messages for IWANT responses */
26
+ mcacheLength: number;
27
+ /** mcacheGossip is the number of windows to gossip about */
28
+ mcacheGossip: number;
29
+ /** seenTTL is the number of milliseconds to retain message IDs in the seen cache */
30
+ seenTTL: number;
31
+ }
32
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,4DAA4D;IAC5D,CAAC,EAAE,MAAM,CAAA;IACT,yFAAyF;IACzF,GAAG,EAAE,MAAM,CAAA;IACX,yFAAyF;IACzF,GAAG,EAAE,MAAM,CAAA;IACX,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAA;IACd,8FAA8F;IAC9F,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,YAAY,EAAE,MAAM,CAAA;IACpB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAA;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":""}
@@ -0,0 +1,213 @@
1
+ export declare const second = 1000;
2
+ export declare const minute: number;
3
+ export declare const FloodsubID = "/floodsub/1.0.0";
4
+ /**
5
+ * The protocol ID for version 1.0.0 of the Gossipsub protocol
6
+ * It is advertised along with GossipsubIDv11 for backwards compatability
7
+ */
8
+ export declare const GossipsubIDv10 = "/meshsub/1.0.0";
9
+ /**
10
+ * The protocol ID for version 1.1.0 of the Gossipsub protocol
11
+ * See the spec for details about how v1.1.0 compares to v1.0.0:
12
+ * https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md
13
+ */
14
+ export declare const GossipsubIDv11 = "/meshsub/1.1.0";
15
+ /**
16
+ * The protocol ID for version 1.2.0 of the Gossipsub protocol
17
+ * See the spec for details about how v1.2.0 compares to v1.1.0:
18
+ * https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md
19
+ */
20
+ export declare const GossipsubIDv12 = "/meshsub/1.2.0";
21
+ /**
22
+ * GossipsubD sets the optimal degree for a Gossipsub topic mesh. For example, if GossipsubD == 6,
23
+ * each peer will want to have about six peers in their mesh for each topic they're subscribed to.
24
+ * GossipsubD should be set somewhere between GossipsubDlo and GossipsubDhi.
25
+ */
26
+ export declare const GossipsubD = 6;
27
+ /**
28
+ * GossipsubDlo sets the lower bound on the number of peers we keep in a Gossipsub topic mesh.
29
+ * If we have fewer than GossipsubDlo peers, we will attempt to graft some more into the mesh at
30
+ * the next heartbeat.
31
+ */
32
+ export declare const GossipsubDlo = 4;
33
+ /**
34
+ * GossipsubDhi sets the upper bound on the number of peers we keep in a Gossipsub topic mesh.
35
+ * If we have more than GossipsubDhi peers, we will select some to prune from the mesh at the next heartbeat.
36
+ */
37
+ export declare const GossipsubDhi = 12;
38
+ /**
39
+ * GossipsubDscore affects how peers are selected when pruning a mesh due to over subscription.
40
+ * At least GossipsubDscore of the retained peers will be high-scoring, while the remainder are
41
+ * chosen randomly.
42
+ */
43
+ export declare const GossipsubDscore = 4;
44
+ /**
45
+ * GossipsubDout sets the quota for the number of outbound connections to maintain in a topic mesh.
46
+ * When the mesh is pruned due to over subscription, we make sure that we have outbound connections
47
+ * to at least GossipsubDout of the survivor peers. This prevents sybil attackers from overwhelming
48
+ * our mesh with incoming connections.
49
+ *
50
+ * GossipsubDout must be set below GossipsubDlo, and must not exceed GossipsubD / 2.
51
+ */
52
+ export declare const GossipsubDout = 2;
53
+ /**
54
+ * GossipsubHistoryLength controls the size of the message cache used for gossip.
55
+ * The message cache will remember messages for GossipsubHistoryLength heartbeats.
56
+ */
57
+ export declare const GossipsubHistoryLength = 5;
58
+ /**
59
+ * GossipsubHistoryGossip controls how many cached message ids we will advertise in
60
+ * IHAVE gossip messages. When asked for our seen message IDs, we will return
61
+ * only those from the most recent GossipsubHistoryGossip heartbeats. The slack between
62
+ * GossipsubHistoryGossip and GossipsubHistoryLength allows us to avoid advertising messages
63
+ * that will be expired by the time they're requested.
64
+ *
65
+ * GossipsubHistoryGossip must be less than or equal to GossipsubHistoryLength to
66
+ * avoid a runtime panic.
67
+ */
68
+ export declare const GossipsubHistoryGossip = 3;
69
+ /**
70
+ * GossipsubDlazy affects how many peers we will emit gossip to at each heartbeat.
71
+ * We will send gossip to at least GossipsubDlazy peers outside our mesh. The actual
72
+ * number may be more, depending on GossipsubGossipFactor and how many peers we're
73
+ * connected to.
74
+ */
75
+ export declare const GossipsubDlazy = 6;
76
+ /**
77
+ * GossipsubGossipFactor affects how many peers we will emit gossip to at each heartbeat.
78
+ * We will send gossip to GossipsubGossipFactor * (total number of non-mesh peers), or
79
+ * GossipsubDlazy, whichever is greater.
80
+ */
81
+ export declare const GossipsubGossipFactor = 0.25;
82
+ /**
83
+ * GossipsubGossipRetransmission controls how many times we will allow a peer to request
84
+ * the same message id through IWANT gossip before we start ignoring them. This is designed
85
+ * to prevent peers from spamming us with requests and wasting our resources.
86
+ */
87
+ export declare const GossipsubGossipRetransmission = 3;
88
+ /**
89
+ * GossipsubHeartbeatInitialDelay is the short delay before the heartbeat timer begins
90
+ * after the router is initialized.
91
+ */
92
+ export declare const GossipsubHeartbeatInitialDelay = 100;
93
+ /**
94
+ * GossipsubHeartbeatInterval controls the time between heartbeats.
95
+ */
96
+ export declare const GossipsubHeartbeatInterval = 1000;
97
+ /**
98
+ * GossipsubFanoutTTL controls how long we keep track of the fanout state. If it's been
99
+ * GossipsubFanoutTTL since we've published to a topic that we're not subscribed to,
100
+ * we'll delete the fanout map for that topic.
101
+ */
102
+ export declare const GossipsubFanoutTTL: number;
103
+ /**
104
+ * GossipsubPrunePeers controls the number of peers to include in prune Peer eXchange.
105
+ * When we prune a peer that's eligible for PX (has a good score, etc), we will try to
106
+ * send them signed peer records for up to GossipsubPrunePeers other peers that we
107
+ * know of.
108
+ */
109
+ export declare const GossipsubPrunePeers = 16;
110
+ /**
111
+ * GossipsubPruneBackoff controls the backoff time for pruned peers. This is how long
112
+ * a peer must wait before attempting to graft into our mesh again after being pruned.
113
+ * When pruning a peer, we send them our value of GossipsubPruneBackoff so they know
114
+ * the minimum time to wait. Peers running older versions may not send a backoff time,
115
+ * so if we receive a prune message without one, we will wait at least GossipsubPruneBackoff
116
+ * before attempting to re-graft.
117
+ */
118
+ export declare const GossipsubPruneBackoff: number;
119
+ /**
120
+ * Backoff to use when unsuscribing from a topic. Should not resubscribe to this topic before it expired.
121
+ */
122
+ export declare const GossipsubUnsubscribeBackoff: number;
123
+ /**
124
+ * GossipsubPruneBackoffTicks is the number of heartbeat ticks for attempting to prune expired
125
+ * backoff timers.
126
+ */
127
+ export declare const GossipsubPruneBackoffTicks = 15;
128
+ /**
129
+ * GossipsubConnectors controls the number of active connection attempts for peers obtained through PX.
130
+ */
131
+ export declare const GossipsubConnectors = 8;
132
+ /**
133
+ * GossipsubMaxPendingConnections sets the maximum number of pending connections for peers attempted through px.
134
+ */
135
+ export declare const GossipsubMaxPendingConnections = 128;
136
+ /**
137
+ * GossipsubConnectionTimeout controls the timeout for connection attempts.
138
+ */
139
+ export declare const GossipsubConnectionTimeout: number;
140
+ /**
141
+ * GossipsubDirectConnectTicks is the number of heartbeat ticks for attempting to reconnect direct peers
142
+ * that are not currently connected.
143
+ */
144
+ export declare const GossipsubDirectConnectTicks = 300;
145
+ /**
146
+ * GossipsubDirectConnectInitialDelay is the initial delay before opening connections to direct peers
147
+ */
148
+ export declare const GossipsubDirectConnectInitialDelay = 1000;
149
+ /**
150
+ * GossipsubOpportunisticGraftTicks is the number of heartbeat ticks for attempting to improve the mesh
151
+ * with opportunistic grafting. Every GossipsubOpportunisticGraftTicks we will attempt to select some
152
+ * high-scoring mesh peers to replace lower-scoring ones, if the median score of our mesh peers falls
153
+ * below a threshold
154
+ */
155
+ export declare const GossipsubOpportunisticGraftTicks = 60;
156
+ /**
157
+ * GossipsubOpportunisticGraftPeers is the number of peers to opportunistically graft.
158
+ */
159
+ export declare const GossipsubOpportunisticGraftPeers = 2;
160
+ /**
161
+ * If a GRAFT comes before GossipsubGraftFloodThreshold has elapsed since the last PRUNE,
162
+ * then there is an extra score penalty applied to the peer through P7.
163
+ */
164
+ export declare const GossipsubGraftFloodThreshold: number;
165
+ /**
166
+ * GossipsubMaxIHaveLength is the maximum number of messages to include in an IHAVE message.
167
+ * Also controls the maximum number of IHAVE ids we will accept and request with IWANT from a
168
+ * peer within a heartbeat, to protect from IHAVE floods. You should adjust this value from the
169
+ * default if your system is pushing more than 5000 messages in GossipsubHistoryGossip heartbeats;
170
+ * with the defaults this is 1666 messages/s.
171
+ */
172
+ export declare const GossipsubMaxIHaveLength = 5000;
173
+ /**
174
+ * GossipsubMaxIHaveMessages is the maximum number of IHAVE messages to accept from a peer within a heartbeat.
175
+ */
176
+ export declare const GossipsubMaxIHaveMessages = 10;
177
+ /**
178
+ * Time to wait for a message requested through IWANT following an IHAVE advertisement.
179
+ * If the message is not received within this window, a broken promise is declared and
180
+ * the router may apply bahavioural penalties.
181
+ */
182
+ export declare const GossipsubIWantFollowupTime: number;
183
+ /**
184
+ * Time in milliseconds to keep message ids in the seen cache
185
+ */
186
+ export declare const GossipsubSeenTTL: number;
187
+ export declare const TimeCacheDuration: number;
188
+ export declare const ERR_TOPIC_VALIDATOR_REJECT = "ERR_TOPIC_VALIDATOR_REJECT";
189
+ export declare const ERR_TOPIC_VALIDATOR_IGNORE = "ERR_TOPIC_VALIDATOR_IGNORE";
190
+ /**
191
+ * If peer score is better than this, we accept messages from this peer
192
+ * within ACCEPT_FROM_WHITELIST_DURATION_MS from the last time computing score.
193
+ */
194
+ export declare const ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE = 0;
195
+ /**
196
+ * If peer score >= ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE, accept up to this
197
+ * number of messages from that peer.
198
+ */
199
+ export declare const ACCEPT_FROM_WHITELIST_MAX_MESSAGES = 128;
200
+ /**
201
+ * If peer score >= ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE, accept messages from
202
+ * this peer up to this time duration.
203
+ */
204
+ export declare const ACCEPT_FROM_WHITELIST_DURATION_MS = 1000;
205
+ /**
206
+ * The default MeshMessageDeliveriesWindow to be used in metrics.
207
+ */
208
+ export declare const DEFAULT_METRIC_MESH_MESSAGE_DELIVERIES_WINDOWS = 1000;
209
+ /** Wait for 1 more heartbeats before clearing a backoff */
210
+ export declare const BACKOFF_SLACK = 1;
211
+ export declare const GossipsubIdontwantMinDataSize = 512;
212
+ export declare const GossipsubIdontwantMaxMessages = 512;
213
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,MAAM,OAAO,CAAA;AAC1B,eAAO,MAAM,MAAM,QAAc,CAAA;AAIjC,eAAO,MAAM,UAAU,oBAAoB,CAAA;AAE3C;;;GAGG;AACH,eAAO,MAAM,cAAc,mBAAmB,CAAA;AAE9C;;;;GAIG;AACH,eAAO,MAAM,cAAc,mBAAmB,CAAA;AAE9C;;;;GAIG;AACH,eAAO,MAAM,cAAc,mBAAmB,CAAA;AAI9C;;;;GAIG;AACH,eAAO,MAAM,UAAU,IAAI,CAAA;AAE3B;;;;GAIG;AACH,eAAO,MAAM,YAAY,IAAI,CAAA;AAE7B;;;GAGG;AACH,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B;;;;GAIG;AACH,eAAO,MAAM,eAAe,IAAI,CAAA;AAEhC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,IAAI,CAAA;AAI9B;;;GAGG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,IAAI,CAAA;AAE/B;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAA;AAEzC;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,IAAI,CAAA;AAI9C;;;GAGG;AACH,eAAO,MAAM,8BAA8B,MAAM,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,0BAA0B,OAAS,CAAA;AAEhD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,QAAS,CAAA;AAExC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAA;AAErC;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,QAAS,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,2BAA2B,QAAc,CAAA;AAEtD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAA;AAE5C;;GAEG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAEpC;;GAEG;AACH,eAAO,MAAM,8BAA8B,MAAM,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,0BAA0B,QAAc,CAAA;AAErD;;;GAGG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAE9C;;GAEG;AACH,eAAO,MAAM,kCAAkC,OAAS,CAAA;AAExD;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,KAAK,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,gCAAgC,IAAI,CAAA;AAEjD;;;GAGG;AACH,eAAO,MAAM,4BAA4B,QAAc,CAAA;AAEvD;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,yBAAyB,KAAK,CAAA;AAE3C;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,QAAa,CAAA;AAEpD;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAa,CAAA;AAE1C,eAAO,MAAM,iBAAiB,QAAa,CAAA;AAE3C,eAAO,MAAM,0BAA0B,+BAA+B,CAAA;AACtE,eAAO,MAAM,0BAA0B,+BAA+B,CAAA;AAEtE;;;GAGG;AACH,eAAO,MAAM,qCAAqC,IAAI,CAAA;AAEtD;;;GAGG;AACH,eAAO,MAAM,kCAAkC,MAAM,CAAA;AAErD;;;GAGG;AACH,eAAO,MAAM,iCAAiC,OAAO,CAAA;AAErD;;GAEG;AACH,eAAO,MAAM,8CAA8C,OAAO,CAAA;AAElE,2DAA2D;AAC3D,eAAO,MAAM,aAAa,IAAI,CAAA;AAE9B,eAAO,MAAM,6BAA6B,MAAM,CAAA;AAChD,eAAO,MAAM,6BAA6B,MAAM,CAAA"}
@@ -0,0 +1,217 @@
1
+ export const second = 1000;
2
+ export const minute = 60 * second;
3
+ // Protocol identifiers
4
+ export const FloodsubID = '/floodsub/1.0.0';
5
+ /**
6
+ * The protocol ID for version 1.0.0 of the Gossipsub protocol
7
+ * It is advertised along with GossipsubIDv11 for backwards compatability
8
+ */
9
+ export const GossipsubIDv10 = '/meshsub/1.0.0';
10
+ /**
11
+ * The protocol ID for version 1.1.0 of the Gossipsub protocol
12
+ * See the spec for details about how v1.1.0 compares to v1.0.0:
13
+ * https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md
14
+ */
15
+ export const GossipsubIDv11 = '/meshsub/1.1.0';
16
+ /**
17
+ * The protocol ID for version 1.2.0 of the Gossipsub protocol
18
+ * See the spec for details about how v1.2.0 compares to v1.1.0:
19
+ * https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md
20
+ */
21
+ export const GossipsubIDv12 = '/meshsub/1.2.0';
22
+ // Overlay parameters
23
+ /**
24
+ * GossipsubD sets the optimal degree for a Gossipsub topic mesh. For example, if GossipsubD == 6,
25
+ * each peer will want to have about six peers in their mesh for each topic they're subscribed to.
26
+ * GossipsubD should be set somewhere between GossipsubDlo and GossipsubDhi.
27
+ */
28
+ export const GossipsubD = 6;
29
+ /**
30
+ * GossipsubDlo sets the lower bound on the number of peers we keep in a Gossipsub topic mesh.
31
+ * If we have fewer than GossipsubDlo peers, we will attempt to graft some more into the mesh at
32
+ * the next heartbeat.
33
+ */
34
+ export const GossipsubDlo = 4;
35
+ /**
36
+ * GossipsubDhi sets the upper bound on the number of peers we keep in a Gossipsub topic mesh.
37
+ * If we have more than GossipsubDhi peers, we will select some to prune from the mesh at the next heartbeat.
38
+ */
39
+ export const GossipsubDhi = 12;
40
+ /**
41
+ * GossipsubDscore affects how peers are selected when pruning a mesh due to over subscription.
42
+ * At least GossipsubDscore of the retained peers will be high-scoring, while the remainder are
43
+ * chosen randomly.
44
+ */
45
+ export const GossipsubDscore = 4;
46
+ /**
47
+ * GossipsubDout sets the quota for the number of outbound connections to maintain in a topic mesh.
48
+ * When the mesh is pruned due to over subscription, we make sure that we have outbound connections
49
+ * to at least GossipsubDout of the survivor peers. This prevents sybil attackers from overwhelming
50
+ * our mesh with incoming connections.
51
+ *
52
+ * GossipsubDout must be set below GossipsubDlo, and must not exceed GossipsubD / 2.
53
+ */
54
+ export const GossipsubDout = 2;
55
+ // Gossip parameters
56
+ /**
57
+ * GossipsubHistoryLength controls the size of the message cache used for gossip.
58
+ * The message cache will remember messages for GossipsubHistoryLength heartbeats.
59
+ */
60
+ export const GossipsubHistoryLength = 5;
61
+ /**
62
+ * GossipsubHistoryGossip controls how many cached message ids we will advertise in
63
+ * IHAVE gossip messages. When asked for our seen message IDs, we will return
64
+ * only those from the most recent GossipsubHistoryGossip heartbeats. The slack between
65
+ * GossipsubHistoryGossip and GossipsubHistoryLength allows us to avoid advertising messages
66
+ * that will be expired by the time they're requested.
67
+ *
68
+ * GossipsubHistoryGossip must be less than or equal to GossipsubHistoryLength to
69
+ * avoid a runtime panic.
70
+ */
71
+ export const GossipsubHistoryGossip = 3;
72
+ /**
73
+ * GossipsubDlazy affects how many peers we will emit gossip to at each heartbeat.
74
+ * We will send gossip to at least GossipsubDlazy peers outside our mesh. The actual
75
+ * number may be more, depending on GossipsubGossipFactor and how many peers we're
76
+ * connected to.
77
+ */
78
+ export const GossipsubDlazy = 6;
79
+ /**
80
+ * GossipsubGossipFactor affects how many peers we will emit gossip to at each heartbeat.
81
+ * We will send gossip to GossipsubGossipFactor * (total number of non-mesh peers), or
82
+ * GossipsubDlazy, whichever is greater.
83
+ */
84
+ export const GossipsubGossipFactor = 0.25;
85
+ /**
86
+ * GossipsubGossipRetransmission controls how many times we will allow a peer to request
87
+ * the same message id through IWANT gossip before we start ignoring them. This is designed
88
+ * to prevent peers from spamming us with requests and wasting our resources.
89
+ */
90
+ export const GossipsubGossipRetransmission = 3;
91
+ // Heartbeat interval
92
+ /**
93
+ * GossipsubHeartbeatInitialDelay is the short delay before the heartbeat timer begins
94
+ * after the router is initialized.
95
+ */
96
+ export const GossipsubHeartbeatInitialDelay = 100;
97
+ /**
98
+ * GossipsubHeartbeatInterval controls the time between heartbeats.
99
+ */
100
+ export const GossipsubHeartbeatInterval = second;
101
+ /**
102
+ * GossipsubFanoutTTL controls how long we keep track of the fanout state. If it's been
103
+ * GossipsubFanoutTTL since we've published to a topic that we're not subscribed to,
104
+ * we'll delete the fanout map for that topic.
105
+ */
106
+ export const GossipsubFanoutTTL = minute;
107
+ /**
108
+ * GossipsubPrunePeers controls the number of peers to include in prune Peer eXchange.
109
+ * When we prune a peer that's eligible for PX (has a good score, etc), we will try to
110
+ * send them signed peer records for up to GossipsubPrunePeers other peers that we
111
+ * know of.
112
+ */
113
+ export const GossipsubPrunePeers = 16;
114
+ /**
115
+ * GossipsubPruneBackoff controls the backoff time for pruned peers. This is how long
116
+ * a peer must wait before attempting to graft into our mesh again after being pruned.
117
+ * When pruning a peer, we send them our value of GossipsubPruneBackoff so they know
118
+ * the minimum time to wait. Peers running older versions may not send a backoff time,
119
+ * so if we receive a prune message without one, we will wait at least GossipsubPruneBackoff
120
+ * before attempting to re-graft.
121
+ */
122
+ export const GossipsubPruneBackoff = minute;
123
+ /**
124
+ * Backoff to use when unsuscribing from a topic. Should not resubscribe to this topic before it expired.
125
+ */
126
+ export const GossipsubUnsubscribeBackoff = 10 * second;
127
+ /**
128
+ * GossipsubPruneBackoffTicks is the number of heartbeat ticks for attempting to prune expired
129
+ * backoff timers.
130
+ */
131
+ export const GossipsubPruneBackoffTicks = 15;
132
+ /**
133
+ * GossipsubConnectors controls the number of active connection attempts for peers obtained through PX.
134
+ */
135
+ export const GossipsubConnectors = 8;
136
+ /**
137
+ * GossipsubMaxPendingConnections sets the maximum number of pending connections for peers attempted through px.
138
+ */
139
+ export const GossipsubMaxPendingConnections = 128;
140
+ /**
141
+ * GossipsubConnectionTimeout controls the timeout for connection attempts.
142
+ */
143
+ export const GossipsubConnectionTimeout = 30 * second;
144
+ /**
145
+ * GossipsubDirectConnectTicks is the number of heartbeat ticks for attempting to reconnect direct peers
146
+ * that are not currently connected.
147
+ */
148
+ export const GossipsubDirectConnectTicks = 300;
149
+ /**
150
+ * GossipsubDirectConnectInitialDelay is the initial delay before opening connections to direct peers
151
+ */
152
+ export const GossipsubDirectConnectInitialDelay = second;
153
+ /**
154
+ * GossipsubOpportunisticGraftTicks is the number of heartbeat ticks for attempting to improve the mesh
155
+ * with opportunistic grafting. Every GossipsubOpportunisticGraftTicks we will attempt to select some
156
+ * high-scoring mesh peers to replace lower-scoring ones, if the median score of our mesh peers falls
157
+ * below a threshold
158
+ */
159
+ export const GossipsubOpportunisticGraftTicks = 60;
160
+ /**
161
+ * GossipsubOpportunisticGraftPeers is the number of peers to opportunistically graft.
162
+ */
163
+ export const GossipsubOpportunisticGraftPeers = 2;
164
+ /**
165
+ * If a GRAFT comes before GossipsubGraftFloodThreshold has elapsed since the last PRUNE,
166
+ * then there is an extra score penalty applied to the peer through P7.
167
+ */
168
+ export const GossipsubGraftFloodThreshold = 10 * second;
169
+ /**
170
+ * GossipsubMaxIHaveLength is the maximum number of messages to include in an IHAVE message.
171
+ * Also controls the maximum number of IHAVE ids we will accept and request with IWANT from a
172
+ * peer within a heartbeat, to protect from IHAVE floods. You should adjust this value from the
173
+ * default if your system is pushing more than 5000 messages in GossipsubHistoryGossip heartbeats;
174
+ * with the defaults this is 1666 messages/s.
175
+ */
176
+ export const GossipsubMaxIHaveLength = 5000;
177
+ /**
178
+ * GossipsubMaxIHaveMessages is the maximum number of IHAVE messages to accept from a peer within a heartbeat.
179
+ */
180
+ export const GossipsubMaxIHaveMessages = 10;
181
+ /**
182
+ * Time to wait for a message requested through IWANT following an IHAVE advertisement.
183
+ * If the message is not received within this window, a broken promise is declared and
184
+ * the router may apply bahavioural penalties.
185
+ */
186
+ export const GossipsubIWantFollowupTime = 3 * second;
187
+ /**
188
+ * Time in milliseconds to keep message ids in the seen cache
189
+ */
190
+ export const GossipsubSeenTTL = 2 * minute;
191
+ export const TimeCacheDuration = 120 * 1000;
192
+ export const ERR_TOPIC_VALIDATOR_REJECT = 'ERR_TOPIC_VALIDATOR_REJECT';
193
+ export const ERR_TOPIC_VALIDATOR_IGNORE = 'ERR_TOPIC_VALIDATOR_IGNORE';
194
+ /**
195
+ * If peer score is better than this, we accept messages from this peer
196
+ * within ACCEPT_FROM_WHITELIST_DURATION_MS from the last time computing score.
197
+ */
198
+ export const ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE = 0;
199
+ /**
200
+ * If peer score >= ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE, accept up to this
201
+ * number of messages from that peer.
202
+ */
203
+ export const ACCEPT_FROM_WHITELIST_MAX_MESSAGES = 128;
204
+ /**
205
+ * If peer score >= ACCEPT_FROM_WHITELIST_THRESHOLD_SCORE, accept messages from
206
+ * this peer up to this time duration.
207
+ */
208
+ export const ACCEPT_FROM_WHITELIST_DURATION_MS = 1000;
209
+ /**
210
+ * The default MeshMessageDeliveriesWindow to be used in metrics.
211
+ */
212
+ export const DEFAULT_METRIC_MESH_MESSAGE_DELIVERIES_WINDOWS = 1000;
213
+ /** Wait for 1 more heartbeats before clearing a backoff */
214
+ export const BACKOFF_SLACK = 1;
215
+ export const GossipsubIdontwantMinDataSize = 512;
216
+ export const GossipsubIdontwantMaxMessages = 512;
217
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare class InvalidPeerScoreParamsError extends Error {
2
+ static name: string;
3
+ constructor(message?: string);
4
+ }
5
+ export declare class InvalidPeerScoreThresholdsError extends Error {
6
+ static name: string;
7
+ constructor(message?: string);
8
+ }
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,MAAM,CAAC,IAAI,SAAgC;gBAE9B,OAAO,SAA8B;CAInD;AAED,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,MAAM,CAAC,IAAI,SAAoC;gBAElC,OAAO,SAAkC;CAIvD"}
@@ -0,0 +1,15 @@
1
+ export class InvalidPeerScoreParamsError extends Error {
2
+ static name = 'InvalidPeerScoreParamsError';
3
+ constructor(message = 'Invalid peer score params') {
4
+ super(message);
5
+ this.name = 'InvalidPeerScoreParamsError';
6
+ }
7
+ }
8
+ export class InvalidPeerScoreThresholdsError extends Error {
9
+ static name = 'InvalidPeerScoreThresholdsError';
10
+ constructor(message = 'Invalid peer score thresholds') {
11
+ super(message);
12
+ this.name = 'InvalidPeerScoreThresholdsError';
13
+ }
14
+ }
15
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IACpD,MAAM,CAAC,IAAI,GAAG,6BAA6B,CAAA;IAE3C,YAAa,OAAO,GAAG,2BAA2B;QAChD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAA;IAC3C,CAAC;;AAGH,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IACxD,MAAM,CAAC,IAAI,GAAG,iCAAiC,CAAA;IAE/C,YAAa,OAAO,GAAG,+BAA+B;QACpD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAA;IAC/C,CAAC"}