@aztec/p2p 0.85.0 → 0.86.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.
Files changed (90) hide show
  1. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  2. package/dest/bootstrap/bootstrap.js +6 -3
  3. package/dest/client/p2p_client.d.ts +41 -3
  4. package/dest/client/p2p_client.d.ts.map +1 -1
  5. package/dest/client/p2p_client.js +58 -18
  6. package/dest/config.d.ts +13 -2
  7. package/dest/config.d.ts.map +1 -1
  8. package/dest/config.js +15 -3
  9. package/dest/enr/generate-enr.d.ts +1 -1
  10. package/dest/enr/generate-enr.d.ts.map +1 -1
  11. package/dest/enr/generate-enr.js +2 -2
  12. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  13. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +11 -11
  14. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +2 -2
  15. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  16. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +4 -4
  17. package/dest/mem_pools/attestation_pool/mocks.d.ts +1 -1
  18. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  19. package/dest/mem_pools/attestation_pool/mocks.js +2 -2
  20. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +3 -0
  21. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  22. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +18 -0
  23. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +3 -0
  24. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
  25. package/dest/mem_pools/tx_pool/memory_tx_pool.js +9 -0
  26. package/dest/mem_pools/tx_pool/tx_pool.d.ts +17 -0
  27. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  29. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +57 -0
  30. package/dest/msg_validators/attestation_validator/attestation_validator.js +1 -1
  31. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +1 -0
  32. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +1 -1
  33. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.js +6 -1
  34. package/dest/services/discv5/discV5_service.d.ts +2 -1
  35. package/dest/services/discv5/discV5_service.d.ts.map +1 -1
  36. package/dest/services/discv5/discV5_service.js +22 -7
  37. package/dest/services/dummy_service.d.ts +2 -2
  38. package/dest/services/dummy_service.d.ts.map +1 -1
  39. package/dest/services/dummy_service.js +2 -2
  40. package/dest/services/libp2p/libp2p_service.d.ts +3 -1
  41. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  42. package/dest/services/libp2p/libp2p_service.js +28 -12
  43. package/dest/services/peer-manager/peer_manager.d.ts +21 -2
  44. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  45. package/dest/services/peer-manager/peer_manager.js +63 -18
  46. package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +2 -2
  47. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +17 -1
  48. package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -1
  49. package/dest/services/reqresp/connection-sampler/connection_sampler.js +84 -36
  50. package/dest/services/reqresp/reqresp.d.ts +2 -2
  51. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  52. package/dest/services/reqresp/reqresp.js +7 -2
  53. package/dest/services/reqresp/status.d.ts +2 -1
  54. package/dest/services/reqresp/status.d.ts.map +1 -1
  55. package/dest/services/reqresp/status.js +3 -0
  56. package/dest/services/service.d.ts +4 -4
  57. package/dest/services/service.d.ts.map +1 -1
  58. package/dest/test-helpers/make-test-p2p-clients.d.ts +6 -1
  59. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  60. package/dest/test-helpers/make-test-p2p-clients.js +19 -2
  61. package/dest/testbench/p2p_client_testbench_worker.js +4 -1
  62. package/dest/util.d.ts.map +1 -1
  63. package/dest/util.js +5 -1
  64. package/package.json +12 -14
  65. package/src/bootstrap/bootstrap.ts +8 -4
  66. package/src/client/p2p_client.ts +212 -131
  67. package/src/config.ts +34 -4
  68. package/src/enr/generate-enr.ts +2 -2
  69. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +11 -15
  70. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +2 -2
  71. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +4 -4
  72. package/src/mem_pools/attestation_pool/mocks.ts +3 -3
  73. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +21 -0
  74. package/src/mem_pools/tx_pool/memory_tx_pool.ts +11 -0
  75. package/src/mem_pools/tx_pool/tx_pool.ts +20 -0
  76. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +43 -0
  77. package/src/msg_validators/attestation_validator/attestation_validator.ts +1 -1
  78. package/src/msg_validators/block_proposal_validator/block_proposal_validator.ts +10 -1
  79. package/src/services/discv5/discV5_service.ts +32 -6
  80. package/src/services/dummy_service.ts +2 -2
  81. package/src/services/libp2p/libp2p_service.ts +37 -12
  82. package/src/services/peer-manager/peer_manager.ts +79 -22
  83. package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +2 -2
  84. package/src/services/reqresp/connection-sampler/connection_sampler.ts +82 -41
  85. package/src/services/reqresp/reqresp.ts +12 -6
  86. package/src/services/reqresp/status.ts +3 -0
  87. package/src/services/service.ts +4 -4
  88. package/src/test-helpers/make-test-p2p-clients.ts +20 -2
  89. package/src/testbench/p2p_client_testbench_worker.ts +3 -0
  90. package/src/util.ts +6 -1
