@aztec/p2p 1.0.0-staging.2 → 1.0.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 (59) hide show
  1. package/dest/bootstrap/bootstrap.js +1 -1
  2. package/dest/client/factory.js +1 -1
  3. package/dest/client/p2p_client.js +1 -1
  4. package/dest/config.d.ts +2 -2
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +4 -11
  7. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  8. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +10 -17
  9. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +2 -2
  10. package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
  11. package/dest/mem_pools/tx_pool/memory_tx_pool.js +2 -2
  12. package/dest/mem_pools/tx_pool/tx_pool.d.ts +2 -3
  13. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
  14. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
  15. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +3 -10
  16. package/dest/msg_validators/tx_validator/factory.d.ts +1 -2
  17. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  18. package/dest/msg_validators/tx_validator/factory.js +2 -3
  19. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +0 -2
  20. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  21. package/dest/msg_validators/tx_validator/metadata_validator.js +7 -13
  22. package/dest/msg_validators/tx_validator/phases_validator.d.ts +2 -3
  23. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -1
  24. package/dest/msg_validators/tx_validator/phases_validator.js +4 -4
  25. package/dest/services/libp2p/instrumentation.d.ts +1 -8
  26. package/dest/services/libp2p/instrumentation.d.ts.map +1 -1
  27. package/dest/services/libp2p/instrumentation.js +2 -130
  28. package/dest/services/libp2p/libp2p_service.d.ts +3 -8
  29. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  30. package/dest/services/libp2p/libp2p_service.js +14 -34
  31. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  32. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  33. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  34. package/dest/test-helpers/reqresp-nodes.js +2 -3
  35. package/dest/testbench/p2p_client_testbench_worker.js +0 -6
  36. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  37. package/dest/testbench/worker_client_manager.js +1 -2
  38. package/dest/util.d.ts +2 -3
  39. package/dest/util.d.ts.map +1 -1
  40. package/dest/util.js +5 -6
  41. package/package.json +13 -13
  42. package/src/bootstrap/bootstrap.ts +1 -1
  43. package/src/client/factory.ts +1 -1
  44. package/src/client/p2p_client.ts +1 -1
  45. package/src/config.ts +1 -2
  46. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +12 -22
  47. package/src/mem_pools/tx_pool/memory_tx_pool.ts +3 -3
  48. package/src/mem_pools/tx_pool/tx_pool.ts +2 -3
  49. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +4 -8
  50. package/src/msg_validators/tx_validator/factory.ts +1 -4
  51. package/src/msg_validators/tx_validator/metadata_validator.ts +9 -20
  52. package/src/msg_validators/tx_validator/phases_validator.ts +2 -3
  53. package/src/services/libp2p/instrumentation.ts +3 -122
  54. package/src/services/libp2p/libp2p_service.ts +15 -41
  55. package/src/test-helpers/make-test-p2p-clients.ts +1 -2
  56. package/src/test-helpers/reqresp-nodes.ts +2 -3
  57. package/src/testbench/p2p_client_testbench_worker.ts +0 -1
  58. package/src/testbench/worker_client_manager.ts +1 -2
  59. package/src/util.ts +7 -8
@@ -8,7 +8,7 @@ import type { MerkleTreeReadOperations, WorldStateSynchronizer } from '@aztec/st
8
8
  import { ClientIvcProof } from '@aztec/stdlib/proofs';
9
9
  import type { TxAddedToPoolStats } from '@aztec/stdlib/stats';
10
10
  import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
11
- import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
11
+ import { Tx, TxHash } from '@aztec/stdlib/tx';
12
12
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
13
13
 
14
14
  import assert from 'assert';
@@ -129,14 +129,8 @@ export class AztecKVTxPool implements TxPool {
129
129
  }
130
130
  return true;
131
131
  }
