@aztec/p2p 0.57.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 (107) hide show
  1. package/dest/client/index.d.ts +4 -4
  2. package/dest/client/index.d.ts.map +1 -1
  3. package/dest/client/index.js +11 -9
  4. package/dest/client/p2p_client.d.ts +9 -10
  5. package/dest/client/p2p_client.d.ts.map +1 -1
  6. package/dest/client/p2p_client.js +375 -350
  7. package/dest/config.js +3 -3
  8. package/dest/index.d.ts +3 -3
  9. package/dest/index.d.ts.map +1 -1
  10. package/dest/index.js +4 -4
  11. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -0
  12. package/dest/{attestation_pool → mem_pools/attestation_pool}/attestation_pool.js +1 -1
  13. package/dest/mem_pools/attestation_pool/index.d.ts.map +1 -0
  14. package/dest/{attestation_pool → mem_pools/attestation_pool}/index.js +1 -1
  15. package/dest/{attestation_pool → mem_pools/attestation_pool}/memory_attestation_pool.d.ts +4 -1
  16. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -0
  17. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +114 -0
  18. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -0
  19. package/dest/mem_pools/attestation_pool/mocks.js +31 -0
  20. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts.map +1 -0
  21. package/dest/mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js +2 -0
  22. package/dest/mem_pools/epoch_proof_quote_pool/index.d.ts.map +1 -0
  23. package/dest/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/index.js +1 -1
  24. package/dest/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/memory_epoch_proof_quote_pool.d.ts +3 -1
  25. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts.map +1 -0
  26. package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js +30 -0
  27. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.d.ts.map +1 -0
  28. package/dest/mem_pools/epoch_proof_quote_pool/test_utils.js +21 -0
  29. package/dest/mem_pools/index.d.ts +5 -0
  30. package/dest/mem_pools/index.d.ts.map +1 -0
  31. package/dest/mem_pools/index.js +2 -0
  32. package/dest/mem_pools/instrumentation.d.ts +25 -0
  33. package/dest/mem_pools/instrumentation.d.ts.map +1 -0
  34. package/dest/mem_pools/instrumentation.js +70 -0
  35. package/dest/mem_pools/interface.d.ts +12 -0
  36. package/dest/mem_pools/interface.d.ts.map +1 -0
  37. package/dest/mem_pools/interface.js +2 -0
  38. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -0
  39. package/dest/{tx_pool → mem_pools/tx_pool}/aztec_kv_tx_pool.js +9 -9
  40. package/dest/mem_pools/tx_pool/index.d.ts.map +1 -0
  41. package/dest/{tx_pool → mem_pools/tx_pool}/index.js +1 -1
  42. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -0
  43. package/dest/mem_pools/tx_pool/memory_tx_pool.js +111 -0
  44. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -0
  45. package/dest/{tx_pool → mem_pools/tx_pool}/tx_pool.js +1 -1
  46. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -0
  47. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +55 -0
  48. package/dest/service/libp2p_service.d.ts +12 -7
  49. package/dest/service/libp2p_service.d.ts.map +1 -1
  50. package/dest/service/libp2p_service.js +453 -381
  51. package/package.json +6 -6
  52. package/src/client/index.ts +16 -20
  53. package/src/client/p2p_client.ts +33 -10
  54. package/src/config.ts +2 -2
  55. package/src/index.ts +3 -3
  56. package/src/{attestation_pool → mem_pools/attestation_pool}/memory_attestation_pool.ts +40 -8
  57. package/src/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/memory_epoch_proof_quote_pool.ts +17 -1
  58. package/src/mem_pools/index.ts +4 -0
  59. package/src/mem_pools/instrumentation.ts +85 -0
  60. package/src/mem_pools/interface.ts +12 -0
  61. package/src/{tx_pool → mem_pools/tx_pool}/aztec_kv_tx_pool.ts +9 -9
  62. package/src/{tx_pool → mem_pools/tx_pool}/memory_tx_pool.ts +9 -9
  63. package/src/service/libp2p_service.ts +76 -18
  64. package/dest/attestation_pool/attestation_pool.d.ts.map +0 -1
  65. package/dest/attestation_pool/index.d.ts.map +0 -1
  66. package/dest/attestation_pool/memory_attestation_pool.d.ts.map +0 -1
  67. package/dest/attestation_pool/memory_attestation_pool.js +0 -89
  68. package/dest/attestation_pool/mocks.d.ts.map +0 -1
  69. package/dest/attestation_pool/mocks.js +0 -31
  70. package/dest/epoch_proof_quote_pool/epoch_proof_quote_pool.d.ts.map +0 -1
  71. package/dest/epoch_proof_quote_pool/epoch_proof_quote_pool.js +0 -2
  72. package/dest/epoch_proof_quote_pool/index.d.ts.map +0 -1
  73. package/dest/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts.map +0 -1
  74. package/dest/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js +0 -22
  75. package/dest/epoch_proof_quote_pool/test_utils.d.ts.map +0 -1
  76. package/dest/epoch_proof_quote_pool/test_utils.js +0 -21
  77. package/dest/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  78. package/dest/tx_pool/index.d.ts.map +0 -1
  79. package/dest/tx_pool/instrumentation.d.ts +0 -25
  80. package/dest/tx_pool/instrumentation.d.ts.map +0 -1
  81. package/dest/tx_pool/instrumentation.js +0 -61
  82. package/dest/tx_pool/memory_tx_pool.d.ts.map +0 -1
  83. package/dest/tx_pool/memory_tx_pool.js +0 -111
  84. package/dest/tx_pool/tx_pool.d.ts.map +0 -1
  85. package/dest/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  86. package/dest/tx_pool/tx_pool_test_suite.js +0 -55
  87. package/src/tx_pool/instrumentation.ts +0 -73
  88. /package/dest/{attestation_pool → mem_pools/attestation_pool}/attestation_pool.d.ts +0 -0
  89. /package/dest/{attestation_pool → mem_pools/attestation_pool}/index.d.ts +0 -0
  90. /package/dest/{attestation_pool → mem_pools/attestation_pool}/mocks.d.ts +0 -0
  91. /package/dest/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/epoch_proof_quote_pool.d.ts +0 -0
  92. /package/dest/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/index.d.ts +0 -0
  93. /package/dest/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/test_utils.d.ts +0 -0
  94. /package/dest/{tx_pool → mem_pools/tx_pool}/aztec_kv_tx_pool.d.ts +0 -0
  95. /package/dest/{tx_pool → mem_pools/tx_pool}/index.d.ts +0 -0
  96. /package/dest/{tx_pool → mem_pools/tx_pool}/memory_tx_pool.d.ts +0 -0
  97. /package/dest/{tx_pool → mem_pools/tx_pool}/tx_pool.d.ts +0 -0
  98. /package/dest/{tx_pool → mem_pools/tx_pool}/tx_pool_test_suite.d.ts +0 -0
  99. /package/src/{attestation_pool → mem_pools/attestation_pool}/attestation_pool.ts +0 -0
  100. /package/src/{attestation_pool → mem_pools/attestation_pool}/index.ts +0 -0
  101. /package/src/{attestation_pool → mem_pools/attestation_pool}/mocks.ts +0 -0
  102. /package/src/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/epoch_proof_quote_pool.ts +0 -0
  103. /package/src/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/index.ts +0 -0
  104. /package/src/{epoch_proof_quote_pool → mem_pools/epoch_proof_quote_pool}/test_utils.ts +0 -0
  105. /package/src/{tx_pool → mem_pools/tx_pool}/index.ts +0 -0
  106. /package/src/{tx_pool → mem_pools/tx_pool}/tx_pool.ts +0 -0
  107. /package/src/{tx_pool → mem_pools/tx_pool}/tx_pool_test_suite.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.57.0",