@@ -21,6 +21,8 @@ export declare class PeerManager {
21
21
  private timedOutPeers;
22
22
  private trustedPeers;
23
23
  private trustedPeersInitialized;
24
+ private privatePeers;
25
+ private privatePeersInitialized;
24
26
  private metrics;
25
27
  private handlers;
26
28
  constructor(libP2PNode: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, config: P2PConfig, telemetryClient: TelemetryClient, logger: import("@aztec/foundation/log").Logger, peerScoring: PeerScoring, reqresp: ReqResp);
@@ -29,7 +31,7 @@ export declare class PeerManager {
29
31
  *
30
32
  * This function is called when the peer manager is initialized.
31
33
  */
32
- initializeTrustedPeers(): Promise<void>;
34
+ initializePeers(): Promise<void>;
33
35
  get tracer(): import("@aztec/telemetry-client").Tracer;
34
36
  heartbeat(): void;
35
37
  /**
@@ -62,6 +64,23 @@ export declare class PeerManager {
62
64
  * @param peerId - The peer ID to add to trusted peers.
63
65
  */
64
66
  addTrustedPeer(peerId: PeerId): void;
67
+ /**
68
+ * Adds a peer to the private peers set.
69
+ * @param peerId - The peer ID to add to private peers.
70
+ */
71
+ addPrivatePeer(peerId: PeerId): void;
72
+ /**
73
+ * Checks if a peer is private.
74
+ * @param peerId - The peer ID.
75
+ * @returns True if the peer is private, false otherwise.
76
+ */
77
+ private isPrivatePeer;
78
+ /**
79
+ * Checks if a peer is protected (either trusted or private).
80
+ * @param peerId - The peer ID.
81
+ * @returns True if the peer is protected, false otherwise.
82
+ */
83
+ private isProtectedPeer;
65
84
  /**
66
85
  * Handles a goodbye received from a peer.
67
86
  *
@@ -77,7 +96,7 @@ export declare class PeerManager {
77
96
  * Discovers peers.
78
97
  */
79
98
  private discover;
80
- private onlyNotTrustedPeers;
99
+ private getNonProtectedPeers;
81
100
  private pruneUnhealthyPeers;
82
101
  /**
83
102
  * If the max peer count is reached, the lowest scoring peers will be pruned to satisfy the max peer count.
@@ -1 +1 @@
1
- {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBrE,qBAAa,WAAW;IAgBpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IArBjB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,8BAA8B,CAAa;IACnD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAId;gBAGQ,UAAU,EAAE,YAAY,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACzB,eAAe,EAAE,eAAe,EACxB,MAAM,wCAAmC,EACzC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO;IAwB1B;;;;OAIG;IACG,sBAAsB;IAU5B,IAAI,MAAM,6CAET;IAGM,SAAS;IAShB;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IASnC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;;OAMG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAQrD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAIvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,QAAQ,CAAC,cAAc,UAAQ,GAAG,QAAQ,EAAE;IAiCnD;;OAEG;IACH,OAAO,CAAC,QAAQ;IAiEhB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;IAwB3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;YAuBb,wBAAwB;YAcxB,cAAc;IAQ5B;;;OAGG;YACW,oBAAoB;YA8DpB,QAAQ;IA2BtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,gBAAgB;IAsBxB;;;OAGG;IACU,IAAI;CAYlB"}
1
+ {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBrE,qBAAa,WAAW;IAkBpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IAvBjB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,8BAA8B,CAAa;IACnD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IACjD,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAId;gBAGQ,UAAU,EAAE,YAAY,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACzB,eAAe,EAAE,eAAe,EACxB,MAAM,wCAAmC,EACzC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO;IAwB1B;;;;OAIG;IACG,eAAe;IA8BrB,IAAI,MAAM,6CAET;IAGM,SAAS;IAShB;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IASnC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ3C;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAU3C;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAQrB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;;OAMG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAQrD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAIvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,QAAQ,CAAC,cAAc,UAAQ,GAAG,QAAQ,EAAE;IAiCnD;;OAEG;IACH,OAAO,CAAC,QAAQ;IAkEhB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,mBAAmB;IAoB3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;YAuBb,wBAAwB;YAcxB,cAAc;IAQ5B;;;OAGG;YACW,oBAAoB;YA8DpB,QAAQ;IA2BtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,gBAAgB;IAsBxB;;;OAGG;IACU,IAAI;CAYlB"}
@@ -30,6 +30,8 @@ export class PeerManager {
30
30
  timedOutPeers;
31
31
  trustedPeers;
32
32
  trustedPeersInitialized;
33
+ privatePeers;
34
+ privatePeersInitialized;
33
35
  metrics;
34
36
  handlers;
35
37
  constructor(libP2PNode, peerDiscoveryService, config, telemetryClient, logger = createLogger('p2p:peer-manager'), peerScoring, reqresp){
@@ -45,6 +47,8 @@ export class PeerManager {
45
47
  this.timedOutPeers = new Map();
46
48
  this.trustedPeers = new Set();
47
49
  this.trustedPeersInitialized = false;
50
+ this.privatePeers = new Set();
51
+ this.privatePeersInitialized = false;
48
52
  this.metrics = new PeerManagerMetrics(telemetryClient, 'PeerManager');
49
53
  // Handle Discovered peers
50
54
  this.handlers = {
@@ -65,11 +69,25 @@ export class PeerManager {
65
69
  * Initializes the trusted peers.
66
70
  *
67
71
  * This function is called when the peer manager is initialized.
68
- */ async initializeTrustedPeers() {
69
- const trustedPeersEnrs = this.config.trustedPeers.map((enr)=>ENR.decodeTxt(enr));
70
- await Promise.all(trustedPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.trustedPeers.add(peerId))).finally(()=>{
71
- this.trustedPeersInitialized = true;
72
- }).catch((e)=>this.logger.error('Error initializing trusted peers', e));
72
+ */ async initializePeers() {
73
+ if (this.config.trustedPeers) {
74
+ const trustedPeersEnrs = this.config.trustedPeers.map((enr)=>ENR.decodeTxt(enr));
75
+ await Promise.all(trustedPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.trustedPeers.add(peerId.toString()))).finally(()=>{
76
+ this.trustedPeersInitialized = true;
77
+ }).catch((e)=>this.logger.error('Error initializing trusted peers', e));
78
+ }
79
+ if (this.config.privatePeers) {
80
+ const privatePeersEnrs = this.config.privatePeers.map((enr)=>ENR.decodeTxt(enr));
81
+ await Promise.all(privatePeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>{
82
+ this.trustedPeers.add(peerId.toString());
83
+ this.privatePeers.add(peerId.toString());
84
+ })).finally(()=>{
85
+ if (!this.config.trustedPeers) {
86
+ this.trustedPeersInitialized = true;
87
+ }
88
+ this.privatePeersInitialized = true;
89
+ }).catch((e)=>this.logger.error('Error initializing private peers', e));
90
+ }
73
91
  }
