@aztec/p2p 0.0.1-commit.88e6f9396 → 0.0.1-commit.8c0b8ff

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 (161) hide show
  1. package/dest/client/factory.d.ts +2 -2
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +5 -5
  4. package/dest/client/p2p_client.d.ts +1 -1
  5. package/dest/client/p2p_client.d.ts.map +1 -1
  6. package/dest/client/p2p_client.js +4 -6
  7. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +5 -6
  8. package/dest/config.d.ts +6 -6
  9. package/dest/config.d.ts.map +1 -1
  10. package/dest/config.js +6 -6
  11. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +4 -4
  12. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  13. package/dest/mem_pools/attestation_pool/attestation_pool.js +4 -8
  14. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +6 -6
  15. package/dest/mem_pools/instrumentation.d.ts +2 -4
  16. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  17. package/dest/mem_pools/instrumentation.js +14 -16
  18. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +5 -7
  19. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  20. package/dest/mem_pools/tx_pool_v2/interfaces.js +0 -1
  21. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +6 -5
  22. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  23. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  24. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  25. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +43 -26
  26. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +1 -1
  27. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  28. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.js +0 -3
  29. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -2
  30. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  31. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +1 -18
  32. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
  33. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  34. package/dest/msg_validators/attestation_validator/attestation_validator.js +4 -5
  35. package/dest/msg_validators/clock_tolerance.d.ts +1 -1
  36. package/dest/msg_validators/clock_tolerance.d.ts.map +1 -1
  37. package/dest/msg_validators/clock_tolerance.js +3 -4
  38. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +1 -1
  39. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
  40. package/dest/msg_validators/proposal_validator/proposal_validator.js +5 -5
  41. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts +9 -0
  42. package/dest/msg_validators/tx_validator/contract_instance_validator.d.ts.map +1 -0
  43. package/dest/msg_validators/tx_validator/contract_instance_validator.js +48 -0
  44. package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
  45. package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/tx_validator/data_validator.js +35 -2
  47. package/dest/msg_validators/tx_validator/factory.d.ts +1 -1
  48. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  49. package/dest/msg_validators/tx_validator/factory.js +8 -2
  50. package/dest/msg_validators/tx_validator/metadata_validator.d.ts +1 -1
  51. package/dest/msg_validators/tx_validator/metadata_validator.d.ts.map +1 -1
  52. package/dest/msg_validators/tx_validator/metadata_validator.js +4 -4
  53. package/dest/msg_validators/tx_validator/phases_validator.js +1 -1
  54. package/dest/services/libp2p/libp2p_service.d.ts +9 -2
  55. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  56. package/dest/services/libp2p/libp2p_service.js +25 -22
  57. package/dest/services/peer-manager/metrics.d.ts +1 -3
  58. package/dest/services/peer-manager/metrics.d.ts.map +1 -1
  59. package/dest/services/peer-manager/metrics.js +0 -6
  60. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  61. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  62. package/dest/services/peer-manager/peer_manager.js +3 -6
  63. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +8 -11
  64. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  65. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +101 -79
  66. package/dest/services/reqresp/batch-tx-requester/interface.d.ts +2 -3
  67. package/dest/services/reqresp/batch-tx-requester/interface.d.ts.map +1 -1
  68. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts +4 -5
  69. package/dest/services/reqresp/batch-tx-requester/missing_txs.d.ts.map +1 -1
  70. package/dest/services/reqresp/batch-tx-requester/missing_txs.js +7 -13
  71. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +11 -19
  72. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  73. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +15 -52
  74. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  75. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  76. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  77. package/dest/services/reqresp/reqresp.d.ts +1 -1
  78. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  79. package/dest/services/reqresp/reqresp.js +3 -4
  80. package/dest/services/tx_collection/fast_tx_collection.d.ts +4 -1
  81. package/dest/services/tx_collection/fast_tx_collection.d.ts.map +1 -1
  82. package/dest/services/tx_collection/fast_tx_collection.js +73 -57
  83. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  84. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  85. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  86. package/dest/services/tx_collection/missing_txs_tracker.d.ts +32 -0
  87. package/dest/services/tx_collection/missing_txs_tracker.d.ts.map +1 -0
  88. package/dest/services/tx_collection/missing_txs_tracker.js +27 -0
  89. package/dest/services/tx_collection/proposal_tx_collector.d.ts +7 -6
  90. package/dest/services/tx_collection/proposal_tx_collector.d.ts.map +1 -1
  91. package/dest/services/tx_collection/proposal_tx_collector.js +4 -4
  92. package/dest/services/tx_collection/slow_tx_collection.js +1 -1
  93. package/dest/services/tx_collection/tx_collection.d.ts +6 -3
  94. package/dest/services/tx_collection/tx_collection.d.ts.map +1 -1
  95. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  96. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  97. package/dest/services/tx_collection/tx_source.js +9 -7
  98. package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
  99. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  100. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  101. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  102. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  103. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  104. package/dest/test-helpers/testbench-utils.js +2 -20
  105. package/dest/testbench/p2p_client_testbench_worker.d.ts +1 -1
  106. package/dest/testbench/p2p_client_testbench_worker.d.ts.map +1 -1
  107. package/dest/testbench/p2p_client_testbench_worker.js +5 -6
  108. package/dest/testbench/worker_client_manager.d.ts +1 -1
  109. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  110. package/dest/testbench/worker_client_manager.js +1 -2
  111. package/dest/util.d.ts +1 -1
  112. package/package.json +14 -14
  113. package/src/client/factory.ts +8 -4
  114. package/src/client/p2p_client.ts +4 -6
  115. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +8 -7
  116. package/src/config.ts +10 -10
  117. package/src/mem_pools/attestation_pool/attestation_pool.ts +7 -8
  118. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +6 -6
  119. package/src/mem_pools/instrumentation.ts +13 -17
  120. package/src/mem_pools/tx_pool_v2/interfaces.ts +4 -7
  121. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +4 -4
  122. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +43 -29
  123. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +0 -3
  124. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +1 -19
  125. package/src/msg_validators/attestation_validator/README.md +1 -1
  126. package/src/msg_validators/attestation_validator/attestation_validator.ts +4 -5
  127. package/src/msg_validators/clock_tolerance.ts +3 -4
  128. package/src/msg_validators/proposal_validator/README.md +3 -3
  129. package/src/msg_validators/proposal_validator/proposal_validator.ts +5 -6
  130. package/src/msg_validators/tx_validator/contract_instance_validator.ts +56 -0
  131. package/src/msg_validators/tx_validator/data_validator.ts +42 -1
  132. package/src/msg_validators/tx_validator/factory.ts +7 -0
  133. package/src/msg_validators/tx_validator/metadata_validator.ts +4 -12
  134. package/src/msg_validators/tx_validator/phases_validator.ts +1 -1
  135. package/src/services/libp2p/libp2p_service.ts +28 -18
  136. package/src/services/peer-manager/metrics.ts +0 -7
  137. package/src/services/peer-manager/peer_manager.ts +3 -7
  138. package/src/services/reqresp/batch-tx-requester/README.md +7 -46
  139. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +111 -75
  140. package/src/services/reqresp/batch-tx-requester/interface.ts +1 -2
  141. package/src/services/reqresp/batch-tx-requester/missing_txs.ts +6 -13
  142. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +24 -68
  143. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  144. package/src/services/reqresp/reqresp.ts +3 -5
  145. package/src/services/tx_collection/fast_tx_collection.ts +83 -57
  146. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  147. package/src/services/tx_collection/missing_txs_tracker.ts +52 -0
  148. package/src/services/tx_collection/proposal_tx_collector.ts +13 -8
  149. package/src/services/tx_collection/slow_tx_collection.ts +1 -1
  150. package/src/services/tx_collection/tx_collection.ts +5 -3
  151. package/src/services/tx_collection/tx_source.ts +8 -7
  152. package/src/test-helpers/make-test-p2p-clients.ts +1 -1
  153. package/src/test-helpers/reqresp-nodes.ts +1 -1
  154. package/src/test-helpers/testbench-utils.ts +3 -28
  155. package/src/testbench/p2p_client_testbench_worker.ts +9 -7
  156. package/src/testbench/worker_client_manager.ts +1 -2
  157. package/src/util.ts +1 -1
  158. package/dest/services/tx_collection/request_tracker.d.ts +0 -53
  159. package/dest/services/tx_collection/request_tracker.d.ts.map +0 -1
  160. package/dest/services/tx_collection/request_tracker.js +0 -84
  161. package/src/services/tx_collection/request_tracker.ts +0 -127
