@aztec/p2p 0.56.0 → 0.58.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 (109) hide show
  1. package/dest/client/index.d.ts +6 -3
  2. package/dest/client/index.d.ts.map +1 -1
  3. package/dest/client/index.js +12 -6
  4. package/dest/client/p2p_client.d.ts +30 -12
  5. package/dest/client/p2p_client.d.ts.map +1 -1
  6. package/dest/client/p2p_client.js +375 -335
  7. package/dest/config.js +3 -3
  8. package/dest/index.d.ts +4 -3
  9. package/dest/index.d.ts.map +1 -1
  10. package/dest/index.js +5 -4
  11. package/dest/{attestation_pool → mem_pools/attestation_pool}/attestation_pool.d.ts +2 -1
  12. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -0
  13. package/dest/{attestation_pool → mem_pools/attestation_pool}/attestation_pool.js +1 -1
  14. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -0
  15. package/dest/{attestation_pool → mem_pools/attestation_pool}/index.js +1 -1
  16. package/dest/{attestation_pool → mem_pools/attestation_pool}/memory_attestation_pool.d.ts +6 -2
  17. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -0
  18. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +114 -0
  19. package/dest/{attestation_pool → mem_pools/attestation_pool}/mocks.d.ts +2 -1
  20. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -0
  21. package/dest/mem_pools/attestation_pool/mocks.js +31 -0
  22. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts +7 -0
  23. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts.map +1 -0
  24. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js +2 -0
  25. package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts +4 -0
  26. package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts.map +1 -0
  27. package/dest/mem_pools/epoch_proof_quote_pool/index.js +4 -0
  28. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts +12 -0
  29. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts.map +1 -0
  30. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js +30 -0
  31. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts +8 -0
  32. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts.map +1 -0
  33. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.js +21 -0
  34. package/dest/mem_pools/index.d.ts +5 -0
  35. package/dest/mem_pools/index.d.ts.map +1 -0
  36. package/dest/mem_pools/index.js +2 -0
  37. package/dest/mem_pools/instrumentation.d.ts +25 -0
  38. package/dest/mem_pools/instrumentation.d.ts.map +1 -0
  39. package/dest/mem_pools/instrumentation.js +70 -0
  40. package/dest/mem_pools/interface.d.ts +12 -0
  41. package/dest/mem_pools/interface.d.ts.map +1 -0
  42. package/dest/mem_pools/interface.js +2 -0
  43. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -0
  44. package/dest/{tx_pool → mem_pools/tx_pool}/aztec_kv_tx_pool.js +9 -9
  45. package/dest/mem_pools/tx_pool/index.d.ts.map +1 -0
  46. package/dest/{tx_pool → mem_pools/tx_pool}/index.js +1 -1
  47. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -0
  48. package/dest/mem_pools/tx_pool/memory_tx_pool.js +111 -0
  49. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -0
  50. package/dest/{tx_pool → mem_pools/tx_pool}/tx_pool.js +1 -1
  51. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -0
  52. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +55 -0
  53. package/dest/service/libp2p_service.d.ts +12 -7
  54. package/dest/service/libp2p_service.d.ts.map +1 -1
  55. package/dest/service/libp2p_service.js +453 -381
  56. package/dest/service/reqresp/reqresp.d.ts +0 -1
  57. package/dest/service/reqresp/reqresp.d.ts.map +1 -1
  58. package/dest/service/reqresp/reqresp.js +7 -4
  59. package/package.json +10 -6
  60. package/src/client/index.ts +21 -8
  61. package/src/client/p2p_client.ts +77 -21
  62. package/src/config.ts +2 -2
  63. package/src/index.ts +4 -3
  64. package/src/{attestation_pool → mem_pools/attestation_pool}/attestation_pool.ts +2 -1
  65. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -0
  66. package/src/{attestation_pool → mem_pools/attestation_pool}/mocks.ts +5 -2
  67. package/src/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.ts +7 -0
  68. package/src/mem_pools/epoch_proof_quote_pool/index.ts +3 -0
  69. package/src/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.ts +42 -0
  70. package/src/mem_pools/epoch_proof_quote_pool/test_utils.ts +26 -0
  71. package/src/mem_pools/index.ts +4 -0
  72. package/src/mem_pools/instrumentation.ts +85 -0
  73. package/src/mem_pools/interface.ts +12 -0
  74. package/src/{tx_pool → mem_pools/tx_pool}/aztec_kv_tx_pool.ts +9 -9
  75. package/src/{tx_pool → mem_pools/tx_pool}/memory_tx_pool.ts +9 -9
  76. package/src/service/libp2p_service.ts +78 -20
  77. package/src/service/reqresp/reqresp.ts +9 -5
  78. package/dest/attestation_pool/attestation_pool.d.ts.map +0 -1
  79. package/dest/attestation_pool/index.d.ts.map +0 -1
  80. package/dest/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  81. package/dest/attestation_pool/memory_attestation_pool.js +0 -57
  82. package/dest/attestation_pool/mocks.d.ts.map +0 -1
  83. package/dest/attestation_pool/mocks.js +0 -32
  84. package/dest/client/mocks.d.ts +0 -65
  85. package/dest/client/mocks.d.ts.map +0 -1
  86. package/dest/client/mocks.js +0 -106
  87. package/dest/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  88. package/dest/tx_pool/index.d.ts.map +0 -1
  89. package/dest/tx_pool/instrumentation.d.ts +0 -25
  90. package/dest/tx_pool/instrumentation.d.ts.map +0 -1
  91. package/dest/tx_pool/instrumentation.js +0 -61
  92. package/dest/tx_pool/memory_tx_pool.d.ts.map +0 -1
  93. package/dest/tx_pool/memory_tx_pool.js +0 -111
  94. package/dest/tx_pool/tx_pool.d.ts.map +0 -1
  95. package/dest/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  96. package/dest/tx_pool/tx_pool_test_suite.js +0 -55
  97. package/src/attestation_pool/memory_attestation_pool.ts +0 -71
  98. package/src/client/mocks.ts +0 -129
  99. package/src/tx_pool/instrumentation.ts +0 -73
  100. /package/dest/{attestation_pool → mem_pools/attestation_pool}/index.d.ts +0 -0
  101. /package/dest/{tx_pool → mem_pools/tx_pool}/aztec_kv_tx_pool.d.ts +0 -0
  102. /package/dest/{tx_pool → mem_pools/tx_pool}/index.d.ts +0 -0
  103. /package/dest/{tx_pool → mem_pools/tx_pool}/memory_tx_pool.d.ts +0 -0
  104. /package/dest/{tx_pool → mem_pools/tx_pool}/tx_pool.d.ts +0 -0
  105. /package/dest/{tx_pool → mem_pools/tx_pool}/tx_pool_test_suite.d.ts +0 -0
  106. /package/src/{attestation_pool → mem_pools/attestation_pool}/index.ts +0 -0
  107. /package/src/{tx_pool → mem_pools/tx_pool}/index.ts +0 -0
  108. /package/src/{tx_pool → mem_pools/tx_pool}/tx_pool.ts +0 -0
  109. /package/src/{tx_pool → mem_pools/tx_pool}/tx_pool_test_suite.ts +0 -0