3
+ "version": "0.58.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -59,11 +59,11 @@
59
59
  "testTimeout": 15000
60
60
  },
61
61
  "dependencies": {
62
- "@aztec/circuit-types": "0.57.0",
63
- "@aztec/circuits.js": "0.57.0",
64
- "@aztec/foundation": "0.57.0",
65
- "@aztec/kv-store": "0.57.0",
66
- "@aztec/telemetry-client": "0.57.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",
67
67
  "@chainsafe/discv5": "9.0.0",
68
68
  "@chainsafe/enr": "3.0.0",
69
69
  "@chainsafe/libp2p-gossipsub": "13.0.0",
@@ -5,16 +5,17 @@ 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
- import { InMemoryAttestationPool } from '../attestation_pool/memory_attestation_pool.js';
10
8
  import { P2PClient } from '../client/p2p_client.js';
11
9
  import { type P2PConfig } from '../config.js';
12
- import { type EpochProofQuotePool } from '../epoch_proof_quote_pool/epoch_proof_quote_pool.js';
13
- import { MemoryEpochProofQuotePool } from '../epoch_proof_quote_pool/memory_epoch_proof_quote_pool.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';
14
16
  import { DiscV5Service } from '../service/discV5_service.js';
15
17
  import { DummyP2PService } from '../service/dummy_service.js';
16
18
  import { LibP2PService, createLibP2PPeerId } from '../service/index.js';
17
- import { AztecKVTxPool, type TxPool } from '../tx_pool/index.js';
18
19
  import { getPublicIp, resolveAddressIfNecessary, splitAddressPort } from '../util.js';
19
20
 
20
21
  export * from './p2p_client.js';
@@ -28,15 +29,18 @@ export const createP2PClient = async (
28
29
  deps: {
29
30
  txPool?: TxPool;
30
31
  store?: AztecKVStore;
31
- attestationsPool?: AttestationPool;
32
+ attestationPool?: AttestationPool;
32
33
  epochProofQuotePool?: EpochProofQuotePool;
33
34
  } = {},
34
35
  ) => {
35
36
  let config = { ..._config };
36
37
  const store = deps.store ?? (await createStore('p2p', config, createDebugLogger('aztec:p2p:lmdb')));
37
- const txPool = deps.txPool ?? new AztecKVTxPool(store, telemetry);
38
- const attestationsPool = deps.attestationsPool ?? new InMemoryAttestationPool();
39
- const epochProofQuotePool = deps.epochProofQuotePool ?? new MemoryEpochProofQuotePool();
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
+ };
40
44
 
41
45
  let p2pService;
42
46
 
@@ -51,25 +55,17 @@ export const createP2PClient = async (
51
55
  config,
52
56
  discoveryService,
53
57
  peerId,
54
- txPool,
55
- attestationsPool,
58
+ mempools,
56
59
  l2BlockSource,
57
60
  proofVerifier,
58
61
  worldStateSynchronizer,
59
62
  store,
63
+ telemetry,
60
64
  );
61
65
  } else {
62
66
  p2pService = new DummyP2PService();
63
67
  }