@@ -1,8 +1,7 @@
1
- import { insertIntoSortedArray, removeFromSortedArray } from '@aztec/foundation/array';
2
1
  import { SlotNumber } from '@aztec/foundation/branded-types';
3
2
  import type { L2BlockId } from '@aztec/stdlib/block';
4
3
 
5
- import { type PriorityComparable, type TxMetaData, type TxState, comparePriority } from './tx_metadata.js';
4
+ import { type TxMetaData, type TxState, compareFee, compareTxHash, txHashFromBigInt } from './tx_metadata.js';
6
5
 
7
6
  /**
8
7
  * Manages in-memory indices for the transaction pool.
@@ -23,8 +22,8 @@ export class TxPoolIndices {
23
22
  #nullifierToTxHash: Map<string, string> = new Map();
24
23
  /** Fee payer to txHashes index (pending txs only) */
25
24
  #feePayerToTxHashes: Map<string, Set<string>> = new Map();
26
- /** Pending transactions sorted ascending by priority fee, ties broken by txHash */
27
- #pendingByPriority: PriorityComparable[] = [];
25
+ /** Pending txHash bigints grouped by priority fee */
26
+ #pendingByPriority: Map<bigint, Set<bigint>> = new Map();
28
27
  /** Protected transactions: txHash -> slotNumber */
29
28
  #protectedTransactions: Map<string, SlotNumber> = new Map();
30
29
 