@@ -20,7 +20,6 @@ export declare class ReqResp {
20
20
  protected readonly libp2p: Libp2p;
21
21
  private peerManager;
22
22
  protected readonly logger: Logger;
23
- private abortController;
24
23
  private overallRequestTimeoutMs;
25
24
  private individualRequestTimeoutMs;
26
25
  private subProtocolHandlers;
@@ -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,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"}
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;IAYoB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAE,OAAO,CAAC,WAAW;IAX5F,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,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;IAiBV;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;IAmC9B;;OAEG;YACW,WAAW;IASzB;;;;;;;;;;;;;;;OAeG;YACW,aAAa;CA6B5B"}
@@ -21,7 +21,6 @@ export class ReqResp {
21
21
  constructor(config, libp2p, peerManager) {
22
22
  this.libp2p = libp2p;
23
23
  this.peerManager = peerManager;
24
- this.abortController = new AbortController();
25
24
  // Warning, if the `start` function is not called as the parent class constructor, then the default sub protocol handlers will be used ( not good )
26
25
  this.subProtocolHandlers = DEFAULT_SUB_PROTOCOL_HANDLERS;
27
26
  this.subProtocolValidators = DEFAULT_SUB_PROTOCOL_VALIDATORS;
@@ -50,9 +49,13 @@ export class ReqResp {
50
49
  for (const protocol of Object.keys(this.subProtocolHandlers)) {
51
50
  await this.libp2p.unhandle(protocol);
52
51
  }
52
+ // Close all active connections
53
+ const closeStreamPromises = this.libp2p.getConnections().map(connection => connection.close());
54
+ await Promise.all(closeStreamPromises);
55
+ this.logger.debug('ReqResp: All active streams closed');
53
56
  this.rateLimiter.stop();
54
- await this.libp2p.stop();
55
- this.abortController.abort();
57
+ this.logger.debug('ReqResp: Rate limiter stopped');
58
+ // NOTE: We assume libp2p instance is managed by the caller
56
59
  }
57
60
  /**
58
61
  * Send a request to peers, returns the first response
@@ -219,4 +222,4 @@ export class ReqResp {
219
222
  }
220
223
  }
221
224
  }
222
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlL3JlcXJlc3AvcmVxcmVzcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4Q0FBOEM7QUFDOUMsT0FBTyxFQUFlLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdkUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHeEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUkvQixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU1RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV2RCxPQUFPLEVBQ0wsNkJBQTZCLEVBQzdCLCtCQUErQixFQUsvQixjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU1RTs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLE9BQU87SUFjbEIsWUFBWSxNQUF3QixFQUFxQixNQUFjLEVBQVUsV0FBd0I7UUFBaEQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUFVLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBWGpHLG9CQUFlLEdBQW9CLElBQUksZUFBZSxFQUFFLENBQUM7UUFLakUsbUpBQW1KO1FBQzNJLHdCQUFtQixHQUErQiw2QkFBNkIsQ0FBQztRQUNoRiwwQkFBcUIsR0FBaUMsK0JBQStCLENBQUM7UUFLNUYsSUFBSSxDQUFDLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBRXJELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxNQUFNLENBQUMsdUJBQXVCLENBQUM7UUFDOUQsSUFBSSxDQUFDLDBCQUEwQixHQUFHLE1BQU0sQ0FBQywwQkFBMEIsQ0FBQztRQUVwRSxJQUFJLENBQUMs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
225
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxcmVzcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlL3JlcXJlc3AvcmVxcmVzcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSw4Q0FBOEM7QUFDOUMsT0FBTyxFQUFlLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDdkUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHeEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUkvQixPQUFPLEVBQUUsNkJBQTZCLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUU1RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUV2RCxPQUFPLEVBQ0wsNkJBQTZCLEVBQzdCLCtCQUErQixFQUsvQixjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU1RTs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLE9BQU87SUFZbEIsWUFBWSxNQUF3QixFQUFxQixNQUFjLEVBQVUsV0FBd0I7UUFBaEQsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUFVLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBTnpHLG1KQUFtSjtRQUMzSSx3QkFBbUIsR0FBK0IsNkJBQTZCLENBQUM7UUFDaEYsMEJBQXFCLEdBQWlDLCtCQUErQixDQUFDO1FBSzVGLElBQUksQ0FBQyxNQUFNLEdBQUcsaUJBQWlCLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUVyRCxJQUFJLENBQUMsdUJBQXVCLEdBQUcsTUFBTSxDQUFDLHVCQUF1QixDQUFDO1FBQzlELElBQUksQ0FBQywwQkFBMEIsR0FBRyxNQUFNLENBQUMsMEJBQTBCLENBQUM7UUFFcEUsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLDBCQUEwQixDQUFDLFdBQVcsQ0FBQyxD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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.56.0",
3
+ "version": "0.58.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -37,6 +37,9 @@
37
37
  "parser": {
38
38
  "syntax": "typescript",
39
39
  "decorators": true
40
+ },
41
+ "transform": {
42
+ "decoratorVersion": "2022-03"
40
43
  }
41
44
  }
42
45
  }
@@ -56,11 +59,11 @@
56
59
  "testTimeout": 15000
57
60
  },
58
61
  "dependencies": {
59
- "@aztec/circuit-types": "0.56.0",
60
- "@aztec/circuits.js": "0.56.0",
61
- "@aztec/foundation": "0.56.0",
62
- "@aztec/kv-store": "0.56.0",
63
- "@aztec/telemetry-client": "0.56.0",
62
+ "@aztec/circuit-types": "0.58.0",
63
+ "@aztec/circuits.js": "0.58.0",
64
+ "@aztec/foundation": "0.58.0",
65
+ "@aztec/kv-store": "0.58.0",
66
+ "@aztec/telemetry-client": "0.58.0",
64
67
  "@chainsafe/discv5": "9.0.0",
65
68
  "@chainsafe/enr": "3.0.0",
66
69
  "@chainsafe/libp2p-gossipsub": "13.0.0",
@@ -86,6 +89,7 @@
86
89
  "tslib": "^2.4.0"
87
90
  },
88
91
  "devDependencies": {
92
+ "@aztec/archiver": "workspace:^",
89
93
  "@jest/globals": "^29.5.0",
90
94
  "@types/jest": "^29.5.0",
91
95
  "@types/node": "^18.14.6",
@@ -5,29 +5,42 @@ import { type DataStoreConfig, createStore } from '@aztec/kv-store/utils';
5
5
  import { type TelemetryClient } from '@aztec/telemetry-client';
6
6
  import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
7
7
 
8
- import { type AttestationPool } from '../attestation_pool/attestation_pool.js';
9
8
  import { P2PClient } from '../client/p2p_client.js';
10
9
  import { type P2PConfig } from '../config.js';
10
+ import { type AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js';
11
+ import { InMemoryAttestationPool } from '../mem_pools/attestation_pool/memory_attestation_pool.js';
12
+ import { type EpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js';
13
+ import { MemoryEpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js';
14
+ import { type MemPools } from '../mem_pools/interface.js';
15
+ import { AztecKVTxPool, type TxPool } from '../mem_pools/tx_pool/index.js';
11
16
  import { DiscV5Service } from '../service/discV5_service.js';
12
17
  import { DummyP2PService } from '../service/dummy_service.js';
13
18
  import { LibP2PService, createLibP2PPeerId } from '../service/index.js';
14
- import { AztecKVTxPool, type TxPool } from '../tx_pool/index.js';
15
19
  import { getPublicIp, resolveAddressIfNecessary, splitAddressPort } from '../util.js';
16
20
 
17
21
  export * from './p2p_client.js';
18
22
 
19
23
  export const createP2PClient = async (
20
24
  _config: P2PConfig & DataStoreConfig,
21
- attestationsPool: AttestationPool,
22
25
  l2BlockSource: L2BlockSource,
23
26
  proofVerifier: ClientProtocolCircuitVerifier,
24
27
  worldStateSynchronizer: WorldStateSynchronizer,
25
28
  telemetry: TelemetryClient = new NoopTelemetryClient(),
26
- deps: { txPool?: TxPool; store?: AztecKVStore } = {},
29
+ deps: {
30
+ txPool?: TxPool;
31
+ store?: AztecKVStore;
32
+ attestationPool?: AttestationPool;
33
+ epochProofQuotePool?: EpochProofQuotePool;
34
+ } = {},
27
35
  ) => {
28
36
  let config = { ..._config };
29
37
  const store = deps.store ?? (await createStore('p2p', config, createDebugLogger('aztec:p2p:lmdb')));
30
- const txPool = deps.txPool ?? new AztecKVTxPool(store, telemetry);
38
+
39
+ const mempools: MemPools = {
40
+ txPool: deps.txPool ?? new AztecKVTxPool(store, telemetry),
41
+ attestationPool: deps.attestationPool ?? new InMemoryAttestationPool(telemetry),
42
+ epochProofQuotePool: deps.epochProofQuotePool ?? new MemoryEpochProofQuotePool(telemetry),
43
+ };
31
44
 
32
45
  let p2pService;
33
46
 
@@ -42,17 +55,17 @@ export const createP2PClient = async (
42
55
  config,
43
56
  discoveryService,
44
57
  peerId,
45
- txPool,
46
- attestationsPool,
58
+ mempools,
47
59
  l2BlockSource,
48
60
  proofVerifier,
49
61
  worldStateSynchronizer,
50
62
  store,
63
+ telemetry,
51
64
  );
52
65
  } else {
53
66
  p2pService = new DummyP2PService();
54
67
  }
55
- return new P2PClient(store, l2BlockSource, txPool, attestationsPool, p2pService, config.keepProvenTxsInPoolFor);
68
+ return new P2PClient(store, l2BlockSource, mempools, p2pService, config.keepProvenTxsInPoolFor, telemetry);
56
69
  };
57
70
 
58
71
  async function configureP2PClientAddresses(_config: P2PConfig & DataStoreConfig): Promise<P2PConfig & DataStoreConfig> {
@@ -1,8 +1,10 @@
1
1
  import {
2
2
  type BlockAttestation,
3
3
  type BlockProposal,
4
+ type EpochProofQuote,
4
5
  type L2Block,
5
6
  L2BlockDownloader,
7
+ type L2BlockId,
6
8
  type L2BlockSource,
7
9
  type Tx,
8
10
  type TxHash,
@@ -10,14 +12,17 @@ import {
10
12
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
11
13
  import { createDebugLogger } from '@aztec/foundation/log';
12
14
  import { type AztecKVStore, type AztecSingleton } from '@aztec/kv-store';
15
+ import { Attributes, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
13
16
 
14
17
  import { type ENR } from '@chainsafe/enr';
15
18
 
16
- import { type AttestationPool } from '../attestation_pool/attestation_pool.js';
17
19
  import { getP2PConfigEnvVars } from '../config.js';
20
+ import { type AttestationPool } from '../mem_pools/attestation_pool/attestation_pool.js';
21
+ import { type EpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js';
22
+ import { type MemPools } from '../mem_pools/interface.js';
23
+ import { type TxPool } from '../mem_pools/tx_pool/index.js';
18
24
  import { TX_REQ_PROTOCOL } from '../service/reqresp/interface.js';
19
25
  import type { P2PService } from '../service/service.js';
20
- import { type TxPool } from '../tx_pool/index.js';
21
26
 
22
27
  /**
23
28
  * Enum defining the possible states of the p2p client.
@@ -40,7 +45,7 @@ export interface P2PSyncState {
40
45
  /**
41
46
  * The block number that the p2p client is synced to.
42
47
  */
43
- syncedToL2Block: number;
48
+ syncedToL2Block: L2BlockId;
44
49
  }
45
50
 
46
51
  /**
@@ -58,9 +63,25 @@ export interface P2P {
58
63
  * Queries the Attestation pool for attestations for the given slot
59
64
  *
60
65
  * @param slot - the slot to query
66
+ * @param proposalId - the proposal id to query
61
67
  * @returns BlockAttestations
62
68
  */
63
- getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]>;
69
+ getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]>;
70
+
71
+ /**
72
+ * Queries the EpochProofQuote pool for quotes for the given epoch
73
+ *
74
+ * @param epoch - the epoch to query
75
+ * @returns EpochProofQuotes
76
+ */
77
+ getEpochProofQuotes(epoch: bigint): Promise<EpochProofQuote[]>;
78
+
79
+ /**
80
+ * Broadcasts an EpochProofQuote to other peers.
81
+ *
82
+ * @param quote - the quote to broadcast
83
+ */
84
+ broadcastEpochProofQuote(quote: EpochProofQuote): void;
64
85
 