64
- return new P2PClient(
65
- store,
66
- l2BlockSource,
67
- txPool,
68
- attestationsPool,
69
- epochProofQuotePool,
70
- p2pService,
71
- config.keepProvenTxsInPoolFor,
72
- );
68
+ return new P2PClient(store, l2BlockSource, mempools, p2pService, config.keepProvenTxsInPoolFor, telemetry);
73
69
  };
74
70
 
75
71
  async function configureP2PClientAddresses(_config: P2PConfig & DataStoreConfig): Promise<P2PConfig & DataStoreConfig> {
@@ -4,6 +4,7 @@ import {
4
4
  type EpochProofQuote,
5
5
  type L2Block,
6
6
  L2BlockDownloader,
7
+ type L2BlockId,
7
8
  type L2BlockSource,
8
9
  type Tx,
9
10
  type TxHash,
@@ -11,15 +12,17 @@ import {
11
12
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
12
13
  import { createDebugLogger } from '@aztec/foundation/log';
13
14
  import { type AztecKVStore, type AztecSingleton } from '@aztec/kv-store';
15
+ import { Attributes, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
14
16
 
15
17
  import { type ENR } from '@chainsafe/enr';
16
18
 
17
- import { type AttestationPool } from '../attestation_pool/attestation_pool.js';
18
19
  import { getP2PConfigEnvVars } from '../config.js';
19
- import { type EpochProofQuotePool } from '../epoch_proof_quote_pool/epoch_proof_quote_pool.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';
20
24
  import { TX_REQ_PROTOCOL } from '../service/reqresp/interface.js';
21
25
  import type { P2PService } from '../service/service.js';
22
- import { type TxPool } from '../tx_pool/index.js';
23
26
 
24
27
  /**
25
28
  * Enum defining the possible states of the p2p client.
@@ -42,7 +45,7 @@ export interface P2PSyncState {
42
45
  /**
43
46
  * The block number that the p2p client is synced to.
44
47
  */
45
- syncedToL2Block: number;
48
+ syncedToL2Block: L2BlockId;
46
49
  }
47
50
 
48
51
  /**
@@ -168,7 +171,7 @@ export interface P2P {
168
171
  /**
169
172
  * The P2P client implementation.
170
173
  */
171
- export class P2PClient implements P2P {
174
+ export class P2PClient extends WithTracer implements P2P {
172
175
  /** L2 block download to stay in sync with latest blocks. */
173
176
  private latestBlockDownloader: L2BlockDownloader;
174
177
 
@@ -190,6 +193,10 @@ export class P2PClient implements P2P {
190
193
  private synchedLatestBlockNumber: AztecSingleton<number>;
191
194
  private synchedProvenBlockNumber: AztecSingleton<number>;
192
195
 
196
+ private txPool: TxPool;
197
+ private attestationPool: AttestationPool;
198
+ private epochProofQuotePool: EpochProofQuotePool;
199
+
193
200
  /**
194
201
  * In-memory P2P client constructor.
195
202
  * @param store - The client's instance of the KV store.
@@ -202,13 +209,14 @@ export class P2PClient implements P2P {
202
209
  constructor(
203
210
  store: AztecKVStore,
204
211
  private l2BlockSource: L2BlockSource,
205
- private txPool: TxPool,
206
- private attestationPool: AttestationPool,
207
- private epochProofQuotePool: EpochProofQuotePool,
212
+ mempools: MemPools,
208
213
  private p2pService: P2PService,
209
214
  private keepProvenTxsFor: number,
215
+ telemetryClient: TelemetryClient,
210
216
  private log = createDebugLogger('aztec:p2p'),
211
217
  ) {
218
+ super(telemetryClient, 'P2PClient');
219
+
212
220
  const { blockCheckIntervalMS: checkInterval, l2QueueSize: p2pL2QueueSize } = getP2PConfigEnvVars();
213
221
  const l2DownloaderOpts = { maxQueueSize: p2pL2QueueSize, pollIntervalMS: checkInterval };
214
222
  // TODO(palla/prover-node): This effectively downloads blocks twice from the archiver, which is an issue
@@ -219,6 +227,10 @@ export class P2PClient implements P2P {
219
227
 
220
228
  this.synchedLatestBlockNumber = store.openSingleton('p2p_pool_last_l2_block');
221
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;
222
234
  }
223
235
 
224
236
  #assertIsReady() {
@@ -311,6 +323,12 @@ export class P2PClient implements P2P {
311
323
  this.log.info('P2P client stopped.');
312
324
  }
313
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
+ }))
314
332
  public broadcastProposal(proposal: BlockProposal): void {
315
333
  this.log.verbose(`Broadcasting proposal ${proposal.p2pMessageIdentifier()} to peers`);
316
334
  return this.p2pService.propagate(proposal);
@@ -455,10 +473,15 @@ export class P2PClient implements P2P {
455
473
  * Method to check the status the p2p client.
456
474
  * @returns Information about p2p client status: state & syncedToBlockNum.
457
475
  */
458
- 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());
459
482
  return Promise.resolve({
460
483
  state: this.currentState,
461
- syncedToL2Block: this.getSyncedLatestBlockNum(),
484
+ syncedToL2Block: { number: blockNumber, hash: blockHash },
462
485
  } as P2PSyncState);
463
486
  }
464
487
 
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,8 +1,8 @@
1
- export * from './attestation_pool/index.js';
1
+ export * from './mem_pools/attestation_pool/index.js';
2
2
  export * from './bootstrap/bootstrap.js';
3
3
  export * from './client/index.js';
4
4
  export * from './config.js';
5
- export * from './epoch_proof_quote_pool/index.js';
5
+ export * from './mem_pools/epoch_proof_quote_pool/index.js';
6
6
  export * from './service/index.js';
7
- export * from './tx_pool/index.js';
7
+ export * from './mem_pools/tx_pool/index.js';
8
8
  export * from './tx_validator/index.js';
@@ -1,13 +1,19 @@
1
1
  import { type BlockAttestation } from '@aztec/circuit-types';
2
2
  import { createDebugLogger } from '@aztec/foundation/log';
3
+ import { type TelemetryClient } from '@aztec/telemetry-client';
4
+ import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
3
5
 
6
+ import { PoolInstrumentation } from '../instrumentation.js';
4
7
  import { type AttestationPool } from './attestation_pool.js';
5
8
 
6
9
  export class InMemoryAttestationPool implements AttestationPool {
10
+ private metrics: PoolInstrumentation<BlockAttestation>;
11
+
7
12
  private attestations: Map</*slot=*/ bigint, Map</*proposalId*/ string, Map</*address=*/ string, BlockAttestation>>>;
8
13
 
9
- constructor(private log = createDebugLogger('aztec:attestation_pool')) {
14
+ constructor(_telemetry: TelemetryClient, private log = createDebugLogger('aztec:attestation_pool')) {
10
15
  this.attestations = new Map();
16
+ this.metrics = new PoolInstrumentation(new NoopTelemetryClient(), 'InMemoryAttestationPool');
11
17
  }
12
18
 
13
19
  public getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]> {
@@ -26,7 +32,7 @@ export class InMemoryAttestationPool implements AttestationPool {
26
32
  // Perf: order and group by slot before insertion
27
33
  const slotNumber = attestation.payload.header.globalVariables.slotNumber;
28
34
 
29
- const proposalId = attestation.p2pMessageIdentifier().toString();
35
+ const proposalId = attestation.archive.toString();
30
36
  const address = attestation.getSender();
31
37
 
32
38
  const slotAttestationMap = getSlotOrDefault(this.attestations, slotNumber.toBigInt());
@@ -35,21 +41,46 @@ export class InMemoryAttestationPool implements AttestationPool {
35
41
 
36
42
  this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`);
37
43
  }
44
+
45
+ // TODO: set these to pending or something ????
46
+ this.metrics.recordAddedObjects(attestations.length);
38
47
  return Promise.resolve();
39
48
  }
40
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
+
41
62
  public deleteAttestationsForSlot(slot: bigint): Promise<void> {
42
- // TODO(md): check if this will free the memory of the inner hash map
63
+ // We count the number of attestations we are removing
64
+ const numberOfAttestations = this.#getNumberOfAttestationsInSlot(slot);
65
+
43
66
  this.attestations.delete(slot);
44
- this.log.verbose(`Removed attestation for slot ${slot}`);
67
+ this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
68
+
69
+ this.metrics.recordRemovedObjects(numberOfAttestations);
45
70
  return Promise.resolve();
46
71
  }
47
72
 
48
73
  public deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void> {
49
- const slotAttestationMap = this.attestations.get(slot);
74
+ const slotAttestationMap = getSlotOrDefault(this.attestations, slot);
50
75
  if (slotAttestationMap) {
51
- slotAttestationMap.delete(proposalId);
52
- this.log.verbose(`Removed attestation for slot ${slot}`);
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
+ }
53
84
  }
54
85
  return Promise.resolve();
55
86
  }
@@ -59,7 +90,7 @@ export class InMemoryAttestationPool implements AttestationPool {
59
90
  const slotNumber = attestation.payload.header.globalVariables.slotNumber;
60
91
  const slotAttestationMap = this.attestations.get(slotNumber.toBigInt());
61
92
  if (slotAttestationMap) {
62
- const proposalId = attestation.p2pMessageIdentifier().toString();
93
+ const proposalId = attestation.archive.toString();
63
94
  const proposalAttestationMap = getProposalOrDefault(slotAttestationMap, proposalId);
64
95
  if (proposalAttestationMap) {
65
96
  const address = attestation.getSender();
@@ -68,6 +99,7 @@ export class InMemoryAttestationPool implements AttestationPool {
68
99
  }
69
100
  }
70
101
  }
102
+ this.metrics.recordRemovedObjects(attestations.length);
71
103
  return Promise.resolve();
72
104
  }
73
105
  }
@@ -1,26 +1,42 @@
1
1
  import { type EpochProofQuote } from '@aztec/circuit-types';
2
+ import { type TelemetryClient } from '@aztec/telemetry-client';
3
+ import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
2
4
 
5
+ import { PoolInstrumentation } from '../instrumentation.js';
3
6
  import { type EpochProofQuotePool } from './epoch_proof_quote_pool.js';
4
7
 
5
8
  export class MemoryEpochProofQuotePool implements EpochProofQuotePool {
6
9
  private quotes: Map<bigint, EpochProofQuote[]>;
7
- constructor() {
10
+ private metrics: PoolInstrumentation<EpochProofQuote>;
11
+
12
+ constructor(_telemetry: TelemetryClient) {
8
13
  this.quotes = new Map();
14
+ this.metrics = new PoolInstrumentation(new NoopTelemetryClient(), 'MemoryEpochProofQuotePool');
9
15
  }
16
+
10
17
  addQuote(quote: EpochProofQuote) {
11
18
  const epoch = quote.payload.epochToProve;
12
19
  if (!this.quotes.has(epoch)) {
13
20
  this.quotes.set(epoch, []);
14
21
  }
15
22
  this.quotes.get(epoch)!.push(quote);
23
+
24
+ this.metrics.recordAddedObjects(1);
16
25
  }
17
26
  getQuotes(epoch: bigint): EpochProofQuote[] {
18
27
  return this.quotes.get(epoch) || [];
19
28
  }
20
29
  deleteQuotesToEpoch(epoch: bigint): void {
21
30
  const expiredEpochs = Array.from(this.quotes.keys()).filter(k => k <= epoch);
31
+
32
+ let removedObjectsCount = 0;
22
33
  for (const expiredEpoch of expiredEpochs) {
34
+ // For logging
35
+ removedObjectsCount += this.quotes.get(expiredEpoch)?.length || 0;
36
+
23
37
  this.quotes.delete(expiredEpoch);
24
38
  }
39
+
40
+ this.metrics.recordRemovedObjects(removedObjectsCount);
25
41
  }
26
42
  }
@@ -0,0 +1,4 @@
1
+ export { TxPool } from './tx_pool/tx_pool.js';
2
+ export { AttestationPool } from './attestation_pool/attestation_pool.js';
3
+ export { EpochProofQuotePool } from './epoch_proof_quote_pool/epoch_proof_quote_pool.js';
4
+ export { type MemPools } from './interface.js';
@@ -0,0 +1,85 @@
1
+ import { type Gossipable } from '@aztec/circuit-types';
2
+ import { Attributes, type Histogram, Metrics, type TelemetryClient, type UpDownCounter } from '@aztec/telemetry-client';
3
+
4
+ /**
5
+ * Instrumentation class for the Pools (TxPool, AttestationPool, etc).
6
+ */
7
+ export class PoolInstrumentation<PoolObject extends Gossipable> {
8
+ /** The number of txs in the mempool */
9
+ private objectsInMempool: UpDownCounter;
10
+ /** Tracks tx size */
11
+ private objectSize: Histogram;
12
+
13
+ private defaultAttributes;
14
+
15
+ constructor(telemetry: TelemetryClient, name: string) {
16
+ const meter = telemetry.getMeter(name);
17
+ this.defaultAttributes = { [Attributes.POOL_NAME]: name };
18
+
19
+ this.objectsInMempool = meter.createUpDownCounter(Metrics.MEMPOOL_TX_COUNT, {
20
+ description: 'The current number of transactions in the mempool',
21
+ });
22
+
23
+ this.objectSize = meter.createHistogram(Metrics.MEMPOOL_TX_SIZE, {
24
+ unit: 'By',
25
+ description: 'The size of transactions in the mempool',
26
+ advice: {
27
+ explicitBucketBoundaries: [
28
+ 5_000, // 5KB
29
+ 10_000,
30
+ 20_000,
31
+ 50_000,
32
+ 75_000,
33
+ 100_000, // 100KB
34
+ 200_000,
35
+ ],
36
+ },
37
+ });
38
+ }
39
+
40
+ public recordSize(poolObject: PoolObject) {
41
+ this.objectSize.record(poolObject.getSize());
42
+ }
43
+
44
+ /**
45
+ * Updates the metrics with the new objects.
46
+ * @param txs - The objects to record
47
+ */
48
+ public recordAddedObjects(count = 1, status?: string) {
49
+ if (count < 0) {
50
+ throw new Error('Count must be positive');
51
+ }
52
+ if (count === 0) {
53
+ return;
54
+ }
55
+ const attributes = status
56
+ ? {
57
+ ...this.defaultAttributes,
58
+ [Attributes.STATUS]: status,
59
+ }
60
+ : this.defaultAttributes;
61
+
62
+ this.objectsInMempool.add(count, attributes);
63
+ }
64
+
65
+ /**
66
+ * Updates the metrics by removing objects from the mempool.
67
+ * @param count - The number of objects to remove from the mempool
68
+ */
69
+ public recordRemovedObjects(count = 1, status?: string) {
70
+ if (count < 0) {
71
+ throw new Error('Count must be positive');
72
+ }
73
+ if (count === 0) {
74
+ return;
75
+ }
76
+
77
+ const attributes = status
78
+ ? {
79
+ ...this.defaultAttributes,
80
+ [Attributes.STATUS]: status,
81
+ }
82
+ : this.defaultAttributes;
83
+ this.objectsInMempool.add(-1 * count, attributes);
84
+ }
85
+ }
@@ -0,0 +1,12 @@
1
+ import { type AttestationPool } from './attestation_pool/attestation_pool.js';
2
+ import { type EpochProofQuotePool } from './epoch_proof_quote_pool/epoch_proof_quote_pool.js';
3
+ import { type TxPool } from './tx_pool/tx_pool.js';
4
+
5
+ /**
6
+ * A interface the combines all mempools
7
+ */
8
+ export interface MemPools {
9
+ txPool: TxPool;
10
+ attestationPool: AttestationPool;
11
+ epochProofQuotePool: EpochProofQuotePool;
12
+ }
@@ -4,7 +4,7 @@ import { type Logger, createDebugLogger } from '@aztec/foundation/log';
4
4
  import { type AztecKVStore, type AztecMap, type AztecSet } from '@aztec/kv-store';
5
5
  import { type TelemetryClient } from '@aztec/telemetry-client';
6
6
 
7
- import { TxPoolInstrumentation } from './instrumentation.js';
7
+ import { PoolInstrumentation } from '../instrumentation.js';
8
8
  import { type TxPool } from './tx_pool.js';
9
9
 
10
10
  /**
@@ -23,7 +23,7 @@ export class AztecKVTxPool implements TxPool {
23
23
 
24
24
  #log: Logger;
25
25
 
26
- #metrics: TxPoolInstrumentation;
26
+ #metrics: PoolInstrumentation<Tx>;
27
27
 
28
28
  /**
29
29
  * Class constructor for in-memory TxPool. Initiates our transaction pool as a JS Map.
@@ -37,7 +37,7 @@ export class AztecKVTxPool implements TxPool {
37
37
 
38
38
  this.#store = store;
39
39
  this.#log = log;
40
- this.#metrics = new TxPoolInstrumentation(telemetry, 'AztecKVTxPool');
40
+ this.#metrics = new PoolInstrumentation(telemetry, 'AztecKVTxPool');
41
41
  }
42
42
 
43
43
  public markAsMined(txHashes: TxHash[]): Promise<void> {
@@ -51,8 +51,8 @@ export class AztecKVTxPool implements TxPool {
51
51
  void this.#pendingTxs.delete(key);
52
52
  }
53
53
  }
54
- this.#metrics.recordRemovedTxs('pending', deleted);
55
- this.#metrics.recordAddedTxs('mined', txHashes.length);
54
+ this.#metrics.recordRemovedObjects(deleted, 'pending');
55
+ this.#metrics.recordAddedObjects(txHashes.length, 'mined');
56
56
  });
57
57
  }
58
58
 
@@ -107,11 +107,11 @@ export class AztecKVTxPool implements TxPool {
107
107
  pendingCount++;
108
108
  // REFACTOR: Use an lmdb conditional write to avoid race conditions with this write tx
109
109
  void this.#pendingTxs.add(key);
110
- this.#metrics.recordTxSize(tx);
110
+ this.#metrics.recordSize(tx);
111
111
  }
112
112
  }
113
113
 
114
- this.#metrics.recordAddedTxs('pending', pendingCount);
114
+ this.#metrics.recordAddedObjects(pendingCount, 'pending');
115
115
  });
116
116
  }
117
117
 
@@ -138,8 +138,8 @@ export class AztecKVTxPool implements TxPool {
138
138
  }
139
139
  }
140
140
 
141
- this.#metrics.recordRemovedTxs('pending', pendingDeleted);
142
- this.#metrics.recordRemovedTxs('mined', minedDeleted);
141
+ this.#metrics.recordRemovedObjects(pendingDeleted, 'pending');
142
+ this.#metrics.recordRemovedObjects(minedDeleted, 'mined');
143
143
  });
144
144
  }
145
145
 
@@ -3,7 +3,7 @@ import { type TxAddedToPoolStats } from '@aztec/circuit-types/stats';
3
3
  import { createDebugLogger } from '@aztec/foundation/log';
4
4
  import { type TelemetryClient } from '@aztec/telemetry-client';
5
5
 
6
- import { TxPoolInstrumentation } from './instrumentation.js';
6
+ import { PoolInstrumentation } from '../instrumentation.js';
7
7
  import { type TxPool } from './tx_pool.js';
8
8
 
9
9
  /**
@@ -17,7 +17,7 @@ export class InMemoryTxPool implements TxPool {
17
17
  private minedTxs: Set<bigint>;
18
18
  private pendingTxs: Set<bigint>;
19
19
 
20
- private metrics: TxPoolInstrumentation;
20
+ private metrics: PoolInstrumentation<Tx>;
21
21
 
22
22
  /**
23
23
  * Class constructor for in-memory TxPool. Initiates our transaction pool as a JS Map.
@@ -27,7 +27,7 @@ export class InMemoryTxPool implements TxPool {
27
27
  this.txs = new Map<bigint, Tx>();
28
28
  this.minedTxs = new Set();
29
29
  this.pendingTxs = new Set();
30
- this.metrics = new TxPoolInstrumentation(telemetry, 'InMemoryTxPool');
30
+ this.metrics = new PoolInstrumentation(telemetry, 'InMemoryTxPool');
31
31
  }
32
32
 
33
33
  public markAsMined(txHashes: TxHash[]): Promise<void> {
@@ -36,8 +36,8 @@ export class InMemoryTxPool implements TxPool {
36
36
  this.minedTxs.add(key);
37
37
  this.pendingTxs.delete(key);
38
38
  }
39
- this.metrics.recordRemovedTxs('pending', txHashes.length);
40
- this.metrics.recordAddedTxs('mined', txHashes.length);
39
+ this.metrics.recordRemovedObjects(txHashes.length, 'pending');
40
+ this.metrics.recordAddedObjects(txHashes.length, 'mined');
41
41
  return Promise.resolve();
42
42
  }
43
43
 
@@ -88,12 +88,12 @@ export class InMemoryTxPool implements TxPool {
88
88
  this.txs.set(key, tx);
89
89
  if (!this.minedTxs.has(key)) {
90
90
  pending++;
91
- this.metrics.recordTxSize(tx);
91
+ this.metrics.recordSize(tx);
92
92
  this.pendingTxs.add(key);
93
93
  }
94
94
  }
95
95
 
96
- this.metrics.recordAddedTxs('pending', pending);
96
+ this.metrics.recordAddedObjects(pending, 'pending');
97
97
  return Promise.resolve();
98
98
  }
99
99
 
@@ -113,8 +113,8 @@ export class InMemoryTxPool implements TxPool {
113
113
  deletedMined += this.minedTxs.delete(key) ? 1 : 0;
114
114
  }
115
115
 
116
- this.metrics.recordRemovedTxs('pending', deletedPending);
117
- this.metrics.recordRemovedTxs('mined', deletedMined);
116
+ this.metrics.recordRemovedObjects(deletedPending, 'pending');
117
+ this.metrics.recordRemovedObjects(deletedMined, 'mined');
118
118
 
119
119
  return Promise.resolve();
120
120
  }