@aztec/p2p 0.0.1-commit.e0f15ab9b → 0.0.1-commit.e304674f1

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 (158) hide show
  1. package/dest/client/factory.d.ts +1 -1
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +5 -4
  4. package/dest/client/interface.d.ts +9 -2
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +3 -2
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +21 -8
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +14 -3
  10. package/dest/errors/p2p-service.error.d.ts +9 -0
  11. package/dest/errors/p2p-service.error.d.ts.map +1 -0
  12. package/dest/errors/p2p-service.error.js +10 -0
  13. package/dest/index.d.ts +1 -2
  14. package/dest/index.d.ts.map +1 -1
  15. package/dest/index.js +0 -1
  16. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +1 -1
  17. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  18. package/dest/mem_pools/attestation_pool/attestation_pool.js +3 -2
  19. package/dest/mem_pools/index.d.ts +1 -2
  20. package/dest/mem_pools/index.d.ts.map +1 -1
  21. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +1 -1
  22. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  23. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +5 -1
  24. package/dest/msg_validators/tx_validator/gas_validator.d.ts +1 -1
  25. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  26. package/dest/msg_validators/tx_validator/gas_validator.js +11 -9
  27. package/dest/services/dummy_service.d.ts +5 -3
  28. package/dest/services/dummy_service.d.ts.map +1 -1
  29. package/dest/services/dummy_service.js +5 -1
  30. package/dest/services/libp2p/libp2p_service.d.ts +12 -17
  31. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  32. package/dest/services/libp2p/libp2p_service.js +25 -59
  33. package/dest/services/peer-manager/peer_manager.d.ts +6 -2
  34. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  35. package/dest/services/peer-manager/peer_manager.js +18 -6
  36. package/dest/services/peer-manager/peer_scoring.d.ts +7 -2
  37. package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -1
  38. package/dest/services/peer-manager/peer_scoring.js +32 -10
  39. package/dest/services/reqresp/interface.d.ts +1 -9
  40. package/dest/services/reqresp/interface.d.ts.map +1 -1
  41. package/dest/services/reqresp/interface.js +0 -11
  42. package/dest/services/reqresp/metrics.d.ts +1 -1
  43. package/dest/services/reqresp/metrics.d.ts.map +1 -1
  44. package/dest/services/reqresp/metrics.js +0 -1
  45. package/dest/services/reqresp/protocols/index.d.ts +1 -2
  46. package/dest/services/reqresp/protocols/index.d.ts.map +1 -1
  47. package/dest/services/reqresp/protocols/index.js +0 -1
  48. package/dest/services/reqresp/protocols/tx.d.ts +1 -1
  49. package/dest/services/reqresp/protocols/tx.d.ts.map +1 -1
  50. package/dest/services/reqresp/protocols/tx.js +1 -3
  51. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts +5 -4
  52. package/dest/services/reqresp/rate-limiter/rate_limiter.d.ts.map +1 -1
  53. package/dest/services/reqresp/rate-limiter/rate_limiter.js +10 -8
  54. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts +1 -1
  55. package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -1
  56. package/dest/services/reqresp/rate-limiter/rate_limits.js +0 -10
  57. package/dest/services/reqresp/reqresp.js +1 -1
  58. package/dest/services/service.d.ts +5 -2
  59. package/dest/services/service.d.ts.map +1 -1
  60. package/dest/services/tx_collection/file_store_tx_source.d.ts +5 -4
  61. package/dest/services/tx_collection/file_store_tx_source.d.ts.map +1 -1
  62. package/dest/services/tx_collection/file_store_tx_source.js +39 -29
  63. package/dest/services/tx_collection/tx_source.d.ts +6 -5
  64. package/dest/services/tx_collection/tx_source.d.ts.map +1 -1
  65. package/dest/services/tx_collection/tx_source.js +9 -7
  66. package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
  67. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  68. package/dest/test-helpers/reqresp-nodes.js +0 -2
  69. package/dest/test-helpers/testbench-utils.d.ts +1 -1
  70. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  71. package/dest/test-helpers/testbench-utils.js +1 -0
  72. package/dest/testbench/p2p_client_testbench_worker.js +63 -12
  73. package/dest/testbench/worker_client_manager.d.ts +8 -1
  74. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  75. package/dest/testbench/worker_client_manager.js +49 -1
  76. package/package.json +14 -14
  77. package/src/client/factory.ts +7 -2
  78. package/src/client/interface.ts +9 -1
  79. package/src/client/p2p_client.ts +23 -8
  80. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +15 -3
  81. package/src/errors/p2p-service.error.ts +11 -0
  82. package/src/index.ts +0 -1
  83. package/src/mem_pools/attestation_pool/attestation_pool.ts +4 -2
  84. package/src/mem_pools/index.ts +0 -3
  85. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +7 -1
  86. package/src/msg_validators/proposal_validator/README.md +1 -1
  87. package/src/msg_validators/tx_validator/gas_validator.ts +25 -9
  88. package/src/services/dummy_service.ts +7 -2
  89. package/src/services/libp2p/libp2p_service.ts +30 -62
  90. package/src/services/peer-manager/peer_manager.ts +21 -6
  91. package/src/services/peer-manager/peer_scoring.ts +27 -5
  92. package/src/services/reqresp/interface.ts +0 -11
  93. package/src/services/reqresp/metrics.ts +0 -1
  94. package/src/services/reqresp/protocols/index.ts +0 -1
  95. package/src/services/reqresp/protocols/tx.ts +1 -3
  96. package/src/services/reqresp/rate-limiter/rate_limiter.ts +13 -9
  97. package/src/services/reqresp/rate-limiter/rate_limits.ts +0 -10
  98. package/src/services/reqresp/reqresp.ts +1 -1
  99. package/src/services/service.ts +6 -1
  100. package/src/services/tx_collection/file_store_tx_source.ts +43 -31
  101. package/src/services/tx_collection/tx_source.ts +8 -7
  102. package/src/test-helpers/reqresp-nodes.ts +0 -2
  103. package/src/test-helpers/testbench-utils.ts +1 -0
  104. package/src/testbench/p2p_client_testbench_worker.ts +67 -9
  105. package/src/testbench/worker_client_manager.ts +55 -1
  106. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +0 -125
  107. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +0 -1
  108. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +0 -596
  109. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts +0 -32
  110. package/dest/mem_pools/tx_pool/eviction/eviction_manager.d.ts.map +0 -1
  111. package/dest/mem_pools/tx_pool/eviction/eviction_manager.js +0 -112
  112. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts +0 -157
  113. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.d.ts.map +0 -1
  114. package/dest/mem_pools/tx_pool/eviction/eviction_strategy.js +0 -52
  115. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts +0 -16
  116. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.d.ts.map +0 -1
  117. package/dest/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.js +0 -123
  118. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts +0 -17
  119. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.d.ts.map +0 -1
  120. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.js +0 -84
  121. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts +0 -19
  122. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.d.ts.map +0 -1
  123. package/dest/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.js +0 -78
  124. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts +0 -26
  125. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.d.ts.map +0 -1
  126. package/dest/mem_pools/tx_pool/eviction/low_priority_eviction_rule.js +0 -84
  127. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts +0 -25
  128. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.d.ts.map +0 -1
  129. package/dest/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.js +0 -57
  130. package/dest/mem_pools/tx_pool/index.d.ts +0 -3
  131. package/dest/mem_pools/tx_pool/index.d.ts.map +0 -1
  132. package/dest/mem_pools/tx_pool/index.js +0 -2
  133. package/dest/mem_pools/tx_pool/priority.d.ts +0 -12
  134. package/dest/mem_pools/tx_pool/priority.d.ts.map +0 -1
  135. package/dest/mem_pools/tx_pool/priority.js +0 -15
  136. package/dest/mem_pools/tx_pool/tx_pool.d.ts +0 -127
  137. package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +0 -1
  138. package/dest/mem_pools/tx_pool/tx_pool.js +0 -3
  139. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts +0 -7
  140. package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +0 -1
  141. package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +0 -402
  142. package/dest/services/reqresp/protocols/block.d.ts +0 -9
  143. package/dest/services/reqresp/protocols/block.d.ts.map +0 -1
  144. package/dest/services/reqresp/protocols/block.js +0 -32
  145. package/src/mem_pools/tx_pool/README.md +0 -270
  146. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +0 -746
  147. package/src/mem_pools/tx_pool/eviction/eviction_manager.ts +0 -132
  148. package/src/mem_pools/tx_pool/eviction/eviction_strategy.ts +0 -208
  149. package/src/mem_pools/tx_pool/eviction/fee_payer_balance_eviction_rule.ts +0 -163
  150. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_mining_rule.ts +0 -104
  151. package/src/mem_pools/tx_pool/eviction/invalid_txs_after_reorg_rule.ts +0 -93
  152. package/src/mem_pools/tx_pool/eviction/low_priority_eviction_rule.ts +0 -106
  153. package/src/mem_pools/tx_pool/eviction/nullifier_conflict_pre_add_rule.ts +0 -75
  154. package/src/mem_pools/tx_pool/index.ts +0 -2
  155. package/src/mem_pools/tx_pool/priority.ts +0 -20
  156. package/src/mem_pools/tx_pool/tx_pool.ts +0 -141
  157. package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +0 -321
  158. package/src/services/reqresp/protocols/block.ts +0 -37
