@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.
- package/README.md +85 -0
- package/dist/index.min.js +19 -0
- package/dist/index.min.js.map +7 -0
- package/dist/src/config.d.ts +32 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +2 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/constants.d.ts +213 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +217 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/errors.d.ts +9 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +15 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/gossipsub.d.ts +419 -0
- package/dist/src/gossipsub.d.ts.map +1 -0
- package/dist/src/gossipsub.js +2520 -0
- package/dist/src/gossipsub.js.map +1 -0
- package/dist/src/index.d.ts +344 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +43 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/message/decodeRpc.d.ts +11 -0
- package/dist/src/message/decodeRpc.d.ts.map +1 -0
- package/dist/src/message/decodeRpc.js +10 -0
- package/dist/src/message/decodeRpc.js.map +1 -0
- package/dist/src/message/index.d.ts +2 -0
- package/dist/src/message/index.d.ts.map +1 -0
- package/dist/src/message/index.js +2 -0
- package/dist/src/message/index.js.map +1 -0
- package/dist/src/message/rpc.d.ts +99 -0
- package/dist/src/message/rpc.d.ts.map +1 -0
- package/dist/src/message/rpc.js +663 -0
- package/dist/src/message/rpc.js.map +1 -0
- package/dist/src/message-cache.d.ts +80 -0
- package/dist/src/message-cache.d.ts.map +1 -0
- package/dist/src/message-cache.js +144 -0
- package/dist/src/message-cache.js.map +1 -0
- package/dist/src/metrics.d.ts +467 -0
- package/dist/src/metrics.d.ts.map +1 -0
- package/dist/src/metrics.js +896 -0
- package/dist/src/metrics.js.map +1 -0
- package/dist/src/score/compute-score.d.ts +4 -0
- package/dist/src/score/compute-score.d.ts.map +1 -0
- package/dist/src/score/compute-score.js +75 -0
- package/dist/src/score/compute-score.js.map +1 -0
- package/dist/src/score/index.d.ts +4 -0
- package/dist/src/score/index.d.ts.map +1 -0
- package/dist/src/score/index.js +4 -0
- package/dist/src/score/index.js.map +1 -0
- package/dist/src/score/message-deliveries.d.ts +45 -0
- package/dist/src/score/message-deliveries.d.ts.map +1 -0
- package/dist/src/score/message-deliveries.js +75 -0
- package/dist/src/score/message-deliveries.js.map +1 -0
- package/dist/src/score/peer-score-params.d.ts +125 -0
- package/dist/src/score/peer-score-params.d.ts.map +1 -0
- package/dist/src/score/peer-score-params.js +159 -0
- package/dist/src/score/peer-score-params.js.map +1 -0
- package/dist/src/score/peer-score-thresholds.d.ts +31 -0
- package/dist/src/score/peer-score-thresholds.d.ts.map +1 -0
- package/dist/src/score/peer-score-thresholds.js +32 -0
- package/dist/src/score/peer-score-thresholds.js.map +1 -0
- package/dist/src/score/peer-score.d.ts +119 -0
- package/dist/src/score/peer-score.d.ts.map +1 -0
- package/dist/src/score/peer-score.js +459 -0
- package/dist/src/score/peer-score.js.map +1 -0
- package/dist/src/score/peer-stats.d.ts +32 -0
- package/dist/src/score/peer-stats.d.ts.map +1 -0
- package/dist/src/score/peer-stats.js +2 -0
- package/dist/src/score/peer-stats.js.map +1 -0
- package/dist/src/score/scoreMetrics.d.ts +23 -0
- package/dist/src/score/scoreMetrics.d.ts.map +1 -0
- package/dist/src/score/scoreMetrics.js +155 -0
- package/dist/src/score/scoreMetrics.js.map +1 -0
- package/dist/src/stream.d.ts +30 -0
- package/dist/src/stream.d.ts.map +1 -0
- package/dist/src/stream.js +55 -0
- package/dist/src/stream.js.map +1 -0
- package/dist/src/tracer.d.ts +53 -0
- package/dist/src/tracer.d.ts.map +1 -0
- package/dist/src/tracer.js +155 -0
- package/dist/src/tracer.js.map +1 -0
- package/dist/src/types.d.ts +148 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +90 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/buildRawMessage.d.ts +20 -0
- package/dist/src/utils/buildRawMessage.d.ts.map +1 -0
- package/dist/src/utils/buildRawMessage.js +151 -0
- package/dist/src/utils/buildRawMessage.js.map +1 -0
- package/dist/src/utils/create-gossip-rpc.d.ts +7 -0
- package/dist/src/utils/create-gossip-rpc.d.ts.map +1 -0
- package/dist/src/utils/create-gossip-rpc.js +31 -0
- package/dist/src/utils/create-gossip-rpc.js.map +1 -0
- package/dist/src/utils/index.d.ts +4 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +4 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/messageIdToString.d.ts +5 -0
- package/dist/src/utils/messageIdToString.d.ts.map +1 -0
- package/dist/src/utils/messageIdToString.js +8 -0
- package/dist/src/utils/messageIdToString.js.map +1 -0
- package/dist/src/utils/msgIdFn.d.ts +10 -0
- package/dist/src/utils/msgIdFn.d.ts.map +1 -0
- package/dist/src/utils/msgIdFn.js +23 -0
- package/dist/src/utils/msgIdFn.js.map +1 -0
- package/dist/src/utils/multiaddr.d.ts +3 -0
- package/dist/src/utils/multiaddr.d.ts.map +1 -0
- package/dist/src/utils/multiaddr.js +15 -0
- package/dist/src/utils/multiaddr.js.map +1 -0
- package/dist/src/utils/publishConfig.d.ts +8 -0
- package/dist/src/utils/publishConfig.d.ts.map +1 -0
- package/dist/src/utils/publishConfig.js +25 -0
- package/dist/src/utils/publishConfig.js.map +1 -0
- package/dist/src/utils/set.d.ts +14 -0
- package/dist/src/utils/set.d.ts.map +1 -0
- package/dist/src/utils/set.js +41 -0
- package/dist/src/utils/set.js.map +1 -0
- package/dist/src/utils/shuffle.d.ts +7 -0
- package/dist/src/utils/shuffle.d.ts.map +1 -0
- package/dist/src/utils/shuffle.js +21 -0
- package/dist/src/utils/shuffle.js.map +1 -0
- package/dist/src/utils/time-cache.d.ts +22 -0
- package/dist/src/utils/time-cache.d.ts.map +1 -0
- package/dist/src/utils/time-cache.js +54 -0
- package/dist/src/utils/time-cache.js.map +1 -0
- package/package.json +142 -0
- package/src/config.ts +31 -0
- package/src/constants.ts +261 -0
- package/src/errors.ts +17 -0
- package/src/gossipsub.ts +3061 -0
- package/src/index.ts +404 -0
- package/src/message/decodeRpc.ts +19 -0
- package/src/message/index.ts +1 -0
- package/src/message/rpc.proto +58 -0
- package/src/message/rpc.ts +848 -0
- package/src/message-cache.ts +196 -0
- package/src/metrics.ts +1014 -0
- package/src/score/compute-score.ts +98 -0
- package/src/score/index.ts +3 -0
- package/src/score/message-deliveries.ts +95 -0
- package/src/score/peer-score-params.ts +316 -0
- package/src/score/peer-score-thresholds.ts +70 -0
- package/src/score/peer-score.ts +565 -0
- package/src/score/peer-stats.ts +33 -0
- package/src/score/scoreMetrics.ts +215 -0
- package/src/stream.ts +79 -0
- package/src/tracer.ts +177 -0
- package/src/types.ts +178 -0
- package/src/utils/buildRawMessage.ts +174 -0
- package/src/utils/create-gossip-rpc.ts +34 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/messageIdToString.ts +8 -0
- package/src/utils/msgIdFn.ts +24 -0
- package/src/utils/multiaddr.ts +19 -0
- package/src/utils/publishConfig.ts +33 -0
- package/src/utils/set.ts +43 -0
- package/src/utils/shuffle.ts +21 -0
- package/src/utils/time-cache.ts +71 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TopicStr } from '../types.js';
|
|
2
|
+
export interface PeerStats {
|
|
3
|
+
/** true if the peer is currently connected */
|
|
4
|
+
connected: boolean;
|
|
5
|
+
/** expiration time of the score stats for disconnected peers */
|
|
6
|
+
expire: number;
|
|
7
|
+
/** per topic stats */
|
|
8
|
+
topics: Record<TopicStr, TopicStats>;
|
|
9
|
+
/** IP tracking; store as set for easy processing */
|
|
10
|
+
knownIPs: Set<string>;
|
|
11
|
+
/** behavioural pattern penalties (applied by the router) */
|
|
12
|
+
behaviourPenalty: number;
|
|
13
|
+
}
|
|
14
|
+
export interface TopicStats {
|
|
15
|
+
/** true if the peer is in the mesh */
|
|
16
|
+
inMesh: boolean;
|
|
17
|
+
/** time when the peer was (last) GRAFTed; valid only when in mesh */
|
|
18
|
+
graftTime: number;
|
|
19
|
+
/** time in mesh (updated during refresh/decay to avoid calling gettimeofday on every score invocation) */
|
|
20
|
+
meshTime: number;
|
|
21
|
+
/** first message deliveries */
|
|
22
|
+
firstMessageDeliveries: number;
|
|
23
|
+
/** mesh message deliveries */
|
|
24
|
+
meshMessageDeliveries: number;
|
|
25
|
+
/** true if the peer has been enough time in the mesh to activate mess message deliveries */
|
|
26
|
+
meshMessageDeliveriesActive: boolean;
|
|
27
|
+
/** sticky mesh rate failure penalty counter */
|
|
28
|
+
meshFailurePenalty: number;
|
|
29
|
+
/** invalid message counter */
|
|
30
|
+
invalidMessageDeliveries: number;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=peer-stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-stats.d.ts","sourceRoot":"","sources":["../../../src/score/peer-stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,MAAM,WAAW,SAAS;IACxB,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAA;IAClB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IACpC,oDAAoD;IACpD,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACrB,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,MAAM,EAAE,OAAO,CAAA;IACf,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;IACjB,0GAA0G;IAC1G,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,sBAAsB,EAAE,MAAM,CAAA;IAC9B,8BAA8B;IAC9B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,4FAA4F;IAC5F,2BAA2B,EAAE,OAAO,CAAA;IACpC,+CAA+C;IAC/C,kBAAkB,EAAE,MAAM,CAAA;IAC1B,8BAA8B;IAC9B,wBAAwB,EAAE,MAAM,CAAA;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"peer-stats.js","sourceRoot":"","sources":["../../../src/score/peer-stats.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { PeerScoreParams } from './peer-score-params.js';
|
|
2
|
+
import type { PeerStats } from './peer-stats.js';
|
|
3
|
+
type TopicLabel = string;
|
|
4
|
+
type TopicStr = string;
|
|
5
|
+
type TopicStrToLabel = Map<TopicStr, TopicLabel>;
|
|
6
|
+
export interface TopicScoreWeights<T> {
|
|
7
|
+
p1w: T;
|
|
8
|
+
p2w: T;
|
|
9
|
+
p3w: T;
|
|
10
|
+
p3bw: T;
|
|
11
|
+
p4w: T;
|
|
12
|
+
}
|
|
13
|
+
export interface ScoreWeights<T> {
|
|
14
|
+
byTopic: Map<TopicLabel, TopicScoreWeights<T>>;
|
|
15
|
+
p5w: T;
|
|
16
|
+
p6w: T;
|
|
17
|
+
p7w: T;
|
|
18
|
+
score: T;
|
|
19
|
+
}
|
|
20
|
+
export declare function computeScoreWeights(peer: string, pstats: PeerStats, params: PeerScoreParams, peerIPs: Map<string, Set<string>>, topicStrToLabel: TopicStrToLabel): ScoreWeights<number>;
|
|
21
|
+
export declare function computeAllPeersScoreWeights(peerIdStrs: Iterable<string>, peerStats: Map<string, PeerStats>, params: PeerScoreParams, peerIPs: Map<string, Set<string>>, topicStrToLabel: TopicStrToLabel): ScoreWeights<number[]>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=scoreMetrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoreMetrics.d.ts","sourceRoot":"","sources":["../../../src/score/scoreMetrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAEhD,KAAK,UAAU,GAAG,MAAM,CAAA;AACxB,KAAK,QAAQ,GAAG,MAAM,CAAA;AACtB,KAAK,eAAe,GAAG,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;AAEhD,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,GAAG,EAAE,CAAC,CAAA;IACN,GAAG,EAAE,CAAC,CAAA;IACN,GAAG,EAAE,CAAC,CAAA;IACN,IAAI,EAAE,CAAC,CAAA;IACP,GAAG,EAAE,CAAC,CAAA;CACP;AACD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9C,GAAG,EAAE,CAAC,CAAA;IACN,GAAG,EAAE,CAAC,CAAA;IACN,GAAG,EAAE,CAAC,CAAA;IACN,KAAK,EAAE,CAAC,CAAA;CACT;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACjC,eAAe,EAAE,eAAe,GAC/B,YAAY,CAAC,MAAM,CAAC,CAmItB;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC5B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,EACjC,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACjC,eAAe,EAAE,eAAe,GAC/B,YAAY,CAAC,MAAM,EAAE,CAAC,CA+CxB"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
export function computeScoreWeights(peer, pstats, params, peerIPs, topicStrToLabel) {
|
|
2
|
+
let score = 0;
|
|
3
|
+
const byTopic = new Map();
|
|
4
|
+
// topic stores
|
|
5
|
+
Object.entries(pstats.topics).forEach(([topic, tstats]) => {
|
|
6
|
+
// the topic parameters
|
|
7
|
+
// Aggregate by known topicLabel or throw to 'unknown'. This prevent too high cardinality
|
|
8
|
+
const topicLabel = topicStrToLabel.get(topic) ?? 'unknown';
|
|
9
|
+
const topicParams = params.topics[topic];
|
|
10
|
+
if (topicParams === undefined) {
|
|
11
|
+
// we are not scoring this topic
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
let topicScores = byTopic.get(topicLabel);
|
|
15
|
+
if (topicScores == null) {
|
|
16
|
+
topicScores = {
|
|
17
|
+
p1w: 0,
|
|
18
|
+
p2w: 0,
|
|
19
|
+
p3w: 0,
|
|
20
|
+
p3bw: 0,
|
|
21
|
+
p4w: 0
|
|
22
|
+
};
|
|
23
|
+
byTopic.set(topicLabel, topicScores);
|
|
24
|
+
}
|
|
25
|
+
let p1w = 0;
|
|
26
|
+
let p2w = 0;
|
|
27
|
+
let p3w = 0;
|
|
28
|
+
let p3bw = 0;
|
|
29
|
+
let p4w = 0;
|
|
30
|
+
// P1: time in Mesh
|
|
31
|
+
if (tstats.inMesh) {
|
|
32
|
+
const p1 = Math.max(tstats.meshTime / topicParams.timeInMeshQuantum, topicParams.timeInMeshCap);
|
|
33
|
+
p1w += p1 * topicParams.timeInMeshWeight;
|
|
34
|
+
}
|
|
35
|
+
// P2: first message deliveries
|
|
36
|
+
let p2 = tstats.firstMessageDeliveries;
|
|
37
|
+
if (p2 > topicParams.firstMessageDeliveriesCap) {
|
|
38
|
+
p2 = topicParams.firstMessageDeliveriesCap;
|
|
39
|
+
}
|
|
40
|
+
p2w += p2 * topicParams.firstMessageDeliveriesWeight;
|
|
41
|
+
// P3: mesh message deliveries
|
|
42
|
+
if (tstats.meshMessageDeliveriesActive &&
|
|
43
|
+
tstats.meshMessageDeliveries < topicParams.meshMessageDeliveriesThreshold) {
|
|
44
|
+
const deficit = topicParams.meshMessageDeliveriesThreshold - tstats.meshMessageDeliveries;
|
|
45
|
+
const p3 = deficit * deficit;
|
|
46
|
+
p3w += p3 * topicParams.meshMessageDeliveriesWeight;
|
|
47
|
+
}
|
|
48
|
+
// P3b:
|
|
49
|
+
// NOTE: the weight of P3b is negative (validated in validateTopicScoreParams) so this detracts
|
|
50
|
+
const p3b = tstats.meshFailurePenalty;
|
|
51
|
+
p3bw += p3b * topicParams.meshFailurePenaltyWeight;
|
|
52
|
+
// P4: invalid messages
|
|
53
|
+
// NOTE: the weight of P4 is negative (validated in validateTopicScoreParams) so this detracts
|
|
54
|
+
const p4 = tstats.invalidMessageDeliveries * tstats.invalidMessageDeliveries;
|
|
55
|
+
p4w += p4 * topicParams.invalidMessageDeliveriesWeight;
|
|
56
|
+
// update score, mixing with topic weight
|
|
57
|
+
score += (p1w + p2w + p3w + p3bw + p4w) * topicParams.topicWeight;
|
|
58
|
+
topicScores.p1w += p1w;
|
|
59
|
+
topicScores.p2w += p2w;
|
|
60
|
+
topicScores.p3w += p3w;
|
|
61
|
+
topicScores.p3bw += p3bw;
|
|
62
|
+
topicScores.p4w += p4w;
|
|
63
|
+
});
|
|
64
|
+
// apply the topic score cap, if any
|
|
65
|
+
if (params.topicScoreCap > 0 && score > params.topicScoreCap) {
|
|
66
|
+
score = params.topicScoreCap;
|
|
67
|
+
// Proportionally apply cap to all individual contributions
|
|
68
|
+
const capF = params.topicScoreCap / score;
|
|
69
|
+
for (const ws of byTopic.values()) {
|
|
70
|
+
ws.p1w *= capF;
|
|
71
|
+
ws.p2w *= capF;
|
|
72
|
+
ws.p3w *= capF;
|
|
73
|
+
ws.p3bw *= capF;
|
|
74
|
+
ws.p4w *= capF;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
let p5w = 0;
|
|
78
|
+
let p6w = 0;
|
|
79
|
+
let p7w = 0;
|
|
80
|
+
// P5: application-specific score
|
|
81
|
+
const p5 = params.appSpecificScore(peer);
|
|
82
|
+
p5w += p5 * params.appSpecificWeight;
|
|
83
|
+
// P6: IP colocation factor
|
|
84
|
+
pstats.knownIPs.forEach((ip) => {
|
|
85
|
+
if (params.IPColocationFactorWhitelist.has(ip)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// P6 has a cliff (IPColocationFactorThreshold)
|
|
89
|
+
// It's only applied if at least that many peers are connected to us from that source IP addr.
|
|
90
|
+
// It is quadratic, and the weight is negative (validated in validatePeerScoreParams)
|
|
91
|
+
const peersInIP = peerIPs.get(ip);
|
|
92
|
+
const numPeersInIP = (peersInIP != null) ? peersInIP.size : 0;
|
|
93
|
+
if (numPeersInIP > params.IPColocationFactorThreshold) {
|
|
94
|
+
const surplus = numPeersInIP - params.IPColocationFactorThreshold;
|
|
95
|
+
const p6 = surplus * surplus;
|
|
96
|
+
p6w += p6 * params.IPColocationFactorWeight;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// P7: behavioural pattern penalty
|
|
100
|
+
const p7 = pstats.behaviourPenalty * pstats.behaviourPenalty;
|
|
101
|
+
p7w += p7 * params.behaviourPenaltyWeight;
|
|
102
|
+
score += p5w + p6w + p7w;
|
|
103
|
+
return {
|
|
104
|
+
byTopic,
|
|
105
|
+
p5w,
|
|
106
|
+
p6w,
|
|
107
|
+
p7w,
|
|
108
|
+
score
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export function computeAllPeersScoreWeights(peerIdStrs, peerStats, params, peerIPs, topicStrToLabel) {
|
|
112
|
+
const sw = {
|
|
113
|
+
byTopic: new Map(),
|
|
114
|
+
p5w: [],
|
|
115
|
+
p6w: [],
|
|
116
|
+
p7w: [],
|
|
117
|
+
score: []
|
|
118
|
+
};
|
|
119
|
+
for (const peerIdStr of peerIdStrs) {
|
|
120
|
+
const pstats = peerStats.get(peerIdStr);
|
|
121
|
+
if (pstats != null) {
|
|
122
|
+
const swPeer = computeScoreWeights(peerIdStr, pstats, params, peerIPs, topicStrToLabel);
|
|
123
|
+
for (const [topic, swPeerTopic] of swPeer.byTopic) {
|
|
124
|
+
let swTopic = sw.byTopic.get(topic);
|
|
125
|
+
if (swTopic == null) {
|
|
126
|
+
swTopic = {
|
|
127
|
+
p1w: [],
|
|
128
|
+
p2w: [],
|
|
129
|
+
p3w: [],
|
|
130
|
+
p3bw: [],
|
|
131
|
+
p4w: []
|
|
132
|
+
};
|
|
133
|
+
sw.byTopic.set(topic, swTopic);
|
|
134
|
+
}
|
|
135
|
+
swTopic.p1w.push(swPeerTopic.p1w);
|
|
136
|
+
swTopic.p2w.push(swPeerTopic.p2w);
|
|
137
|
+
swTopic.p3w.push(swPeerTopic.p3w);
|
|
138
|
+
swTopic.p3bw.push(swPeerTopic.p3bw);
|
|
139
|
+
swTopic.p4w.push(swPeerTopic.p4w);
|
|
140
|
+
}
|
|
141
|
+
sw.p5w.push(swPeer.p5w);
|
|
142
|
+
sw.p6w.push(swPeer.p6w);
|
|
143
|
+
sw.p7w.push(swPeer.p7w);
|
|
144
|
+
sw.score.push(swPeer.score);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
sw.p5w.push(0);
|
|
148
|
+
sw.p6w.push(0);
|
|
149
|
+
sw.p7w.push(0);
|
|
150
|
+
sw.score.push(0);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return sw;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=scoreMetrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scoreMetrics.js","sourceRoot":"","sources":["../../../src/score/scoreMetrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AbortOptions, Stream } from '@libp2p/interface';
|
|
2
|
+
import type { Uint8ArrayList } from 'uint8arraylist';
|
|
3
|
+
interface OutboundStreamOpts {
|
|
4
|
+
/** Max size in bytes for pushable buffer. If full, will throw on .push */
|
|
5
|
+
maxBufferSize?: number;
|
|
6
|
+
}
|
|
7
|
+
interface InboundStreamOpts {
|
|
8
|
+
/** Max size in bytes for reading messages from the stream */
|
|
9
|
+
maxDataLength?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class OutboundStream {
|
|
12
|
+
private readonly rawStream;
|
|
13
|
+
constructor(rawStream: Stream, errCallback: (e: Error) => void, opts: OutboundStreamOpts);
|
|
14
|
+
get protocol(): string;
|
|
15
|
+
push(data: Uint8Array): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Same to push() but this is prefixed data so no need to encode length prefixed again
|
|
18
|
+
*/
|
|
19
|
+
pushPrefixed(data: Uint8ArrayList): void;
|
|
20
|
+
close(options?: AbortOptions): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export declare class InboundStream {
|
|
23
|
+
readonly source: AsyncIterable<Uint8ArrayList>;
|
|
24
|
+
private readonly rawStream;
|
|
25
|
+
private readonly closeController;
|
|
26
|
+
constructor(rawStream: Stream, opts?: InboundStreamOpts);
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,UAAU,kBAAkB;IAC1B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,UAAU,iBAAiB;IACzB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,qBAAa,cAAc;IACZ,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,EAAE,IAAI,EAAE,kBAAkB;IAY1G,IAAI,QAAQ,IAAK,MAAM,CAEtB;IAEK,IAAI,CAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C;;OAEG;IACH,YAAY,CAAE,IAAI,EAAE,cAAc,GAAG,IAAI;IAKnC,KAAK,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAMpD;AAED,qBAAa,aAAa;IACxB,SAAgB,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;IAErD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;gBAEpC,SAAS,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB;IAiBtD,KAAK,IAAK,OAAO,CAAC,IAAI,CAAC;CAG9B"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { pipe } from '@libp2p/utils';
|
|
2
|
+
import { encode, decode } from 'it-length-prefixed';
|
|
3
|
+
export class OutboundStream {
|
|
4
|
+
rawStream;
|
|
5
|
+
constructor(rawStream, errCallback, opts) {
|
|
6
|
+
this.rawStream = rawStream;
|
|
7
|
+
if (opts.maxBufferSize != null) {
|
|
8
|
+
rawStream.maxWriteBufferLength = opts.maxBufferSize;
|
|
9
|
+
}
|
|
10
|
+
rawStream.addEventListener('close', (evt) => {
|
|
11
|
+
if (evt.error != null) {
|
|
12
|
+
errCallback(evt.error);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
get protocol() {
|
|
17
|
+
return this.rawStream.protocol;
|
|
18
|
+
}
|
|
19
|
+
async push(data) {
|
|
20
|
+
return this.pushPrefixed(encode.single(data));
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Same to push() but this is prefixed data so no need to encode length prefixed again
|
|
24
|
+
*/
|
|
25
|
+
pushPrefixed(data) {
|
|
26
|
+
// TODO: backpressure
|
|
27
|
+
this.rawStream.send(data);
|
|
28
|
+
}
|
|
29
|
+
async close(options) {
|
|
30
|
+
await this.rawStream.close(options)
|
|
31
|
+
.catch(err => {
|
|
32
|
+
this.rawStream.abort(err);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class InboundStream {
|
|
37
|
+
source;
|
|
38
|
+
rawStream;
|
|
39
|
+
closeController;
|
|
40
|
+
constructor(rawStream, opts = {}) {
|
|
41
|
+
this.rawStream = rawStream;
|
|
42
|
+
this.closeController = new AbortController();
|
|
43
|
+
this.closeController.signal.addEventListener('abort', () => {
|
|
44
|
+
rawStream.close()
|
|
45
|
+
.catch(err => {
|
|
46
|
+
rawStream.abort(err);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
this.source = pipe(this.rawStream, (source) => decode(source, opts));
|
|
50
|
+
}
|
|
51
|
+
async close() {
|
|
52
|
+
this.closeController.abort();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAcnD,MAAM,OAAO,cAAc;IACK;IAA9B,YAA8B,SAAiB,EAAE,WAA+B,EAAE,IAAwB;QAA5E,cAAS,GAAT,SAAS,CAAQ;QAC7C,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,EAAE,CAAC;YAC/B,SAAS,CAAC,oBAAoB,GAAG,IAAI,CAAC,aAAa,CAAA;QACrD,CAAC;QAED,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YAC1C,IAAI,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;gBACtB,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACxB,CAAC;QACH,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,IAAI,CAAE,IAAgB;QAC1B,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IAC/C,CAAC;IAED;;OAEG;IACH,YAAY,CAAE,IAAoB;QAChC,qBAAqB;QACrB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAED,KAAK,CAAC,KAAK,CAAE,OAAsB;QACjC,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;aAChC,KAAK,CAAC,GAAG,CAAC,EAAE;YACX,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC3B,CAAC,CAAC,CAAA;IACN,CAAC;CACF;AAED,MAAM,OAAO,aAAa;IACR,MAAM,CAA+B;IAEpC,SAAS,CAAQ;IACjB,eAAe,CAAiB;IAEjD,YAAa,SAAiB,EAAE,OAA0B,EAAE;QAC1D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAE5C,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACzD,SAAS,CAAC,KAAK,EAAE;iBACd,KAAK,CAAC,GAAG,CAAC,EAAE;gBACX,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACtB,CAAC,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,GAAG,IAAI,CAChB,IAAI,CAAC,SAAS,EACd,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CACjC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAA;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { RejectReason } from './types.js';
|
|
2
|
+
import type { Metrics } from './metrics.js';
|
|
3
|
+
import type { MsgIdStr, MsgIdToStrFn, PeerIdStr } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* IWantTracer is an internal tracer that tracks IWANT requests in order to penalize
|
|
6
|
+
* peers who don't follow up on IWANT requests after an IHAVE advertisement.
|
|
7
|
+
* The tracking of promises is probabilistic to avoid using too much memory.
|
|
8
|
+
*
|
|
9
|
+
* Note: Do not confuse these 'promises' with JS Promise objects.
|
|
10
|
+
* These 'promises' are merely expectations of a peer's behavior.
|
|
11
|
+
*/
|
|
12
|
+
export declare class IWantTracer {
|
|
13
|
+
private readonly gossipsubIWantFollowupMs;
|
|
14
|
+
private readonly msgIdToStrFn;
|
|
15
|
+
private readonly metrics;
|
|
16
|
+
/**
|
|
17
|
+
* Promises to deliver a message
|
|
18
|
+
* Map per message id, per peer, promise expiration time
|
|
19
|
+
*/
|
|
20
|
+
private readonly promises;
|
|
21
|
+
/**
|
|
22
|
+
* First request time by msgId. Used for metrics to track expire times.
|
|
23
|
+
* Necessary to know if peers are actually breaking promises or simply sending them a bit later
|
|
24
|
+
*/
|
|
25
|
+
private readonly requestMsByMsg;
|
|
26
|
+
private readonly requestMsByMsgExpire;
|
|
27
|
+
constructor(gossipsubIWantFollowupMs: number, msgIdToStrFn: MsgIdToStrFn, metrics: Metrics | null);
|
|
28
|
+
get size(): number;
|
|
29
|
+
get requestMsByMsgSize(): number;
|
|
30
|
+
/**
|
|
31
|
+
* Track a promise to deliver a message from a list of msgIds we are requesting
|
|
32
|
+
*/
|
|
33
|
+
addPromise(from: PeerIdStr, msgIds: Uint8Array[]): void;
|
|
34
|
+
/**
|
|
35
|
+
* Returns the number of broken promises for each peer who didn't follow up on an IWANT request.
|
|
36
|
+
*
|
|
37
|
+
* This should be called not too often relative to the expire times, since it iterates over the whole data.
|
|
38
|
+
*/
|
|
39
|
+
getBrokenPromises(): Map<PeerIdStr, number>;
|
|
40
|
+
/**
|
|
41
|
+
* Someone delivered a message, stop tracking promises for it
|
|
42
|
+
*/
|
|
43
|
+
deliverMessage(msgIdStr: MsgIdStr, isDuplicate?: boolean): void;
|
|
44
|
+
/**
|
|
45
|
+
* A message got rejected, so we can stop tracking promises and let the score penalty apply from invalid message delivery,
|
|
46
|
+
* unless its an obviously invalid message.
|
|
47
|
+
*/
|
|
48
|
+
rejectMessage(msgIdStr: MsgIdStr, reason: RejectReason): void;
|
|
49
|
+
clear(): void;
|
|
50
|
+
prune(): void;
|
|
51
|
+
private trackMessage;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=tracer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracer.d.ts","sourceRoot":"","sources":["../../src/tracer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAEnE;;;;;;;GAOG;AACH,qBAAa,WAAW;IAcpB,OAAO,CAAC,QAAQ,CAAC,wBAAwB;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAf1B;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA8C;IACvE;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA8B;IAC7D,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAQ;gBAG1B,wBAAwB,EAAE,MAAM,EAChC,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,OAAO,GAAG,IAAI;IAK1C,IAAI,IAAI,IAAK,MAAM,CAElB;IAED,IAAI,kBAAkB,IAAK,MAAM,CAEhC;IAED;;OAEG;IACH,UAAU,CAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI;IA2BxD;;;;OAIG;IACH,iBAAiB,IAAK,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC;IA6B5C;;OAEG;IACH,cAAc,CAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,UAAQ,GAAG,IAAI;IAiB9D;;;OAGG;IACH,aAAa,CAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IAe9D,KAAK,IAAK,IAAI;IAId,KAAK,IAAK,IAAI;IAmBd,OAAO,CAAC,YAAY;CASrB"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { RejectReason } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* IWantTracer is an internal tracer that tracks IWANT requests in order to penalize
|
|
4
|
+
* peers who don't follow up on IWANT requests after an IHAVE advertisement.
|
|
5
|
+
* The tracking of promises is probabilistic to avoid using too much memory.
|
|
6
|
+
*
|
|
7
|
+
* Note: Do not confuse these 'promises' with JS Promise objects.
|
|
8
|
+
* These 'promises' are merely expectations of a peer's behavior.
|
|
9
|
+
*/
|
|
10
|
+
export class IWantTracer {
|
|
11
|
+
gossipsubIWantFollowupMs;
|
|
12
|
+
msgIdToStrFn;
|
|
13
|
+
metrics;
|
|
14
|
+
/**
|
|
15
|
+
* Promises to deliver a message
|
|
16
|
+
* Map per message id, per peer, promise expiration time
|
|
17
|
+
*/
|
|
18
|
+
promises = new Map();
|
|
19
|
+
/**
|
|
20
|
+
* First request time by msgId. Used for metrics to track expire times.
|
|
21
|
+
* Necessary to know if peers are actually breaking promises or simply sending them a bit later
|
|
22
|
+
*/
|
|
23
|
+
requestMsByMsg = new Map();
|
|
24
|
+
requestMsByMsgExpire;
|
|
25
|
+
constructor(gossipsubIWantFollowupMs, msgIdToStrFn, metrics) {
|
|
26
|
+
this.gossipsubIWantFollowupMs = gossipsubIWantFollowupMs;
|
|
27
|
+
this.msgIdToStrFn = msgIdToStrFn;
|
|
28
|
+
this.metrics = metrics;
|
|
29
|
+
this.requestMsByMsgExpire = 10 * gossipsubIWantFollowupMs;
|
|
30
|
+
}
|
|
31
|
+
get size() {
|
|
32
|
+
return this.promises.size;
|
|
33
|
+
}
|
|
34
|
+
get requestMsByMsgSize() {
|
|
35
|
+
return this.requestMsByMsg.size;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Track a promise to deliver a message from a list of msgIds we are requesting
|
|
39
|
+
*/
|
|
40
|
+
addPromise(from, msgIds) {
|
|
41
|
+
// pick msgId randomly from the list
|
|
42
|
+
const ix = Math.floor(Math.random() * msgIds.length);
|
|
43
|
+
const msgId = msgIds[ix];
|
|
44
|
+
const msgIdStr = this.msgIdToStrFn(msgId);
|
|
45
|
+
let expireByPeer = this.promises.get(msgIdStr);
|
|
46
|
+
if (expireByPeer == null) {
|
|
47
|
+
expireByPeer = new Map();
|
|
48
|
+
this.promises.set(msgIdStr, expireByPeer);
|
|
49
|
+
}
|
|
50
|
+
const now = Date.now();
|
|
51
|
+
// If a promise for this message id and peer already exists we don't update the expiry
|
|
52
|
+
if (!expireByPeer.has(from)) {
|
|
53
|
+
expireByPeer.set(from, now + this.gossipsubIWantFollowupMs);
|
|
54
|
+
if (this.metrics != null) {
|
|
55
|
+
this.metrics.iwantPromiseStarted.inc(1);
|
|
56
|
+
if (!this.requestMsByMsg.has(msgIdStr)) {
|
|
57
|
+
this.requestMsByMsg.set(msgIdStr, now);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns the number of broken promises for each peer who didn't follow up on an IWANT request.
|
|
64
|
+
*
|
|
65
|
+
* This should be called not too often relative to the expire times, since it iterates over the whole data.
|
|
66
|
+
*/
|
|
67
|
+
getBrokenPromises() {
|
|
68
|
+
const now = Date.now();
|
|
69
|
+
const result = new Map();
|
|
70
|
+
let brokenPromises = 0;
|
|
71
|
+
this.promises.forEach((expireByPeer, msgId) => {
|
|
72
|
+
expireByPeer.forEach((expire, p) => {
|
|
73
|
+
// the promise has been broken
|
|
74
|
+
if (expire < now) {
|
|
75
|
+
// add 1 to result
|
|
76
|
+
result.set(p, (result.get(p) ?? 0) + 1);
|
|
77
|
+
// delete from tracked promises
|
|
78
|
+
expireByPeer.delete(p);
|
|
79
|
+
// for metrics
|
|
80
|
+
brokenPromises++;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
// clean up empty promises for a msgId
|
|
84
|
+
if (expireByPeer.size === 0) {
|
|
85
|
+
this.promises.delete(msgId);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
this.metrics?.iwantPromiseBroken.inc(brokenPromises);
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Someone delivered a message, stop tracking promises for it
|
|
93
|
+
*/
|
|
94
|
+
deliverMessage(msgIdStr, isDuplicate = false) {
|
|
95
|
+
this.trackMessage(msgIdStr);
|
|
96
|
+
const expireByPeer = this.promises.get(msgIdStr);
|
|
97
|
+
// Expired promise, check requestMsByMsg
|
|
98
|
+
if (expireByPeer != null) {
|
|
99
|
+
this.promises.delete(msgIdStr);
|
|
100
|
+
if (this.metrics != null) {
|
|
101
|
+
this.metrics.iwantPromiseResolved.inc(1);
|
|
102
|
+
if (isDuplicate) {
|
|
103
|
+
this.metrics.iwantPromiseResolvedFromDuplicate.inc(1);
|
|
104
|
+
}
|
|
105
|
+
this.metrics.iwantPromiseResolvedPeers.inc(expireByPeer.size);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A message got rejected, so we can stop tracking promises and let the score penalty apply from invalid message delivery,
|
|
111
|
+
* unless its an obviously invalid message.
|
|
112
|
+
*/
|
|
113
|
+
rejectMessage(msgIdStr, reason) {
|
|
114
|
+
this.trackMessage(msgIdStr);
|
|
115
|
+
// A message got rejected, so we can stop tracking promises and let the score penalty apply.
|
|
116
|
+
// With the expection of obvious invalid messages
|
|
117
|
+
switch (reason) {
|
|
118
|
+
case RejectReason.Error:
|
|
119
|
+
return;
|
|
120
|
+
default:
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
this.promises.delete(msgIdStr);
|
|
124
|
+
}
|
|
125
|
+
clear() {
|
|
126
|
+
this.promises.clear();
|
|
127
|
+
}
|
|
128
|
+
prune() {
|
|
129
|
+
const maxMs = Date.now() - this.requestMsByMsgExpire;
|
|
130
|
+
let count = 0;
|
|
131
|
+
for (const [k, v] of this.requestMsByMsg.entries()) {
|
|
132
|
+
if (v < maxMs) {
|
|
133
|
+
// messages that stay too long in the requestMsByMsg map, delete
|
|
134
|
+
this.requestMsByMsg.delete(k);
|
|
135
|
+
count++;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// recent messages, keep them
|
|
139
|
+
// sort by insertion order
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
this.metrics?.iwantMessagePruned.inc(count);
|
|
144
|
+
}
|
|
145
|
+
trackMessage(msgIdStr) {
|
|
146
|
+
if (this.metrics != null) {
|
|
147
|
+
const requestMs = this.requestMsByMsg.get(msgIdStr);
|
|
148
|
+
if (requestMs !== undefined) {
|
|
149
|
+
this.metrics.iwantPromiseDeliveryTime.observe((Date.now() - requestMs) / 1000);
|
|
150
|
+
this.requestMsByMsg.delete(msgIdStr);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=tracer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracer.js","sourceRoot":"","sources":["../../src/tracer.ts"],"names":[],"mappings":"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"}
|