@@ -74,14 +73,20 @@ export class TxPoolIndices {
74
73
  * @param order - 'desc' for highest priority first, 'asc' for lowest priority first
75
74
  */
76
75
  *iteratePendingByPriority(order: 'asc' | 'desc', filter?: (hash: string) => boolean): Generator<string> {
77
- const arr = this.#pendingByPriority;
78
- const start = order === 'asc' ? 0 : arr.length - 1;
79
- const step = order === 'asc' ? 1 : -1;
80
- const inBounds = order === 'asc' ? (i: number) => i < arr.length : (i: number) => i >= 0;
81
-
82
- for (let i = start; inBounds(i); i += step) {
83
- if (filter === undefined || filter(arr[i].txHash)) {
84
- yield arr[i].txHash;
76
+ const feeCompareFn = order === 'desc' ? (a: bigint, b: bigint) => compareFee(b, a) : compareFee;
77
+ const hashCompareFn =
78
+ order === 'desc' ? (a: bigint, b: bigint) => compareTxHash(b, a) : (a: bigint, b: bigint) => compareTxHash(a, b);
79
+
80
+ const sortedFees = [...this.#pendingByPriority.keys()].sort(feeCompareFn);
81
+
82
+ for (const fee of sortedFees) {
83
+ const hashesAtFee = this.#pendingByPriority.get(fee)!;
84
+ const sortedHashes = [...hashesAtFee].sort(hashCompareFn);
85
+ for (const hashBigInt of sortedHashes) {
86
+ const hash = txHashFromBigInt(hashBigInt);
87
+ if (filter === undefined || filter(hash)) {
88
+ yield hash;
89
+ }
85
90
  }
86
91
  }
87
92
  }
@@ -222,7 +227,11 @@ export class TxPoolIndices {
222
227
 
223
228
  /** Gets the count of pending transactions */
224
229
  getPendingTxCount(): number {
225
- return this.#pendingByPriority.length;
230
+ let count = 0;
231
+ for (const hashes of this.#pendingByPriority.values()) {
232
+ count += hashes.size;
233
+ }
234
+ return count;
226
235
  }
227
236
 
228
237
  /** Gets the lowest priority pending transaction hashes (up to limit) */
@@ -255,10 +264,12 @@ export class TxPoolIndices {
255
264
  /** Gets all pending transactions */
256
265
  getPendingTxs(): TxMetaData[] {
257
266
  const result: TxMetaData[] = [];
258
- for (const entry of this.#pendingByPriority) {
259
- const meta = this.#metadata.get(entry.txHash);
260
- if (meta) {
261
- result.push(meta);
267
+ for (const hashSet of this.#pendingByPriority.values()) {
268
+ for (const txHashBigInt of hashSet) {
269
+ const meta = this.#metadata.get(txHashFromBigInt(txHashBigInt));
270
+ if (meta) {
271
+ result.push(meta);
272
+ }
262
273
  }
263
274
  }
264
275
  return result;
@@ -397,12 +408,13 @@ export class TxPoolIndices {
397
408
  }
398
409
  feePayerSet.add(meta.txHash);
399
410
 
400
- insertIntoSortedArray(
401
- this.#pendingByPriority,
402
- { txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
403
- comparePriority,
404
- false,
405
- );
411
+ // Add to priority bucket
412
+ let prioritySet = this.#pendingByPriority.get(meta.priorityFee);
413
+ if (!prioritySet) {
414
+ prioritySet = new Set();
415
+ this.#pendingByPriority.set(meta.priorityFee, prioritySet);
416
+ }
417
+ prioritySet.add(meta.txHashBigInt);
406
418
  }
407
419
 
408
420
  #removeFromPendingIndices(meta: TxMetaData): void {
@@ -420,11 +432,13 @@ export class TxPoolIndices {
420
432
  }
421
433
  }
422
434
 
423
- // Remove from priority array
424
- removeFromSortedArray(
425
- this.#pendingByPriority,
426
- { txHash: meta.txHash, priorityFee: meta.priorityFee, txHashBigInt: meta.txHashBigInt },
427
- comparePriority,
428
- );
435
+ // Remove from priority map
436
+ const hashSet = this.#pendingByPriority.get(meta.priorityFee);
437
+ if (hashSet) {
438
+ hashSet.delete(meta.txHashBigInt);
439
+ if (hashSet.size === 0) {
440
+ this.#pendingByPriority.delete(meta.priorityFee);
441
+ }
442
+ }
429
443
  }
430
444
  }
@@ -65,9 +65,6 @@ export class AztecKVTxPoolV2 extends (EventEmitter as new () => TypedEventEmitte
65
65
  const hashes = txHashes.map(h => (typeof h === 'string' ? TxHash.fromString(h) : TxHash.fromBigInt(h)));
66
66
  this.emit('txs-removed', { txHashes: hashes });
67
67
  },
68
- onTxsMined: (txHashes: string[]) => {
69
- this.#metrics?.transactionsRemoved(txHashes);
70
- },
71
68
  };
72
69
 
73
70
  // Create the implementation
@@ -45,7 +45,6 @@ import { TxPoolIndices } from './tx_pool_indices.js';
45
45
  export interface TxPoolV2Callbacks {
46
46
  onTxsAdded: (txs: Tx[], opts: { source?: string }) => void;
47
47
  onTxsRemoved: (txHashes: string[] | bigint[]) => void;
48
- onTxsMined: (txHashes: string[]) => void;
49
48
  }
50
49
 
51
50
  /**
@@ -340,12 +339,6 @@ export class TxPoolV2Impl {
340
339
  }
341
340
  }
342
341
 
343
- // Randomly drop the transaction for testing purposes (report as accepted so it propagates)
344
- if (this.#config.dropTransactionsProbability > 0 && Math.random() < this.#config.dropTransactionsProbability) {
345
- this.#log.debug(`Dropping tx ${txHashStr} (simulated drop for testing)`);
346
- return { status: 'accepted' };
347
- }
348
-
349
342
  // Add the transaction
350
343
  await this.#addTx(tx, 'pending', opts, precomputedMeta);
351
344
  return { status: 'accepted' };
@@ -356,7 +349,6 @@ export class TxPoolV2Impl {
356
349
 
357
350
  // Check if already in pool
358
351
  if (this.#indices.has(txHashStr)) {
359
- this.#log.verbose(`canAddPendingTx: tx ${txHashStr} already in pool`);
360
352
  return 'ignored';
361
353
  }
362
354
 
@@ -365,13 +357,7 @@ export class TxPoolV2Impl {
365
357
  const poolAccess = this.#createPreAddPoolAccess();
366
358
  const preAddResult = await this.#evictionManager.runPreAddRules(meta, poolAccess);
367
359
 
368
- if (preAddResult.shouldIgnore) {
369
- this.#log.verbose(`canAddPendingTx: tx ${txHashStr} ignored by pre-add rule`, {
370
- reason: preAddResult.reason?.message ?? 'no reason provided',
371
- });
372
- return 'ignored';
373
- }
374
- return 'accepted';
360
+ return preAddResult.shouldIgnore ? 'ignored' : 'accepted';
375
361
  }
376
362
 
377
363
  async addProtectedTxs(txs: Tx[], block: BlockHeader, opts: { source?: string }): Promise<void> {
@@ -515,10 +501,6 @@ export class TxPoolV2Impl {
515
501
  await this.#evictionManager.evictAfterNewBlock(block.header, nullifiers, feePayers);
516
502
  });
517
503
 
518
- if (found.length > 0) {
519
- this.#callbacks.onTxsMined(found.map(m => m.txHash));
520
- }
521
-
522
504
  this.#log.info(`Marked ${found.length} txs as mined in block ${blockId.number}`);
523
505
  }
524
506
 
@@ -24,7 +24,7 @@ This module validates `CheckpointAttestation` gossipsub messages. Attestations a
24
24
  |---|------|-------------|
25
25
  | 8 | Sender recoverable (pool-side) | Silent drop |
26
26
  | 9 | Not a duplicate (same slot + proposalId + signer) | IGNORE |
27
- | 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` = 2 | IGNORE |
27
+ | 10 | Per-signer cap: `MAX_ATTESTATIONS_PER_SLOT_AND_SIGNER` = 3 | IGNORE |
28
28
 
29
29
  Own attestations added via `addOwnCheckpointAttestations` bypass the per-signer cap.
30
30
 
@@ -23,14 +23,13 @@ export class CheckpointAttestationValidator implements P2PValidator<CheckpointAt
23
23
  const slotNumber = message.payload.header.slotNumber;
24
24
 
25
25
  try {
26
- // Use target slots since proposals target pipeline slots (slot + 1 when pipelining)
27
- const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();
26
+ const { currentSlot, nextSlot } = this.epochCache.getCurrentAndNextSlot();
28
27
 
29
- if (slotNumber !== targetSlot && slotNumber !== nextSlot) {
28
+ if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
30
29
  // Check if message is for previous slot and within clock tolerance
31
- if (!isWithinClockTolerance(slotNumber, targetSlot, this.epochCache)) {
30
+ if (!isWithinClockTolerance(slotNumber, currentSlot, this.epochCache)) {
32
31
  this.logger.warn(
33
- `Checkpoint attestation slot ${slotNumber} is not current (${targetSlot}) or next (${nextSlot}) slot`,
32
+ `Checkpoint attestation slot ${slotNumber} is not current (${currentSlot}) or next (${nextSlot}) slot`,
34
33
  );
35
34
  return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
36
35
  }
@@ -36,11 +36,10 @@ export function isWithinClockTolerance(
36
36
  }
37
37
 
38
38
  // Check how far we are into the current slot (in milliseconds)
39
- const { ts: slotStartTs, nowMs } = epochCache.getEpochAndSlotNow();
40
- const targetSlot = epochCache.getTargetSlot();
39
+ const { ts: slotStartTs, nowMs, slot } = epochCache.getEpochAndSlotNow();
41
40
 
42
- // Sanity check: ensure the epoch cache's target slot matches the expected current slot
43
- if (targetSlot !== currentSlot) {
41
+ // Sanity check: ensure the epoch cache's current slot matches the expected current slot
42
+ if (slot !== currentSlot) {
44
43
  return false;
45
44
  }
46
45
 
@@ -28,7 +28,7 @@ Deserialization guards: `BlockProposal.fromBuffer` and `SignedTxs.fromBuffer` bo
28
28
  | # | Rule | Consequence |
29
29
  |---|------|-------------|
30
30
  | 9 | **Duplicate**: same archive root already stored | IGNORE (no penalty) |
31
- | 10 | **Per-position cap**: max 2 proposals per (slot, indexWithinCheckpoint) | REJECT + HighToleranceError |
31
+ | 10 | **Per-position cap**: max 3 proposals per (slot, indexWithinCheckpoint) | REJECT + HighToleranceError |
32
32
  | 11 | **Equivocation**: >1 distinct proposal for same (slot, index) | ACCEPT (rebroadcast for detection). At count=2: `duplicateProposalCallback` fires -> slash event (`OffenseType.DUPLICATE_PROPOSAL`, configured via `slashDuplicateProposalPenalty`) |
33
33
 
34
34
  ### Stage 3: Validator-Client Processing (BlockProposalHandler)
@@ -84,7 +84,7 @@ The checkpoint's embedded `lastBlock` is extracted via `getBlockProposal()` and
84
84
  | Rule | Consequence | File |
85
85
  |------|-------------|------|
86
86
  | Block proposal must pass `BlockProposalValidator.validate()` | If REJECT: entire checkpoint REJECTED | `libp2p_service.ts` |
87
- | Block proposal must not exceed per-position cap (2) | Checkpoint REJECTED + HighToleranceError | same |
87
+ | Block proposal must not exceed per-position cap (3) | Checkpoint REJECTED + HighToleranceError | same |
88
88
  | Block equivocation detected (>1 proposals for same slot+index) | Checkpoint REJECTED (block itself is ACCEPT for re-broadcast) | same |
89
89
 
90
90
  ### Stage 3: Mempool (Attestation Pool)
@@ -92,7 +92,7 @@ The checkpoint's embedded `lastBlock` is extracted via `getBlockProposal()` and
92
92
  | Rule | Consequence | File |
93
93
  |------|-------------|------|
94
94
  | Duplicate (same archive ID) | IGNORE (no penalty). Embedded block still processed if valid. | `attestation_pool.ts` |
95
- | Per-slot cap: `MAX_CHECKPOINT_PROPOSALS_PER_SLOT` = 2 | REJECT + HighToleranceError. Embedded block still processed. | same |
95
+ | Per-slot cap: `MAX_CHECKPOINT_PROPOSALS_PER_SLOT` = 5 | REJECT + HighToleranceError. Embedded block still processed. | same |
96
96
 
97
97
  ### Stage 4: Equivocation Detection
98
98
 
@@ -31,14 +31,13 @@ export class ProposalValidator {
31
31
  /** Validates header-level fields: slot, signature, and proposer. */
32
32
  public async validate(proposal: BlockProposal | CheckpointProposalCore): Promise<ValidationResult> {
33
33
  try {
34
- // Slot check: use target slots since proposals target pipeline slots (slot + 1 when pipelining)
35
- const { targetSlot, nextSlot } = this.epochCache.getTargetAndNextSlot();
36
-
34
+ // Slot check
35
+ const { currentSlot, nextSlot } = this.epochCache.getCurrentAndNextSlot();
37
36
  const slotNumber = proposal.slotNumber;
38
- if (slotNumber !== targetSlot && slotNumber !== nextSlot) {
37
+ if (slotNumber !== currentSlot && slotNumber !== nextSlot) {
39
38
  // Check if message is for previous slot and within clock tolerance
40
- if (!isWithinClockTolerance(slotNumber, targetSlot, this.epochCache)) {
41
- this.logger.warn(`Penalizing peer for invalid slot number ${slotNumber}`, { targetSlot, nextSlot });
39
+ if (!isWithinClockTolerance(slotNumber, currentSlot, this.epochCache)) {
40
+ this.logger.warn(`Penalizing peer for invalid slot number ${slotNumber}`, { currentSlot, nextSlot });
42
41
  return { result: 'reject', severity: PeerErrorSeverity.HighToleranceError };
43
42
  }
44
43
  this.logger.verbose(`Ignoring proposal for previous slot ${slotNumber} within clock tolerance`);
@@ -0,0 +1,56 @@
1
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
2
+ import { ContractInstancePublishedEvent } from '@aztec/protocol-contracts/instance-registry';
3
+ import { computeContractAddressFromInstance } from '@aztec/stdlib/contract';
4
+ import {
5
+ TX_ERROR_INCORRECT_CONTRACT_ADDRESS,
6
+ TX_ERROR_MALFORMED_CONTRACT_INSTANCE_LOG,
7
+ type Tx,
8
+ type TxValidationResult,
9
+ type TxValidator,
10
+ } from '@aztec/stdlib/tx';
11
+
12
+ /** Validates that contract instance deployment logs contain correct addresses. */
13
+ export class ContractInstanceTxValidator implements TxValidator<Tx> {
14
+ #log: Logger;
15
+
16
+ constructor(bindings?: LoggerBindings) {
17
+ this.#log = createLogger('p2p:tx_validator:contract_instance', bindings);
18
+ }
19
+
20
+ async validateTx(tx: Tx): Promise<TxValidationResult> {
21
+ const reason = await this.#hasCorrectContractInstanceAddresses(tx);
22
+ return reason ? { result: 'invalid', reason: [reason] } : { result: 'valid' };
23
+ }
24
+
25
+ async #hasCorrectContractInstanceAddresses(tx: Tx): Promise<string | undefined> {
26
+ const privateLogs = tx.data.getNonEmptyPrivateLogs();
27
+ for (const log of privateLogs) {
28
+ if (!ContractInstancePublishedEvent.isContractInstancePublishedEvent(log)) {
29
+ continue;
30
+ }
31
+
32
+ let event;
33
+ try {
34
+ event = ContractInstancePublishedEvent.fromLog(log);
35
+ } catch (e) {
36
+ this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to parse contract instance event: ${e}`);
37
+ return TX_ERROR_MALFORMED_CONTRACT_INSTANCE_LOG;
38
+ }
39
+
40
+ try {
41
+ const instance = event.toContractInstance();
42
+ const computedAddress = await computeContractAddressFromInstance(instance);
43
+ if (!computedAddress.equals(instance.address)) {
44
+ this.#log.warn(
45
+ `Rejecting tx ${tx.getTxHash()}: contract instance address mismatch. Claimed ${instance.address}, computed ${computedAddress}`,
46
+ );
47
+ return TX_ERROR_INCORRECT_CONTRACT_ADDRESS;
48
+ }
49
+ } catch (e) {
50
+ this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to compute contract instance address: ${e}`);
51
+ return TX_ERROR_MALFORMED_CONTRACT_INSTANCE_LOG;
52
+ }
53
+ }
54
+ return undefined;
55
+ }
56
+ }
@@ -1,5 +1,7 @@
1
1
  import { MAX_FR_CALLDATA_TO_ALL_ENQUEUED_CALLS } from '@aztec/constants';
2
2
  import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
3
+ import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
4
+ import { computeContractClassId } from '@aztec/stdlib/contract';
3
5
  import { computeCalldataHash } from '@aztec/stdlib/hash';
4
6
  import {
5
7
  TX_ERROR_CALLDATA_COUNT_MISMATCH,
@@ -9,7 +11,9 @@ import {
9
11
  TX_ERROR_CONTRACT_CLASS_LOG_LENGTH,
10
12
  TX_ERROR_CONTRACT_CLASS_LOG_SORTING,
11
13
  TX_ERROR_INCORRECT_CALLDATA,
14
+ TX_ERROR_INCORRECT_CONTRACT_CLASS_ID,
12
15
  TX_ERROR_INCORRECT_HASH,
16
+ TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG,
13
17
  Tx,
14
18
  type TxValidationResult,
15
19
  type TxValidator,
@@ -26,7 +30,8 @@ export class DataTxValidator implements TxValidator<Tx> {
26
30
  const reason =
27
31
  (await this.#hasCorrectHash(tx)) ??
28
32
  (await this.#hasCorrectCalldata(tx)) ??
29
- (await this.#hasCorrectContractClassLogs(tx));
33
+ (await this.#hasCorrectContractClassLogs(tx)) ??
34
+ (await this.#hasCorrectContractClassIds(tx));
30
35
  return reason ? { result: 'invalid', reason: [reason] } : { result: 'valid' };
31
36
  }
32
37
 
@@ -127,4 +132,40 @@ export class DataTxValidator implements TxValidator<Tx> {
127
132
 
128
133
  return undefined;
129
134
  }
135
+
136
+ async #hasCorrectContractClassIds(tx: Tx): Promise<string | undefined> {
137
+ const contractClassLogs = tx.getContractClassLogs();
138
+ for (const log of contractClassLogs) {
139
+ if (!ContractClassPublishedEvent.isContractClassPublishedEvent(log)) {
140
+ continue;
141
+ }
142
+
143
+ let event;
144
+ try {
145
+ event = ContractClassPublishedEvent.fromLog(log);
146
+ } catch (e) {
147
+ this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to parse contract class event: ${e}`);
148
+ return TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG;
149
+ }
150
+
151
+ try {
152
+ const { publicBytecodeCommitment } = await event.toContractClassPublicWithBytecodeCommitment();
153
+ const computedClassId = await computeContractClassId({
154
+ artifactHash: event.artifactHash,
155
+ privateFunctionsRoot: event.privateFunctionsRoot,
156
+ publicBytecodeCommitment,
157
+ });
158
+ if (!computedClassId.equals(event.contractClassId)) {
159
+ this.#log.warn(
160
+ `Rejecting tx ${tx.getTxHash()}: contract class id mismatch. Claimed ${event.contractClassId}, computed ${computedClassId}`,
161
+ );
162
+ return TX_ERROR_INCORRECT_CONTRACT_CLASS_ID;
163
+ }
164
+ } catch (e) {
165
+ this.#log.warn(`Rejecting tx ${tx.getTxHash()}: failed to compute contract class id: ${e}`);
166
+ return TX_ERROR_MALFORMED_CONTRACT_CLASS_LOG;
167
+ }
168
+ }
169
+ return undefined;
170
+ }
130
171
  }
@@ -53,6 +53,7 @@ import type { TxMetaData } from '../../mem_pools/tx_pool_v2/tx_metadata.js';
53
53
  import { AggregateTxValidator } from './aggregate_tx_validator.js';
54
54
  import { ArchiveCache } from './archive_cache.js';
55
55
  import { type ArchiveSource, BlockHeaderTxValidator } from './block_header_validator.js';
56
+ import { ContractInstanceTxValidator } from './contract_instance_validator.js';
56
57
  import { DataTxValidator } from './data_validator.js';
57
58
  import { DoubleSpendTxValidator, type NullifierSource } from './double_spend_validator.js';
58
59
  import { GasLimitsValidator, GasTxValidator } from './gas_validator.js';
@@ -167,6 +168,10 @@ export function createFirstStageTxValidationsForGossipedTransactions(
167
168
  validator: new DataTxValidator(bindings),
168
169
  severity: PeerErrorSeverity.MidToleranceError,
169
170
  },
171
+ contractInstanceValidator: {
172
+ validator: new ContractInstanceTxValidator(bindings),
173
+ severity: PeerErrorSeverity.MidToleranceError,
174
+ },
170
175
  };
171
176
  }
172
177
 
@@ -218,6 +223,7 @@ function createTxValidatorForMinimumTxIntegrityChecks(
218
223
  ),
219
224
  new SizeTxValidator(bindings),
220
225
  new DataTxValidator(bindings),
226
+ new ContractInstanceTxValidator(bindings),
221
227
  new TxProofValidator(verifier, bindings),
222
228
  );
223
229
  }
@@ -321,6 +327,7 @@ export function createTxValidatorForAcceptingTxsOverRPC(
321
327
  new BlockHeaderTxValidator(new ArchiveCache(db), bindings),
322
328
  new DoubleSpendTxValidator(new NullifierCache(db), bindings),
323
329
  new DataTxValidator(bindings),
330
+ new ContractInstanceTxValidator(bindings),
324
331
  ];
325
332
 
326
333
  if (!skipFeeEnforcement) {
@@ -28,24 +28,16 @@ export class MetadataTxValidator<T extends AnyTx> implements TxValidator<T> {
28
28
  validateTx(tx: T): Promise<TxValidationResult> {
29
29
  const errors = [];
30
30
  if (!this.#hasCorrectL1ChainId(tx)) {
31
- errors.push(
32
- `${TX_ERROR_INCORRECT_L1_CHAIN_ID} (tx: ${tx.data.constants.txContext.chainId.toNumber()}, expected: ${this.values.l1ChainId.toNumber()})`,
33
- );
31
+ errors.push(TX_ERROR_INCORRECT_L1_CHAIN_ID);
34
32
  }
35
33
  if (!this.#hasCorrectRollupVersion(tx)) {
36
- errors.push(
37
- `${TX_ERROR_INCORRECT_ROLLUP_VERSION} (tx: ${tx.data.constants.txContext.version.toNumber()}, expected: ${this.values.rollupVersion.toNumber()})`,
38
- );
34
+ errors.push(TX_ERROR_INCORRECT_ROLLUP_VERSION);
39
35
  }
40
36
  if (!this.#hasCorrectVkTreeRoot(tx)) {
41
- errors.push(
42
- `${TX_ERROR_INCORRECT_VK_TREE_ROOT} (tx: ${tx.data.constants.vkTreeRoot.toString()}, expected: ${this.values.vkTreeRoot.toString()})`,
43
- );
37
+ errors.push(TX_ERROR_INCORRECT_VK_TREE_ROOT);
44
38
  }
45
39
  if (!this.#hasCorrectprotocolContractsHash(tx)) {
46
- errors.push(
47
- `${TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH} (tx: ${tx.data.constants.protocolContractsHash.toString()}, expected: ${this.values.protocolContractsHash.toString()})`,
48
- );
40
+ errors.push(TX_ERROR_INCORRECT_PROTOCOL_CONTRACTS_HASH);
49
41
  }
50
42
  return Promise.resolve(errors.length > 0 ? { result: 'invalid', reason: errors } : { result: 'valid' });
51
43
  }
@@ -40,7 +40,7 @@ export class PhasesTxValidator implements TxValidator<Tx> {
40
40
  // which are needed for public FPC flows, but fail if the account contract hasnt been deployed yet,
41
41
  // which is what we're trying to do as part of the current txs.
42
42
  // We only need to create/revert checkpoint here because of this addNewContracts call.
43
- await this.contractsDB.addNewContracts(tx);
43
+ this.contractsDB.addNewContracts(tx);
44
44
 
45
45
  if (!tx.data.forPublic) {
46
46
  this.#log.debug(
@@ -18,6 +18,7 @@ import {
18
18
  type CheckpointProposalCore,
19
19
  type Gossipable,
20
20
  P2PMessage,
21
+ type ValidationResult as P2PValidationResult,
21
22
  PeerErrorSeverity,
22
23
  PeerErrorSeverityByHarshness,
23
24
  TopicType,
@@ -753,9 +754,6 @@ export class LibP2PService extends WithTracer implements P2PService {
753
754
  if (!validator || !validator.addMessage(msgId)) {
754
755
  this.instrumentation.incMessagePrevalidationStatus(false, topicType);
755
756
  this.node.services.pubsub.reportMessageValidationResult(msgId, source.toString(), TopicValidatorResult.Ignore);
756
- if (topicType === TopicType.tx) {
757
- this.logger.verbose(`Ignoring already-seen tx gossip message`, { msgId, source: source.toString() });
758
- }
759
757
  return { result: false, topicType };
760
758
  }
761
759
 
@@ -925,11 +923,6 @@ export class LibP2PService extends WithTracer implements P2PService {
925
923
  severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
926
924
  }
927
925
 
928
- this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 1 validation failed`, {
929
- validator: name,
930
- severity,
931
- source: source.toString(),
932
- });
933
926
  this.peerManager.penalizePeer(source, severity);
934
927
  return { result: TopicValidatorResult.Reject };
935
928
  }
@@ -937,9 +930,6 @@ export class LibP2PService extends WithTracer implements P2PService {
937
930
  // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
938
931
  const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
939
932
  if (canAdd === 'ignored') {
940
- this.logger.verbose(`Ignoring gossiped tx ${tx.getTxHash().toString()}: pool pre-check returned ignored`, {
941
- source: source.toString(),
942
- });
943
933
  return { result: TopicValidatorResult.Ignore, obj: tx };
944
934
  }
945
935
 
@@ -947,12 +937,7 @@ export class LibP2PService extends WithTracer implements P2PService {
947
937
  const secondStageValidators = this.createSecondStageMessageValidators();
948
938
  const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
949
939
  if (!secondStageOutcome.allPassed) {
950
- const { severity, name } = secondStageOutcome.failure;
951
- this.logger.verbose(`Rejecting gossiped tx ${tx.getTxHash().toString()}: stage 2 validation failed`, {
952
- validator: name,
953
- severity,
954
- source: source.toString(),
955
- });
940
+ const { severity } = secondStageOutcome.failure;
956
941
  this.peerManager.penalizePeer(source, severity);
957
942
  return { result: TopicValidatorResult.Reject };
958
943
  }
@@ -964,7 +949,7 @@ export class LibP2PService extends WithTracer implements P2PService {
964
949
  const wasAccepted = addResult.accepted.some(h => h.equals(txHash));
965
950
  const wasIgnored = addResult.ignored.some(h => h.equals(txHash));
966
951
 
967
- this.logger.verbose(`Validate propagated tx ${txHash.toString()}`, {
952
+ this.logger.trace(`Validate propagated tx`, {
968
953
  wasAccepted,
969
954
  wasIgnored,
970
955
  [Attributes.P2P_ID]: source.toString(),
@@ -1746,6 +1731,31 @@ export class LibP2PService extends WithTracer implements P2PService {
1746
1731
  return PeerErrorSeverity.HighToleranceError;
1747
1732
  }
1748
1733
 
1734
+ /**
1735
+ * Validate a checkpoint attestation.
1736
+ *
1737
+ * @param attestation - The checkpoint attestation to validate.
1738
+ * @returns True if the checkpoint attestation is valid, false otherwise.
1739
+ */
1740
+ @trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation) => ({
1741
+ [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
1742
+ [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
1743
+ [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then(i => i.toString()),
1744
+ }))
1745
+ public async validateCheckpointAttestation(
1746
+ peerId: PeerId,
1747
+ attestation: CheckpointAttestation,
1748
+ ): Promise<P2PValidationResult> {
1749
+ const result = await this.checkpointAttestationValidator.validate(attestation);
1750
+
1751
+ if (result.result === 'reject') {
1752
+ this.logger.warn(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1753
+ this.peerManager.penalizePeer(peerId, result.severity);
1754
+ }
1755
+
1756
+ return result;
1757
+ }
1758
+
1749
1759
  public getPeerScore(peerId: PeerId): number {
1750
1760
  return this.node.services.pubsub.score.score(peerId.toString());
1751
1761
  }
@@ -18,7 +18,6 @@ export class PeerManagerMetrics {
18
18
  private sentGoodbyes: UpDownCounter;
19
19
  private receivedGoodbyes: UpDownCounter;
20
20
  private peerCount: Gauge;
21
- private healthyPeerCount: Gauge;
22
21
  private lowScoreDisconnects: UpDownCounter;
23
22
  private peerConnectionDuration: Histogram;
24
23
 
@@ -50,7 +49,6 @@ export class PeerManagerMetrics {
50
49
  goodbyeReasonAttrs,
51
50
  );
52
51
  this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT);
53
- this.healthyPeerCount = meter.createGauge(Metrics.PEER_MANAGER_HEALTHY_PEER_COUNT);
54
52
  this.lowScoreDisconnects = createUpDownCounterWithDefault(meter, Metrics.PEER_MANAGER_LOW_SCORE_DISCONNECTS, {
55
53
  [Attributes.P2P_PEER_SCORE_STATE]: ['Banned', 'Disconnect'],
56
54
  });
@@ -69,10 +67,6 @@ export class PeerManagerMetrics {
69
67
  this.peerCount.record(count);
70
68
  }
71
69
 
72
- public recordHealthyPeerCount(count: number) {
73
- this.healthyPeerCount.record(count);
74
- }
75
-
76
70
  public recordLowScoreDisconnect(scoreState: 'Banned' | 'Disconnect') {
77
71
  this.lowScoreDisconnects.add(1, { [Attributes.P2P_PEER_SCORE_STATE]: scoreState });
78
72
  }
@@ -85,7 +79,6 @@ export class PeerManagerMetrics {
85
79
  const connectedAt = this.peerConnectedAt.get(id.toString());
86
80
  if (connectedAt) {
87
81
  this.peerConnectionDuration.record(Date.now() - connectedAt);
88
- this.peerConnectedAt.delete(id.toString());
89
82
  }
90
83
  }
91
84
  }
@@ -32,7 +32,7 @@ import { PeerScoreState, type PeerScoring } from './peer_scoring.js';
32
32
  const MAX_DIAL_ATTEMPTS = 3;
33
33
  const MAX_CACHED_PEERS = 100;
34
34
  const MAX_CACHED_PEER_AGE_MS = 5 * 60 * 1000; // 5 minutes
35
- const DEFAULT_FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
35
+ const FAILED_PEER_BAN_TIME_MS = 5 * 60 * 1000; // 5 minutes timeout after failing MAX_DIAL_ATTEMPTS
36
36
  const GOODBYE_DIAL_TIMEOUT_MS = 1000;
37
37
  const FAILED_AUTH_HANDSHAKE_EXPIRY_MS = 60 * 60 * 1000; // 1 hour
38
38
 
@@ -515,8 +515,7 @@ export class PeerManager implements PeerManagerInterface {
515
515
  ...this.peerScoring.getStats(),
516
516
  });
517
517
 
518
- this.metrics.recordPeerCount(connections.length);
519
- this.metrics.recordHealthyPeerCount(healthyConnections.length);
518
+ this.metrics.recordPeerCount(healthyConnections.length);
520
519
 
521
520
  // Exit if no peers to connect
522
521
  if (peersToConnect <= 0) {
@@ -776,8 +775,7 @@ export class PeerManager implements PeerManagerInterface {
776
775
  // Add to timed out peers
777
776
  this.timedOutPeers.set(id, {
778
777
  peerId: id,
779
- timeoutUntilMs:
780
- this.dateProvider.now() + (this.config.peerFailedBanTimeMs ?? DEFAULT_FAILED_PEER_BAN_TIME_MS),
778
+ timeoutUntilMs: this.dateProvider.now() + FAILED_PEER_BAN_TIME_MS,
781
779
  });
782
780
  }
783
781
  }
@@ -939,8 +937,6 @@ export class PeerManager implements PeerManagerInterface {
939
937
  `Received auth for validator ${sender.toString()} from peer ${peerIdString}, but this validator is already authenticated to peer ${peerForAddress.toString()}`,
940
938
  { ...logData, address: sender.toString() },
941
939
  );
942
- this.markAuthHandshakeFailed(peerId);
943
- this.markPeerForDisconnect(peerId);
944
940
  return;
945
941
  }
946
942