@lodestar/reqresp 1.43.0-dev.b05ea98d04 → 1.43.0-dev.b0e1143d06
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/lib/ReqResp.d.ts.map +1 -1
- package/lib/ReqResp.js +7 -3
- package/lib/ReqResp.js.map +1 -1
- package/lib/interface.d.ts +1 -1
- package/lib/interface.js +1 -1
- package/lib/rate_limiter/selfRateLimiter.d.ts +7 -5
- package/lib/rate_limiter/selfRateLimiter.d.ts.map +1 -1
- package/lib/rate_limiter/selfRateLimiter.js +36 -27
- package/lib/rate_limiter/selfRateLimiter.js.map +1 -1
- package/lib/request/errors.d.ts +3 -2
- package/lib/request/errors.d.ts.map +1 -1
- package/lib/request/errors.js +3 -2
- package/lib/request/errors.js.map +1 -1
- package/package.json +7 -7
- package/src/ReqResp.ts +7 -3
- package/src/interface.ts +1 -1
- package/src/rate_limiter/selfRateLimiter.ts +51 -31
- package/src/request/errors.ts +6 -5
package/lib/ReqResp.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReqResp.d.ts","sourceRoot":"","sources":["../src/ReqResp.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,MAAM,EAAS,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAC,MAAM,EAAE,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAAC,OAAO,EAAa,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAC,YAAY,EAAoB,eAAe,EAAc,MAAM,oBAAoB,CAAC;AAEhG,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAGpB,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,eAAO,MAAM,uBAAuB,2BAA2B,CAAC;AAEhE,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,oBAAoB,GAAG,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,WAAY,SAAQ,eAAe,EAAE,sBAAsB;IAC1E,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CACjD;AAED;;;;;GAKG;AACH,qBAAa,OAAO;IAsBhB,OAAO,CAAC,QAAQ,CAAC,IAAI;IApBvB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAG3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IAEjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAElD,OAAO,CAAC,UAAU,CAAyB;IAC3C,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAwC;IAC5E,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkC;IAEpE,YACE,OAAO,EAAE,sBAAsB,EACd,IAAI,GAAE,WAAgB,EAexC;IAED;;;;;OAKG;IACH,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAKzD;IAED;;;;;OAKG;IACG,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAYxD;IAED;;;;;OAKG;IACG,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9D;IAED;;OAEG;IACG,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAI5C;IAED,sBAAsB,IAAI,UAAU,EAAE,CAErC;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAO3B;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAI1B;IAGM,WAAW,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,UAAU,GACf,aAAa,CAAC,gBAAgB,CAAC,
|
|
1
|
+
{"version":3,"file":"ReqResp.d.ts","sourceRoot":"","sources":["../src/ReqResp.ts"],"names":[],"mappings":"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"}
|
package/lib/ReqResp.js
CHANGED
|
@@ -121,10 +121,12 @@ export class ReqResp {
|
|
|
121
121
|
if (!protocol) {
|
|
122
122
|
throw Error(`Request to send to protocol ${protocolID} but it has not been declared`);
|
|
123
123
|
}
|
|
124
|
-
|
|
124
|
+
const allows = this.selfRateLimiter.allows(peerIdStr, protocolID, requestId);
|
|
125
|
+
if (allows !== true) {
|
|
125
126
|
// we technically don't send request in this case but would be nice just to track this in the same `outgoingErrorReasons` metric
|
|
126
127
|
this.metrics?.outgoingErrorReasons.inc({ reason: RequestErrorCode.REQUEST_SELF_RATE_LIMITED });
|
|
127
|
-
|
|
128
|
+
const rateLimitedUntilMs = typeof allows === "number" ? allows : undefined;
|
|
129
|
+
throw new RequestError({ code: RequestErrorCode.REQUEST_SELF_RATE_LIMITED, rateLimitedUntilMs });
|
|
128
130
|
// don't call this.onOutgoingRequestError() to penalize peer
|
|
129
131
|
}
|
|
130
132
|
protocols.push(protocol);
|
|
@@ -142,7 +144,9 @@ export class ReqResp {
|
|
|
142
144
|
this.metrics?.dialErrors.inc();
|
|
143
145
|
}
|
|
144
146
|
if (e.type.code === RequestErrorCode.RESP_RATE_LIMITED) {
|
|
145
|
-
|
|
147
|
+
for (const protocolID of protocolIDs) {
|
|
148
|
+
this.selfRateLimiter.onRateLimited(peerIdStr, protocolID, e.type.rateLimitedUntilMs);
|
|
149
|
+
}
|
|
146
150
|
}
|
|
147
151
|
this.metrics?.outgoingErrorReasons.inc({ reason: e.type.code });
|
|
148
152
|
this.onOutgoingRequestError(peerId, method, e);
|
package/lib/ReqResp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReqResp.js","sourceRoot":"","sources":["../src/ReqResp.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ReqResp.js","sourceRoot":"","sources":["../src/ReqResp.ts"],"names":[],"mappings":"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"}
|
package/lib/interface.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare enum RespStatus {
|
|
|
13
13
|
*/
|
|
14
14
|
SERVER_ERROR = 2,
|
|
15
15
|
/**
|
|
16
|
-
* The responder does not have requested resource.
|
|
16
|
+
* The responder does not have requested resource. The response payload adheres to the ErrorMessage schema.
|
|
17
17
|
*/
|
|
18
18
|
RESOURCE_UNAVAILABLE = 3,
|
|
19
19
|
/**
|
package/lib/interface.js
CHANGED
|
@@ -16,7 +16,7 @@ var RespStatus;
|
|
|
16
16
|
*/
|
|
17
17
|
RespStatus[RespStatus["SERVER_ERROR"] = 2] = "SERVER_ERROR";
|
|
18
18
|
/**
|
|
19
|
-
* The responder does not have requested resource.
|
|
19
|
+
* The responder does not have requested resource. The response payload adheres to the ErrorMessage schema.
|
|
20
20
|
*/
|
|
21
21
|
RespStatus[RespStatus["RESOURCE_UNAVAILABLE"] = 3] = "RESOURCE_UNAVAILABLE";
|
|
22
22
|
/**
|
|
@@ -10,7 +10,7 @@ export declare const CHECK_DISCONNECTED_PEERS_INTERVAL_MS: number;
|
|
|
10
10
|
**/
|
|
11
11
|
export declare const REQUEST_TIMEOUT_MS: number;
|
|
12
12
|
/** Default backoff when a peer rate limits us. */
|
|
13
|
-
export declare const DEFAULT_RATE_LIMIT_BACKOFF_MS =
|
|
13
|
+
export declare const DEFAULT_RATE_LIMIT_BACKOFF_MS = 2000;
|
|
14
14
|
type RequestId = number;
|
|
15
15
|
/**
|
|
16
16
|
* Simple rate limiter that allows a maximum of 2 concurrent requests per protocol per peer.
|
|
@@ -28,8 +28,6 @@ export declare class SelfRateLimiter {
|
|
|
28
28
|
* This is the same design to `ReqRespRateLimiter`.
|
|
29
29
|
**/
|
|
30
30
|
private lastSeenRequestsByPeer;
|
|
31
|
-
/** Tracks the timestamp (ms) until which we should not send requests to a peer */
|
|
32
|
-
private rateLimitedUntilByPeer;
|
|
33
31
|
/** Interval to check lastSeenMessagesByPeer */
|
|
34
32
|
private cleanupInterval;
|
|
35
33
|
constructor(logger?: Logger | undefined);
|
|
@@ -37,8 +35,12 @@ export declare class SelfRateLimiter {
|
|
|
37
35
|
stop(): void;
|
|
38
36
|
/**
|
|
39
37
|
* called before we send a request to a peer.
|
|
38
|
+
* Returns one of three outcomes:
|
|
39
|
+
* - if the peer has rate-limited us and we're still in backoff, returns the timestamp until which we should back off,
|
|
40
|
+
* - if we've reached the concurrent request limit, returns false,
|
|
41
|
+
* - otherwise, returns true.
|
|
40
42
|
*/
|
|
41
|
-
allows(peerId: PeerIdStr, protocolId: ProtocolID, requestId: RequestId): boolean;
|
|
43
|
+
allows(peerId: PeerIdStr, protocolId: ProtocolID, requestId: RequestId): number | boolean;
|
|
42
44
|
/**
|
|
43
45
|
* called when a request to a peer is completed, regardless of success or failure.
|
|
44
46
|
* This should NOT be called when the request was not allowed
|
|
@@ -47,7 +49,7 @@ export declare class SelfRateLimiter {
|
|
|
47
49
|
/**
|
|
48
50
|
* Called when a peer responds with a rate-limit error, to enforce a backoff period before retrying.
|
|
49
51
|
*/
|
|
50
|
-
onRateLimited(peerId: PeerIdStr): void;
|
|
52
|
+
onRateLimited(peerId: PeerIdStr, protocolId: ProtocolID, rateLimitedUntilMs?: number): void;
|
|
51
53
|
getPeerCount(): number;
|
|
52
54
|
getRateLimitedPeerCount(): number;
|
|
53
55
|
private checkDisconnectedPeers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selfRateLimiter.d.ts","sourceRoot":"","sources":["../../src/rate_limiter/selfRateLimiter.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAS,MAAM,iBAAiB,CAAC;AAE/C,KAAK,SAAS,GAAG,MAAM,CAAC;AACxB,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,yGAAyG;AACzG,eAAO,MAAM,oCAAoC,QAAgB,CAAC;AAKlE;;;;IAII;AACJ,eAAO,MAAM,kBAAkB,QAAY,CAAC;AAE5C,kDAAkD;AAClD,eAAO,MAAM,6BAA6B,OAAQ,CAAC;AAEnD,KAAK,SAAS,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"selfRateLimiter.d.ts","sourceRoot":"","sources":["../../src/rate_limiter/selfRateLimiter.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,MAAM,EAAS,MAAM,iBAAiB,CAAC;AAE/C,KAAK,SAAS,GAAG,MAAM,CAAC;AACxB,KAAK,UAAU,GAAG,MAAM,CAAC;AAEzB,yGAAyG;AACzG,eAAO,MAAM,oCAAoC,QAAgB,CAAC;AAKlE;;;;IAII;AACJ,eAAO,MAAM,kBAAkB,QAAY,CAAC;AAE5C,kDAAkD;AAClD,eAAO,MAAM,6BAA6B,OAAQ,CAAC;AAEnD,KAAK,SAAS,GAAG,MAAM,CAAC;AASxB;;;;;;;GAOG;AACH,qBAAa,eAAe;IAUd,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IATpC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6D;IACjG;;;QAGI;IACJ,OAAO,CAAC,sBAAsB,CAAsB;IACpD,+CAA+C;IAC/C,OAAO,CAAC,eAAe,CAAyC;IAEhE,YAA6B,MAAM,CAAC,oBAAQ,EAM3C;IAED,KAAK,IAAI,IAAI,CAEZ;IAED,IAAI,IAAI,IAAI,CAKX;IAED;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,CAuCxF;IAED;;;OAGG;IACH,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAItF;IAED;;OAEG;IACH,aAAa,CACX,MAAM,EAAE,SAAS,EACjB,UAAU,EAAE,UAAU,EACtB,kBAAkB,SAA6C,GAC9D,IAAI,CAKN;IAED,YAAY,IAAI,MAAM,CAErB;IAED,uBAAuB,IAAI,MAAM,CAWhC;IAED,OAAO,CAAC,sBAAsB;CAgB/B"}
|
|
@@ -11,7 +11,7 @@ const DISCONNECTED_TIMEOUT_MS = 60 * 1000;
|
|
|
11
11
|
**/
|
|
12
12
|
export const REQUEST_TIMEOUT_MS = 30 * 1000;
|
|
13
13
|
/** Default backoff when a peer rate limits us. */
|
|
14
|
-
export const DEFAULT_RATE_LIMIT_BACKOFF_MS =
|
|
14
|
+
export const DEFAULT_RATE_LIMIT_BACKOFF_MS = 2_000;
|
|
15
15
|
/**
|
|
16
16
|
* Simple rate limiter that allows a maximum of 2 concurrent requests per protocol per peer.
|
|
17
17
|
* Also tracks when a peer has rate-limited us and enforces a backoff period before allowing new requests.
|
|
@@ -28,15 +28,12 @@ export class SelfRateLimiter {
|
|
|
28
28
|
* This is the same design to `ReqRespRateLimiter`.
|
|
29
29
|
**/
|
|
30
30
|
lastSeenRequestsByPeer;
|
|
31
|
-
/** Tracks the timestamp (ms) until which we should not send requests to a peer */
|
|
32
|
-
rateLimitedUntilByPeer;
|
|
33
31
|
/** Interval to check lastSeenMessagesByPeer */
|
|
34
32
|
cleanupInterval = undefined;
|
|
35
33
|
constructor(logger) {
|
|
36
34
|
this.logger = logger;
|
|
37
|
-
this.rateLimitersPerPeer = new MapDef(() => new MapDef(() => new Map()));
|
|
35
|
+
this.rateLimitersPerPeer = new MapDef(() => new MapDef(() => ({ activeRequests: new Map(), rateLimitedUntilMs: undefined })));
|
|
38
36
|
this.lastSeenRequestsByPeer = new Map();
|
|
39
|
-
this.rateLimitedUntilByPeer = new Map();
|
|
40
37
|
}
|
|
41
38
|
start() {
|
|
42
39
|
this.cleanupInterval = setInterval(this.checkDisconnectedPeers.bind(this), CHECK_DISCONNECTED_PEERS_INTERVAL_MS);
|
|
@@ -49,28 +46,30 @@ export class SelfRateLimiter {
|
|
|
49
46
|
}
|
|
50
47
|
/**
|
|
51
48
|
* called before we send a request to a peer.
|
|
49
|
+
* Returns one of three outcomes:
|
|
50
|
+
* - if the peer has rate-limited us and we're still in backoff, returns the timestamp until which we should back off,
|
|
51
|
+
* - if we've reached the concurrent request limit, returns false,
|
|
52
|
+
* - otherwise, returns true.
|
|
52
53
|
*/
|
|
53
54
|
allows(peerId, protocolId, requestId) {
|
|
54
55
|
const now = Date.now();
|
|
56
|
+
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
57
|
+
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
58
|
+
this.lastSeenRequestsByPeer.set(peerId, now);
|
|
55
59
|
// Check if peer has rate-limited us and we're still in backoff
|
|
56
|
-
const rateLimitedUntil =
|
|
60
|
+
const rateLimitedUntil = trackedRequests.rateLimitedUntilMs;
|
|
57
61
|
if (rateLimitedUntil !== undefined) {
|
|
58
62
|
if (now < rateLimitedUntil) {
|
|
59
|
-
|
|
60
|
-
this.lastSeenRequestsByPeer.set(peerId, now);
|
|
61
|
-
return false;
|
|
63
|
+
return rateLimitedUntil;
|
|
62
64
|
}
|
|
63
65
|
// Backoff expired, clean up
|
|
64
|
-
|
|
66
|
+
trackedRequests.rateLimitedUntilMs = undefined;
|
|
65
67
|
}
|
|
66
|
-
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
67
|
-
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
68
|
-
this.lastSeenRequestsByPeer.set(peerId, now);
|
|
69
68
|
let inProgressRequests = 0;
|
|
70
|
-
for (const [trackedRequestId, trackedRequestTimeMs] of trackedRequests.entries()) {
|
|
69
|
+
for (const [trackedRequestId, trackedRequestTimeMs] of trackedRequests.activeRequests.entries()) {
|
|
71
70
|
if (trackedRequestTimeMs + REQUEST_TIMEOUT_MS <= now) {
|
|
72
71
|
// request timed out, remove it
|
|
73
|
-
trackedRequests.delete(trackedRequestId);
|
|
72
|
+
trackedRequests.activeRequests.delete(trackedRequestId);
|
|
74
73
|
this.logger?.debug("SelfRateLimiter: request timed out, removing it", {
|
|
75
74
|
requestId: trackedRequestId,
|
|
76
75
|
requestTime: trackedRequestTimeMs,
|
|
@@ -85,7 +84,7 @@ export class SelfRateLimiter {
|
|
|
85
84
|
if (inProgressRequests >= MAX_CONCURRENT_REQUESTS) {
|
|
86
85
|
return false;
|
|
87
86
|
}
|
|
88
|
-
trackedRequests.set(requestId, now);
|
|
87
|
+
trackedRequests.activeRequests.set(requestId, now);
|
|
89
88
|
return true;
|
|
90
89
|
}
|
|
91
90
|
/**
|
|
@@ -95,21 +94,31 @@ export class SelfRateLimiter {
|
|
|
95
94
|
requestCompleted(peerId, protocolId, requestId) {
|
|
96
95
|
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
97
96
|
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
98
|
-
trackedRequests.delete(requestId);
|
|
97
|
+
trackedRequests.activeRequests.delete(requestId);
|
|
99
98
|
}
|
|
100
99
|
/**
|
|
101
100
|
* Called when a peer responds with a rate-limit error, to enforce a backoff period before retrying.
|
|
102
101
|
*/
|
|
103
|
-
onRateLimited(peerId) {
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
onRateLimited(peerId, protocolId, rateLimitedUntilMs = Date.now() + DEFAULT_RATE_LIMIT_BACKOFF_MS) {
|
|
103
|
+
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
104
|
+
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
105
|
+
trackedRequests.rateLimitedUntilMs = rateLimitedUntilMs;
|
|
106
|
+
this.logger?.debug("SelfRateLimiter: peer rate limited us, backing off", { peerId, protocolId });
|
|
107
107
|
}
|
|
108
108
|
getPeerCount() {
|
|
109
109
|
return this.rateLimitersPerPeer.size;
|
|
110
110
|
}
|
|
111
111
|
getRateLimitedPeerCount() {
|
|
112
|
-
|
|
112
|
+
let count = 0;
|
|
113
|
+
for (const peerRateLimiter of this.rateLimitersPerPeer.values()) {
|
|
114
|
+
for (const trackedRequests of peerRateLimiter.values()) {
|
|
115
|
+
if (trackedRequests.rateLimitedUntilMs !== undefined) {
|
|
116
|
+
count++;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return count;
|
|
113
122
|
}
|
|
114
123
|
checkDisconnectedPeers() {
|
|
115
124
|
const now = Date.now();
|
|
@@ -117,13 +126,13 @@ export class SelfRateLimiter {
|
|
|
117
126
|
if (now - lastSeenTime >= DISCONNECTED_TIMEOUT_MS) {
|
|
118
127
|
this.rateLimitersPerPeer.delete(peerIdStr);
|
|
119
128
|
this.lastSeenRequestsByPeer.delete(peerIdStr);
|
|
120
|
-
this.rateLimitedUntilByPeer.delete(peerIdStr);
|
|
121
129
|
}
|
|
122
130
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
for (const peerRateLimiter of this.rateLimitersPerPeer.values()) {
|
|
132
|
+
for (const trackedRequests of peerRateLimiter.values()) {
|
|
133
|
+
if (trackedRequests.rateLimitedUntilMs !== undefined && now >= trackedRequests.rateLimitedUntilMs) {
|
|
134
|
+
trackedRequests.rateLimitedUntilMs = undefined;
|
|
135
|
+
}
|
|
127
136
|
}
|
|
128
137
|
}
|
|
129
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selfRateLimiter.js","sourceRoot":"","sources":["../../src/rate_limiter/selfRateLimiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,uBAAuB,EAAC,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAS,MAAM,EAAC,MAAM,iBAAiB,CAAC;AAK/C,yGAAyG;AACzG,MAAM,CAAC,MAAM,oCAAoC,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAElE,sHAAsH;AACtH,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C;;;;IAII;AACJ,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE5C,kDAAkD;AAClD,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"selfRateLimiter.js","sourceRoot":"","sources":["../../src/rate_limiter/selfRateLimiter.ts"],"names":[],"mappings":"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"}
|
package/lib/request/errors.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export declare enum RequestErrorCode {
|
|
|
32
32
|
/** For malformed SSZ (metadata) responses */
|
|
33
33
|
SSZ_OVER_MAX_SIZE = "SSZ_SNAPPY_ERROR_OVER_SSZ_MAX_SIZE"
|
|
34
34
|
}
|
|
35
|
-
type RequestErrorType = {
|
|
35
|
+
export type RequestErrorType = {
|
|
36
36
|
code: RequestErrorCode.INVALID_REQUEST;
|
|
37
37
|
errorMessage: string;
|
|
38
38
|
} | {
|
|
@@ -66,8 +66,10 @@ type RequestErrorType = {
|
|
|
66
66
|
code: RequestErrorCode.REQUEST_RATE_LIMITED;
|
|
67
67
|
} | {
|
|
68
68
|
code: RequestErrorCode.REQUEST_SELF_RATE_LIMITED;
|
|
69
|
+
rateLimitedUntilMs?: number;
|
|
69
70
|
} | {
|
|
70
71
|
code: RequestErrorCode.RESP_RATE_LIMITED;
|
|
72
|
+
rateLimitedUntilMs: number;
|
|
71
73
|
} | {
|
|
72
74
|
code: RequestErrorCode.SSZ_OVER_MAX_SIZE;
|
|
73
75
|
};
|
|
@@ -80,5 +82,4 @@ export declare class RequestError extends LodestarError<RequestErrorType> {
|
|
|
80
82
|
* Parse response status errors into detailed request errors for each status code for easier debugging
|
|
81
83
|
*/
|
|
82
84
|
export declare function responseStatusErrorToRequestError(e: ResponseError): RequestErrorType;
|
|
83
|
-
export {};
|
|
84
85
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/request/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAa,sBAAsB,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/request/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAa,sBAAsB,EAAC,MAAM,iBAAiB,CAAC;AAEnE,OAAO,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAC;AAEnD,oBAAY,gBAAgB;IAE1B,4DAA4D;IAC5D,eAAe,kCAAkC;IACjD,oBAAoB,uCAAuC;IAC3D,yDAAyD;IACzD,YAAY,+BAA+B;IAC3C,iEAAiE;IACjE,oBAAoB,+BAA+B;IACnD,wEAAwE;IACxE,oBAAoB,uCAAuC;IAC3D,4DAA4D;IAC5D,YAAY,+BAA+B;IAC3C,uCAAuC;IACvC,UAAU,6BAA6B;IACvC,iEAAiE;IACjE,eAAe,kCAAkC;IACjD,8CAA8C;IAC9C,aAAa,gCAAgC;IAC7C,iDAAiD;IACjD,cAAc,iCAAiC;IAC/C,yCAAyC;IACzC,YAAY,+BAA+B;IAC3C,2BAA2B;IAC3B,oBAAoB,+BAA+B;IACnD,gCAAgC;IAChC,yBAAyB,oCAAoC;IAC7D,4BAA4B;IAC5B,iBAAiB,gCAAgC;IACjD,6CAA6C;IAC7C,iBAAiB,uCAAuC;CACzD;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAC,IAAI,EAAE,gBAAgB,CAAC,eAAe,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,GAC9D;IAAC,IAAI,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,GACnE;IAAC,IAAI,EAAE,gBAAgB,CAAC,YAAY,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,GAC3D;IAAC,IAAI,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,GACnE;IAAC,IAAI,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAC,GACnG;IAAC,IAAI,EAAE,gBAAgB,CAAC,YAAY,CAAA;CAAC,GACrC;IAAC,IAAI,EAAE,gBAAgB,CAAC,UAAU,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAC,GACjD;IAAC,IAAI,EAAE,gBAAgB,CAAC,eAAe,CAAA;CAAC,GACxC;IAAC,IAAI,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAC,GACpD;IAAC,IAAI,EAAE,gBAAgB,CAAC,cAAc,CAAA;CAAC,GACvC;IAAC,IAAI,EAAE,gBAAgB,CAAC,YAAY,CAAA;CAAC,GACrC;IAAC,IAAI,EAAE,gBAAgB,CAAC,oBAAoB,CAAA;CAAC,GAC7C;IAAC,IAAI,EAAE,gBAAgB,CAAC,yBAAyB,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAC,GAC/E;IAAC,IAAI,EAAE,gBAAgB,CAAC,iBAAiB,CAAC;IAAC,kBAAkB,EAAE,MAAM,CAAA;CAAC,GACtE;IAAC,IAAI,EAAE,gBAAgB,CAAC,iBAAiB,CAAA;CAAC,CAAC;AAE/C,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAEvD,qBAAa,YAAa,SAAQ,aAAa,CAAC,gBAAgB,CAAC;IAC/D,YAAY,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAEnE;IAED,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,mBAAmB,GAAG,YAAY,CAMxD;CACF;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,CAAC,EAAE,aAAa,GAAG,gBAAgB,CAkCpF"}
|
package/lib/request/errors.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LodestarError } from "@lodestar/utils";
|
|
2
2
|
import { RespStatus } from "../interface.js";
|
|
3
|
+
import { DEFAULT_RATE_LIMIT_BACKOFF_MS } from "../rate_limiter/selfRateLimiter.js";
|
|
3
4
|
export { RequestErrorCode };
|
|
4
5
|
var RequestErrorCode;
|
|
5
6
|
(function (RequestErrorCode) {
|
|
@@ -61,7 +62,7 @@ export function responseStatusErrorToRequestError(e) {
|
|
|
61
62
|
// See https://github.com/ChainSafe/lodestar/issues/8065#issuecomment-3157266196
|
|
62
63
|
const errorMessageLowercase = errorMessage.toLowerCase();
|
|
63
64
|
if (errorMessageLowercase.includes("rate limit")) {
|
|
64
|
-
return { code: RequestErrorCode.RESP_RATE_LIMITED };
|
|
65
|
+
return { code: RequestErrorCode.RESP_RATE_LIMITED, rateLimitedUntilMs: Date.now() + DEFAULT_RATE_LIMIT_BACKOFF_MS };
|
|
65
66
|
}
|
|
66
67
|
// Grandine's eth2_libp2p fork uses the old Lighthouse GCRA inbound rate limiter which sends
|
|
67
68
|
// "Wait <Duration>" with an explicit backoff (e.g. "Wait 2.816488536s") using Rust's
|
|
@@ -69,7 +70,7 @@ export function responseStatusErrorToRequestError(e) {
|
|
|
69
70
|
// is intentionally not parsed.
|
|
70
71
|
// See https://github.com/ChainSafe/lodestar/issues/8110
|
|
71
72
|
if (errorMessageLowercase.startsWith("wait ")) {
|
|
72
|
-
return { code: RequestErrorCode.RESP_RATE_LIMITED };
|
|
73
|
+
return { code: RequestErrorCode.RESP_RATE_LIMITED, rateLimitedUntilMs: Date.now() + DEFAULT_RATE_LIMIT_BACKOFF_MS };
|
|
73
74
|
}
|
|
74
75
|
switch (status) {
|
|
75
76
|
case RespStatus.INVALID_REQUEST:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/request/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAsB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAC,UAAU,EAAyB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/request/errors.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"bugs": {
|
|
12
12
|
"url": "https://github.com/ChainSafe/lodestar/issues"
|
|
13
13
|
},
|
|
14
|
-
"version": "1.43.0-dev.
|
|
14
|
+
"version": "1.43.0-dev.b0e1143d06",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"exports": {
|
|
17
17
|
".": {
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"@chainsafe/fast-crc32c": "^4.2.0",
|
|
48
48
|
"@libp2p/interface": "^3.1.0",
|
|
49
49
|
"@libp2p/utils": "^7.0.13",
|
|
50
|
-
"@lodestar/config": "^1.43.0-dev.
|
|
51
|
-
"@lodestar/params": "^1.43.0-dev.
|
|
52
|
-
"@lodestar/utils": "^1.43.0-dev.
|
|
50
|
+
"@lodestar/config": "^1.43.0-dev.b0e1143d06",
|
|
51
|
+
"@lodestar/params": "^1.43.0-dev.b0e1143d06",
|
|
52
|
+
"@lodestar/utils": "^1.43.0-dev.b0e1143d06",
|
|
53
53
|
"snappy": "^7.2.2",
|
|
54
54
|
"snappyjs": "^0.7.0",
|
|
55
55
|
"uint8-varint": "^2.0.2",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"@libp2p/crypto": "^5.1.13",
|
|
61
61
|
"@libp2p/logger": "^6.2.2",
|
|
62
62
|
"@libp2p/peer-id": "^6.0.4",
|
|
63
|
-
"@lodestar/logger": "^1.43.0-dev.
|
|
64
|
-
"@lodestar/types": "^1.43.0-dev.
|
|
63
|
+
"@lodestar/logger": "^1.43.0-dev.b0e1143d06",
|
|
64
|
+
"@lodestar/types": "^1.43.0-dev.b0e1143d06",
|
|
65
65
|
"libp2p": "3.1.6"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"reqresp",
|
|
76
76
|
"blockchain"
|
|
77
77
|
],
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "80391da9ce6415471bc83182fafb39157c1be763"
|
|
79
79
|
}
|
package/src/ReqResp.ts
CHANGED
|
@@ -177,10 +177,12 @@ export class ReqResp {
|
|
|
177
177
|
throw Error(`Request to send to protocol ${protocolID} but it has not been declared`);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
const allows = this.selfRateLimiter.allows(peerIdStr, protocolID, requestId);
|
|
181
|
+
if (allows !== true) {
|
|
181
182
|
// we technically don't send request in this case but would be nice just to track this in the same `outgoingErrorReasons` metric
|
|
182
183
|
this.metrics?.outgoingErrorReasons.inc({reason: RequestErrorCode.REQUEST_SELF_RATE_LIMITED});
|
|
183
|
-
|
|
184
|
+
const rateLimitedUntilMs = typeof allows === "number" ? allows : undefined;
|
|
185
|
+
throw new RequestError({code: RequestErrorCode.REQUEST_SELF_RATE_LIMITED, rateLimitedUntilMs});
|
|
184
186
|
// don't call this.onOutgoingRequestError() to penalize peer
|
|
185
187
|
}
|
|
186
188
|
|
|
@@ -210,7 +212,9 @@ export class ReqResp {
|
|
|
210
212
|
this.metrics?.dialErrors.inc();
|
|
211
213
|
}
|
|
212
214
|
if (e.type.code === RequestErrorCode.RESP_RATE_LIMITED) {
|
|
213
|
-
|
|
215
|
+
for (const protocolID of protocolIDs) {
|
|
216
|
+
this.selfRateLimiter.onRateLimited(peerIdStr, protocolID, e.type.rateLimitedUntilMs);
|
|
217
|
+
}
|
|
214
218
|
}
|
|
215
219
|
this.metrics?.outgoingErrorReasons.inc({reason: e.type.code});
|
|
216
220
|
|
package/src/interface.ts
CHANGED
|
@@ -14,7 +14,7 @@ export enum RespStatus {
|
|
|
14
14
|
*/
|
|
15
15
|
SERVER_ERROR = 2,
|
|
16
16
|
/**
|
|
17
|
-
* The responder does not have requested resource.
|
|
17
|
+
* The responder does not have requested resource. The response payload adheres to the ErrorMessage schema.
|
|
18
18
|
*/
|
|
19
19
|
RESOURCE_UNAVAILABLE = 3,
|
|
20
20
|
/**
|
|
@@ -18,11 +18,17 @@ const DISCONNECTED_TIMEOUT_MS = 60 * 1000;
|
|
|
18
18
|
export const REQUEST_TIMEOUT_MS = 30 * 1000;
|
|
19
19
|
|
|
20
20
|
/** Default backoff when a peer rate limits us. */
|
|
21
|
-
export const DEFAULT_RATE_LIMIT_BACKOFF_MS =
|
|
21
|
+
export const DEFAULT_RATE_LIMIT_BACKOFF_MS = 2_000;
|
|
22
22
|
|
|
23
23
|
type RequestId = number;
|
|
24
24
|
type RequestIdMs = number;
|
|
25
25
|
|
|
26
|
+
type ProtocolRateLimiter = {
|
|
27
|
+
activeRequests: Map<RequestId, RequestIdMs>;
|
|
28
|
+
/** Tracks the timestamp (ms) until which we should not send requests to a peer */
|
|
29
|
+
rateLimitedUntilMs?: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
26
32
|
/**
|
|
27
33
|
* Simple rate limiter that allows a maximum of 2 concurrent requests per protocol per peer.
|
|
28
34
|
* Also tracks when a peer has rate-limited us and enforces a backoff period before allowing new requests.
|
|
@@ -32,23 +38,21 @@ type RequestIdMs = number;
|
|
|
32
38
|
* peers. This class acts as the authoritative safety net at the protocol level.
|
|
33
39
|
*/
|
|
34
40
|
export class SelfRateLimiter {
|
|
35
|
-
private readonly rateLimitersPerPeer: MapDef<PeerIdStr, MapDef<ProtocolID,
|
|
41
|
+
private readonly rateLimitersPerPeer: MapDef<PeerIdStr, MapDef<ProtocolID, ProtocolRateLimiter>>;
|
|
36
42
|
/**
|
|
37
43
|
* It's not convenient to handle a peer disconnected event so we track the last seen requests by peer.
|
|
38
44
|
* This is the same design to `ReqRespRateLimiter`.
|
|
39
45
|
**/
|
|
40
46
|
private lastSeenRequestsByPeer: Map<string, number>;
|
|
41
|
-
/** Tracks the timestamp (ms) until which we should not send requests to a peer */
|
|
42
|
-
private rateLimitedUntilByPeer: Map<PeerIdStr, number>;
|
|
43
47
|
/** Interval to check lastSeenMessagesByPeer */
|
|
44
48
|
private cleanupInterval: NodeJS.Timeout | undefined = undefined;
|
|
45
49
|
|
|
46
50
|
constructor(private readonly logger?: Logger) {
|
|
47
|
-
this.rateLimitersPerPeer = new MapDef<PeerIdStr, MapDef<ProtocolID,
|
|
48
|
-
() =>
|
|
51
|
+
this.rateLimitersPerPeer = new MapDef<PeerIdStr, MapDef<ProtocolID, ProtocolRateLimiter>>(
|
|
52
|
+
() =>
|
|
53
|
+
new MapDef<ProtocolID, ProtocolRateLimiter>(() => ({activeRequests: new Map(), rateLimitedUntilMs: undefined}))
|
|
49
54
|
);
|
|
50
55
|
this.lastSeenRequestsByPeer = new Map();
|
|
51
|
-
this.rateLimitedUntilByPeer = new Map();
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
start(): void {
|
|
@@ -64,31 +68,33 @@ export class SelfRateLimiter {
|
|
|
64
68
|
|
|
65
69
|
/**
|
|
66
70
|
* called before we send a request to a peer.
|
|
71
|
+
* Returns one of three outcomes:
|
|
72
|
+
* - if the peer has rate-limited us and we're still in backoff, returns the timestamp until which we should back off,
|
|
73
|
+
* - if we've reached the concurrent request limit, returns false,
|
|
74
|
+
* - otherwise, returns true.
|
|
67
75
|
*/
|
|
68
|
-
allows(peerId: PeerIdStr, protocolId: ProtocolID, requestId: RequestId): boolean {
|
|
76
|
+
allows(peerId: PeerIdStr, protocolId: ProtocolID, requestId: RequestId): number | boolean {
|
|
69
77
|
const now = Date.now();
|
|
70
78
|
|
|
79
|
+
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
80
|
+
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
81
|
+
this.lastSeenRequestsByPeer.set(peerId, now);
|
|
82
|
+
|
|
71
83
|
// Check if peer has rate-limited us and we're still in backoff
|
|
72
|
-
const rateLimitedUntil =
|
|
84
|
+
const rateLimitedUntil = trackedRequests.rateLimitedUntilMs;
|
|
73
85
|
if (rateLimitedUntil !== undefined) {
|
|
74
86
|
if (now < rateLimitedUntil) {
|
|
75
|
-
|
|
76
|
-
this.lastSeenRequestsByPeer.set(peerId, now);
|
|
77
|
-
return false;
|
|
87
|
+
return rateLimitedUntil;
|
|
78
88
|
}
|
|
79
89
|
// Backoff expired, clean up
|
|
80
|
-
|
|
90
|
+
trackedRequests.rateLimitedUntilMs = undefined;
|
|
81
91
|
}
|
|
82
92
|
|
|
83
|
-
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
84
|
-
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
85
|
-
this.lastSeenRequestsByPeer.set(peerId, now);
|
|
86
|
-
|
|
87
93
|
let inProgressRequests = 0;
|
|
88
|
-
for (const [trackedRequestId, trackedRequestTimeMs] of trackedRequests.entries()) {
|
|
94
|
+
for (const [trackedRequestId, trackedRequestTimeMs] of trackedRequests.activeRequests.entries()) {
|
|
89
95
|
if (trackedRequestTimeMs + REQUEST_TIMEOUT_MS <= now) {
|
|
90
96
|
// request timed out, remove it
|
|
91
|
-
trackedRequests.delete(trackedRequestId);
|
|
97
|
+
trackedRequests.activeRequests.delete(trackedRequestId);
|
|
92
98
|
this.logger?.debug("SelfRateLimiter: request timed out, removing it", {
|
|
93
99
|
requestId: trackedRequestId,
|
|
94
100
|
requestTime: trackedRequestTimeMs,
|
|
@@ -104,7 +110,7 @@ export class SelfRateLimiter {
|
|
|
104
110
|
return false;
|
|
105
111
|
}
|
|
106
112
|
|
|
107
|
-
trackedRequests.set(requestId, now);
|
|
113
|
+
trackedRequests.activeRequests.set(requestId, now);
|
|
108
114
|
return true;
|
|
109
115
|
}
|
|
110
116
|
|
|
@@ -115,16 +121,21 @@ export class SelfRateLimiter {
|
|
|
115
121
|
requestCompleted(peerId: PeerIdStr, protocolId: ProtocolID, requestId: RequestId): void {
|
|
116
122
|
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
117
123
|
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
118
|
-
trackedRequests.delete(requestId);
|
|
124
|
+
trackedRequests.activeRequests.delete(requestId);
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
/**
|
|
122
128
|
* Called when a peer responds with a rate-limit error, to enforce a backoff period before retrying.
|
|
123
129
|
*/
|
|
124
|
-
onRateLimited(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
130
|
+
onRateLimited(
|
|
131
|
+
peerId: PeerIdStr,
|
|
132
|
+
protocolId: ProtocolID,
|
|
133
|
+
rateLimitedUntilMs = Date.now() + DEFAULT_RATE_LIMIT_BACKOFF_MS
|
|
134
|
+
): void {
|
|
135
|
+
const peerRateLimiter = this.rateLimitersPerPeer.getOrDefault(peerId);
|
|
136
|
+
const trackedRequests = peerRateLimiter.getOrDefault(protocolId);
|
|
137
|
+
trackedRequests.rateLimitedUntilMs = rateLimitedUntilMs;
|
|
138
|
+
this.logger?.debug("SelfRateLimiter: peer rate limited us, backing off", {peerId, protocolId});
|
|
128
139
|
}
|
|
129
140
|
|
|
130
141
|
getPeerCount(): number {
|
|
@@ -132,7 +143,16 @@ export class SelfRateLimiter {
|
|
|
132
143
|
}
|
|
133
144
|
|
|
134
145
|
getRateLimitedPeerCount(): number {
|
|
135
|
-
|
|
146
|
+
let count = 0;
|
|
147
|
+
for (const peerRateLimiter of this.rateLimitersPerPeer.values()) {
|
|
148
|
+
for (const trackedRequests of peerRateLimiter.values()) {
|
|
149
|
+
if (trackedRequests.rateLimitedUntilMs !== undefined) {
|
|
150
|
+
count++;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return count;
|
|
136
156
|
}
|
|
137
157
|
|
|
138
158
|
private checkDisconnectedPeers(): void {
|
|
@@ -141,13 +161,13 @@ export class SelfRateLimiter {
|
|
|
141
161
|
if (now - lastSeenTime >= DISCONNECTED_TIMEOUT_MS) {
|
|
142
162
|
this.rateLimitersPerPeer.delete(peerIdStr);
|
|
143
163
|
this.lastSeenRequestsByPeer.delete(peerIdStr);
|
|
144
|
-
this.rateLimitedUntilByPeer.delete(peerIdStr);
|
|
145
164
|
}
|
|
146
165
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
166
|
+
for (const peerRateLimiter of this.rateLimitersPerPeer.values()) {
|
|
167
|
+
for (const trackedRequests of peerRateLimiter.values()) {
|
|
168
|
+
if (trackedRequests.rateLimitedUntilMs !== undefined && now >= trackedRequests.rateLimitedUntilMs) {
|
|
169
|
+
trackedRequests.rateLimitedUntilMs = undefined;
|
|
170
|
+
}
|
|
151
171
|
}
|
|
152
172
|
}
|
|
153
173
|
}
|
package/src/request/errors.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {LodestarError, LodestarErrorObject} from "@lodestar/utils";
|
|
2
2
|
import {RespStatus, RpcResponseStatusError} from "../interface.js";
|
|
3
|
+
import {DEFAULT_RATE_LIMIT_BACKOFF_MS} from "../rate_limiter/selfRateLimiter.js";
|
|
3
4
|
import {ResponseError} from "../response/index.js";
|
|
4
5
|
|
|
5
6
|
export enum RequestErrorCode {
|
|
@@ -35,7 +36,7 @@ export enum RequestErrorCode {
|
|
|
35
36
|
SSZ_OVER_MAX_SIZE = "SSZ_SNAPPY_ERROR_OVER_SSZ_MAX_SIZE",
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
type RequestErrorType =
|
|
39
|
+
export type RequestErrorType =
|
|
39
40
|
| {code: RequestErrorCode.INVALID_REQUEST; errorMessage: string}
|
|
40
41
|
| {code: RequestErrorCode.INVALID_RESPONSE_SSZ; errorMessage: string}
|
|
41
42
|
| {code: RequestErrorCode.SERVER_ERROR; errorMessage: string}
|
|
@@ -48,8 +49,8 @@ type RequestErrorType =
|
|
|
48
49
|
| {code: RequestErrorCode.EMPTY_RESPONSE}
|
|
49
50
|
| {code: RequestErrorCode.RESP_TIMEOUT}
|
|
50
51
|
| {code: RequestErrorCode.REQUEST_RATE_LIMITED}
|
|
51
|
-
| {code: RequestErrorCode.REQUEST_SELF_RATE_LIMITED}
|
|
52
|
-
| {code: RequestErrorCode.RESP_RATE_LIMITED}
|
|
52
|
+
| {code: RequestErrorCode.REQUEST_SELF_RATE_LIMITED; rateLimitedUntilMs?: number}
|
|
53
|
+
| {code: RequestErrorCode.RESP_RATE_LIMITED; rateLimitedUntilMs: number}
|
|
53
54
|
| {code: RequestErrorCode.SSZ_OVER_MAX_SIZE};
|
|
54
55
|
|
|
55
56
|
export const REQUEST_ERROR_CLASS_NAME = "RequestError";
|
|
@@ -83,7 +84,7 @@ export function responseStatusErrorToRequestError(e: ResponseError): RequestErro
|
|
|
83
84
|
// See https://github.com/ChainSafe/lodestar/issues/8065#issuecomment-3157266196
|
|
84
85
|
const errorMessageLowercase = errorMessage.toLowerCase();
|
|
85
86
|
if (errorMessageLowercase.includes("rate limit")) {
|
|
86
|
-
return {code: RequestErrorCode.RESP_RATE_LIMITED};
|
|
87
|
+
return {code: RequestErrorCode.RESP_RATE_LIMITED, rateLimitedUntilMs: Date.now() + DEFAULT_RATE_LIMIT_BACKOFF_MS};
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
// Grandine's eth2_libp2p fork uses the old Lighthouse GCRA inbound rate limiter which sends
|
|
@@ -92,7 +93,7 @@ export function responseStatusErrorToRequestError(e: ResponseError): RequestErro
|
|
|
92
93
|
// is intentionally not parsed.
|
|
93
94
|
// See https://github.com/ChainSafe/lodestar/issues/8110
|
|
94
95
|
if (errorMessageLowercase.startsWith("wait ")) {
|
|
95
|
-
return {code: RequestErrorCode.RESP_RATE_LIMITED};
|
|
96
|
+
return {code: RequestErrorCode.RESP_RATE_LIMITED, rateLimitedUntilMs: Date.now() + DEFAULT_RATE_LIMIT_BACKOFF_MS};
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
switch (status) {
|