@@ -357,6 +357,8 @@ export class P2PClient extends WithTracer implements P2P {
357
357
  // Store our own last-block proposal so we can respond to req/resp requests for it.
358
358
  await this.attestationPool.tryAddBlockProposal(blockProposal);
359
359
  }
360
+ // Gossipsub doesn't deliver own messages, so fire the all-nodes handler locally
361
+ await this.p2pService.notifyOwnCheckpointProposal(proposal.toCore());
360
362
  return this.p2pService.propagate(proposal);
361
363
  }
362
364
 
@@ -388,8 +390,12 @@ export class P2PClient extends WithTracer implements P2P {
388
390
  this.p2pService.registerBlockReceivedCallback(handler);
389
391
  }
390
392
 
391
- public registerCheckpointProposalHandler(handler: P2PCheckpointReceivedCallback): void {
392
- this.p2pService.registerCheckpointReceivedCallback(handler);
393
+ public registerValidatorCheckpointProposalHandler(handler: P2PCheckpointReceivedCallback): void {
394
+ this.p2pService.registerValidatorCheckpointReceivedCallback(handler);
395
+ }
396
+
397
+ public registerAllNodesCheckpointProposalHandler(handler: P2PCheckpointReceivedCallback): void {
398
+ this.p2pService.registerAllNodesCheckpointReceivedCallback(handler);
393
399
  }
394
400
 
395
401
  public registerDuplicateProposalCallback(callback: (info: DuplicateProposalInfo) => void): void {
@@ -696,14 +702,23 @@ export class P2PClient extends WithTracer implements P2P {
696
702
 
697
703
  /** Checks if the slot has changed and calls prepareForSlot if so. */
698
704
  private async maybeCallPrepareForSlot(): Promise<void> {
699
- // If we have a pending checkpoint available, we want to prepare the target slot - otherwise we prepare the current slot
700
- // Knowledege of pending checkpoints is in the PR above
701
- const { targetSlot } = this.epochCache.getTargetAndNextSlot();
702
- if (targetSlot <= this.lastSlotProcessed) {
705
+ // If we have a proposed checkpoint available, we want to prepare the target slot - otherwise we prepare the current slot
706
+ const l2Tips = await this.l2Tips.getL2Tips();
707
+ const hasProposedCheckpoint = l2Tips.proposedCheckpoint.checkpoint.number > l2Tips.checkpointed.checkpoint.number;
708
+
709
+ let slot;
710
+ if (this.epochCache.isProposerPipeliningEnabled() && hasProposedCheckpoint) {
711
+ const { targetSlot } = this.epochCache.getTargetAndNextSlot();
712
+ slot = targetSlot;
713
+ } else {
714
+ const { currentSlot } = this.epochCache.getCurrentAndNextSlot();
715
+ slot = currentSlot;
716
+ }
717
+ if (slot <= this.lastSlotProcessed) {
703
718
  return;
704
719
  }
705
- this.lastSlotProcessed = targetSlot;
706
- await this.txPool.prepareForSlot(targetSlot);
720
+ this.lastSlotProcessed = slot;
721
+ await this.txPool.prepareForSlot(slot);
707
722
  }
708
723
 
709
724
  private async startServiceIfSynched() {
@@ -259,9 +259,20 @@ async function stopClient() {
259
259
  attestationPool = undefined;
260
260
  }
261
261
 
262
+ function gracefulExit(code: number = 0) {
263
+ try {
264
+ if (process.connected) {
265
+ process.disconnect();
266
+ }
267
+ } catch {
268
+ // IPC channel already closed
269
+ }
270
+ setTimeout(() => process.exit(code), 5000).unref();
271
+ }
272
+
262
273
  process.on('disconnect', () => {
263
274
  ipcDisconnected = true;
264
- void stopClient().finally(() => process.exit(0));
275
+ void stopClient();
265
276
  });
266
277
 
267
278
  process.on('error', err => {
@@ -325,7 +336,7 @@ process.on('message', (msg: WorkerCommand) => {
325
336
  case 'STOP': {
326
337
  await stopClient();
327
338
  await sendMessage({ type: 'STOPPED', requestId });
328
- process.exit(0);
339
+ gracefulExit(0);
329
340
  break;
330
341
  }
331
342
  default: {
@@ -336,7 +347,8 @@ process.on('message', (msg: WorkerCommand) => {
336
347
  } catch (err: any) {
337
348
  await sendMessage({ type: 'ERROR', requestId, error: err?.message ?? String(err) });
338
349
  if (msg.type === 'START') {
339
- process.exit(1);
350
+ await stopClient();
351
+ gracefulExit(1);
340
352
  }
341
353
  }
342
354
  })();
@@ -0,0 +1,11 @@
1
+ /** Checkpoint Proposal Received Callback Not Registered Error
2
+ *
3
+ * Error triggered if the allNodesCheckpointReceivedCallback is not registered
4
+ * @category Errors
5
+ */
6
+ export class CheckpointProposalReceivedCallbackNotRegisteredError extends Error {
7
+ constructor() {
8
+ super('FATAL (allNodesCheckpointReceivedCallback): All nodes should register a checkpoint proposal handler');
9
+ this.name = 'CheckpointProposalReceivedCallbackNotRegisteredError';
10
+ }
11
+ }
package/src/index.ts CHANGED
@@ -6,7 +6,6 @@ export * from './client/index.js';
6
6
  export * from './enr/index.js';
7
7
  export * from './config.js';
8
8
  export * from './mem_pools/attestation_pool/index.js';
9
- export * from './mem_pools/tx_pool/index.js';
10
9
  export * from './mem_pools/tx_pool_v2/index.js';
11
10
  export * from './msg_validators/index.js';
12
11
  export * from './services/index.js';
@@ -278,7 +278,7 @@ export class AttestationPool {
278
278
  * @returns Result indicating whether the proposal was added and duplicate detection info
279
279
  */
280
280
  public async tryAddCheckpointProposal(proposal: CheckpointProposalCore): Promise<TryAddResult> {
281
- return await this.store.transactionAsync(async () => {
281
+ const result = await this.store.transactionAsync(async () => {
282
282
  const proposalId = proposal.archive.toString();
283
283
 
284
284
  // Check if already exists
@@ -304,6 +304,8 @@ export class AttestationPool {
304
304
 
305
305
  return { added: true, alreadyExists: false, count: count + 1 };
306
306
  });
307
+
308
+ return result;
307
309
  }
308
310
 
309
311
  /** Internal method - must be called within a transaction. */
@@ -345,7 +347,7 @@ export class AttestationPool {
345
347
  await this.store.transactionAsync(async () => {
346
348
  for (const attestation of attestations) {
347
349
  const slotNumber = attestation.payload.header.slotNumber;
348
- const proposalId = attestation.archive;
350
+ const proposalId = attestation.archive.toString();
349
351
  const sender = attestation.getSender();
350
352
 
351
353
  // Skip attestations with invalid signatures
@@ -1,6 +1,3 @@
1
1
  export { AttestationPool, type AttestationPoolApi } from './attestation_pool/attestation_pool.js';
2
2
  export { type MemPools } from './interface.js';
3
- // Old TxPool exports - kept temporarily for external consumers
4
- export { type TxPool } from './tx_pool/tx_pool.js';
5
- // New TxPoolV2 exports
6
3
  export { type TxPoolV2, type TxPoolV2Config, type TxPoolV2Events, type AddTxsResult } from './tx_pool_v2/index.js';
@@ -1,3 +1,4 @@
1
+ import { minBigint } from '@aztec/foundation/bigint';
1
2
  import { BlockNumber } from '@aztec/foundation/branded-types';
2
3
  import { Fr } from '@aztec/foundation/curves/bn254';
3
4
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
@@ -6,7 +7,6 @@ import { Gas } from '@aztec/stdlib/gas';
6
7
  import { type Tx, TxHash } from '@aztec/stdlib/tx';
7
8
 
8
9
  import { getFeePayerBalanceDelta } from '../../msg_validators/tx_validator/fee_payer_balance.js';
9
- import { getTxPriorityFee } from '../tx_pool/priority.js';
10
10
  import { type PreAddResult, TxPoolRejectionCode } from './eviction/interfaces.js';
11
11
 
12
12
  /** Validator-compatible data interface, mirroring the subset of PrivateKernelTailCircuitPublicInputs used by validators. */
@@ -335,3 +335,9 @@ export function stubTxMetaData(
335
335
  data: stubTxMetaValidationData({ expirationTimestamp }),
336
336
  };
337
337
  }
338
+
339
+ /** Returns the priority fee for a tx, based on the L2 priority fee capped by the max fee per gas. */
340
+ function getTxPriorityFee(tx: Tx): bigint {
341
+ const { maxPriorityFeesPerGas: priorityFees, maxFeesPerGas } = tx.getGasSettings();
342
+ return minBigint(maxFeesPerGas.feePerL2Gas, priorityFees.feePerL2Gas);
343
+ }
@@ -53,7 +53,7 @@ Only runs on validator nodes. Non-validator nodes use a default handler that tri
53
53
 
54
54
  **Escape hatch**: during escape hatch periods (`isEscapeHatchOpenAtSlot`), re-execution and slashing are both disabled, and the proposal is rejected locally.
55
55
 
56
- **Conditional re-execution**: rules 22-24 only run when at least one condition is true: `fishermanMode` enabled, `slashBroadcastedInvalidBlockPenalty > 0` with `validatorReexecute`, committee membership with `validatorReexecute`, `alwaysReexecuteBlockProposals`, or `blobClient.canUpload()`.
56
+ **Conditional re-execution**: rules 22-24 only run when at least one condition is true: `fishermanMode` enabled, `slashBroadcastedInvalidBlockPenalty > 0`, committee membership, `alwaysReexecuteBlockProposals`, or `blobClient.canUpload()`.
57
57
 
58
58
  **Slashing**: only `state_mismatch` and `failed_txs` trigger on-chain slashing (`OffenseType.BROADCASTED_INVALID_BLOCK_PROPOSAL`, gated by `slashBroadcastedInvalidBlockPenalty > 0`). Unknown errors during re-execution do NOT slash.
59
59
 
@@ -87,7 +87,12 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
87
87
  gasLimits,
88
88
  minGasLimits,
89
89
  });
90
- return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_GAS_LIMIT] };
90
+ return {
91
+ result: 'invalid',
92
+ reason: [
93
+ `${TX_ERROR_INSUFFICIENT_GAS_LIMIT} (required=da:${minGasLimits.daGas},l2:${minGasLimits.l2Gas} got=da:${gasLimits.daGas},l2:${gasLimits.l2Gas})`,
94
+ ],
95
+ };
91
96
  }
92
97
 
93
98
  if (gasLimits.l2Gas > this.#effectiveMaxL2Gas) {
@@ -97,7 +102,10 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
97
102
  rollupManaLimit: this.#rollupManaLimit,
98
103
  maxBlockL2Gas: this.#maxBlockL2Gas,
99
104
  });
100
- return { result: 'invalid', reason: [TX_ERROR_GAS_LIMIT_TOO_HIGH] };
105
+ return {
106
+ result: 'invalid',
107
+ reason: [`${TX_ERROR_GAS_LIMIT_TOO_HIGH} (l2Gas=${gasLimits.l2Gas}, max=${this.#effectiveMaxL2Gas})`],
108
+ };
101
109
  }
102
110
 
103
111
  if (gasLimits.daGas > this.#effectiveMaxDAGas) {
@@ -106,7 +114,10 @@ export class GasLimitsValidator<T extends HasGasLimitData> implements TxValidato
106
114
  effectiveMaxDAGas: this.#effectiveMaxDAGas,
107
115
  maxBlockDAGas: this.#maxBlockDAGas,
108
116
  });
109
- return { result: 'invalid', reason: [TX_ERROR_GAS_LIMIT_TOO_HIGH] };
117
+ return {
118
+ result: 'invalid',
119
+ reason: [`${TX_ERROR_GAS_LIMIT_TOO_HIGH} (daGas=${gasLimits.daGas}, max=${this.#effectiveMaxDAGas})`],
120
+ };
110
121
  }
111
122
 
112
123
  return { result: 'valid' };
@@ -157,19 +168,20 @@ export class GasTxValidator implements TxValidator<Tx> {
157
168
  if (gasLimitValidation.result === 'invalid') {
158
169
  return Promise.resolve(gasLimitValidation);
159
170
  }
160
- if (this.#shouldSkip(tx)) {
161
- return Promise.resolve({ result: 'skipped', reason: [TX_ERROR_INSUFFICIENT_FEE_PER_GAS] });
171
+ const skipReason = this.#getSkipReason(tx);
172
+ if (skipReason) {
173
+ return Promise.resolve({ result: 'skipped', reason: [skipReason] });
162
174
  }
163
175
  return await this.validateTxFee(tx);
164
176
  }
165
177
 
166
178
  /**
167
- * Check whether the tx's max fees are valid for the current block, and skip if not.
179
+ * Check whether the tx's max fees are valid for the current block, and return a skip reason if not.
168
180
  * We skip instead of invalidating since the tx may become eligible later.
169
181
  * Note that circuits check max fees even if fee payer is unset, so we
170
182
  * keep this validation even if the tx does not pay fees.
171
183
  */
172
- #shouldSkip(tx: Tx): boolean {
184
+ #getSkipReason(tx: Tx): string | undefined {
173
185
  const gasSettings = tx.data.constants.txContext.gasSettings;
174
186
 
175
187
  // Skip the tx if its max fees are not enough for the current block's gas fees.
@@ -182,8 +194,9 @@ export class GasTxValidator implements TxValidator<Tx> {
182
194
  txMaxFeesPerGas: maxFeesPerGas.toInspect(),
183
195
  currentGasFees: this.#gasFees.toInspect(),
184
196
  });
197
+ return `${TX_ERROR_INSUFFICIENT_FEE_PER_GAS} (maxFee=da:${maxFeesPerGas.feePerDaGas},l2:${maxFeesPerGas.feePerL2Gas} required=da:${this.#gasFees.feePerDaGas},l2:${this.#gasFees.feePerL2Gas})`;
185
198
  }
186
- return notEnoughMaxFees;
199
+ return undefined;
187
200
  }
188
201
 
189
202
  /**
@@ -212,7 +225,10 @@ export class GasTxValidator implements TxValidator<Tx> {
212
225
  balance,
213
226
  feeLimit,
214
227
  });
215
- return { result: 'invalid', reason: [TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE] };
228
+ return {
229
+ result: 'invalid',
230
+ reason: [`${TX_ERROR_INSUFFICIENT_FEE_PAYER_BALANCE} (required=${feeLimit}, available=${balance})`],
231
+ };
216
232
  }
217
233
  return { result: 'valid' };
218
234
  }
@@ -1,6 +1,6 @@
1
1
  import type { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
3
- import type { Gossipable, PeerErrorSeverity, TopicType } from '@aztec/stdlib/p2p';
3
+ import type { CheckpointProposalCore, Gossipable, PeerErrorSeverity, TopicType } from '@aztec/stdlib/p2p';
4
4
  import { Tx, TxHash } from '@aztec/stdlib/tx';
5
5
 
6
6
  import type { PeerId } from '@libp2p/interface';
@@ -86,7 +86,12 @@ export class DummyP2PService implements P2PService {
86
86
  /**
87
87
  * Register a callback into the validator client for when a checkpoint proposal is received
88
88
  */
89
- public registerCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {}
89
+ public registerValidatorCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {}
90
+ public registerAllNodesCheckpointReceivedCallback(_callback: P2PCheckpointReceivedCallback) {}
91
+
92
+ public notifyOwnCheckpointProposal(_checkpoint: CheckpointProposalCore): Promise<void> {
93
+ return Promise.resolve();
94
+ }
90
95
 
91
96
  /**
92
97
  * Register a callback for when a duplicate proposal is detected
@@ -1,13 +1,12 @@
1
1
  import type { EpochCacheInterface } from '@aztec/epoch-cache';
2
2
  import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { maxBy } from '@aztec/foundation/collection';
4
- import { Fr } from '@aztec/foundation/curves/bn254';
5
4
  import { type Logger, createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
6
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
7
6
  import { Timer } from '@aztec/foundation/timer';
8
7
  import type { AztecAsyncKVStore } from '@aztec/kv-store';
9
8
  import { protocolContractsHash } from '@aztec/protocol-contracts';
10
- import type { EthAddress, L2Block, L2BlockSource } from '@aztec/stdlib/block';
9
+ import type { EthAddress, L2BlockSource } from '@aztec/stdlib/block';
11
10
  import type { ContractDataSource } from '@aztec/stdlib/contract';
12
11
  import { GasFees } from '@aztec/stdlib/gas';
13
12
  import type { ClientProtocolCircuitVerifier, PeerInfo, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
@@ -58,6 +57,7 @@ import { ENR } from '@nethermindeth/enr';
58
57
  import { createLibp2p } from 'libp2p';
59
58
 
60
59
  import type { P2PConfig } from '../../config.js';
60
+ import { CheckpointProposalReceivedCallbackNotRegisteredError } from '../../errors/p2p-service.error.js';
61
61
  import type { MemPools } from '../../mem_pools/interface.js';
62
62
  import {
63
63
  BlockProposalValidator,
@@ -104,7 +104,6 @@ import {
104
104
  ValidationError,
105
105
  pingHandler,
106
106
  reqGoodbyeHandler,
107
- reqRespBlockHandler,
108
107
  reqRespBlockTxsHandler,
109
108
  reqRespStatusHandler,
110
109
  reqRespTxHandler,
@@ -171,7 +170,13 @@ export class LibP2PService extends WithTracer implements P2PService {
171
170
  * @param checkpoint - The checkpoint proposal received from the peer.
172
171
  * @returns The attestations for the checkpoint, if any.
173
172
  */
174
- private checkpointReceivedCallback: P2PCheckpointReceivedCallback;
173
+ private allNodesCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
174
+ /**
175
+ * Callback for when a checkpoint proposal is received - specifically for validators - from a peer.
176
+ * @param checkpoint - The checkpoint proposal received from the peer.
177
+ * @returns The attestations for the checkpoint, if any.
178
+ */
179
+ private validatorCheckpointReceivedCallback: P2PCheckpointReceivedCallback;
175
180
 
176
181
  private gossipSubEventHandler: (e: CustomEvent<GossipsubMessage>) => void;
177
182
 
@@ -243,12 +248,15 @@ export class LibP2PService extends WithTracer implements P2PService {
243
248
  return true;
244
249
  };
245
250
 
246
- this.checkpointReceivedCallback = (
247
- checkpoint: CheckpointProposalCore,
251
+ this.allNodesCheckpointReceivedCallback = (
252
+ _checkpoint: CheckpointProposalCore,
253
+ ): Promise<CheckpointAttestation[] | undefined> => {
254
+ throw new CheckpointProposalReceivedCallbackNotRegisteredError();
255
+ };
256
+
257
+ this.validatorCheckpointReceivedCallback = (
258
+ _checkpoint: CheckpointProposalCore,
248
259
  ): Promise<CheckpointAttestation[] | undefined> => {
249
- this.logger.debug(
250
- `Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`,
251
- );
252
260
  return Promise.resolve(undefined);
253
261
  };
254
262
  }
@@ -510,14 +518,12 @@ export class LibP2PService extends WithTracer implements P2PService {
510
518
  // Create request response protocol handlers
511
519
  const txHandler = reqRespTxHandler(this.mempools);
512
520
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
513
- const blockHandler = reqRespBlockHandler(this.archiver);
514
521
  const statusHandler = reqRespStatusHandler(this.protocolVersion, this.worldStateSynchronizer, this.logger);
515
522
 
516
523
  const requestResponseHandlers: Partial<ReqRespSubProtocolHandlers> = {
517
524
  [ReqRespSubProtocol.PING]: pingHandler,
518
525
  [ReqRespSubProtocol.STATUS]: statusHandler.bind(this),
519
526
  [ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
520
- [ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
521
527
  };
522
528
 
523
529
  if (!this.config.disableTransactions) {
@@ -538,7 +544,6 @@ export class LibP2PService extends WithTracer implements P2PService {
538
544
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
539
545
  [ReqRespSubProtocol.TX]: this.validateRequestedTxs.bind(this),
540
546
  [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
541
- [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this),
542
547
  };
543
548
 
544
549
  await this.peerManager.initializePeers();
@@ -666,8 +671,16 @@ export class LibP2PService extends WithTracer implements P2PService {
666
671
  this.blockReceivedCallback = callback;
667
672
  }
668
673
 
669
- public registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
670
- this.checkpointReceivedCallback = callback;
674
+ public registerValidatorCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
675
+ this.validatorCheckpointReceivedCallback = callback;
676
+ }
677
+
678
+ public registerAllNodesCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback) {
679
+ this.allNodesCheckpointReceivedCallback = callback;
680
+ }
681
+
682
+ public async notifyOwnCheckpointProposal(checkpoint: CheckpointProposalCore): Promise<void> {
683
+ await this.allNodesCheckpointReceivedCallback(checkpoint, this.node.peerId);
671
684
  }
672
685
 
673
686
  /**
@@ -1404,9 +1417,11 @@ export class LibP2PService extends WithTracer implements P2PService {
1404
1417
  source: sender.toString(),
1405
1418
  });
1406
1419
 
1420
+ await this.allNodesCheckpointReceivedCallback(checkpoint, sender);
1421
+
1407
1422
  // Call the checkpoint received callback with the core version (without lastBlock)
1408
1423
  // to validate and potentially generate attestations
1409
- const attestations = await this.checkpointReceivedCallback(checkpoint, sender);
1424
+ const attestations = await this.validatorCheckpointReceivedCallback(checkpoint, sender);
1410
1425
  if (attestations && attestations.length > 0) {
1411
1426
  // If the callback returned attestations, add them to the pool and propagate them
1412
1427
  await this.mempools.attestationPool.addOwnCheckpointAttestations(attestations);
@@ -1554,53 +1569,6 @@ export class LibP2PService extends WithTracer implements P2PService {
1554
1569
  }
1555
1570
  }
1556
1571
 
1557
- /**
1558
- * Validates a BLOCK response.
1559
- *
1560
- * If a local copy exists, enforces hash equality. If missing, rejects (no penalty) since the hash cannot be verified.
1561
- * Penalizes on block number mismatch or hash mismatch.
1562
- *
1563
- * @param requestedBlockNumber - The requested block number.
1564
- * @param responseBlock - The block returned by the peer.
1565
- * @param peerId - The peer that returned the block.
1566
- * @returns True if the response is valid, false otherwise.
1567
- */
1568
- @trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock) => ({
1569
- [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString(),
1570
- }))
1571
- protected async validateRequestedBlock(
1572
- requestedBlockNumber: Fr,
1573
- responseBlock: L2Block,
1574
- peerId: PeerId,
1575
- ): Promise<boolean> {
1576
- try {
1577
- const reqNum = Number(requestedBlockNumber.toString());
1578
- if (responseBlock.number !== reqNum) {
1579
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.LowToleranceError);
1580
- return false;
1581
- }
1582
-
1583
- const local = await this.archiver.getBlock(BlockNumber(reqNum));
1584
- if (!local) {
1585
- // We are missing the local block; we cannot verify the hash yet. Reject without penalizing.
1586
- // TODO: Consider extending this validator to accept an expected hash or
1587
- // performing quorum-based checks when using P2P syncing prior to L1 sync.
1588
- this.logger.warn(`Local block ${reqNum} not found; rejecting BLOCK response without hash verification`);
1589
- return false;
1590
- }
1591
- const [localHash, respHash] = await Promise.all([local.hash(), responseBlock.hash()]);
1592
- if (!localHash.equals(respHash)) {
1593
- this.peerManager.penalizePeer(peerId, PeerErrorSeverity.MidToleranceError);
1594
- return false;
1595
- }
1596
-
1597
- return true;
1598
- } catch (e) {
1599
- this.logger.warn(`Error validating requested block`, e);
1600
- return false;
1601
- }
1602
- }
1603
-
1604
1572
  protected async validateRequestedTx(
1605
1573
  tx: Tx,
1606
1574
  peerId: PeerId,
@@ -226,20 +226,30 @@ export class PeerManager implements PeerManagerInterface {
226
226
  }
227
227
 
228
228
  /**
229
- * Cleans up expired timeouts.
229
+ * Cleans up expired timeouts and stale failed-auth-handshake entries.
230
230
  *
231
231
  * When peers fail to dial after a number of retries, they are temporarily timed out.
232
232
  * This function removes any peers that have been in the timed out state for too long.
233
233
  * To give them a chance to reconnect.
234
+ *
235
+ * Also evicts entries from the failed-auth-handshake map whose expiry window has passed.
236
+ * Without this, peers that probe once and never reconnect would leave their entries in the
237
+ * map forever, causing an unbounded memory leak.
234
238
  */
235
239
  private cleanupExpiredTimeouts() {
236
- // Clean up expired timeouts
237
240
  const now = this.dateProvider.now();
241
+
238
242
  for (const [peerId, timedOutPeer] of this.timedOutPeers.entries()) {
239
243
  if (now >= timedOutPeer.timeoutUntilMs) {
240
244
  this.timedOutPeers.delete(peerId);
241
245
  }
242
246
  }
247
+
248
+ for (const [id, entry] of this.failedAuthHandshakes.entries()) {
249
+ if (now - entry.lastFailureTimestamp > FAILED_AUTH_HANDSHAKE_EXPIRY_MS) {
250
+ this.failedAuthHandshakes.delete(id);
251
+ }
252
+ }
243
253
  }
244
254
 
245
255
  /**
@@ -303,15 +313,20 @@ export class PeerManager implements PeerManagerInterface {
303
313
  */
304
314
  private handleDisconnectedPeerEvent(e: CustomEvent<PeerId>) {
305
315
  const peerId = e.detail;
316
+ const peerIdStr = peerId.toString();
306
317
  this.metrics.peerDisconnected(peerId);
307
- this.logger.verbose(`Disconnected from peer ${peerId.toString()}`);
308
- const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerId.toString());
318
+ this.logger.verbose(`Disconnected from peer ${peerIdStr}`);
319
+ const validatorAddress = this.authenticatedPeerIdToValidatorAddress.get(peerIdStr);
309
320
  if (validatorAddress !== undefined) {
310
321
  this.logger.info(
311
- `Removing authentication for validator ${validatorAddress} at peer id ${peerId.toString()} due to disconnection`,
322
+ `Removing authentication for validator ${validatorAddress} at peer id ${peerIdStr} due to disconnection`,
312
323
  );
313
324
  this.authenticatedValidatorAddressToPeerId.delete(validatorAddress.toString());
314
- this.authenticatedPeerIdToValidatorAddress.delete(peerId.toString());
325
+ this.authenticatedPeerIdToValidatorAddress.delete(peerIdStr);
326
+ }
327
+
328
+ if (this.peerScoring.getScoreState(peerIdStr) === PeerScoreState.Healthy) {
329
+ this.peerScoring.removePeer(peerIdStr);
315
330
  }
316
331
  }
317
332
 
@@ -1,5 +1,6 @@
1
1
  import { median } from '@aztec/foundation/collection';
2
2
  import { createLogger } from '@aztec/foundation/log';
3
+ import { DateProvider } from '@aztec/foundation/timer';
3
4
  import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
4
5
  import {
5
6
  Attributes,
@@ -54,6 +55,7 @@ export enum PeerScoreState {
54
55
  // TODO: move into config / constants
55
56
  const MIN_SCORE_BEFORE_BAN = -100;
56
57
  const MIN_SCORE_BEFORE_DISCONNECT = -50;
58
+ const SCORE_CLEANUP_THRESHOLD = 0.1;
57
59
 
58
60
  export class PeerScoring {
59
61
  private logger = createLogger('p2p:peer-scoring');
@@ -65,7 +67,11 @@ export class PeerScoring {
65
67
 
66
68
  private peerStateCounter: UpDownCounter;
67
69
 
68
- constructor(config: P2PConfig, telemetry: TelemetryClient = getTelemetryClient()) {
70
+ constructor(
71
+ config: P2PConfig,
72
+ telemetry: TelemetryClient = getTelemetryClient(),
73
+ private readonly dateProvider: DateProvider = new DateProvider(),
74
+ ) {
69
75
  const orderedValues = config.peerPenaltyValues?.sort((a, b) => a - b);
70
76
  this.peerPenalties = {
71
77
  [PeerErrorSeverity.HighToleranceError]:
@@ -92,7 +98,7 @@ export class PeerScoring {
92
98
  }
93
99
 
94
100
  updateScore(peerId: string, scoreDelta: number): number {
95
- const currentTime = Date.now();
101
+ const currentTime = this.dateProvider.now();
96
102
  const lastUpdate = this.lastUpdateTime.get(peerId) || currentTime;
97
103
  const timePassed = currentTime - lastUpdate;
98
104
  const decayPeriods = Math.floor(timePassed / this.decayInterval);
@@ -111,19 +117,35 @@ export class PeerScoring {
111
117
  }
112
118
 
113
119
  decayAllScores(): void {
114
- const currentTime = Date.now();
120
+ const currentTime = this.dateProvider.now();
115
121
  for (const [peerId, lastUpdate] of this.lastUpdateTime.entries()) {
116
122
  const timePassed = currentTime - lastUpdate;
117
123
  const decayPeriods = Math.floor(timePassed / this.decayInterval);
118
124
  if (decayPeriods > 0) {
119
125
  let score = this.scores.get(peerId) || 0;
120
126
  score *= Math.pow(this.decayFactor, decayPeriods);
121
- this.scores.set(peerId, score);
122
- this.lastUpdateTime.set(peerId, currentTime);
127
+ if (Math.abs(score) < SCORE_CLEANUP_THRESHOLD) {
128
+ this.scores.delete(peerId);
129
+ this.lastUpdateTime.delete(peerId);
130
+ } else {
131
+ this.scores.set(peerId, score);
132
+ this.lastUpdateTime.set(peerId, currentTime);
133
+ }
123
134
  }
124
135
  }
125
136
  }
126
137
 
138
+ /** Resets all peer scores. Useful for benchmarks to prevent cross-case contamination. */
139
+ resetAllScores(): void {
140
+ this.scores.clear();
141
+ this.lastUpdateTime.clear();
142
+ }
143
+
144
+ removePeer(peerId: string): void {
145
+ this.scores.delete(peerId);
146
+ this.lastUpdateTime.delete(peerId);
147
+ }
148
+
127
149
  getScore(peerId: string): number {
128
150
  return this.scores.get(peerId) || 0;
129
151
  }
@@ -1,6 +1,3 @@
1
- import { Fr } from '@aztec/foundation/curves/bn254';
2
- import { L2Block } from '@aztec/stdlib/block';
3
- import { MAX_L2_BLOCK_SIZE_KB } from '@aztec/stdlib/p2p';
4
1
  import { TxArray, TxHashArray } from '@aztec/stdlib/tx';
5
2
 
6
3
  import type { PeerId } from '@libp2p/interface';
@@ -24,7 +21,6 @@ export const PING_PROTOCOL = '/aztec/req/ping/1.0.0';
24
21
  export const STATUS_PROTOCOL = '/aztec/req/status/1.0.0';
25
22
  export const GOODBYE_PROTOCOL = '/aztec/req/goodbye/1.0.0';
26
23
  export const TX_REQ_PROTOCOL = '/aztec/req/tx/1.0.0';
27
- export const BLOCK_REQ_PROTOCOL = '/aztec/req/block/1.0.0';
28
24
  export const AUTH_PROTOCOL = '/aztec/req/auth/1.0.0';
29
25
  export const BLOCK_TXS_REQ_PROTOCOL = '/aztec/req/block_txs/1.0.0';
30
26
 
@@ -33,7 +29,6 @@ export enum ReqRespSubProtocol {
33
29
  STATUS = STATUS_PROTOCOL,
34
30
  GOODBYE = GOODBYE_PROTOCOL,
35
31
  TX = TX_REQ_PROTOCOL,
36
- BLOCK = BLOCK_REQ_PROTOCOL,
37
32
  AUTH = AUTH_PROTOCOL,
38
33
  BLOCK_TXS = BLOCK_TXS_REQ_PROTOCOL,
39
34
  }
@@ -105,7 +100,6 @@ export const DEFAULT_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = {
105
100
  [ReqRespSubProtocol.STATUS]: noopValidator,
106
101
  [ReqRespSubProtocol.TX]: noopValidator,
107
102
  [ReqRespSubProtocol.GOODBYE]: noopValidator,
108
- [ReqRespSubProtocol.BLOCK]: noopValidator,
109
103
  [ReqRespSubProtocol.AUTH]: noopValidator,
110
104
  [ReqRespSubProtocol.BLOCK_TXS]: noopValidator,
111
105
  };
@@ -203,10 +197,6 @@ export const subProtocolMap = {
203
197
  request: RequestableBuffer,
204
198
  response: RequestableBuffer,
205
199
  },
206
- [ReqRespSubProtocol.BLOCK]: {
207
- request: Fr, // block number
208
- response: L2Block,
209
- },
210
200
  [ReqRespSubProtocol.AUTH]: {
211
201
  request: AuthRequest,
212
202
  response: AuthResponse,
@@ -229,7 +219,6 @@ export type ExpectedResponseSizeCalculator = (requestBuffer: Buffer) => number;
229
219
  export const subProtocolSizeCalculators: Record<ReqRespSubProtocol, ExpectedResponseSizeCalculator> = {
230
220
  [ReqRespSubProtocol.TX]: calculateTxResponseSize,
231
221
  [ReqRespSubProtocol.BLOCK_TXS]: calculateBlockTxsResponseSize,
232
- [ReqRespSubProtocol.BLOCK]: () => MAX_L2_BLOCK_SIZE_KB,
233
222
  [ReqRespSubProtocol.STATUS]: () => 1,
234
223
  [ReqRespSubProtocol.PING]: () => 1,
235
224
  [ReqRespSubProtocol.AUTH]: () => 1,
@@ -26,7 +26,6 @@ export class ReqRespMetrics {
26
26
  ReqRespSubProtocol.STATUS,
27
27
  ReqRespSubProtocol.GOODBYE,
28
28
  ReqRespSubProtocol.TX,
29
- ReqRespSubProtocol.BLOCK,
30
29
  ReqRespSubProtocol.AUTH,
31
30
  ReqRespSubProtocol.BLOCK_TXS,
32
31
  ],
@@ -5,6 +5,5 @@ export * from './ping.js';
5
5
  export * from './status.js';
6
6
  export * from './tx.js';
7
7
  export * from './goodbye.js';
8
- export * from './block.js';
9
8
  export * from './auth.js';
10
9
  export * from './block_txs/index.js';