132
- /**
133
- * Marks transactions as mined in a block and updates the pool state accordingly.
134
- * Removes the transactions from the pending set and adds them to the mined set.
135
- * Also evicts any transactions that become invalid after the block is mined.
136
- * @param txHashes - Array of transaction hashes that were mined
137
- * @param blockHeader - The header of the block the transactions were mined in
138
- */
139
- public async markAsMined(txHashes: TxHash[], blockHeader: BlockHeader): Promise<void> {
132
+
133
+ public async markAsMined(txHashes: TxHash[], blockNumber: number): Promise<void> {
140
134
  if (txHashes.length === 0) {
141
135
  return Promise.resolve();
142
136
  }
@@ -148,7 +142,7 @@ export class AztecKVTxPool implements TxPool {
148
142
  let pendingTxSize = (await this.#pendingTxSize.getAsync()) ?? 0;
149
143
  for (const hash of txHashes) {
150
144
  const key = hash.toString();
151
- await this.#minedTxHashToBlock.set(key, blockHeader.globalVariables.blockNumber);
145
+ await this.#minedTxHashToBlock.set(key, blockNumber);
152
146
 
153
147
  const tx = await this.getPendingTxByHash(hash);
154
148
  if (tx) {
@@ -161,7 +155,7 @@ export class AztecKVTxPool implements TxPool {
161
155
  }
162
156
  await this.#pendingTxSize.set(pendingTxSize);
163
157
 
164
- await this.evictInvalidTxsAfterMining(txHashes, blockHeader, minedNullifiers, minedFeePayers);
158
+ await this.evictInvalidTxsAfterMining(txHashes, blockNumber, minedNullifiers, minedFeePayers);
165
159
  });
166
160
  // We update this after the transaction above. This ensures that the non-evictable transactions are not evicted
167
161
  // until any that have been mined are marked as such.
@@ -541,15 +535,15 @@ export class AztecKVTxPool implements TxPool {
541
535
  * Eviction criteria includes:
542
536
  * - txs with nullifiers that are already included in the mined block
543
537
  * - txs with an insufficient fee payer balance
544
- * - txs with an expiration timestamp lower than that of the mined block
538
+ * - txs with a max block number lower than the mined block
545
539
  *
546
540
  * @param minedTxHashes - The tx hashes of the txs mined in the block.
547
- * @param blockHeader - The header of the mined block.
541
+ * @param blockNumber - The block number of the mined block.
548
542
  * @returns The total number of txs evicted from the pool.
549
543
  */
550
544
  private async evictInvalidTxsAfterMining(
551
545
  minedTxHashes: TxHash[],
552
- blockHeader: BlockHeader,
546
+ blockNumber: number,
553
547
  minedNullifiers: Set<string>,
554
548
  minedFeePayers: Set<string>,
555
549
  ): Promise<number> {
@@ -557,8 +551,6 @@ export class AztecKVTxPool implements TxPool {
557
551
  return 0;
558
552
  }
559
553
 
560
- const { blockNumber, timestamp } = blockHeader.globalVariables;
561
-
562
554
  // Wait for world state to be synced to at least the mined block number
563
555
  await this.#worldStateSynchronizer.syncImmediate(blockNumber);
564
556
 
@@ -590,12 +582,10 @@ export class AztecKVTxPool implements TxPool {
590
582
  continue;
591
583
  }
592
584
 
593
- // Evict pending txs with an expiration timestamp less than or equal to the mined block timestamp
594
- const includeByTimestamp = tx.data.rollupValidationRequests.includeByTimestamp;
595
- if (includeByTimestamp.isSome && includeByTimestamp.value <= timestamp) {
596
- this.#log.verbose(
597
- `Evicting tx ${txHash} from pool due to the tx being expired (includeByTimestamp: ${includeByTimestamp.value}, mined block timestamp: ${timestamp})`,
598
- );
585
+ // Evict pending txs with a max block number less than or equal to the mined block
586
+ const maxBlockNumber = tx.data.rollupValidationRequests.maxBlockNumber;
587
+ if (maxBlockNumber.isSome && maxBlockNumber.value <= blockNumber) {
588
+ this.#log.verbose(`Evicting tx ${txHash} from pool due to an invalid max block number`);
599
589
  txsToEvict.push(TxHash.fromString(txHash));
600
590
  continue;
601
591
  }
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from '@aztec/foundation/log';
2
2
  import type { TxAddedToPoolStats } from '@aztec/stdlib/stats';
3
- import { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
3
+ import { Tx, TxHash } from '@aztec/stdlib/tx';
4
4
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
5
5
 
6
6
  import { PoolInstrumentation, PoolName, type PoolStatsCallback } from '../instrumentation.js';
@@ -47,10 +47,10 @@ export class InMemoryTxPool implements TxPool {
47
47
  return Promise.resolve(this.txs.size === 0);
48
48
  }
49
49
 
50
- public markAsMined(txHashes: TxHash[], blockHeader: BlockHeader): Promise<void> {
50
+ public markAsMined(txHashes: TxHash[], blockNumber: number): Promise<void> {
51
51
  const keys = txHashes.map(x => x.toBigInt());
52
52
  for (const key of keys) {
53
- this.minedTxs.set(key, blockHeader.globalVariables.blockNumber);
53
+ this.minedTxs.set(key, blockNumber);
54
54
  this.pendingTxs.delete(key);
55
55
  }
56
56
  return Promise.resolve();
@@ -1,4 +1,4 @@
1
- import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
1
+ import type { Tx, TxHash } from '@aztec/stdlib/tx';
2
2
 
3
3
  export type TxPoolOptions = {
4
4
  maxTxPoolSize?: number;
@@ -48,9 +48,8 @@ export interface TxPool {
48
48
  /**
49
49
  * Marks the set of txs as mined, as opposed to pending.
50
50
  * @param txHashes - Hashes of the txs to flag as mined.
51
- * @param blockHeader - The header of the mined block.
52
51
  */
53
- markAsMined(txHashes: TxHash[], blockHeader: BlockHeader): Promise<void>;
52
+ markAsMined(txHashes: TxHash[], blockNumber: number): Promise<void>;
54
53
 
55
54
  /**
56
55
  * Moves mined txs back to the pending set in the case of a reorg.
@@ -1,7 +1,7 @@
1
1
  import { unfreeze } from '@aztec/foundation/types';
2
2
  import { GasFees } from '@aztec/stdlib/gas';
3
3
  import { mockTx } from '@aztec/stdlib/testing';
4
- import { BlockHeader, GlobalVariables, type Tx } from '@aztec/stdlib/tx';
4
+ import type { Tx } from '@aztec/stdlib/tx';
5
5
 
6
6
  import type { TxPool } from './tx_pool.js';
7
7
 
@@ -12,10 +12,6 @@ import type { TxPool } from './tx_pool.js';
12
12
  export function describeTxPool(getTxPool: () => TxPool) {
13
13
  let pool: TxPool;
14
14
 
15
- const minedBlockHeader = BlockHeader.empty({
16
- globalVariables: GlobalVariables.empty({ blockNumber: 1, timestamp: 0n }),
17
- });
18
-
19
15
  beforeEach(() => {
20
16
  pool = getTxPool();
21
17
  });
@@ -47,7 +43,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
47
43
  const tx2 = await mockTx(2);
48
44
 
49
45
  await pool.addTxs([tx1, tx2]);
50
- await pool.markAsMined([await tx1.getTxHash()], minedBlockHeader);
46
+ await pool.markAsMined([await tx1.getTxHash()], 1);
51
47
 
52
48
  await expect(pool.getTxByHash(await tx1.getTxHash())).resolves.toEqual(tx1);
53
49
  await expect(pool.getTxStatus(await tx1.getTxHash())).resolves.toEqual('mined');
@@ -61,7 +57,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
61
57
  const tx2 = await mockTx(2);
62
58
 
63
59
  await pool.addTxs([tx1, tx2]);
64
- await pool.markAsMined([await tx1.getTxHash()], minedBlockHeader);
60
+ await pool.markAsMined([await tx1.getTxHash()], 1);
65
61
 
66
62
  await pool.markMinedAsPending([await tx1.getTxHash()]);
67
63
  await expect(pool.getMinedTxHashes()).resolves.toEqual([]);
@@ -78,7 +74,7 @@ export function describeTxPool(getTxPool: () => TxPool) {
78
74
  const someTxHashThatThisPeerDidNotSee = await tx2.getTxHash();
79
75
  await pool.addTxs([tx1]);
80
76
  // this peer knows that tx2 was mined, but it does not have the tx object
81
- await pool.markAsMined([await tx1.getTxHash(), someTxHashThatThisPeerDidNotSee], minedBlockHeader);
77
+ await pool.markAsMined([await tx1.getTxHash(), someTxHashThatThisPeerDidNotSee], 1);
82
78
  expect(await pool.getMinedTxHashes()).toEqual(
83
79
  expect.arrayContaining([
84
80
  [await tx1.getTxHash(), 1],
@@ -11,7 +11,6 @@ import type {
11
11
  import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
12
12
  import { DatabasePublicStateSource, MerkleTreeId } from '@aztec/stdlib/trees';
13
13
  import type { Tx, TxValidationResult } from '@aztec/stdlib/tx';
14
- import type { UInt64 } from '@aztec/stdlib/types';
15
14
 
16
15
  import { ArchiveCache } from './archive_cache.js';
17
16
  import { BlockHeaderTxValidator } from './block_header_validator.js';
@@ -30,7 +29,6 @@ export interface MessageValidator {
30
29
  }
31
30
 
32
31
  export function createTxMessageValidators(
33
- timestamp: UInt64,
34
32
  blockNumber: number,
35
33
  worldStateSynchronizer: WorldStateSynchronizer,
36
34
  gasFees: GasFees,
@@ -53,7 +51,6 @@ export function createTxMessageValidators(
53
51
  validator: new MetadataTxValidator({
54
52
  l1ChainId: new Fr(l1ChainId),
55
53
  rollupVersion: new Fr(rollupVersion),
56
- timestamp,
57
54
  blockNumber,
58
55
  protocolContractTreeRoot,
59
56
  vkTreeRoot: getVKTreeRoot(),
@@ -79,7 +76,7 @@ export function createTxMessageValidators(
79
76
  severity: PeerErrorSeverity.HighToleranceError,
80
77
  },
81
78
  phasesValidator: {
82
- validator: new PhasesTxValidator(contractDataSource, allowedInSetup, timestamp),
79
+ validator: new PhasesTxValidator(contractDataSource, allowedInSetup, blockNumber),
83
80
  severity: PeerErrorSeverity.MidToleranceError,
84
81
  },
85
82
  blockHeaderValidator: {
@@ -6,12 +6,11 @@ import {
6
6
  TX_ERROR_INCORRECT_PROTOCOL_CONTRACT_TREE_ROOT,
7
7
  TX_ERROR_INCORRECT_ROLLUP_VERSION,
8
8
  TX_ERROR_INCORRECT_VK_TREE_ROOT,
9
- TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP,
9
+ TX_ERROR_INVALID_MAX_BLOCK_NUMBER,
10
10
  Tx,
11
11
  type TxValidationResult,
12
12
  type TxValidator,
13
13
  } from '@aztec/stdlib/tx';
14
- import type { UInt64 } from '@aztec/stdlib/types';
15
14
 
16
15
  export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
17
16
  #log = createLogger('p2p:tx_validator:tx_metadata');
@@ -20,10 +19,6 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
20
19
  private values: {
21
20
  l1ChainId: Fr;
22
21
  rollupVersion: Fr;
23
- // Timestamp at which we will validate that the tx is not expired. This is typically the timestamp of the block
24
- // being built.
25
- timestamp: UInt64;
26
- // Block number in which the tx is considered to be included.
27
22
  blockNumber: number;
28
23
  vkTreeRoot: Fr;
29
24
  protocolContractTreeRoot: Fr;
@@ -38,8 +33,8 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
38
33
  if (!(await this.#hasCorrectRollupVersion(tx))) {
39
34
  errors.push(TX_ERROR_INCORRECT_ROLLUP_VERSION);
40
35
  }
41
- if (!(await this.#isValidForTimestamp(tx))) {
42
- errors.push(TX_ERROR_INVALID_INCLUDE_BY_TIMESTAMP);
36
+ if (!(await this.#isValidForBlockNumber(tx))) {
37
+ errors.push(TX_ERROR_INVALID_MAX_BLOCK_NUMBER);
43
38
  }
44
39
  if (!(await this.#hasCorrectVkTreeRoot(tx))) {
45
40
  errors.push(TX_ERROR_INCORRECT_VK_TREE_ROOT);
@@ -89,20 +84,14 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
89
84
  }
90
85
  }
91
86
 
92
- async #isValidForTimestamp(tx: T): Promise<boolean> {
93
- const includeByTimestamp = tx.data.rollupValidationRequests.includeByTimestamp;
94
- // If building block 1, we skip the expiration check. For details on why see the `validate_include_by_timestamp`
95
- // function in `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
96
- const buildingBlock1 = this.values.blockNumber === 1;
87
+ async #isValidForBlockNumber(tx: T): Promise<boolean> {
88
+ const maxBlockNumber = tx.data.rollupValidationRequests.maxBlockNumber;
97
89
 
98
- if (!buildingBlock1 && includeByTimestamp.isSome && includeByTimestamp.value < this.values.timestamp) {
99
- if (tx.data.constants.historicalHeader.globalVariables.blockNumber === 0) {
100
- this.#log.warn(
101
- `A tx built against a genesis block failed to be included in block 1 which is the only block in which txs built against a genesis block are allowed to be included.`,
102
- );
103
- }
90
+ if (maxBlockNumber.isSome && maxBlockNumber.value < this.values.blockNumber) {
104
91
  this.#log.verbose(
105
- `Rejecting tx ${await Tx.getHash(tx)} for low expiration timestamp. Tx expiration timestamp: ${includeByTimestamp.value}, timestamp: ${this.values.timestamp}.`,
92
+ `Rejecting tx ${await Tx.getHash(tx)} for low max block number. Tx max block number: ${
93
+ maxBlockNumber.value
94
+ }, current block number: ${this.values.blockNumber}.`,
106
95
  );
107
96
  return false;
108
97
  } else {
@@ -11,7 +11,6 @@ import {
11
11
  type TxValidationResult,
12
12
  type TxValidator,
13
13
  } from '@aztec/stdlib/tx';
14
- import type { UInt64 } from '@aztec/stdlib/types';
15
14
 
16
15
  export class PhasesTxValidator implements TxValidator<Tx> {
17
16
  #log = createLogger('sequencer:tx_validator:tx_phases');
@@ -20,7 +19,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
20
19
  constructor(
21
20
  contracts: ContractDataSource,
22
21
  private setupAllowList: AllowedElement[],
23
- private timestamp: UInt64,
22
+ private blockNumber: number,
24
23
  ) {
25
24
  this.contractsDB = new PublicContractsDB(contracts);
26
25
  }
@@ -87,7 +86,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
87
86
  }
88
87
  }
89
88
 
90
- const contractClass = await this.contractsDB.getContractInstance(contractAddress, this.timestamp);
89
+ const contractClass = await this.contractsDB.getContractInstance(contractAddress, this.blockNumber);
91
90
 
92
91
  if (!contractClass) {
93
92
  throw new Error(`Contract not found: ${contractAddress}`);
@@ -1,28 +1,17 @@
1
1
  import type { Timer } from '@aztec/foundation/timer';
2
- import { TopicType } from '@aztec/stdlib/p2p';
2
+ import type { TopicType } from '@aztec/stdlib/p2p';
3
3
  import {
4
4
  Attributes,
5
- type BatchObservableResult,
6
5
  type Histogram,
7
6
  Metrics,
8
- type ObservableGauge,
9
7
  type TelemetryClient,
10
8
  type UpDownCounter,
11
9
  ValueType,
12
10
  } from '@aztec/telemetry-client';
13
11
 
14
- import { type RecordableHistogram, createHistogram } from 'node:perf_hooks';
15
-
16
12
  export class P2PInstrumentation {
17
13
  private messageValidationDuration: Histogram;
18
14
  private messagePrevalidationCount: UpDownCounter;
19
- private messageLatency: Histogram;
20
-
21
- private aggLatencyHisto = new Map<TopicType, RecordableHistogram>();
22
- private aggValidationHisto = new Map<TopicType, RecordableHistogram>();
23
-
24
- private aggLatencyMetrics: Record<'min' | 'max' | 'p50' | 'p90' | 'avg', ObservableGauge>;
25
- private aggValidationMetrics: Record<'min' | 'max' | 'p50' | 'p90' | 'avg', ObservableGauge>;
26
15
 
27
16
  constructor(client: TelemetryClient, name: string) {
28
17
  const meter = client.getMeter(name);
@@ -37,122 +26,14 @@ export class P2PInstrumentation {
37
26
  description: 'How many message pass/fail prevalidation',
38
27
  valueType: ValueType.INT,
39
28
  });
40
-
41
- this.messageLatency = meter.createHistogram(Metrics.P2P_GOSSIP_MESSAGE_LATENCY, {
42
- unit: 'ms',
43
- description: 'P2P message latency',
44
- valueType: ValueType.INT,
45
- });
46
-
47
- this.aggLatencyMetrics = {
48
- avg: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_LATENCY_AVG, {
49
- valueType: ValueType.DOUBLE,
50
- description: 'AVG msg latency',
51
- unit: 'ms',
52
- }),
53
- max: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_LATENCY_MAX, {
54
- valueType: ValueType.DOUBLE,
55
- description: 'MAX msg latency',
56
- unit: 'ms',
57
- }),
58
- min: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_LATENCY_MIN, {
59
- valueType: ValueType.DOUBLE,
60
- description: 'MIN msg latency',
61
- unit: 'ms',
62
- }),
63
- p50: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_LATENCY_P50, {
64
- valueType: ValueType.DOUBLE,
65
- description: 'P50 msg latency',
66
- unit: 'ms',
67
- }),
68
- p90: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_LATENCY_P90, {
69
- valueType: ValueType.DOUBLE,
70
- description: 'P90 msg latency',
71
- unit: 'ms',
72
- }),
73
- };
74
-
75
- this.aggValidationMetrics = {
76
- avg: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_AVG, {
77
- valueType: ValueType.DOUBLE,
78
- description: 'AVG msg validation',
79
- unit: 'ms',
80
- }),
81
- max: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_MAX, {
82
- valueType: ValueType.DOUBLE,
83
- description: 'MAX msg validation',
84
- unit: 'ms',
85
- }),
86
- min: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_MIN, {
87
- valueType: ValueType.DOUBLE,
88
- description: 'MIN msg validation',
89
- unit: 'ms',
90
- }),
91
- p50: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_P50, {
92
- valueType: ValueType.DOUBLE,
93
- description: 'P50 msg validation',
94
- unit: 'ms',
95
- }),
96
- p90: meter.createObservableGauge(Metrics.P2P_GOSSIP_AGG_MESSAGE_VALIDATION_DURATION_P90, {
97
- valueType: ValueType.DOUBLE,
98
- description: 'P90 msg validation',
99
- unit: 'ms',
100
- }),
101
- };
102
-
103
- meter.addBatchObservableCallback(this.aggregate, [
104
- ...Object.values(this.aggValidationMetrics),
105
- ...Object.values(this.aggLatencyMetrics),
106
- ]);
107
29
  }
108
30
 
109
31
  public recordMessageValidation(topicName: TopicType, timerOrMs: Timer | number) {
110
- const ms = Math.ceil(typeof timerOrMs === 'number' ? timerOrMs : timerOrMs.ms());
111
- this.messageValidationDuration.record(ms, { [Attributes.TOPIC_NAME]: topicName });
112
-
113
- let validationHistogram = this.aggValidationHisto.get(topicName);
114
- if (!validationHistogram) {
115
- validationHistogram = createHistogram({ min: 1, max: 5 * 60 * 1000 }); // 5 mins
116
- this.aggValidationHisto.set(topicName, validationHistogram);
117
- }
118
-
119
- validationHistogram.record(Math.max(ms, 1));
32
+ const ms = typeof timerOrMs === 'number' ? timerOrMs : timerOrMs.ms();
33
+ this.messageValidationDuration.record(Math.ceil(ms), { [Attributes.TOPIC_NAME]: topicName });
120
34
  }
121
35
 
122
36
  public incMessagePrevalidationStatus(passed: boolean, topicName: TopicType | undefined) {
123
37
  this.messagePrevalidationCount.add(1, { [Attributes.TOPIC_NAME]: topicName, [Attributes.OK]: passed });
124
38
  }
125
-
126
- public recordMessageLatency(topicName: TopicType, timerOrMs: Timer | number) {
127
- const ms = Math.ceil(typeof timerOrMs === 'number' ? timerOrMs : timerOrMs.ms());
128
- this.messageLatency.record(ms, { [Attributes.TOPIC_NAME]: topicName });
129
-
130
- let latencyHistogram = this.aggLatencyHisto.get(topicName);
131
- if (!latencyHistogram) {
132
- latencyHistogram = createHistogram({ min: 1, max: 24 * 60 * 60 * 1000 }); // 24hrs
133
- this.aggLatencyHisto.set(topicName, latencyHistogram);
134
- }
135
-
136
- latencyHistogram.record(Math.max(ms, 1));
137
- }
138
-
139
- private aggregate = (res: BatchObservableResult) => {
140
- for (const [metrics, histograms] of [
141
- [this.aggLatencyMetrics, this.aggLatencyHisto],
142
- [this.aggValidationMetrics, this.aggValidationHisto],
143
- ] as const) {
144
- for (const topicName of Object.values(TopicType)) {
145
- const histogram = histograms.get(topicName);
146
- if (!histogram) {
147
- continue;
148
- }
149
-
150
- res.observe(metrics.avg, histogram.mean, { [Attributes.TOPIC_NAME]: topicName });
151
- res.observe(metrics.max, histogram.max, { [Attributes.TOPIC_NAME]: topicName });
152
- res.observe(metrics.min, histogram.min, { [Attributes.TOPIC_NAME]: topicName });
153
- res.observe(metrics.p50, histogram.percentile(50), { [Attributes.TOPIC_NAME]: topicName });
154
- res.observe(metrics.p90, histogram.percentile(90), { [Attributes.TOPIC_NAME]: topicName });
155
- }
156
- }
157
- };
158
39
  }
@@ -23,7 +23,6 @@ import {
23
23
  } from '@aztec/stdlib/p2p';
24
24
  import { MerkleTreeId } from '@aztec/stdlib/trees';
25
25
  import { Tx, type TxHash, type TxValidationResult } from '@aztec/stdlib/tx';
26
- import type { UInt64 } from '@aztec/stdlib/types';
27
26
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
28
27
  import { Attributes, OtelMetricsAdapter, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
29
28
 
@@ -126,7 +125,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
126
125
  private peerManager: PeerManagerInterface,
127
126
  protected mempools: MemPools<T>,
128
127
  private archiver: L2BlockSource & ContractDataSource,
129
- private epochCache: EpochCacheInterface,
128
+ epochCache: EpochCacheInterface,
130
129
  private proofVerifier: ClientProtocolCircuitVerifier,
131
130
  private worldStateSynchronizer: WorldStateSynchronizer,
132
131
  telemetry: TelemetryClient,
@@ -537,11 +536,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
537
536
  return result.recipients.length;
538
537
  }
539
538
 
540
- protected preValidateReceivedMessage(
541
- msg: Message,
542
- msgId: string,
543
- source: PeerId,
544
- ): { result: boolean; topicType?: TopicType } {
539
+ protected preValidateReceivedMessage(msg: Message, msgId: string, source: PeerId) {
545
540
  let topicType: TopicType | undefined;
546
541
 
547
542
  switch (msg.topic) {
@@ -564,12 +559,12 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
564
559
  if (!validator || !validator.addMessage(msgId)) {
565
560
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
566
561
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
567
- return { result: false, topicType };
562
+ return false;
568
563
  }
569
564
 
570
565
  this.instrumentation.incMessagePrevalidationStatus(true, topicType);
571
566
 
572
- return { result: true, topicType };
567
+ return true;
573
568
  }
574
569
 
575
570
  /**
@@ -587,15 +582,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
587
582
  messageLatency,
588
583
  });
589
584
 
590
- const preValidationResult = this.preValidateReceivedMessage(msg, msgId, source);
591
-
592
- if (!preValidationResult.result) {
585
+ if (!this.preValidateReceivedMessage(msg, msgId, source)) {
593
586
  return;
594
- } else if (preValidationResult.topicType !== undefined) {
595
- // guard against clock skew & DST
596
- if (messageLatency > 0) {
597
- this.instrumentation.recordMessageLatency(preValidationResult.topicType, messageLatency);
598
- }
599
587
  }
600
588
 
601
589
  if (msg.topic === this.topicStrings[TopicType.tx]) {
@@ -839,11 +827,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
839
827
  [Attributes.TX_HASH]: (await tx.getTxHash()).toString(),
840
828
  }))
841
829
  private async validatePropagatedTx(tx: Tx, peerId: PeerId): Promise<boolean> {
842
- const currentBlockNumber = await this.archiver.getBlockNumber();
843
-
844
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
845
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
846
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
830
+ const blockNumber = (await this.archiver.getBlockNumber()) + 1;
831
+ const messageValidators = await this.createMessageValidators(blockNumber);
847
832
 
848
833
  for (const validator of messageValidators) {
849
834
  const outcome = await this.runValidations(tx, validator);
@@ -856,8 +841,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
856
841
 
857
842
  // Double spend validator has a special case handler
858
843
  if (name === 'doubleSpendValidator') {
859
- const txBlockNumber = currentBlockNumber + 1; // tx is expected to be in the next block
860
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
844
+ severity = await this.handleDoubleSpendFailure(tx, blockNumber);
861
845
  }
862
846
 
863
847
  this.peerManager.penalizePeer(peerId, severity);
@@ -878,11 +862,8 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
878
862
  }
879
863
 
880
864
  public async validate(txs: Tx[]): Promise<void> {
881
- const currentBlockNumber = await this.archiver.getBlockNumber();
882
-
883
- // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
884
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
885
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
865
+ const blockNumber = (await this.archiver.getBlockNumber()) + 1;
866
+ const messageValidators = await this.createMessageValidators(blockNumber);
886
867
 
887
868
  await Promise.all(
888
869
  txs.map(async tx => {
@@ -897,27 +878,20 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
897
878
  }
898
879
 
899
880
  /**
900
- * Create message validators for the given block number and timestamp.
881
+ * Create message validators for the given block number.
901
882
  *
902
883
  * Each validator is a pair of a validator and a severity.
903
884
  * If a validator fails, the peer is penalized with the severity of the validator.
904
885
  *
905
- * @param currentBlockNumber - The current synced block number.
906
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
886
+ * @param blockNumber - The block number to create validators for.
907
887
  * @returns The message validators.
908
888
  */
909
- private async createMessageValidators(
910
- currentBlockNumber: number,
911
- nextSlotTimestamp: UInt64,
912
- ): Promise<Record<string, MessageValidator>[]> {
913
- const gasFees = await this.getGasFees(currentBlockNumber);
889
+ private async createMessageValidators(blockNumber: number): Promise<Record<string, MessageValidator>[]> {
890
+ const gasFees = await this.getGasFees(blockNumber - 1);
914
891
  const allowedInSetup = this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
915
892
 
916
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = currentBlockNumber + 1;
917
-
918
893
  return createTxMessageValidators(
919
- nextSlotTimestamp,
920
- blockNumberInWhichTheTxIsConsideredToBeIncluded,
894
+ blockNumber,
921
895
  this.worldStateSynchronizer,
922
896
  gasFees,
923
897
  this.config.l1ChainId,
@@ -1,6 +1,5 @@
1
1
  import { MockL2BlockSource } from '@aztec/archiver/test';
2
2
  import type { EpochCache } from '@aztec/epoch-cache';
3
- import { SecretValue } from '@aztec/foundation/config';
4
3
  import { type Logger, createLogger } from '@aztec/foundation/log';
5
4
  import { sleep } from '@aztec/foundation/sleep';
6
5
  import type { DataStoreConfig } from '@aztec/kv-store/config';
@@ -79,7 +78,7 @@ export async function makeTestP2PClient(
79
78
  const config: P2PConfig & DataStoreConfig = {
80
79
  ...p2pBaseConfig,
81
80
  p2pEnabled: true,
82
- peerIdPrivateKey: new SecretValue(peerIdPrivateKey),
81
+ peerIdPrivateKey,
83
82
  p2pIp: `127.0.0.1`,
84
83
  listenAddress: `127.0.0.1`,
85
84
  p2pPort: port,
@@ -1,6 +1,5 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
2
  import { timesParallel } from '@aztec/foundation/collection';
3
- import { SecretValue } from '@aztec/foundation/config';
4
3
  import { createLogger } from '@aztec/foundation/log';
5
4
  import type { DataStoreConfig } from '@aztec/kv-store/config';
6
5
  import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
@@ -126,7 +125,7 @@ export async function createTestLibP2PService<T extends P2PClientType>(
126
125
  peerCheckIntervalMS: 1000,
127
126
  maxPeerCount: 5,
128
127
  p2pEnabled: true,
129
- peerIdPrivateKey: new SecretValue(Buffer.from(peerId.privateKey!).toString('hex')),
128
+ peerIdPrivateKey: Buffer.from(peerId.privateKey!).toString('hex'),
130
129
  bootstrapNodeEnrVersionCheck: false,
131
130
  ...chainConfig,
132
131
  } as P2PConfig & DataStoreConfig;
@@ -279,7 +278,7 @@ export function createBootstrapNodeConfig(privateKey: string, port: number, chai
279
278
  l1ChainId: chainConfig.l1ChainId,
280
279
  p2pIp: '127.0.0.1',
281
280
  p2pPort: port,
282
- peerIdPrivateKey: new SecretValue(privateKey),
281
+ peerIdPrivateKey: privateKey,
283
282
  dataDirectory: undefined,
284
283
  dataStoreMapSizeKB: 0,
285
284
  bootstrapNodes: [],
@@ -82,7 +82,6 @@ function mockEpochCache(): EpochCacheInterface {
82
82
  currentSlot: 0n,
83
83
  nextSlot: 0n,
84
84
  }),
85
- getEpochAndSlotInNextL1Slot: () => ({ epoch: 0n, slot: 0n, ts: 0n, now: 0n }),
86
85
  isInCommittee: () => Promise.resolve(false),
87
86
  };
88
87
  }
@@ -1,4 +1,3 @@
1
- import { SecretValue } from '@aztec/foundation/config';
2
1
  import { EthAddress } from '@aztec/foundation/eth-address';
3
2
  import type { Logger } from '@aztec/foundation/log';
4
3
  import { sleep } from '@aztec/foundation/sleep';
@@ -56,7 +55,7 @@ class WorkerClientManager {
56
55
  return {
57
56
  ...getP2PDefaultConfig(),
58
57
  p2pEnabled: true,
59
- peerIdPrivateKey: new SecretValue(this.peerIdPrivateKeys[clientIndex]),
58
+ peerIdPrivateKey: this.peerIdPrivateKeys[clientIndex],
60
59
  listenAddress: '127.0.0.1',
61
60
  p2pIp: '127.0.0.1',
62
61
  p2pPort: port,