74
92
  get tracer() {
75
93
  return this.metrics.tracer;
@@ -127,15 +145,45 @@ export class PeerManager {
127
145
  this.logger.warn('Trusted peers not initialized, returning false');
128
146
  return false;
129
147
  }
130
- return this.trustedPeers.has(peerId);
148
+ return this.trustedPeers.has(peerId.toString());
131
149
  }
132
150
  /**
133
151
  * Adds a peer to the trusted peers set.
134
152
  * @param peerId - The peer ID to add to trusted peers.
135
153
  */ addTrustedPeer(peerId) {
136
- this.trustedPeers.add(peerId);
154
+ const peerIdStr = peerId.toString();
155
+ this.trustedPeers.add(peerIdStr);
156
+ this.trustedPeersInitialized = true;
157
+ this.logger.verbose(`Added trusted peer ${peerIdStr}`);
158
+ }
159
+ /**
160
+ * Adds a peer to the private peers set.
161
+ * @param peerId - The peer ID to add to private peers.
162
+ */ addPrivatePeer(peerId) {
163
+ const peerIdStr = peerId.toString();
164
+ this.trustedPeers.add(peerIdStr);
165
+ this.privatePeers.add(peerIdStr);
137
166
  this.trustedPeersInitialized = true;
138
- this.logger.verbose(`Added trusted peer ${peerId.toString()}`);
167
+ this.privatePeersInitialized = true;
168
+ this.logger.verbose(`Added private peer ${peerIdStr}`);
169
+ }
170
+ /**
171
+ * Checks if a peer is private.
172
+ * @param peerId - The peer ID.
173
+ * @returns True if the peer is private, false otherwise.
174
+ */ isPrivatePeer(peerId) {
175
+ if (!this.privatePeersInitialized) {
176
+ this.logger.warn('Private peers not initialized, returning false');
177
+ return false;
178
+ }
179
+ return this.privatePeers.has(peerId.toString());
180
+ }
181
+ /**
182
+ * Checks if a peer is protected (either trusted or private).
183
+ * @param peerId - The peer ID.
184
+ * @returns True if the peer is protected, false otherwise.
185
+ */ isProtectedPeer(peerId) {
186
+ return this.isTrustedPeer(peerId) || this.isPrivatePeer(peerId);
139
187
  }
