@aztec/p2p 0.55.1 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/attestation_pool/memory_attestation_pool.js +8 -7
- package/dest/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/attestation_pool/mocks.js +6 -5
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +1 -3
- package/dest/mocks/index.d.ts +13 -4
- package/dest/mocks/index.d.ts.map +1 -1
- package/dest/mocks/index.js +26 -9
- package/dest/service/libp2p_service.d.ts +16 -1
- package/dest/service/libp2p_service.d.ts.map +1 -1
- package/dest/service/libp2p_service.js +53 -23
- package/dest/service/reqresp/interface.d.ts +7 -0
- package/dest/service/reqresp/interface.d.ts.map +1 -1
- package/dest/service/reqresp/interface.js +7 -1
- package/dest/service/reqresp/rate_limiter/rate_limiter.d.ts +13 -3
- package/dest/service/reqresp/rate_limiter/rate_limiter.d.ts.map +1 -1
- package/dest/service/reqresp/rate_limiter/rate_limiter.js +29 -7
- package/dest/service/reqresp/reqresp.d.ts +56 -5
- package/dest/service/reqresp/reqresp.d.ts.map +1 -1
- package/dest/service/reqresp/reqresp.js +73 -9
- package/dest/tx_validator/aggregate_tx_validator.d.ts +1 -0
- package/dest/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/tx_validator/aggregate_tx_validator.js +10 -1
- package/dest/tx_validator/data_validator.d.ts +1 -0
- package/dest/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/tx_validator/data_validator.js +4 -1
- package/dest/tx_validator/double_spend_validator.d.ts +1 -0
- package/dest/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/tx_validator/double_spend_validator.js +4 -1
- package/dest/tx_validator/metadata_validator.d.ts +1 -0
- package/dest/tx_validator/metadata_validator.d.ts.map +1 -1
- package/dest/tx_validator/metadata_validator.js +4 -1
- package/package.json +6 -6
- package/src/attestation_pool/memory_attestation_pool.ts +7 -6
- package/src/attestation_pool/mocks.ts +6 -4
- package/src/client/p2p_client.ts +0 -2
- package/src/mocks/index.ts +35 -7
- package/src/service/libp2p_service.ts +57 -24
- package/src/service/reqresp/interface.ts +20 -0
- package/src/service/reqresp/rate_limiter/rate_limiter.ts +30 -7
- package/src/service/reqresp/reqresp.ts +82 -8
- package/src/tx_validator/aggregate_tx_validator.ts +10 -0
- package/src/tx_validator/data_validator.ts +4 -0
- package/src/tx_validator/double_spend_validator.ts +4 -0
- package/src/tx_validator/metadata_validator.ts +4 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/interface.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/interface.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD,eAAO,MAAM,aAAa,0BAA0B,CAAC;AACrD,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,eAAe,wBAAwB,CAAC;AAGrD,MAAM,MAAM,kBAAkB,GAAG,OAAO,aAAa,GAAG,OAAO,eAAe,GAAG,OAAO,eAAe,CAAC;AAExG;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;AAE9F;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,SAAS,EAAE,cAAc,CAAC;IAC1B;;OAEG;IACH,WAAW,EAAE,cAAc,CAAC;CAC7B;AAED,eAAO,MAAM,aAAa,wBAA8B,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG,MAAM,CAAC,kBAAkB,EAAE,yBAAyB,CAAC,CAAC;AAE/F,KAAK,iBAAiB,CAAC,iBAAiB,EAAE,QAAQ,IAAI,CACpD,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,4BAA4B,GAAG;KACxC,CAAC,IAAI,kBAAkB,GAAG,iBAAiB,CAAC,GAAG,EAAE,GAAG,CAAC;CACvD,CAAC;AAEF,eAAO,MAAM,+BAA+B,EAAE,4BAI7C,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG;KAC1B,CAAC,IAAI,kBAAkB,GAAG,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC;CACzD,CAAC;AAUF;;GAEG;AACH,eAAO,MAAM,6BAA6B,EAAE,0BAI3C,CAAC;AAEF;;;GAGG;AACH,UAAU,mBAAmB,CAAC,GAAG,EAAE,GAAG;IACpC,OAAO,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IACrC;;OAEG;IACH,QAAQ,EAAE;QACR,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC;QAC1B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC;KACjC,CAAC;CACH;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IACT,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM;IAEjC,QAAQ;IAIR,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM;CAGjC;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAa5B,CAAC"}
|
|
@@ -5,6 +5,12 @@ import { Tx, TxHash } from '@aztec/circuit-types';
|
|
|
5
5
|
export const PING_PROTOCOL = '/aztec/req/ping/0.1.0';
|
|
6
6
|
export const STATUS_PROTOCOL = '/aztec/req/status/0.1.0';
|
|
7
7
|
export const TX_REQ_PROTOCOL = '/aztec/req/tx/0.1.0';
|
|
8
|
+
export const noopValidator = () => Promise.resolve(true);
|
|
9
|
+
export const DEFAULT_SUB_PROTOCOL_VALIDATORS = {
|
|
10
|
+
[PING_PROTOCOL]: noopValidator,
|
|
11
|
+
[STATUS_PROTOCOL]: noopValidator,
|
|
12
|
+
[TX_REQ_PROTOCOL]: noopValidator,
|
|
13
|
+
};
|
|
8
14
|
/**
|
|
9
15
|
* Default handler for unimplemented sub protocols, this SHOULD be overwritten
|
|
10
16
|
* by the service, but is provided as a fallback
|
|
@@ -56,4 +62,4 @@ export const subProtocolMap = {
|
|
|
56
62
|
response: Tx,
|
|
57
63
|
},
|
|
58
64
|
};
|
|
59
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlcnZpY2UvcmVxcmVzcC9pbnRlcmZhY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUlsRDs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyx1QkFBdUIsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcseUJBQXlCLENBQUM7QUFDekQsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLHFCQUFxQixDQUFDO0FBeUNyRCxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQWlCekQsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQWlDO0lBQzNFLENBQUMsYUFBYSxDQUFDLEVBQUUsYUFBYTtJQUM5QixDQUFDLGVBQWUsQ0FBQyxFQUFFLGFBQWE7SUFDaEMsQ0FBQyxlQUFlLENBQUMsRUFBRSxhQUFhO0NBQ2pDLENBQUM7QUFVRjs7O0dBR0c7QUFDSCxNQUFNLGNBQWMsR0FBRyxDQUFDLElBQVMsRUFBdUIsRUFBRTtJQUN4RCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4RSxDQUFDLENBQUM7QUFFRjs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUErQjtJQUN2RSxDQUFDLGFBQWEsQ0FBQyxFQUFFLGNBQWM7SUFDL0IsQ0FBQyxlQUFlLENBQUMsRUFBRSxjQUFjO0lBQ2pDLENBQUMsZUFBZSxDQUFDLEVBQUUsY0FBYztDQUNsQyxDQUFDO0FBaUJGOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUM1QixZQUFtQixNQUFjO1FBQWQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtJQUFHLENBQUM7SUFFckMsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyQixDQUFDO0lBRUQsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFjO1FBQzlCLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN2QyxDQUFDO0NBQ0Y7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUFtQjtJQUM1QyxDQUFDLGFBQWEsQ0FBQyxFQUFFO1FBQ2YsT0FBTyxFQUFFLGlCQUFpQjtRQUMxQixRQUFRLEVBQUUsaUJBQWlCO0tBQzVCO0lBQ0QsQ0FBQyxlQUFlLENBQUMsRUFBRTtRQUNqQixPQUFPLEVBQUUsaUJBQWlCO1FBQzFCLFFBQVEsRUFBRSxpQkFBaUI7S0FDNUI7SUFDRCxDQUFDLGVBQWUsQ0FBQyxFQUFFO1FBQ2pCLE9BQU8sRUFBRSxNQUFNO1FBQ2YsUUFBUSxFQUFFLEVBQUU7S0FDYjtDQUNGLENBQUMifQ==
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* https://github.com/ChainSafe/lodestar
|
|
5
5
|
*/
|
|
6
6
|
import { type PeerId } from '@libp2p/interface';
|
|
7
|
+
import { type PeerManager } from '../../peer_manager.js';
|
|
7
8
|
import { type ReqRespSubProtocol, type ReqRespSubProtocolRateLimits } from '../interface.js';
|
|
8
9
|
/**
|
|
9
10
|
* GCRARateLimiter: A Generic Cell Rate Algorithm (GCRA) based rate limiter.
|
|
@@ -36,6 +37,11 @@ export declare class GCRARateLimiter {
|
|
|
36
37
|
constructor(quotaCount: number, quotaTimeMs: number);
|
|
37
38
|
allow(): boolean;
|
|
38
39
|
}
|
|
40
|
+
declare enum RateLimitStatus {
|
|
41
|
+
Allowed = 0,
|
|
42
|
+
DeniedGlobal = 1,
|
|
43
|
+
DeniedPeer = 2
|
|
44
|
+
}
|
|
39
45
|
/**
|
|
40
46
|
* SubProtocolRateLimiter: A rate limiter for managing request rates on a per-peer and global basis for a specific subprotocol.
|
|
41
47
|
*
|
|
@@ -58,7 +64,7 @@ export declare class SubProtocolRateLimiter {
|
|
|
58
64
|
private readonly peerQuotaCount;
|
|
59
65
|
private readonly peerQuotaTimeMs;
|
|
60
66
|
constructor(peerQuotaCount: number, peerQuotaTimeMs: number, globalQuotaCount: number, globalQuotaTimeMs: number);
|
|
61
|
-
allow(peerId: PeerId):
|
|
67
|
+
allow(peerId: PeerId): RateLimitStatus;
|
|
62
68
|
cleanupInactivePeers(): void;
|
|
63
69
|
}
|
|
64
70
|
/**
|
|
@@ -71,21 +77,24 @@ export declare class SubProtocolRateLimiter {
|
|
|
71
77
|
* - Initializes with a set of rate limit configurations for different subprotocols.
|
|
72
78
|
* - Creates a separate SubProtocolRateLimiter for each configured subprotocol.
|
|
73
79
|
* - When a request comes in, it routes the rate limiting decision to the appropriate subprotocol limiter.
|
|
80
|
+
* - Peers who exceed their peer rate limits will be penalised by the peer manager.
|
|
74
81
|
*
|
|
75
82
|
* Usage:
|
|
76
83
|
* ```
|
|
84
|
+
* const peerManager = new PeerManager(...);
|
|
77
85
|
* const rateLimits = {
|
|
78
86
|
* subprotocol1: { peerLimit: { quotaCount: 10, quotaTimeMs: 1000 }, globalLimit: { quotaCount: 100, quotaTimeMs: 1000 } },
|
|
79
87
|
* subprotocol2: { peerLimit: { quotaCount: 5, quotaTimeMs: 1000 }, globalLimit: { quotaCount: 50, quotaTimeMs: 1000 } }
|
|
80
88
|
* };
|
|
81
|
-
* const limiter = new RequestResponseRateLimiter(rateLimits);
|
|
89
|
+
* const limiter = new RequestResponseRateLimiter(peerManager, rateLimits);
|
|
82
90
|
*
|
|
83
91
|
* Note: Ensure to call `stop()` when shutting down to properly clean up all subprotocol limiters.
|
|
84
92
|
*/
|
|
85
93
|
export declare class RequestResponseRateLimiter {
|
|
94
|
+
private peerManager;
|
|
86
95
|
private subProtocolRateLimiters;
|
|
87
96
|
private cleanupInterval;
|
|
88
|
-
constructor(rateLimits?: ReqRespSubProtocolRateLimits);
|
|
97
|
+
constructor(peerManager: PeerManager, rateLimits?: ReqRespSubProtocolRateLimits);
|
|
89
98
|
start(): void;
|
|
90
99
|
allow(subProtocol: ReqRespSubProtocol, peerId: PeerId): boolean;
|
|
91
100
|
cleanupInactivePeers(): void;
|
|
@@ -94,4 +103,5 @@ export declare class RequestResponseRateLimiter {
|
|
|
94
103
|
*/
|
|
95
104
|
stop(): void;
|
|
96
105
|
}
|
|
106
|
+
export {};
|
|
97
107
|
//# sourceMappingURL=rate_limiter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rate_limiter.d.ts","sourceRoot":"","sources":["../../../../src/service/reqresp/rate_limiter/rate_limiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAM7F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAe;IAE1B,OAAO,CAAC,GAAG,CAAS;IAEpB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC;;;OAGG;gBACS,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMnD,KAAK,IAAI,OAAO;CAWjB;AASD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM;IAOhH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"rate_limiter.d.ts","sourceRoot":"","sources":["../../../../src/service/reqresp/rate_limiter/rate_limiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAM7F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,eAAe;IAE1B,OAAO,CAAC,GAAG,CAAS;IAEpB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC;;;OAGG;gBACS,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMnD,KAAK,IAAI,OAAO;CAWjB;AASD,aAAK,eAAe;IAClB,OAAO,IAAA;IACP,YAAY,IAAA;IACZ,UAAU,IAAA;CACX;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM;IAOhH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe;IAwBtC,oBAAoB;CAQrB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,0BAA0B;IAKzB,OAAO,CAAC,WAAW;IAJ/B,OAAO,CAAC,uBAAuB,CAAkD;IAEjF,OAAO,CAAC,eAAe,CAAyC;gBAE5C,WAAW,EAAE,WAAW,EAAE,UAAU,GAAE,4BAAkD;IAgB5G,KAAK;IAML,KAAK,CAAC,WAAW,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAkB/D,oBAAoB;IAIpB;;OAEG;IACH,IAAI;CAGL"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PeerErrorSeverity } from '../../peer_scoring.js';
|
|
1
2
|
import { DEFAULT_RATE_LIMITS } from './rate_limits.js';
|
|
2
3
|
// Check for disconnected peers every 10 minutes
|
|
3
4
|
const CHECK_DISCONNECTED_PEERS_INTERVAL_MS = 10 * 60 * 1000;
|
|
@@ -41,6 +42,12 @@ export class GCRARateLimiter {
|
|
|
41
42
|
return false;
|
|
42
43
|
}
|
|
43
44
|
}
|
|
45
|
+
var RateLimitStatus;
|
|
46
|
+
(function (RateLimitStatus) {
|
|
47
|
+
RateLimitStatus[RateLimitStatus["Allowed"] = 0] = "Allowed";
|
|
48
|
+
RateLimitStatus[RateLimitStatus["DeniedGlobal"] = 1] = "DeniedGlobal";
|
|
49
|
+
RateLimitStatus[RateLimitStatus["DeniedPeer"] = 2] = "DeniedPeer";
|
|
50
|
+
})(RateLimitStatus || (RateLimitStatus = {}));
|
|
44
51
|
/**
|
|
45
52
|
* SubProtocolRateLimiter: A rate limiter for managing request rates on a per-peer and global basis for a specific subprotocol.
|
|
46
53
|
*
|
|
@@ -67,7 +74,7 @@ export class SubProtocolRateLimiter {
|
|
|
67
74
|
}
|
|
68
75
|
allow(peerId) {
|
|
69
76
|
if (!this.globalLimiter.allow()) {
|
|
70
|
-
return
|
|
77
|
+
return RateLimitStatus.DeniedGlobal;
|
|
71
78
|
}
|
|
72
79
|
const peerIdStr = peerId.toString();
|
|
73
80
|
let peerLimiter = this.peerLimiters.get(peerIdStr);
|
|
@@ -82,7 +89,11 @@ export class SubProtocolRateLimiter {
|
|
|
82
89
|
else {
|
|
83
90
|
peerLimiter.lastAccess = Date.now();
|
|
84
91
|
}
|
|
85
|
-
|
|
92
|
+
const peerLimitAllowed = peerLimiter.limiter.allow();
|
|
93
|
+
if (!peerLimitAllowed) {
|
|
94
|
+
return RateLimitStatus.DeniedPeer;
|
|
95
|
+
}
|
|
96
|
+
return RateLimitStatus.Allowed;
|
|
86
97
|
}
|
|
87
98
|
cleanupInactivePeers() {
|
|
88
99
|
const now = Date.now();
|
|
@@ -103,19 +114,22 @@ export class SubProtocolRateLimiter {
|
|
|
103
114
|
* - Initializes with a set of rate limit configurations for different subprotocols.
|
|
104
115
|
* - Creates a separate SubProtocolRateLimiter for each configured subprotocol.
|
|
105
116
|
* - When a request comes in, it routes the rate limiting decision to the appropriate subprotocol limiter.
|
|
117
|
+
* - Peers who exceed their peer rate limits will be penalised by the peer manager.
|
|
106
118
|
*
|
|
107
119
|
* Usage:
|
|
108
120
|
* ```
|
|
121
|
+
* const peerManager = new PeerManager(...);
|
|
109
122
|
* const rateLimits = {
|
|
110
123
|
* subprotocol1: { peerLimit: { quotaCount: 10, quotaTimeMs: 1000 }, globalLimit: { quotaCount: 100, quotaTimeMs: 1000 } },
|
|
111
124
|
* subprotocol2: { peerLimit: { quotaCount: 5, quotaTimeMs: 1000 }, globalLimit: { quotaCount: 50, quotaTimeMs: 1000 } }
|
|
112
125
|
* };
|
|
113
|
-
* const limiter = new RequestResponseRateLimiter(rateLimits);
|
|
126
|
+
* const limiter = new RequestResponseRateLimiter(peerManager, rateLimits);
|
|
114
127
|
*
|
|
115
128
|
* Note: Ensure to call `stop()` when shutting down to properly clean up all subprotocol limiters.
|
|
116
129
|
*/
|
|
117
130
|
export class RequestResponseRateLimiter {
|
|
118
|
-
constructor(rateLimits = DEFAULT_RATE_LIMITS) {
|
|
131
|
+
constructor(peerManager, rateLimits = DEFAULT_RATE_LIMITS) {
|
|
132
|
+
this.peerManager = peerManager;
|
|
119
133
|
this.cleanupInterval = undefined;
|
|
120
134
|
this.subProtocolRateLimiters = new Map();
|
|
121
135
|
for (const [subProtocol, protocolLimits] of Object.entries(rateLimits)) {
|
|
@@ -130,10 +144,18 @@ export class RequestResponseRateLimiter {
|
|
|
130
144
|
allow(subProtocol, peerId) {
|
|
131
145
|
const limiter = this.subProtocolRateLimiters.get(subProtocol);
|
|
132
146
|
if (!limiter) {
|
|
133
|
-
// TODO: maybe throw an error here if no rate limiter is configured?
|
|
134
147
|
return true;
|
|
135
148
|
}
|
|
136
|
-
|
|
149
|
+
const rateLimitStatus = limiter.allow(peerId);
|
|
150
|
+
switch (rateLimitStatus) {
|
|
151
|
+
case RateLimitStatus.DeniedPeer:
|
|
152
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
|
|
153
|
+
return false;
|
|
154
|
+
case RateLimitStatus.DeniedGlobal:
|
|
155
|
+
return false;
|
|
156
|
+
default:
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
137
159
|
}
|
|
138
160
|
cleanupInactivePeers() {
|
|
139
161
|
this.subProtocolRateLimiters.forEach(limiter => limiter.cleanupInactivePeers());
|
|
@@ -145,4 +167,4 @@ export class RequestResponseRateLimiter {
|
|
|
145
167
|
clearInterval(this.cleanupInterval);
|
|
146
168
|
}
|
|
147
169
|
}
|
|
148
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
170
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF0ZV9saW1pdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3NlcnZpY2UvcmVxcmVzcC9yYXRlX2xpbWl0ZXIvcmF0ZV9saW1pdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTFELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXZELGdEQUFnRDtBQUNoRCxNQUFNLG9DQUFvQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRTVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFRMUI7OztPQUdHO0lBQ0gsWUFBWSxVQUFrQixFQUFFLFdBQW1CO1FBQ2pELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxXQUFXLEdBQUcsVUFBVSxDQUFDO1FBQ2pELElBQUksQ0FBQyxhQUFhLEdBQUcsV0FBVyxDQUFDO1FBQ2pDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRCxLQUFLO1FBQ0gsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRXZCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFDL0QsSUFBSSxNQUFNLEdBQUcsR0FBRyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QyxJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztZQUNsQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7Q0FDRjtBQVNELElBQUssZUFJSjtBQUpELFdBQUssZUFBZTtJQUNsQiwyREFBTyxDQUFB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
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
import { type Logger } from '@aztec/foundation/log';
|
|
3
3
|
import { type PeerId } from '@libp2p/interface';
|
|
4
4
|
import { type Libp2p } from 'libp2p';
|
|
5
|
+
import { type PeerManager } from '../peer_manager.js';
|
|
5
6
|
import { type P2PReqRespConfig } from './config.js';
|
|
6
|
-
import { type ReqRespSubProtocol, type ReqRespSubProtocolHandlers } from './interface.js';
|
|
7
|
+
import { type ReqRespSubProtocol, type ReqRespSubProtocolHandlers, type ReqRespSubProtocolValidators, type SubProtocolMap } from './interface.js';
|
|
7
8
|
/**
|
|
8
9
|
* The Request Response Service
|
|
9
10
|
*
|
|
@@ -17,17 +18,19 @@ import { type ReqRespSubProtocol, type ReqRespSubProtocolHandlers } from './inte
|
|
|
17
18
|
*/
|
|
18
19
|
export declare class ReqResp {
|
|
19
20
|
protected readonly libp2p: Libp2p;
|
|
21
|
+
private peerManager;
|
|
20
22
|
protected readonly logger: Logger;
|
|
21
23
|
private abortController;
|
|
22
24
|
private overallRequestTimeoutMs;
|
|
23
25
|
private individualRequestTimeoutMs;
|
|
24
26
|
private subProtocolHandlers;
|
|
27
|
+
private subProtocolValidators;
|
|
25
28
|
private rateLimiter;
|
|
26
|
-
constructor(config: P2PReqRespConfig, libp2p: Libp2p);
|
|
29
|
+
constructor(config: P2PReqRespConfig, libp2p: Libp2p, peerManager: PeerManager);
|
|
27
30
|
/**
|
|
28
31
|
* Start the reqresp service
|
|
29
32
|
*/
|
|
30
|
-
start(subProtocolHandlers: ReqRespSubProtocolHandlers): Promise<void>;
|
|
33
|
+
start(subProtocolHandlers: ReqRespSubProtocolHandlers, subProtocolValidators: ReqRespSubProtocolValidators): Promise<void>;
|
|
31
34
|
/**
|
|
32
35
|
* Stop the reqresp service
|
|
33
36
|
*/
|
|
@@ -36,17 +39,55 @@ export declare class ReqResp {
|
|
|
36
39
|
* Send a request to peers, returns the first response
|
|
37
40
|
*
|
|
38
41
|
* @param subProtocol - The protocol being requested
|
|
39
|
-
* @param
|
|
42
|
+
* @param request - The request to send
|
|
40
43
|
* @returns - The response from the peer, otherwise undefined
|
|
44
|
+
*
|
|
45
|
+
* @description
|
|
46
|
+
* This method attempts to send a request to all active peers using the specified sub-protocol.
|
|
47
|
+
* It opens a stream with each peer, sends the request, and awaits a response.
|
|
48
|
+
* If a valid response is received, it returns the response; otherwise, it continues to the next peer.
|
|
49
|
+
* If no response is received from any peer, it returns undefined.
|
|
50
|
+
*
|
|
51
|
+
* The method performs the following steps:
|
|
52
|
+
* - Iterates over all active peers.
|
|
53
|
+
* - Opens a stream with each peer using the specified sub-protocol.
|
|
54
|
+
*
|
|
55
|
+
* When a response is received, it is validated using the given sub protocols response validator.
|
|
56
|
+
* To see the interface for the response validator - see `interface.ts`
|
|
57
|
+
*
|
|
58
|
+
* Failing a response validation requests in a severe peer penalty, and will
|
|
59
|
+
* prompt the node to continue to search to the next peer.
|
|
60
|
+
* For example, a transaction request validator will check that the payload returned does in fact
|
|
61
|
+
* match the txHash that was requested. A peer that fails this check an only be an extremely naughty peer.
|
|
62
|
+
*
|
|
63
|
+
* This entire operation is wrapped in an overall timeout, that is independent of the
|
|
64
|
+
* peer it is requesting data from.
|
|
65
|
+
*
|
|
41
66
|
*/
|
|
42
|
-
sendRequest(subProtocol:
|
|
67
|
+
sendRequest<SubProtocol extends ReqRespSubProtocol>(subProtocol: SubProtocol, request: InstanceType<SubProtocolMap[SubProtocol]['request']>): Promise<InstanceType<SubProtocolMap[SubProtocol]['response']> | undefined>;
|
|
43
68
|
/**
|
|
44
69
|
* Sends a request to a specific peer
|
|
45
70
|
*
|
|
71
|
+
* We first dial a particular protocol for the peer, this ensures that the peer knows
|
|
72
|
+
* what to respond with
|
|
73
|
+
*
|
|
74
|
+
*
|
|
46
75
|
* @param peerId - The peer to send the request to
|
|
47
76
|
* @param subProtocol - The protocol to use to request
|
|
48
77
|
* @param payload - The payload to send
|
|
49
78
|
* @returns If the request is successful, the response is returned, otherwise undefined
|
|
79
|
+
*
|
|
80
|
+
* @description
|
|
81
|
+
* This method attempts to open a stream with the specified peer, send the payload,
|
|
82
|
+
* and await a response.
|
|
83
|
+
* If an error occurs, it penalizes the peer and returns undefined.
|
|
84
|
+
*
|
|
85
|
+
* The method performs the following steps:
|
|
86
|
+
* - Opens a stream with the peer using the specified sub-protocol.
|
|
87
|
+
* - Sends the payload and awaits a response with a timeout.
|
|
88
|
+
*
|
|
89
|
+
* If the stream is not closed by the dialled peer, and a timeout occurs, then
|
|
90
|
+
* the stream is closed on the requester's end and sender (us) updates its peer score
|
|
50
91
|
*/
|
|
51
92
|
sendRequestToPeer(peerId: PeerId, subProtocol: ReqRespSubProtocol, payload: Buffer): Promise<Buffer | undefined>;
|
|
52
93
|
/**
|
|
@@ -58,6 +99,16 @@ export declare class ReqResp {
|
|
|
58
99
|
* Reads the incoming stream, determines the protocol, then triggers the appropriate handler
|
|
59
100
|
*
|
|
60
101
|
* @param param0 - The incoming stream data
|
|
102
|
+
*
|
|
103
|
+
* @description
|
|
104
|
+
* An individual stream handler will be bound to each sub protocol, and handles returning data back
|
|
105
|
+
* to the requesting peer.
|
|
106
|
+
*
|
|
107
|
+
* The sub protocol handler interface is defined within `interface.ts` and will be assigned to the
|
|
108
|
+
* req resp service on start up.
|
|
109
|
+
*
|
|
110
|
+
* We check rate limits for each peer, note the peer will be penalised within the rate limiter implementation
|
|
111
|
+
* if they exceed their peer specific limits.
|
|
61
112
|
*/
|
|
62
113
|
private streamHandler;
|
|
63
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/reqresp.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,MAAM,EAAqB,MAAM,uBAAuB,CAAC;AAGvE,OAAO,EAA2B,KAAK,MAAM,EAAe,MAAM,mBAAmB,CAAC;AAEtF,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIrC,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,
|
|
1
|
+
{"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/service/reqresp/reqresp.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,MAAM,EAAqB,MAAM,uBAAuB,CAAC;AAGvE,OAAO,EAA2B,KAAK,MAAM,EAAe,MAAM,mBAAmB,CAAC;AAEtF,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIrC,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EAEpB,MAAM,gBAAgB,CAAC;AAGxB;;;;;;;;;;GAUG;AACH,qBAAa,OAAO;IAcoB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAE,OAAO,CAAC,WAAW;IAb5F,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,eAAe,CAA0C;IAEjE,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,0BAA0B,CAAS;IAG3C,OAAO,CAAC,mBAAmB,CAA6D;IACxF,OAAO,CAAC,qBAAqB,CAAiE;IAE9F,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,EAAE,gBAAgB,EAAqB,MAAM,EAAE,MAAM,EAAU,WAAW,EAAE,WAAW;IASzG;;OAEG;IACG,KAAK,CAAC,mBAAmB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,4BAA4B;IAWhH;;OAEG;IACG,IAAI;IAUV;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,WAAW,CAAC,WAAW,SAAS,kBAAkB,EACtD,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,GAC5D,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC;IAwC7E;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAoC9B;;OAEG;YACW,WAAW;IASzB;;;;;;;;;;;;;;;OAeG;YACW,aAAa;CA6B5B"}
|
|
@@ -3,7 +3,8 @@ import { createDebugLogger } from '@aztec/foundation/log';
|
|
|
3
3
|
import { executeTimeoutWithCustomError } from '@aztec/foundation/timer';
|
|
4
4
|
import { pipe } from 'it-pipe';
|
|
5
5
|
import { CollectiveReqRespTimeoutError, IndiviualReqRespTimeoutError } from '../../errors/reqresp.error.js';
|
|
6
|
-
import {
|
|
6
|
+
import { PeerErrorSeverity } from '../peer_scoring.js';
|
|
7
|
+
import { DEFAULT_SUB_PROTOCOL_HANDLERS, DEFAULT_SUB_PROTOCOL_VALIDATORS, subProtocolMap, } from './interface.js';
|
|
7
8
|
import { RequestResponseRateLimiter } from './rate_limiter/rate_limiter.js';
|
|
8
9
|
/**
|
|
9
10
|
* The Request Response Service
|
|
@@ -17,20 +18,24 @@ import { RequestResponseRateLimiter } from './rate_limiter/rate_limiter.js';
|
|
|
17
18
|
* see: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-reqresp-domain
|
|
18
19
|
*/
|
|
19
20
|
export class ReqResp {
|
|
20
|
-
constructor(config, libp2p) {
|
|
21
|
+
constructor(config, libp2p, peerManager) {
|
|
21
22
|
this.libp2p = libp2p;
|
|
23
|
+
this.peerManager = peerManager;
|
|
22
24
|
this.abortController = new AbortController();
|
|
25
|
+
// Warning, if the `start` function is not called as the parent class constructor, then the default sub protocol handlers will be used ( not good )
|
|
23
26
|
this.subProtocolHandlers = DEFAULT_SUB_PROTOCOL_HANDLERS;
|
|
27
|
+
this.subProtocolValidators = DEFAULT_SUB_PROTOCOL_VALIDATORS;
|
|
24
28
|
this.logger = createDebugLogger('aztec:p2p:reqresp');
|
|
25
29
|
this.overallRequestTimeoutMs = config.overallRequestTimeoutMs;
|
|
26
30
|
this.individualRequestTimeoutMs = config.individualRequestTimeoutMs;
|
|
27
|
-
this.rateLimiter = new RequestResponseRateLimiter();
|
|
31
|
+
this.rateLimiter = new RequestResponseRateLimiter(peerManager);
|
|
28
32
|
}
|
|
29
33
|
/**
|
|
30
34
|
* Start the reqresp service
|
|
31
35
|
*/
|
|
32
|
-
async start(subProtocolHandlers) {
|
|
36
|
+
async start(subProtocolHandlers, subProtocolValidators) {
|
|
33
37
|
this.subProtocolHandlers = subProtocolHandlers;
|
|
38
|
+
this.subProtocolValidators = subProtocolValidators;
|
|
34
39
|
// Register all protocol handlers
|
|
35
40
|
for (const subProtocol of Object.keys(this.subProtocolHandlers)) {
|
|
36
41
|
await this.libp2p.handle(subProtocol, this.streamHandler.bind(this, subProtocol));
|
|
@@ -53,20 +58,51 @@ export class ReqResp {
|
|
|
53
58
|
* Send a request to peers, returns the first response
|
|
54
59
|
*
|
|
55
60
|
* @param subProtocol - The protocol being requested
|
|
56
|
-
* @param
|
|
61
|
+
* @param request - The request to send
|
|
57
62
|
* @returns - The response from the peer, otherwise undefined
|
|
63
|
+
*
|
|
64
|
+
* @description
|
|
65
|
+
* This method attempts to send a request to all active peers using the specified sub-protocol.
|
|
66
|
+
* It opens a stream with each peer, sends the request, and awaits a response.
|
|
67
|
+
* If a valid response is received, it returns the response; otherwise, it continues to the next peer.
|
|
68
|
+
* If no response is received from any peer, it returns undefined.
|
|
69
|
+
*
|
|
70
|
+
* The method performs the following steps:
|
|
71
|
+
* - Iterates over all active peers.
|
|
72
|
+
* - Opens a stream with each peer using the specified sub-protocol.
|
|
73
|
+
*
|
|
74
|
+
* When a response is received, it is validated using the given sub protocols response validator.
|
|
75
|
+
* To see the interface for the response validator - see `interface.ts`
|
|
76
|
+
*
|
|
77
|
+
* Failing a response validation requests in a severe peer penalty, and will
|
|
78
|
+
* prompt the node to continue to search to the next peer.
|
|
79
|
+
* For example, a transaction request validator will check that the payload returned does in fact
|
|
80
|
+
* match the txHash that was requested. A peer that fails this check an only be an extremely naughty peer.
|
|
81
|
+
*
|
|
82
|
+
* This entire operation is wrapped in an overall timeout, that is independent of the
|
|
83
|
+
* peer it is requesting data from.
|
|
84
|
+
*
|
|
58
85
|
*/
|
|
59
|
-
async sendRequest(subProtocol,
|
|
86
|
+
async sendRequest(subProtocol, request) {
|
|
60
87
|
const requestFunction = async () => {
|
|
88
|
+
const responseValidator = this.subProtocolValidators[subProtocol];
|
|
89
|
+
const requestBuffer = request.toBuffer();
|
|
61
90
|
// Get active peers
|
|
62
91
|
const peers = this.libp2p.getPeers();
|
|
63
92
|
// Attempt to ask all of our peers
|
|
64
93
|
for (const peer of peers) {
|
|
65
|
-
const response = await this.sendRequestToPeer(peer, subProtocol,
|
|
94
|
+
const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffer);
|
|
66
95
|
// If we get a response, return it, otherwise we iterate onto the next peer
|
|
67
96
|
// We do not consider it a success if we have an empty buffer
|
|
68
97
|
if (response && response.length > 0) {
|
|
69
|
-
|
|
98
|
+
const object = subProtocolMap[subProtocol].response.fromBuffer(response);
|
|
99
|
+
// The response validator handles peer punishment within
|
|
100
|
+
const isValid = await responseValidator(request, object, peer);
|
|
101
|
+
if (!isValid) {
|
|
102
|
+
this.logger.error(`Invalid response for ${subProtocol} from ${peer.toString()}`);
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
return object;
|
|
70
106
|
}
|
|
71
107
|
}
|
|
72
108
|
return undefined;
|
|
@@ -82,16 +118,33 @@ export class ReqResp {
|
|
|
82
118
|
/**
|
|
83
119
|
* Sends a request to a specific peer
|
|
84
120
|
*
|
|
121
|
+
* We first dial a particular protocol for the peer, this ensures that the peer knows
|
|
122
|
+
* what to respond with
|
|
123
|
+
*
|
|
124
|
+
*
|
|
85
125
|
* @param peerId - The peer to send the request to
|
|
86
126
|
* @param subProtocol - The protocol to use to request
|
|
87
127
|
* @param payload - The payload to send
|
|
88
128
|
* @returns If the request is successful, the response is returned, otherwise undefined
|
|
129
|
+
*
|
|
130
|
+
* @description
|
|
131
|
+
* This method attempts to open a stream with the specified peer, send the payload,
|
|
132
|
+
* and await a response.
|
|
133
|
+
* If an error occurs, it penalizes the peer and returns undefined.
|
|
134
|
+
*
|
|
135
|
+
* The method performs the following steps:
|
|
136
|
+
* - Opens a stream with the peer using the specified sub-protocol.
|
|
137
|
+
* - Sends the payload and awaits a response with a timeout.
|
|
138
|
+
*
|
|
139
|
+
* If the stream is not closed by the dialled peer, and a timeout occurs, then
|
|
140
|
+
* the stream is closed on the requester's end and sender (us) updates its peer score
|
|
89
141
|
*/
|
|
90
142
|
async sendRequestToPeer(peerId, subProtocol, payload) {
|
|
91
143
|
let stream;
|
|
92
144
|
try {
|
|
93
145
|
stream = await this.libp2p.dialProtocol(peerId, subProtocol);
|
|
94
146
|
this.logger.debug(`Stream opened with ${peerId.toString()} for ${subProtocol}`);
|
|
147
|
+
// Open the stream with a timeout
|
|
95
148
|
const result = await executeTimeoutWithCustomError(() => pipe([payload], stream, this.readMessage), this.individualRequestTimeoutMs, () => new IndiviualReqRespTimeoutError());
|
|
96
149
|
await stream.close();
|
|
97
150
|
this.logger.debug(`Stream closed with ${peerId.toString()} for ${subProtocol}`);
|
|
@@ -99,6 +152,7 @@ export class ReqResp {
|
|
|
99
152
|
}
|
|
100
153
|
catch (e) {
|
|
101
154
|
this.logger.error(`${e.message} | peerId: ${peerId.toString()} | subProtocol: ${subProtocol}`);
|
|
155
|
+
this.peerManager.penalizePeer(peerId, PeerErrorSeverity.HighToleranceError);
|
|
102
156
|
}
|
|
103
157
|
finally {
|
|
104
158
|
if (stream) {
|
|
@@ -129,6 +183,16 @@ export class ReqResp {
|
|
|
129
183
|
* Reads the incoming stream, determines the protocol, then triggers the appropriate handler
|
|
130
184
|
*
|
|
131
185
|
* @param param0 - The incoming stream data
|
|
186
|
+
*
|
|
187
|
+
* @description
|
|
188
|
+
* An individual stream handler will be bound to each sub protocol, and handles returning data back
|
|
189
|
+
* to the requesting peer.
|
|
190
|
+
*
|
|
191
|
+
* The sub protocol handler interface is defined within `interface.ts` and will be assigned to the
|
|
192
|
+
* req resp service on start up.
|
|
193
|
+
*
|
|
194
|
+
* We check rate limits for each peer, note the peer will be penalised within the rate limiter implementation
|
|
195
|
+
* if they exceed their peer specific limits.
|
|
132
196
|
*/
|
|
133
197
|
async streamHandler(protocol, { stream, connection }) {
|
|
134
198
|
// Store a reference to from this for the async generator
|
|
@@ -155,4 +219,4 @@ export class ReqResp {
|
|
|
155
219
|
}
|
|
156
220
|
}
|
|
157
221
|
}
|
|
158
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
222
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlL3JlcXJlc3AvcmVxcmVzcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4Q0FBOEM7QUFDOUMsT0FBTyxFQUFlLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdkUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHeEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUkvQixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU1RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV2RCxPQUFPLEVBQ0wsNkJBQTZCLEVBQzdCLCtCQUErQixFQUsvQixjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU1RTs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLE9BQU87SUFjbEIsWUFBWSxNQUF3QixFQUFxQixNQUFjLEVBQVUsV0FBd0I7UUFBaEQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUFVLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBWGpHLG9CQUFlLEdBQW9CLElBQUksZUFBZSxFQUFFLENBQUM7UUFLakUsbUpBQW1KO1FBQzNJLHdCQUFtQixHQUErQiw2QkFBNkIsQ0FBQztRQUNoRiwwQkFBcUIsR0FBaUMsK0JBQStCLENBQUM7UUFLNUYsSUFBSSxDQUFDLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBRXJELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxNQUFNLENBQUMsdUJBQXVCLENBQUM7UUFDOUQsSUFBSSxDQUFDLDBCQUEwQixHQUFHLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQztRQUVwRSxJQUFJLENBQUMs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
|
|
@@ -3,5 +3,6 @@ export declare class AggregateTxValidator<T extends Tx | ProcessedTx> implements
|
|
|
3
3
|
#private;
|
|
4
4
|
constructor(...validators: TxValidator<T>[]);
|
|
5
5
|
validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]>;
|
|
6
|
+
validateTx(tx: T): Promise<boolean>;
|
|
6
7
|
}
|
|
7
8
|
//# sourceMappingURL=aggregate_tx_validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aggregate_tx_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/aggregate_tx_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnF,qBAAa,oBAAoB,CAAC,CAAC,SAAS,EAAE,GAAG,WAAW,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;gBAEzE,GAAG,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE;IAQrC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"aggregate_tx_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/aggregate_tx_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnF,qBAAa,oBAAoB,CAAC,CAAC,SAAS,EAAE,GAAG,WAAW,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;gBAEzE,GAAG,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE;IAQrC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAYhE,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAS1C"}
|
|
@@ -18,6 +18,15 @@ export class AggregateTxValidator {
|
|
|
18
18
|
}
|
|
19
19
|
return [txPool, invalidTxs];
|
|
20
20
|
}
|
|
21
|
+
async validateTx(tx) {
|
|
22
|
+
for (const validator of __classPrivateFieldGet(this, _AggregateTxValidator_validators, "f")) {
|
|
23
|
+
const valid = await validator.validateTx(tx);
|
|
24
|
+
if (!valid) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
21
30
|
}
|
|
22
31
|
_AggregateTxValidator_validators = new WeakMap();
|
|
23
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
32
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdncmVnYXRlX3R4X3ZhbGlkYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eF92YWxpZGF0b3IvYWdncmVnYXRlX3R4X3ZhbGlkYXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLE1BQU0sT0FBTyxvQkFBb0I7SUFFL0IsWUFBWSxHQUFHLFVBQTRCO1FBRDNDLG1EQUE4QjtRQUU1QixJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDNUIsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1FBQzdELENBQUM7UUFFRCx1QkFBQSxJQUFJLG9DQUFlLFVBQVUsTUFBQSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVE7UUFDeEIsTUFBTSxVQUFVLEdBQVEsRUFBRSxDQUFDO1FBQzNCLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQztRQUNqQixLQUFLLE1BQU0sU0FBUyxJQUFJLHVCQUFBLElBQUksd0NBQVksRUFBRSxDQUFDO1lBQ3pDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsTUFBTSxTQUFTLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzdELFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztZQUM1QixNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLENBQUM7UUFFRCxPQUFPLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUs7UUFDcEIsS0FBSyxNQUFNLFNBQVMsSUFBSSx1QkFBQSxJQUFJLHdDQUFZLEVBQUUsQ0FBQztZQUN6QyxNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNYLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Q0FDRiJ9
|
|
@@ -2,5 +2,6 @@ import { Tx, type TxValidator } from '@aztec/circuit-types';
|
|
|
2
2
|
export declare class DataTxValidator implements TxValidator<Tx> {
|
|
3
3
|
#private;
|
|
4
4
|
validateTxs(txs: Tx[]): Promise<[validTxs: Tx[], invalidTxs: Tx[]]>;
|
|
5
|
+
validateTx(tx: Tx): Promise<boolean>;
|
|
5
6
|
}
|
|
6
7
|
//# sourceMappingURL=data_validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/data_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG5D,qBAAa,eAAgB,YAAW,WAAW,CAAC,EAAE,CAAC;;IAGrD,WAAW,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"data_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/data_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAG5D,qBAAa,eAAgB,YAAW,WAAW,CAAC,EAAE,CAAC;;IAGrD,WAAW,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IAenE,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CA2CrC"}
|
|
@@ -20,6 +20,9 @@ export class DataTxValidator {
|
|
|
20
20
|
}
|
|
21
21
|
return Promise.resolve([validTxs, invalidTxs]);
|
|
22
22
|
}
|
|
23
|
+
validateTx(tx) {
|
|
24
|
+
return Promise.resolve(__classPrivateFieldGet(this, _DataTxValidator_instances, "m", _DataTxValidator_hasCorrectExecutionRequests).call(this, tx));
|
|
25
|
+
}
|
|
23
26
|
}
|
|
24
27
|
_DataTxValidator_log = new WeakMap(), _DataTxValidator_instances = new WeakSet(), _DataTxValidator_hasCorrectExecutionRequests = function _DataTxValidator_hasCorrectExecutionRequests(tx) {
|
|
25
28
|
const callRequests = [
|
|
@@ -44,4 +47,4 @@ _DataTxValidator_log = new WeakMap(), _DataTxValidator_instances = new WeakSet()
|
|
|
44
47
|
}
|
|
45
48
|
return true;
|
|
46
49
|
};
|
|
47
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV92YWxpZGF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHhfdmFsaWRhdG9yL2RhdGFfdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsT0FBTyxFQUFFLEVBQUUsRUFBb0IsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUxRCxNQUFNLE9BQU8sZUFBZTtJQUE1Qjs7UUFDRSwrQkFBTyxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxFQUFDO1FBMkRqRSxvQkFBb0I7SUFDdEIsQ0FBQztJQTFEQyxXQUFXLENBQUMsR0FBUztRQUNuQixNQUFNLFFBQVEsR0FBUyxFQUFFLENBQUM7UUFDMUIsTUFBTSxVQUFVLEdBQVMsRUFBRSxDQUFDO1FBQzVCLEtBQUssTUFBTSxFQUFFLElBQUksR0FBRyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLHVCQUFBLElBQUksZ0ZBQTZCLE1BQWpDLElBQUksRUFBOEIsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDM0MsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDcEIsU0FBUztZQUNYLENBQUM7WUFFRCxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BCLENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQsVUFBVSxDQUFDLEVBQU07UUFDZixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsdUJBQUEsSUFBSSxnRkFBNkIsTUFBakMsSUFBSSxFQUE4QixFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7Q0F5Q0Y7dUxBdkM4QixFQUFNO0lBQ2pDLE1BQU0sWUFBWSxHQUFHO1FBQ25CLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQywrQkFBK0IsRUFBRTtRQUM1QyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0NBQWtDLEVBQUU7S0FDaEQsQ0FBQztJQUNGLElBQUksWUFBWSxDQUFDLE1BQU0sS0FBSyxFQUFFLENBQUMsMkJBQTJCLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbEUsdUJBQUEsSUFBSSw0QkFBSyxDQUFDLElBQUksQ0FDWixnQkFBZ0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsZ0ZBQzVCLFlBQVksQ0FBQyxNQUNmLFNBQVMsRUFBRSxDQUFDLDJCQUEyQixDQUFDLE1BQU0sR0FBRyxDQUNsRCxDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQsTUFBTSw0QkFBNEIsR0FBRyxFQUFFLENBQUMsMkJBQTJCLENBQUMsU0FBUyxDQUMzRSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNuRSxDQUFDO0lBQ0YsSUFBSSw0QkFBNEIsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3hDLHVCQUFBLElBQUksNEJBQUssQ0FBQyxJQUFJLENBQ1osZ0JBQWdCLEVBQUUsQ0FBQyxPQUFPLENBQ3hCLEVBQUUsQ0FDSCxxRUFBcUUsNEJBQTRCLEdBQUcsQ0FDdEcsQ0FBQztRQUNGLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELE1BQU0sbUJBQW1CLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDO0lBQ25FLE1BQU0saUNBQWlDLEdBQ3JDLENBQUMsQ0FBQyxtQkFBbUIsSUFBSSxDQUFDLEVBQUUsQ0FBQywwQkFBMEIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNsRSxDQUFDLG1CQUFtQixJQUFJLENBQUMsRUFBRSxDQUFDLDBCQUEwQixDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztJQUNoRyxJQUFJLGlDQUFpQyxFQUFFLENBQUM7UUFDdEMsdUJBQUEsSUFBSSw0QkFBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsb0RBQW9ELENBQUMsQ0FBQztRQUNuRyxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMifQ==
|
|
@@ -8,5 +8,6 @@ export declare class DoubleSpendTxValidator<T extends AnyTx> implements TxValida
|
|
|
8
8
|
private readonly isValidatingBlock;
|
|
9
9
|
constructor(nullifierSource: NullifierSource, isValidatingBlock?: boolean);
|
|
10
10
|
validateTxs(txs: T[]): Promise<[validTxs: T[], invalidTxs: T[]]>;
|
|
11
|
+
validateTx(tx: T): Promise<boolean>;
|
|
11
12
|
}
|
|
12
13
|
//# sourceMappingURL=double_spend_validator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"double_spend_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/double_spend_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAGxC,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,CAAC,SAAS,EAAE,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACnE;AAED,qBAAa,sBAAsB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAI9B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAApE,eAAe,EAAE,eAAe,EAAmB,iBAAiB,GAAE,OAAc;IAI1F,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"double_spend_validator.d.ts","sourceRoot":"","sources":["../../src/tx_validator/double_spend_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAM,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAGxC,MAAM,WAAW,eAAe;IAC9B,iBAAiB,EAAE,CAAC,SAAS,EAAE,EAAE,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;CACnE;AAED,qBAAa,sBAAsB,CAAC,CAAC,SAAS,KAAK,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAI9B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAApE,eAAe,EAAE,eAAe,EAAmB,iBAAiB,GAAE,OAAc;IAI1F,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAiBtE,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;CAmCpC"}
|