65
86
  /**
66
87
  * Registers a callback from the validator client that determines how to behave when
@@ -134,7 +155,7 @@ export interface P2P {
134
155
  * Indicates if the p2p client is ready for transaction submission.
135
156
  * @returns A boolean flag indicating readiness.
136
157
  */
137
- isReady(): Promise<boolean>;
158
+ isReady(): boolean;
138
159
 
139
160
  /**
140
161
  * Returns the current status of the p2p client.
@@ -150,7 +171,7 @@ export interface P2P {
150
171
  /**
151
172
  * The P2P client implementation.
152
173
  */
153
- export class P2PClient implements P2P {
174
+ export class P2PClient extends WithTracer implements P2P {
154
175
  /** L2 block download to stay in sync with latest blocks. */
155
176
  private latestBlockDownloader: L2BlockDownloader;
156
177
 
@@ -172,6 +193,10 @@ export class P2PClient implements P2P {
172
193
  private synchedLatestBlockNumber: AztecSingleton<number>;
173
194
  private synchedProvenBlockNumber: AztecSingleton<number>;
174
195
 
196
+ private txPool: TxPool;
197
+ private attestationPool: AttestationPool;
198
+ private epochProofQuotePool: EpochProofQuotePool;
199
+
175
200
  /**
176
201
  * In-memory P2P client constructor.
177
202
  * @param store - The client's instance of the KV store.
@@ -184,12 +209,14 @@ export class P2PClient implements P2P {
184
209
  constructor(
185
210
  store: AztecKVStore,
186
211
  private l2BlockSource: L2BlockSource,
187
- private txPool: TxPool,
188
- private attestationPool: AttestationPool,
212
+ mempools: MemPools,
189
213
  private p2pService: P2PService,
190
214
  private keepProvenTxsFor: number,
215
+ telemetryClient: TelemetryClient,
191
216
  private log = createDebugLogger('aztec:p2p'),
192
217
  ) {
218
+ super(telemetryClient, 'P2PClient');
219
+
193
220
  const { blockCheckIntervalMS: checkInterval, l2QueueSize: p2pL2QueueSize } = getP2PConfigEnvVars();
194
221
  const l2DownloaderOpts = { maxQueueSize: p2pL2QueueSize, pollIntervalMS: checkInterval };
195
222
  // TODO(palla/prover-node): This effectively downloads blocks twice from the archiver, which is an issue
@@ -200,6 +227,26 @@ export class P2PClient implements P2P {
200
227
 
201
228
  this.synchedLatestBlockNumber = store.openSingleton('p2p_pool_last_l2_block');
202
229
  this.synchedProvenBlockNumber = store.openSingleton('p2p_pool_last_proven_l2_block');
230
+
231
+ this.txPool = mempools.txPool;
232
+ this.attestationPool = mempools.attestationPool;
233
+ this.epochProofQuotePool = mempools.epochProofQuotePool;
234
+ }
235
+
236
+ #assertIsReady() {
237
+ if (!this.isReady()) {
238
+ throw new Error('P2P client not ready');
239
+ }
240
+ }
241
+
242
+ getEpochProofQuotes(epoch: bigint): Promise<EpochProofQuote[]> {
243
+ return Promise.resolve(this.epochProofQuotePool.getQuotes(epoch));
244
+ }
245
+
246
+ broadcastEpochProofQuote(quote: EpochProofQuote): void {
247
+ this.#assertIsReady();
248
+ this.epochProofQuotePool.addQuote(quote);
249
+ return this.p2pService.propagate(quote);
203
250
  }
204
251
 
205
252
  /**
@@ -276,13 +323,19 @@ export class P2PClient implements P2P {
276
323
  this.log.info('P2P client stopped.');
277
324
  }
278
325
 
326
+ @trackSpan('p2pClient.broadcastProposal', proposal => ({
327
+ [Attributes.BLOCK_NUMBER]: proposal.payload.header.globalVariables.blockNumber.toNumber(),
328
+ [Attributes.SLOT_NUMBER]: proposal.payload.header.globalVariables.slotNumber.toNumber(),
329
+ [Attributes.BLOCK_ARCHIVE]: proposal.archive.toString(),
330
+ [Attributes.P2P_ID]: proposal.p2pMessageIdentifier().toString(),
331
+ }))
279
332
  public broadcastProposal(proposal: BlockProposal): void {
280
333
  this.log.verbose(`Broadcasting proposal ${proposal.p2pMessageIdentifier()} to peers`);
281
334
  return this.p2pService.propagate(proposal);
282
335
  }
283
336
 
284
- public getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]> {
285
- return Promise.resolve(this.attestationPool.getAttestationsForSlot(slot));
337
+ public getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]> {
338
+ return Promise.resolve(this.attestationPool.getAttestationsForSlot(slot, proposalId));
286
339
  }
287
340
 
288
341
  // REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
@@ -363,10 +416,7 @@ export class P2PClient implements P2P {
363
416
  * @returns Empty promise.
364
417
  **/
365
418
  public async sendTx(tx: Tx): Promise<void> {
366
- const ready = await this.isReady();
367
- if (!ready) {
368
- throw new Error('P2P client not ready');
369
- }
419
+ this.#assertIsReady();
370
420
  await this.txPool.addTxs([tx]);
371
421
  this.p2pService.propagate(tx);
372
422
  }
@@ -391,10 +441,7 @@ export class P2PClient implements P2P {
391
441
  * @returns Empty promise.
392
442
  **/
393
443
  public async deleteTxs(txHashes: TxHash[]): Promise<void> {
394
- const ready = await this.isReady();
395
- if (!ready) {
396
- throw new Error('P2P client not ready');
397
- }
444
+ this.#assertIsReady();
398
445
  await this.txPool.deleteTxs(txHashes);
399
446
  }
400
447
 
@@ -403,7 +450,7 @@ export class P2PClient implements P2P {
403
450
  * @returns True if the P2P client is ready to receive txs.
404
451
  */
405
452
  public isReady() {
406
- return Promise.resolve(this.currentState === P2PClientState.RUNNING);
453
+ return this.currentState === P2PClientState.RUNNING;
407
454
  }
408
455
 
409
456
  /**
@@ -426,10 +473,15 @@ export class P2PClient implements P2P {
426
473
  * Method to check the status the p2p client.
427
474
  * @returns Information about p2p client status: state & syncedToBlockNum.
428
475
  */
429
- public getStatus(): Promise<P2PSyncState> {
476
+ public async getStatus(): Promise<P2PSyncState> {
477
+ const blockNumber = this.getSyncedLatestBlockNum();
478
+ const blockHash =
479
+ blockNumber == 0
480
+ ? ''
481
+ : await this.l2BlockSource.getBlockHeader(blockNumber).then(header => header?.hash().toString());
430
482
  return Promise.resolve({
431
483
  state: this.currentState,
432
- syncedToL2Block: this.getSyncedLatestBlockNum(),
484
+ syncedToL2Block: { number: blockNumber, hash: blockHash },
433
485
  } as P2PSyncState);
434
486
  }
435
487
 
@@ -499,6 +551,10 @@ export class P2PClient implements P2P {
499
551
 
500
552
  await this.synchedProvenBlockNumber.set(lastBlockNum);
501
553
  this.log.debug(`Synched to proven block ${lastBlockNum}`);
554
+ const provenEpochNumber = await this.l2BlockSource.getProvenL2EpochNumber();
555
+ if (provenEpochNumber !== undefined) {
556
+ this.epochProofQuotePool.deleteQuotesToEpoch(BigInt(provenEpochNumber));
557
+ }
502
558
  await this.startServiceIfSynched();
503
559
  }
504
560
 
package/src/config.ts CHANGED
@@ -174,12 +174,12 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
174
174
  ...numberConfigHelper(1_000),
175
175
  },
176
176
  tcpListenAddress: {
177
- env: 'TCP_LISTEN_ADDR',
177
+ env: 'P2P_TCP_LISTEN_ADDR',
178
178
  defaultValue: '0.0.0.0:40400',
179
179
  description: 'The listen address for TCP. Format: <IP_ADDRESS>:<PORT>.',
180
180
  },
181
181
  udpListenAddress: {
182
- env: 'UDP_LISTEN_ADDR',
182
+ env: 'P2P_UDP_LISTEN_ADDR',
183
183
  defaultValue: '0.0.0.0:40400',
184
184
  description: 'The listen address for UDP. Format: <IP_ADDRESS>:<PORT>.',
185
185
  },
package/src/index.ts CHANGED
@@ -1,7 +1,8 @@
1
+ export * from './mem_pools/attestation_pool/index.js';
2
+ export * from './bootstrap/bootstrap.js';
1
3
  export * from './client/index.js';
2
4
  export * from './config.js';
3
- export * from './tx_pool/index.js';
4
- export * from './attestation_pool/index.js';
5
+ export * from './mem_pools/epoch_proof_quote_pool/index.js';
5
6
  export * from './service/index.js';
6
- export * from './bootstrap/bootstrap.js';
7
+ export * from './mem_pools/tx_pool/index.js';
7
8
  export * from './tx_validator/index.js';
@@ -36,7 +36,8 @@ export interface AttestationPool {
36
36
  * Retrieve all of the attestations observed pertaining to a given slot
37
37
  *
38
38
  * @param slot - The slot to query
39
+ * @param proposalId - The proposal to query
39
40
  * @return BlockAttestations
40
41
  */
41
- getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]>;
42
+ getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]>;
42
43
  }
@@ -0,0 +1,141 @@
1
+ import { type BlockAttestation } from '@aztec/circuit-types';
2
+ import { createDebugLogger } from '@aztec/foundation/log';
3
+ import { type TelemetryClient } from '@aztec/telemetry-client';
4
+ import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
5
+
6
+ import { PoolInstrumentation } from '../instrumentation.js';
7
+ import { type AttestationPool } from './attestation_pool.js';
8
+
9
+ export class InMemoryAttestationPool implements AttestationPool {
10
+ private metrics: PoolInstrumentation<BlockAttestation>;
11
+
12
+ private attestations: Map</*slot=*/ bigint, Map</*proposalId*/ string, Map</*address=*/ string, BlockAttestation>>>;
13
+
14
+ constructor(_telemetry: TelemetryClient, private log = createDebugLogger('aztec:attestation_pool')) {
15
+ this.attestations = new Map();
16
+ this.metrics = new PoolInstrumentation(new NoopTelemetryClient(), 'InMemoryAttestationPool');
17
+ }
18
+
19
+ public getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]> {
20
+ const slotAttestationMap = this.attestations.get(slot);
21
+ if (slotAttestationMap) {
22
+ const proposalAttestationMap = slotAttestationMap.get(proposalId);
23
+ if (proposalAttestationMap) {
24
+ return Promise.resolve(Array.from(proposalAttestationMap.values()));
25
+ }
26
+ }
27
+ return Promise.resolve([]);
28
+ }
29
+
30
+ public addAttestations(attestations: BlockAttestation[]): Promise<void> {
31
+ for (const attestation of attestations) {
32
+ // Perf: order and group by slot before insertion
33
+ const slotNumber = attestation.payload.header.globalVariables.slotNumber;
34
+
35
+ const proposalId = attestation.archive.toString();
36
+ const address = attestation.getSender();
37
+
38
+ const slotAttestationMap = getSlotOrDefault(this.attestations, slotNumber.toBigInt());
39
+ const proposalAttestationMap = getProposalOrDefault(slotAttestationMap, proposalId);
40
+ proposalAttestationMap.set(address.toString(), attestation);
41
+
42
+ this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`);
43
+ }
44
+
45
+ // TODO: set these to pending or something ????
46
+ this.metrics.recordAddedObjects(attestations.length);
47
+ return Promise.resolve();
48
+ }
49
+
50
+ #getNumberOfAttestationsInSlot(slot: bigint): number {
51
+ let total = 0;
52
+ const slotAttestationMap = getSlotOrDefault(this.attestations, slot);
53
+
54
+ if (slotAttestationMap) {
55
+ for (const proposalAttestationMap of slotAttestationMap.values() ?? []) {
56
+ total += proposalAttestationMap.size;
57
+ }
58
+ }
59
+ return total;
60
+ }
61
+
62
+ public deleteAttestationsForSlot(slot: bigint): Promise<void> {
63
+ // We count the number of attestations we are removing
64
+ const numberOfAttestations = this.#getNumberOfAttestationsInSlot(slot);
65
+
66
+ this.attestations.delete(slot);
67
+ this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
68
+
69
+ this.metrics.recordRemovedObjects(numberOfAttestations);
70
+ return Promise.resolve();
71
+ }
72
+
73
+ public deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void> {
74
+ const slotAttestationMap = getSlotOrDefault(this.attestations, slot);
75
+ if (slotAttestationMap) {
76
+ if (slotAttestationMap.has(proposalId)) {
77
+ const numberOfAttestations = slotAttestationMap.get(proposalId)?.size ?? 0;
78
+
79
+ slotAttestationMap.delete(proposalId);
80
+
81
+ this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
82
+ this.metrics.recordRemovedObjects(numberOfAttestations);
83
+ }
84
+ }
85
+ return Promise.resolve();
86
+ }
87
+
88
+ public deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
89
+ for (const attestation of attestations) {
90
+ const slotNumber = attestation.payload.header.globalVariables.slotNumber;
91
+ const slotAttestationMap = this.attestations.get(slotNumber.toBigInt());
92
+ if (slotAttestationMap) {
93
+ const proposalId = attestation.archive.toString();
94
+ const proposalAttestationMap = getProposalOrDefault(slotAttestationMap, proposalId);
95
+ if (proposalAttestationMap) {
96
+ const address = attestation.getSender();
97
+ proposalAttestationMap.delete(address.toString());
98
+ this.log.debug(`Deleted attestation for slot ${slotNumber} from ${address}`);
99
+ }
100
+ }
101
+ }
102
+ this.metrics.recordRemovedObjects(attestations.length);
103
+ return Promise.resolve();
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Get Slot or Default
109
+ *
110
+ * Fetch the slot mapping, if it does not exist, then create a mapping and return it
111
+ * @param map - The map to fetch from
112
+ * @param slot - The slot to fetch
113
+ * @returns The slot mapping
114
+ */
115
+ function getSlotOrDefault(
116
+ map: Map<bigint, Map<string, Map<string, BlockAttestation>>>,
117
+ slot: bigint,
118
+ ): Map<string, Map<string, BlockAttestation>> {
119
+ if (!map.has(slot)) {
120
+ map.set(slot, new Map<string, Map<string, BlockAttestation>>());
121
+ }
122
+ return map.get(slot)!;
123
+ }
124
+
125
+ /**
126
+ * Get Proposal or Default
127
+ *
128
+ * Fetch the proposal mapping, if it does not exist, then create a mapping and return it
129
+ * @param map - The map to fetch from
130
+ * @param proposalId - The proposal id to fetch
131
+ * @returns The proposal mapping
132
+ */
133
+ function getProposalOrDefault(
134
+ map: Map<string, Map<string, BlockAttestation>>,
135
+ proposalId: string,
136
+ ): Map<string, BlockAttestation> {
137
+ if (!map.has(proposalId)) {
138
+ map.set(proposalId, new Map<string, BlockAttestation>());
139
+ }
140
+ return map.get(proposalId)!;
141
+ }
@@ -22,10 +22,13 @@ export const generateAccount = () => {
22
22
  * @param slot The slot number the attestation is for
23
23
  * @returns A Block Attestation
24
24
  */
25
- export const mockAttestation = async (signer: PrivateKeyAccount, slot: number = 0): Promise<BlockAttestation> => {
25
+ export const mockAttestation = async (
26
+ signer: PrivateKeyAccount,
27
+ slot: number = 0,
28
+ archive: Fr = Fr.random(),
29
+ ): Promise<BlockAttestation> => {
26
30
  // Use arbitrary numbers for all other than slot
27
31
  const header = makeHeader(1, 2, slot);
28
- const archive = Fr.random();
29
32
  const txs = [0, 1, 2, 3, 4, 5].map(() => TxHash.random());
30
33
 
31
34
  const payload = new ConsensusPayload(header, archive, txs);
@@ -0,0 +1,7 @@
1
+ import { type EpochProofQuote } from '@aztec/circuit-types';
2
+
3
+ export interface EpochProofQuotePool {
4
+ addQuote(quote: EpochProofQuote): void;
5
+ getQuotes(epoch: bigint): EpochProofQuote[];
6
+ deleteQuotesToEpoch(epoch: bigint): void;
7
+ }
@@ -0,0 +1,3 @@
1
+ export * from './epoch_proof_quote_pool.js';
2
+ export * from './memory_epoch_proof_quote_pool.js';
3
+ export * from './test_utils.js';
@@ -0,0 +1,42 @@
1
+ import { type EpochProofQuote } from '@aztec/circuit-types';
2
+ import { type TelemetryClient } from '@aztec/telemetry-client';
3
+ import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
4
+
5
+ import { PoolInstrumentation } from '../instrumentation.js';
6
+ import { type EpochProofQuotePool } from './epoch_proof_quote_pool.js';
7
+
8
+ export class MemoryEpochProofQuotePool implements EpochProofQuotePool {
9
+ private quotes: Map<bigint, EpochProofQuote[]>;
10
+ private metrics: PoolInstrumentation<EpochProofQuote>;
11
+
12
+ constructor(_telemetry: TelemetryClient) {
13
+ this.quotes = new Map();
14
+ this.metrics = new PoolInstrumentation(new NoopTelemetryClient(), 'MemoryEpochProofQuotePool');
15
+ }
16
+
17
+ addQuote(quote: EpochProofQuote) {
18
+ const epoch = quote.payload.epochToProve;
19
+ if (!this.quotes.has(epoch)) {
20
+ this.quotes.set(epoch, []);
21
+ }
22
+ this.quotes.get(epoch)!.push(quote);
23
+
24
+ this.metrics.recordAddedObjects(1);
25
+ }
26
+ getQuotes(epoch: bigint): EpochProofQuote[] {
27
+ return this.quotes.get(epoch) || [];
28
+ }
29
+ deleteQuotesToEpoch(epoch: bigint): void {
30
+ const expiredEpochs = Array.from(this.quotes.keys()).filter(k => k <= epoch);
31
+
32
+ let removedObjectsCount = 0;
33
+ for (const expiredEpoch of expiredEpochs) {
34
+ // For logging
35
+ removedObjectsCount += this.quotes.get(expiredEpoch)?.length || 0;
36
+
37
+ this.quotes.delete(expiredEpoch);
38
+ }
39
+
40
+ this.metrics.recordRemovedObjects(removedObjectsCount);
41
+ }
42
+ }