140
188
  /**
141
189
  * Handles a goodbye received from a peer.
@@ -188,12 +236,13 @@ export class PeerManager {
188
236
  * Discovers peers.
189
237
  */ discover() {
190
238
  const connections = this.libP2PNode.getConnections();
191
- const healthyConnections = this.prioritizePeers(this.onlyNotTrustedPeers(this.pruneUnhealthyPeers(this.pruneDuplicatePeers(connections))));
239
+ const healthyConnections = this.prioritizePeers(this.pruneUnhealthyPeers(this.getNonProtectedPeers(this.pruneDuplicatePeers(connections))));
192
240
  // Calculate how many connections we're looking to make
193
241
  const peersToConnect = this.config.maxPeerCount - healthyConnections.length - this.trustedPeers.size;
194
242
  const logLevel = this.heartbeatCounter % this.displayPeerCountsPeerHeartbeat === 0 ? 'info' : 'debug';
195
- this.logger[logLevel](`Connected to ${healthyConnections.length} peers`, {
196
- connections: healthyConnections.length,
243
+ this.logger[logLevel](`Connected to ${healthyConnections.length + this.trustedPeers.size} peers`, {
244
+ discoveredConnections: healthyConnections.length,
245
+ protectedConnections: this.trustedPeers.size,
197
246
  maxPeerCount: this.config.maxPeerCount,
198
247
  cachedPeers: this.cachedPeers.size,
199
248
  ...this.peerScoring.getStats()
@@ -228,16 +277,12 @@ export class PeerManager {
228
277
  void this.peerDiscoveryService.runRandomNodesQuery();
229
278
  }
230
279
  }
231
- onlyNotTrustedPeers(connections) {
232
- return connections.filter((conn)=>!this.isTrustedPeer(conn.remotePeer));
280
+ getNonProtectedPeers(connections) {
281
+ return connections.filter((conn)=>!this.isProtectedPeer(conn.remotePeer));
233
282
  }
234
283
  pruneUnhealthyPeers(connections) {
235
284
  const connectedHealthyPeers = [];
236
285
  for (const peer of connections){
237
- if (this.isTrustedPeer(peer.remotePeer)) {
238
- this.logger.debug(`Not pruning trusted peer ${peer.remotePeer.toString()}`);
239
- continue;
240
- }
241
286
  const score = this.peerScoring.getScoreState(peer.remotePeer.toString());
242
287
  switch(score){
243
288
  case PeerScoreState.Banned:
@@ -434,7 +479,7 @@ export class PeerManager {
434
479
  }
435
480
  // Remove the oldest peers
436
481
  for (const [key, value] of this.cachedPeers.entries()){
437
- if (this.isTrustedPeer(value.peerId)) {
482
+ if (this.isProtectedPeer(value.peerId)) {
438
483
  this.logger.debug(`Not pruning trusted peer ${key}`);
439
484
  continue;
440
485
  }
@@ -63,14 +63,14 @@ import { createLogger } from '@aztec/foundation/log';
63
63
  const newPeer = this.connectionSampler.getPeer(excluding);
64
64
  if (newPeer) {
65
65
  this.batch[index] = newPeer;
66
- this.logger.trace(`Replaced peer ${peerId} with ${newPeer}`, {
66
+ this.logger.trace('Replaced peer', {
67
67
  peerId,
68
68
  newPeer
69
69
  });
70
70
  } else {
71
71
  // If we couldn't get a replacement, remove the peer and compact the array
72
72
  this.batch.splice(index, 1);
73
- this.logger.trace(`Removed peer ${peerId}`, {
73
+ this.logger.trace('Removed peer', {
74
74
  peerId
75
75
  });
76
76
  }
@@ -3,7 +3,7 @@ export declare class RandomSampler {
3
3
  random(max: number): number;
4
4
  }
5
5
  /**
6
- * A class that samples peers from the libp2p node and returns a peer that we don't already have a connection open to.
6
+ * A class that samples peers from the libp2p node and returns a peer that we don't already have a reqresp connection open to.
7
7
  * If we already have a connection open, we try to sample a different peer.
8
8
  * We do this MAX_SAMPLE_ATTEMPTS times, if we still don't find a peer we just go for it.
9
9
  *
@@ -32,6 +32,22 @@ export declare class ConnectionSampler {
32
32
  * @returns
33
33
  */
34
34
  getPeer(excluding?: Map<string, boolean>): PeerId | undefined;
35
+ /**
36
+ * Samples a peer from a list of peers, excluding those that have active (reqresp) connections or are in the exclusion list
37
+ *
38
+ * @param peers - The list of peers to sample from
39
+ * @param excluding - The peers to exclude from the sampling
40
+ * @returns - A peer from the list, or undefined if no peers are available,
41
+ * - a boolean indicating if the peer has active connections, and
42
+ * - all sampled peers - to enable optional resampling
43
+ *
44
+ * @dev The provided list peers, should be mutated by this function. This allows batch sampling
45
+ * to be performed without making extra copies of the list.
46
+ */
47
+ getPeerFromList(peers: PeerId[], excluding?: Map<string, boolean>): {
48
+ peer: PeerId | undefined;
49
+ sampledPeers: PeerId[];
50
+ };
35
51
  /**
36
52
  * Samples a batch of unique peers from the libp2p node, prioritizing peers without active connections
37
53
  *
@@ -1 +1 @@
1
- {"version":3,"file":"connection_sampler.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/connection-sampler/connection_sampler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAShE,qBAAa,aAAa;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM;CAGnB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAY1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;IACzE,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,eAAe,CAA0C;IAEjE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAkC;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IAGnE,OAAO,CAAC,SAAS,CAAkC;gBAGhC,MAAM,EAAE,MAAM,EACd,iBAAiB,GAAE,MAAc,EAAE,sBAAsB;IACzD,OAAO,GAAE,aAAmC;IAO/D;;OAEG;IACG,IAAI;IAaV;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS;IA+B7D;;;;;OAKG;IACH,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE;IAkClD;;;;;;OAMG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBrE;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B5C;;OAEG;YACW,uBAAuB;CAetC"}
1
+ {"version":3,"file":"connection_sampler.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/connection-sampler/connection_sampler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAShE,qBAAa,aAAa;IACxB,MAAM,CAAC,GAAG,EAAE,MAAM;CAGnB;AAED;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAY1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAb1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkD;IACzE,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,eAAe,CAA0C;IAEjE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAkC;IACzE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IAGnE,OAAO,CAAC,SAAS,CAAkC;gBAGhC,MAAM,EAAE,MAAM,EACd,iBAAiB,GAAE,MAAc,EAAE,sBAAsB;IACzD,OAAO,GAAE,aAAmC;IAO/D;;OAEG;IACG,IAAI;IAaV;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS;IAO7D;;;;;;;;;;;OAWG;IACH,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B;QACD,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QACzB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB;IAuCD;;;;;OAKG;IACH,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,EAAE;IAyClD;;;;;;OAMG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoBrE;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4B5C;;OAEG;YACW,uBAAuB;CAetC"}
@@ -7,7 +7,7 @@ export class RandomSampler {
7
7
  }
8
8
  }
9
9
  /**
10
- * A class that samples peers from the libp2p node and returns a peer that we don't already have a connection open to.
10
+ * A class that samples peers from the libp2p node and returns a peer that we don't already have a reqresp connection open to.
11
11
  * If we already have a connection open, we try to sample a different peer.
12
12
  * We do this MAX_SAMPLE_ATTEMPTS times, if we still don't find a peer we just go for it.
13
13
  *
@@ -55,24 +55,60 @@ export class RandomSampler {
55
55
  */ getPeer(excluding) {
56
56
  // In libp2p getPeers performs a shallow copy, so this array can be sliced from safetly
57
57
  const peers = this.libp2p.getPeers();
58
+ const { peer } = this.getPeerFromList(peers, excluding);
59
+ return peer;
60
+ }
61
+ /**
62
+ * Samples a peer from a list of peers, excluding those that have active (reqresp) connections or are in the exclusion list
63
+ *
64
+ * @param peers - The list of peers to sample from
65
+ * @param excluding - The peers to exclude from the sampling
66
+ * @returns - A peer from the list, or undefined if no peers are available,
67
+ * - a boolean indicating if the peer has active connections, and
68
+ * - all sampled peers - to enable optional resampling
69
+ *
70
+ * @dev The provided list peers, should be mutated by this function. This allows batch sampling
71
+ * to be performed without making extra copies of the list.
72
+ */ getPeerFromList(peers, excluding) {
58
73
  if (peers.length === 0) {
59
- return undefined;
74
+ return {
75
+ peer: undefined,
76
+ sampledPeers: []
77
+ };
60
78
  }
61
- let randomIndex = this.sampler.random(peers.length);
62
- let attempts = 0;
63
- // Keep sampling while:
64
- // - we haven't exceeded max attempts AND
65
- // - either the peer has active connections OR is in the exclusion list
66
- while(attempts < MAX_SAMPLE_ATTEMPTS && ((this.activeConnectionsCount.get(peers[randomIndex]) ?? 0) > 0 || (excluding?.get(peers[randomIndex]?.toString()) ?? false))){
79
+ const sampledPeers = [];
80
+ // Try to find a peer that has no active connections and is not in the exclusion list
81
+ for(let attempts = 0; attempts < MAX_SAMPLE_ATTEMPTS && peers.length > 0; attempts++){
82
+ const randomIndex = this.sampler.random(peers.length);
83
+ const peer = peers[randomIndex];
84
+ const hasActiveConnections = (this.activeConnectionsCount.get(peer) ?? 0) > 0;
85
+ const isExcluded = excluding?.get(peer.toString()) ?? false;
86
+ // Remove this peer from consideration
67
87
  peers.splice(randomIndex, 1);
68
- randomIndex = this.sampler.random(peers.length);
69
- attempts++;
88
+ // If peer is suitable (no active connections and not excluded), return it
89
+ if (!hasActiveConnections && !isExcluded) {
90
+ this.logger.trace('Sampled peer', {
91
+ attempts,
92
+ peer
93
+ });
94
+ return {
95
+ peer,
96
+ sampledPeers
97
+ };
98
+ }
99
+ // Keep track of peers that have active reqresp channels, batch sampling will use these to resample
100
+ sampledPeers.push(peer);
70
101
  }
71
- this.logger.trace(`Sampled peer in ${attempts} attempts`, {
72
- attempts,
73
- peer: peers[randomIndex]?.toString()
102
+ // If we've exhausted our attempts or peers list is empty, return the last peer if available
103
+ const lastPeer = peers.length > 0 ? peers[this.sampler.random(peers.length)] : undefined;
104
+ this.logger.trace('Sampled peer', {
105
+ attempts: MAX_SAMPLE_ATTEMPTS,
106
+ peer: lastPeer?.toString()
74
107
  });
75
- return peers[randomIndex];
108
+ return {
109
+ peer: lastPeer,
110
+ sampledPeers
111
+ };
76
112
  }
77
113
  /**
78
114
  * Samples a batch of unique peers from the libp2p node, prioritizing peers without active connections
@@ -81,30 +117,38 @@ export class RandomSampler {
81
117
  * @returns Array of unique sampled peers, prioritizing those without active connections
82
118
  */ samplePeersBatch(numberToSample) {
83
119
  const peers = this.libp2p.getPeers();
84
- const sampledPeers = [];
85
- const peersWithConnections = []; // Hold onto peers with active connections incase we need to sample more
86
- for (const peer of peers){
87
- const activeConnections = this.activeConnectionsCount.get(peer) ?? 0;
88
- if (activeConnections === 0) {
89
- if (sampledPeers.push(peer) === numberToSample) {
90
- return sampledPeers;
91
- }
92
- } else {
93
- peersWithConnections.push(peer);
120
+ this.logger.debug('Sampling peers batch', {
121
+ numberToSample,
122
+ peers
123
+ });
124
+ // Only sample as many peers as we have available
125
+ numberToSample = Math.min(numberToSample, peers.length);
126
+ const batch = [];
127
+ const withActiveConnections = new Set();
128
+ for(let i = 0; i < numberToSample; i++){
129
+ const { peer, sampledPeers } = this.getPeerFromList(peers, undefined);
130
+ if (peer) {
131
+ batch.push(peer);
132
+ }
133
+ if (sampledPeers.length > 0) {
134
+ sampledPeers.forEach((peer)=>withActiveConnections.add(peer));
94
135
  }
95
136
  }
137
+ const lengthWithoutConnections = batch.length;
96
138
  // If we still need more peers, sample from those with connections
97
- while(sampledPeers.length < numberToSample && peersWithConnections.length > 0){
98
- const randomIndex = this.sampler.random(peersWithConnections.length);
99
- const [peer] = peersWithConnections.splice(randomIndex, 1);
100
- sampledPeers.push(peer);
139
+ while(batch.length < numberToSample && withActiveConnections.size > 0){
140
+ const randomIndex = this.sampler.random(withActiveConnections.size);
141
+ const peer = Array.from(withActiveConnections)[randomIndex];
142
+ withActiveConnections.delete(peer);
143
+ batch.push(peer);
101
144
  }
102
- this.logger.trace(`Batch sampled ${sampledPeers.length} unique peers`, {
103
- peers: sampledPeers,
104
- withoutConnections: sampledPeers.length - peersWithConnections.length,
105
- withConnections: peersWithConnections.length
145
+ this.logger.trace('Batch sampled peers', {
146
+ length: batch.length,
147
+ peers: batch,
148
+ withoutConnections: lengthWithoutConnections,
149
+ withConnections: numberToSample - lengthWithoutConnections
106
150
  });
107
- return sampledPeers;
151
+ return batch;
108
152
  }
109
153
  // Set of passthrough functions to keep track of active connections
110
154
  /**
@@ -125,8 +169,9 @@ export class RandomSampler {
125
169
  });
126
170
  const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 0) + 1;
127
171
  this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
128
- this.logger.trace(`Dialed protocol ${protocol} with peer ${peerId.toString()}`, {
172
+ this.logger.trace('Dialed protocol', {
129
173
  streamId: stream.id,
174
+ protocol,
130
175
  peerId: peerId.toString(),
131
176
  activeConnectionsCount: updatedActiveConnectionsCount
132
177
  });
@@ -146,7 +191,7 @@ export class RandomSampler {
146
191
  const { stream, peerId } = streamAndPeerId;
147
192
  const updatedActiveConnectionsCount = (this.activeConnectionsCount.get(peerId) ?? 1) - 1;
148
193
  this.activeConnectionsCount.set(peerId, updatedActiveConnectionsCount);
149
- this.logger.trace(`Closing connection to peer ${peerId.toString()}`, {
194
+ this.logger.trace('Closing connection', {
150
195
  streamId,
151
196
  peerId: peerId.toString(),
152
197
  protocol: stream.protocol,
@@ -169,7 +214,10 @@ export class RandomSampler {
169
214
  // Check if we have lost track of accounting
170
215
  if (this.activeConnectionsCount.get(peerId) === 0) {
171
216
  await this.close(streamId);
172
- this.logger.debug(`Cleaned up stale connection ${streamId} to peer ${peerId.toString()}`);
217
+ this.logger.debug('Cleaned up stale connection', {
218
+ streamId,
219
+ peerId: peerId.toString()
220
+ });
173
221
  }
174
222
  } catch (error) {
175
223
  this.logger.error(`Error cleaning up stale connection ${streamId}`, {
@@ -95,7 +95,7 @@ export declare class ReqResp {
95
95
  *
96
96
  * @throws {CollectiveReqRespTimeoutError} - If the request batch exceeds the specified timeout (`timeoutMs`).
97
97
  */
98
- sendBatchRequest<SubProtocol extends ReqRespSubProtocol>(subProtocol: SubProtocol, requests: InstanceType<SubProtocolMap[SubProtocol]['request']>[], timeoutMs?: number, maxPeers?: number, maxRetryAttempts?: number): Promise<InstanceType<SubProtocolMap[SubProtocol]['response']>[]>;
98
+ sendBatchRequest<SubProtocol extends ReqRespSubProtocol>(subProtocol: SubProtocol, requests: InstanceType<SubProtocolMap[SubProtocol]['request']>[], timeoutMs?: number, maxPeers?: number, maxRetryAttempts?: number): Promise<(InstanceType<SubProtocolMap[SubProtocol]['response']> | undefined)[]>;
99
99
  /**
100
100
  * Sends a request to a specific peer
101
101
  *
@@ -120,7 +120,7 @@ export declare class ReqResp {
120
120
  * If the stream is not closed by the dialled peer, and a timeout occurs, then
121
121
  * the stream is closed on the requester's end and sender (us) updates its peer score
122
122
  */
123
- sendRequestToPeer(peerId: PeerId, subProtocol: ReqRespSubProtocol, payload: Buffer): Promise<ReqRespResponse | undefined>;
123
+ sendRequestToPeer(peerId: PeerId, subProtocol: ReqRespSubProtocol, payload: Buffer): Promise<ReqRespResponse>;
124
124
  /**
125
125
  * Handle a response error
126
126
  *
@@ -1 +1 @@
1
- {"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/reqresp.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAc,KAAK,eAAe,EAAiC,MAAM,yBAAyB,CAAC;AAE1G,OAAO,KAAK,EAAsB,MAAM,EAAU,MAAM,mBAAmB,CAAC;AAE5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AASrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAGL,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EAEpB,MAAM,gBAAgB,CAAC;AASxB;;;;;;;;;;;;;GAaG;AACH,qBAAa,OAAO;IAmBhB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAnBrB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,0BAA0B,CAAS;IAG3C,OAAO,CAAC,mBAAmB,CAA6D;IACxF,OAAO,CAAC,qBAAqB,CAAiE;IAE9F,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO,CAAC,eAAe,CAAkB;IAEzC,OAAO,CAAC,OAAO,CAAiB;gBAG9B,MAAM,EAAE,gBAAgB,EAChB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EAChC,eAAe,GAAE,eAAsC;IAgBzD,IAAI,MAAM,6CAET;IAED;;OAEG;IACG,KAAK,CAAC,mBAAmB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,4BAA4B;IAiBhH;;OAEG;IACG,IAAI;IAoBV;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;IA8D7E;;;;;;;;;;;;;;;;;;;;;OAqBG;IAQG,gBAAgB,CAAC,WAAW,SAAS,kBAAkB,EAC3D,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAChE,SAAS,SAAQ,EACjB,QAAQ,SAAgC,EACxC,gBAAgB,SAAI,GACnB,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;IA6HnE;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IAKU,iBAAiB,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAgCvC;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoDvB;;;;;;OAMG;YACW,WAAW;IAoCzB;;;;;;;;;;;;;;;OAeG;YAKW,aAAa;YAkEZ,cAAc;CAI9B"}
1
+ {"version":3,"file":"reqresp.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/reqresp.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAc,KAAK,eAAe,EAAiC,MAAM,yBAAyB,CAAC;AAE1G,OAAO,KAAK,EAAsB,MAAM,EAAU,MAAM,mBAAmB,CAAC;AAE5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AASrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,EAGL,KAAK,eAAe,EACpB,kBAAkB,EAClB,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EAEpB,MAAM,gBAAgB,CAAC;AASxB;;;;;;;;;;;;;GAaG;AACH,qBAAa,OAAO;IAmBhB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IAnBrB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,0BAA0B,CAAS;IAG3C,OAAO,CAAC,mBAAmB,CAA6D;IACxF,OAAO,CAAC,qBAAqB,CAAiE;IAE9F,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,WAAW,CAA6B;IAEhD,OAAO,CAAC,eAAe,CAAkB;IAEzC,OAAO,CAAC,OAAO,CAAiB;gBAG9B,MAAM,EAAE,gBAAgB,EAChB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,EAChC,eAAe,GAAE,eAAsC;IAgBzD,IAAI,MAAM,6CAET;IAED;;OAEG;IACG,KAAK,CAAC,mBAAmB,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,4BAA4B;IAiBhH;;OAEG;IACG,IAAI;IAoBV;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;IA8D7E;;;;;;;;;;;;;;;;;;;;;OAqBG;IAQG,gBAAgB,CAAC,WAAW,SAAS,kBAAkB,EAC3D,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAChE,SAAS,SAAQ,EACjB,QAAQ,SAAgC,EACxC,gBAAgB,SAAI,GACnB,OAAO,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;IA6HjF;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IAKU,iBAAiB,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC;IAsC3B;;;;;;;;;OASG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAoDvB;;;;;;OAMG;YACW,WAAW;IAoCzB;;;;;;;;;;;;;;;OAeG;YAKW,aAAa;YAkEZ,cAAc;CAI9B"}
@@ -140,7 +140,7 @@ import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqResp
140
140
  attemptedPeers.set(peer.toString(), true);
141
141
  this.logger.trace(`Sending request to peer: ${peer.toString()}`);
142
142
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffer);
143
- if (response && response.status !== ReqRespStatus.SUCCESS) {
143
+ if (response.status !== ReqRespStatus.SUCCESS) {
144
144
  this.logger.debug(`Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(response.status)}`);
145
145
  continue;
146
146
  }
@@ -232,7 +232,7 @@ import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqResp
232
232
  for (const index of indices){
233
233
  const response = await this.sendRequestToPeer(peer, subProtocol, requestBuffers[index]);
234
234
  // Check the status of the response buffer
235
- if (response && response.status !== ReqRespStatus.SUCCESS) {
235
+ if (response.status !== ReqRespStatus.SUCCESS) {
236
236
  this.logger.debug(`Request to peer ${peer.toString()} failed with status ${prettyPrintReqRespStatus(response.status)}`);
237
237
  // If we hit a rate limit or some failure, we remove the peer and return the results,
238
238
  // they will be split among remaining peers and the new sampled peer
@@ -325,6 +325,11 @@ import { ReqRespStatus, ReqRespStatusError, parseStatusChunk, prettyPrintReqResp
325
325
  } catch (e) {
326
326
  this.metrics.recordRequestError(subProtocol);
327
327
  this.handleResponseError(e, peerId, subProtocol);
328
+ // If there is an exception, we return an unknown response
329
+ return {
330
+ status: ReqRespStatus.FAILURE,
331
+ data: Buffer.from([])
332
+ };
328
333
  } finally{
329
334
  // Only close the stream if we created it
330
335
  if (stream) {
@@ -5,6 +5,7 @@ export declare enum ReqRespStatus {
5
5
  SUCCESS = 0,
6
6
  RATE_LIMIT_EXCEEDED = 1,
7
7
  BADLY_FORMED_REQUEST = 2,
8
+ FAILURE = 126,
8
9
  UNKNOWN = 127
9
10
  }
10
11
  export declare class ReqRespStatusError extends Error {
@@ -27,5 +28,5 @@ export declare function parseStatusChunk(chunk: Uint8Array): ReqRespStatus;
27
28
  * @param status
28
29
  * @returns
29
30
  */
30
- export declare function prettyPrintReqRespStatus(status: ReqRespStatus): "SUCCESS" | "RATE_LIMIT_EXCEEDED" | "BADLY_FORMED_REQUEST" | "UNKNOWN";
31
+ export declare function prettyPrintReqRespStatus(status: ReqRespStatus): "SUCCESS" | "RATE_LIMIT_EXCEEDED" | "BADLY_FORMED_REQUEST" | "FAILURE" | "UNKNOWN";
31
32
  //# sourceMappingURL=status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,aAAa;IACvB,OAAO,IAAI;IACX,mBAAmB,IAAI;IACvB,oBAAoB,IAAI;IACxB,OAAO,MAAM;CACd;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;gBAEV,MAAM,EAAE,aAAa;CAIlC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAWjE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,0EAW7D"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/services/reqresp/status.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,aAAa;IACvB,OAAO,IAAI;IACX,mBAAmB,IAAI;IACvB,oBAAoB,IAAI;IACxB,OAAO,MAAM;IACb,OAAO,MAAM;CACd;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C;;OAEG;IACH,MAAM,EAAE,aAAa,CAAC;gBAEV,MAAM,EAAE,aAAa;CAIlC;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,CAWjE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,aAAa,sFAa7D"}
@@ -4,6 +4,7 @@
4
4
  ReqRespStatus[ReqRespStatus["SUCCESS"] = 0] = "SUCCESS";
5
5
  ReqRespStatus[ReqRespStatus["RATE_LIMIT_EXCEEDED"] = 1] = "RATE_LIMIT_EXCEEDED";
6
6
  ReqRespStatus[ReqRespStatus["BADLY_FORMED_REQUEST"] = 2] = "BADLY_FORMED_REQUEST";
7
+ ReqRespStatus[ReqRespStatus["FAILURE"] = 126] = "FAILURE";
7
8
  ReqRespStatus[ReqRespStatus["UNKNOWN"] = 127] = "UNKNOWN";
8
9
  return ReqRespStatus;
9
10
  }({});
@@ -45,6 +46,8 @@ export class ReqRespStatusError extends Error {
45
46
  return 'RATE_LIMIT_EXCEEDED';
46
47
  case 2:
47
48
  return 'BADLY_FORMED_REQUEST';
49
+ case 126:
50
+ return 'FAILURE';
48
51
  case 127:
49
52
  return 'UNKNOWN';
50
53
  }
@@ -43,7 +43,7 @@ export interface P2PService {
43
43
  * @param requests - The requests to send to the peers
44
44
  * @returns The responses to the requests
45
45
  */
46
- sendBatchRequest<Protocol extends ReqRespSubProtocol>(protocol: Protocol, requests: InstanceType<SubProtocolMap[Protocol]['request']>[]): Promise<InstanceType<SubProtocolMap[Protocol]['response']>[] | undefined>;
46
+ sendBatchRequest<Protocol extends ReqRespSubProtocol>(protocol: Protocol, requests: InstanceType<SubProtocolMap[Protocol]['request']>[]): Promise<(InstanceType<SubProtocolMap[Protocol]['response']> | undefined)[]>;
47
47
  registerBlockReceivedCallback(callback: (block: BlockProposal) => Promise<BlockAttestation | undefined>): void;
48
48
  getEnr(): ENR | undefined;
49
49
  getPeers(includePending?: boolean): PeerInfo[];
@@ -61,10 +61,10 @@ export interface PeerDiscoveryService extends EventEmitter {
61
61
  * */
62
62
  stop(): Promise<void>;
63
63
  /**
64
- * Gets all peers.
65
- * @returns An array of peer ENRs.
64
+ * Gets all KadValues.
65
+ * @returns An array of ENRs.
66
66
  */
67
- getAllPeers(): ENR[];
67
+ getKadValues(): ENR[];
68
68
  /**
69
69
  * Runs findRandomNode query.
70
70
  */
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAErF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEjF,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAElD;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,SAAS,kBAAkB,EAC7C,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,gBAAgB,CAAC,QAAQ,SAAS,kBAAkB,EAClD,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAC5D,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC;IAG7E,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;IAE/G,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;IAE1B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;SAEK;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;SAEK;IACL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,IAAI,GAAG,EAAE,CAAC;IAErB;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;IAElD,SAAS,IAAI,kBAAkB,CAAC;IAEhC,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;IAE1B,iBAAiB,EAAE,GAAG,EAAE,CAAC;CAC1B"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAErF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEjF,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAElD;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,SAAS,kBAAkB,EAC7C,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAE3E;;;;;;OAMG;IACH,gBAAgB,CAAC,QAAQ,SAAS,kBAAkB,EAClD,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAC5D,OAAO,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;IAG/E,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;IAE/G,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;IAE1B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;SAEK;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;SAEK;IACL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,YAAY,IAAI,GAAG,EAAE,CAAC;IAEtB;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;IAElD,SAAS,IAAI,kBAAkB,CAAC;IAEhC,MAAM,IAAI,GAAG,GAAG,SAAS,CAAC;IAE1B,iBAAiB,EAAE,GAAG,EAAE,CAAC;CAC1B"}
@@ -31,6 +31,11 @@ export declare function makeTestP2PClient(peerIdPrivateKey: string, port: number
31
31
  * @param options - The options for the clients.
32
32
  * @returns The created clients.
33
33
  */
34
- export declare function makeTestP2PClients(numberOfPeers: number, testConfig: MakeTestP2PClientOptions): Promise<P2PClient<P2PClientType.Full>[]>;
34
+ export declare function makeTestP2PClients(numberOfPeers: number, testConfig: MakeTestP2PClientOptions): Promise<{
35
+ client: P2PClient<P2PClientType.Full>;
36
+ peerPrivateKey: string;
37
+ port: number;
38
+ enr: string;
39
+ }[]>;
35
40
  export {};
36
41
  //# sourceMappingURL=make-test-p2p-clients.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"make-test-p2p-clients.d.ts","sourceRoot":"","sources":["../../src/test-helpers/make-test-p2p-clients.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACzF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAM5D,UAAU,wBAAwB;IAChC,mBAAmB,EAAE,eAAe,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,sBAAsB,CAAC;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,EAAE,SAAS,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,EACE,kBAAyB,EACzB,aAAa,EACb,kBAAuB,EACvB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,cAAc,EACd,MAAwC,GACzC,EAAE,wBAAwB,0CAyC5B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB,4CAiBnG"}
1
+ {"version":3,"file":"make-test-p2p-clients.d.ts","sourceRoot":"","sources":["../../src/test-helpers/make-test-p2p-clients.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAIlE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AACzF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAM5D,UAAU,wBAAwB;IAChC,mBAAmB,EAAE,eAAe,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,UAAU,CAAC;IAC3B,cAAc,EAAE,sBAAsB,CAAC;IACvC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,EAAE,SAAS,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EAAE,EACf,EACE,kBAAyB,EACzB,aAAa,EACb,kBAAuB,EACvB,mBAAmB,EACnB,UAAU,EACV,cAAc,EACd,cAAc,EACd,MAAwC,GACzC,EAAE,wBAAwB,0CA0C5B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,wBAAwB;;;;;KAiCnG"}