@aztec/p2p 4.0.0-nightly.20260111 → 4.0.0-nightly.20260113

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 (86) hide show
  1. package/dest/client/interface.d.ts +18 -5
  2. package/dest/client/interface.d.ts.map +1 -1
  3. package/dest/client/p2p_client.d.ts +9 -12
  4. package/dest/client/p2p_client.d.ts.map +1 -1
  5. package/dest/client/p2p_client.js +59 -103
  6. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +61 -42
  7. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  8. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
  9. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
  10. package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +225 -262
  11. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +21 -18
  12. package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
  13. package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +113 -108
  14. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +17 -16
  15. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  16. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +89 -128
  17. package/dest/mem_pools/attestation_pool/mocks.d.ts +7 -6
  18. package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
  19. package/dest/mem_pools/attestation_pool/mocks.js +9 -8
  20. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +4 -4
  21. package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
  22. package/dest/msg_validators/attestation_validator/attestation_validator.js +12 -10
  23. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts +5 -5
  24. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.d.ts.map +1 -1
  25. package/dest/msg_validators/attestation_validator/fisherman_attestation_validator.js +5 -5
  26. package/dest/msg_validators/index.d.ts +2 -2
  27. package/dest/msg_validators/index.d.ts.map +1 -1
  28. package/dest/msg_validators/index.js +1 -1
  29. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts +9 -0
  30. package/dest/msg_validators/proposal_validator/block_proposal_validator.d.ts.map +1 -0
  31. package/dest/msg_validators/proposal_validator/block_proposal_validator.js +6 -0
  32. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts +9 -0
  33. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.d.ts.map +1 -0
  34. package/dest/msg_validators/proposal_validator/checkpoint_proposal_validator.js +6 -0
  35. package/dest/msg_validators/proposal_validator/index.d.ts +4 -0
  36. package/dest/msg_validators/proposal_validator/index.d.ts.map +1 -0
  37. package/dest/msg_validators/proposal_validator/index.js +3 -0
  38. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +13 -0
  39. package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -0
  40. package/dest/msg_validators/{block_proposal_validator/block_proposal_validator.js → proposal_validator/proposal_validator.js} +19 -21
  41. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts +23 -0
  42. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.d.ts.map +1 -0
  43. package/dest/msg_validators/proposal_validator/proposal_validator_test_suite.js +183 -0
  44. package/dest/services/dummy_service.d.ts +6 -2
  45. package/dest/services/dummy_service.d.ts.map +1 -1
  46. package/dest/services/dummy_service.js +3 -0
  47. package/dest/services/encoding.d.ts +1 -1
  48. package/dest/services/encoding.d.ts.map +1 -1
  49. package/dest/services/encoding.js +4 -2
  50. package/dest/services/libp2p/libp2p_service.d.ts +26 -10
  51. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  52. package/dest/services/libp2p/libp2p_service.js +218 -88
  53. package/dest/services/service.d.ts +16 -3
  54. package/dest/services/service.d.ts.map +1 -1
  55. package/dest/testbench/p2p_client_testbench_worker.js +25 -11
  56. package/dest/testbench/worker_client_manager.d.ts +1 -1
  57. package/dest/testbench/worker_client_manager.d.ts.map +1 -1
  58. package/dest/testbench/worker_client_manager.js +6 -1
  59. package/package.json +14 -14
  60. package/src/client/interface.ts +19 -4
  61. package/src/client/p2p_client.ts +69 -110
  62. package/src/mem_pools/attestation_pool/attestation_pool.ts +68 -41
  63. package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +231 -287
  64. package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +162 -140
  65. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +141 -164
  66. package/src/mem_pools/attestation_pool/mocks.ts +13 -9
  67. package/src/msg_validators/attestation_validator/attestation_validator.ts +16 -13
  68. package/src/msg_validators/attestation_validator/fisherman_attestation_validator.ts +7 -7
  69. package/src/msg_validators/index.ts +1 -1
  70. package/src/msg_validators/proposal_validator/block_proposal_validator.ts +10 -0
  71. package/src/msg_validators/proposal_validator/checkpoint_proposal_validator.ts +13 -0
  72. package/src/msg_validators/proposal_validator/index.ts +3 -0
  73. package/src/msg_validators/{block_proposal_validator/block_proposal_validator.ts → proposal_validator/proposal_validator.ts} +23 -28
  74. package/src/msg_validators/proposal_validator/proposal_validator_test_suite.ts +206 -0
  75. package/src/services/dummy_service.ts +6 -0
  76. package/src/services/encoding.ts +3 -1
  77. package/src/services/libp2p/libp2p_service.ts +258 -94
  78. package/src/services/service.ts +19 -4
  79. package/src/testbench/p2p_client_testbench_worker.ts +34 -11
  80. package/src/testbench/worker_client_manager.ts +6 -1
  81. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts +0 -12
  82. package/dest/msg_validators/block_proposal_validator/block_proposal_validator.d.ts.map +0 -1
  83. package/dest/msg_validators/block_proposal_validator/index.d.ts +0 -2
  84. package/dest/msg_validators/block_proposal_validator/index.d.ts.map +0 -1
  85. package/dest/msg_validators/block_proposal_validator/index.js +0 -1
  86. package/src/msg_validators/block_proposal_validator/index.ts +0 -1
@@ -370,8 +370,8 @@ function applyDecs2203RFactory() {
370
370
  function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
371
371
  return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
372
372
  }
373
- var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _initProto;
374
- import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
373
+ var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto;
374
+ import { BlockNumber } from '@aztec/foundation/branded-types';
375
375
  import { randomInt } from '@aztec/foundation/crypto/random';
376
376
  import { Fr } from '@aztec/foundation/curves/bn254';
377
377
  import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
@@ -380,7 +380,7 @@ import { Timer } from '@aztec/foundation/timer';
380
380
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
381
381
  import { protocolContractsHash } from '@aztec/protocol-contracts';
382
382
  import { GasFees } from '@aztec/stdlib/gas';
383
- import { BlockAttestation, BlockProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
383
+ import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
384
384
  import { MerkleTreeId } from '@aztec/stdlib/trees';
385
385
  import { Tx } from '@aztec/stdlib/tx';
386
386
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
@@ -398,7 +398,7 @@ import { tcp } from '@libp2p/tcp';
398
398
  import { ENR } from '@nethermindeth/enr';
399
399
  import { createLibp2p } from 'libp2p';
400
400
  import { ProposalSlotCapExceededError } from '../../errors/attestation-pool.error.js';
401
- import { AttestationValidator, BlockProposalValidator, FishermanAttestationValidator } from '../../msg_validators/index.js';
401
+ import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, FishermanAttestationValidator } from '../../msg_validators/index.js';
402
402
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
403
403
  import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
404
404
  import { createTxMessageValidators } from '../../msg_validators/tx_validator/factory.js';
@@ -422,10 +422,10 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
422
422
  [Attributes.SLOT_NUMBER]: block.slotNumber,
423
423
  [Attributes.BLOCK_ARCHIVE]: block.archive.toString(),
424
424
  [Attributes.P2P_ID]: await block.p2pMessageLoggingIdentifier().then((i)=>i.toString())
425
- })), _dec1 = trackSpan('Libp2pService.broadcastAttestation', async (attestation)=>({
426
- [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
427
- [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
428
- [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
425
+ })), _dec1 = trackSpan('Libp2pService.processValidCheckpointProposal', async (checkpoint)=>({
426
+ [Attributes.SLOT_NUMBER]: checkpoint.slotNumber,
427
+ [Attributes.BLOCK_ARCHIVE]: checkpoint.archive.toString(),
428
+ [Attributes.P2P_ID]: await checkpoint.p2pMessageLoggingIdentifier().then((i)=>i.toString())
429
429
  })), _dec2 = trackSpan('Libp2pService.validateRequestedBlockTxs', (request)=>({
430
430
  [Attributes.BLOCK_HASH]: request.blockHash.toString()
431
431
  })), _dec3 = trackSpan('Libp2pService.validateRequestedTx', (requestedTxHash, _responseTx)=>({
@@ -434,12 +434,14 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
434
434
  [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
435
435
  })), _dec5 = trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
436
436
  [Attributes.TX_HASH]: tx.getTxHash().toString()
437
- })), _dec6 = trackSpan('Libp2pService.validateAttestation', async (_, attestation)=>({
437
+ })), _dec6 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
438
438
  [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
439
439
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
440
440
  [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
441
441
  })), _dec7 = trackSpan('Libp2pService.validateBlockProposal', (_peerId, block)=>({
442
- [Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString()
442
+ [Attributes.SLOT_NUMBER]: block.slotNumber.toString()
443
+ })), _dec8 = trackSpan('Libp2pService.validateCheckpointProposal', (_peerId, checkpoint)=>({
444
+ [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString()
443
445
  }));
444
446
  /**
445
447
  * Lib P2P implementation of the P2PService interface.
@@ -465,7 +467,7 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
465
467
  [
466
468
  _dec1,
467
469
  2,
468
- "broadcastAttestation"
470
+ "processValidCheckpointProposal"
469
471
  ],
470
472
  [
471
473
  _dec2,
@@ -490,20 +492,26 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
490
492
  [
491
493
  _dec6,
492
494
  2,
493
- "validateAttestation"
495
+ "validateCheckpointAttestation"
494
496
  ],
495
497
  [
496
498
  _dec7,
497
499
  2,
498
500
  "validateBlockProposal"
501
+ ],
502
+ [
503
+ _dec8,
504
+ 2,
505
+ "validateCheckpointProposal"
499
506
  ]
500
507
  ], []));
501
508
  }
502
509
  discoveryRunningPromise;
503
510
  msgIdSeenValidators;
504
511
  // Message validators
505
- attestationValidator;
506
512
  blockProposalValidator;
513
+ checkpointProposalValidator;
514
+ checkpointAttestationValidator;
507
515
  protocolVersion;
508
516
  topicStrings;
509
517
  feesCache;
@@ -512,6 +520,11 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
512
520
  * @param block - The block received from the peer.
513
521
  * @returns The attestation for the block, if any.
514
522
  */ blockReceivedCallback;
523
+ /**
524
+ * Callback for when a checkpoint proposal is received from a peer.
525
+ * @param checkpoint - The checkpoint proposal received from the peer.
526
+ * @returns The attestations for the checkpoint, if any.
527
+ */ checkpointReceivedCallback;
515
528
  gossipSubEventHandler;
516
529
  instrumentation;
517
530
  telemetry;
@@ -524,24 +537,32 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
524
537
  this.instrumentation = new P2PInstrumentation(telemetry, 'LibP2PService');
525
538
  this.msgIdSeenValidators[TopicType.tx] = new MessageSeenValidator(config.seenMessageCacheSize);
526
539
  this.msgIdSeenValidators[TopicType.block_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
527
- this.msgIdSeenValidators[TopicType.block_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
540
+ this.msgIdSeenValidators[TopicType.checkpoint_proposal] = new MessageSeenValidator(config.seenMessageCacheSize);
541
+ this.msgIdSeenValidators[TopicType.checkpoint_attestation] = new MessageSeenValidator(config.seenMessageCacheSize);
528
542
  const versions = getVersions(config);
529
543
  this.protocolVersion = compressComponentVersions(versions);
530
544
  logger.info(`Started libp2p service with protocol version ${this.protocolVersion}`);
531
545
  this.topicStrings[TopicType.tx] = createTopicString(TopicType.tx, this.protocolVersion);
532
546
  this.topicStrings[TopicType.block_proposal] = createTopicString(TopicType.block_proposal, this.protocolVersion);
533
- this.topicStrings[TopicType.block_attestation] = createTopicString(TopicType.block_attestation, this.protocolVersion);
534
- // Use FishermanAttestationValidator in fisherman mode to validate attestation payloads against proposals
535
- this.attestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new AttestationValidator(epochCache);
547
+ this.topicStrings[TopicType.checkpoint_proposal] = createTopicString(TopicType.checkpoint_proposal, this.protocolVersion);
548
+ this.topicStrings[TopicType.checkpoint_attestation] = createTopicString(TopicType.checkpoint_attestation, this.protocolVersion);
536
549
  this.blockProposalValidator = new BlockProposalValidator(epochCache, {
537
550
  txsPermitted: !config.disableTransactions
538
551
  });
552
+ this.checkpointProposalValidator = new CheckpointProposalValidator(epochCache, {
553
+ txsPermitted: !config.disableTransactions
554
+ });
555
+ this.checkpointAttestationValidator = config.fishermanMode ? new FishermanAttestationValidator(epochCache, mempools.attestationPool, telemetry) : new CheckpointAttestationValidator(epochCache);
539
556
  this.gossipSubEventHandler = this.handleGossipSubEvent.bind(this);
540
557
  this.blockReceivedCallback = async (block)=>{
541
558
  this.logger.debug(`Handler not yet registered: Block received callback not set. Received block for slot ${block.slotNumber} from peer.`, {
542
559
  p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier()
543
560
  });
544
- return undefined;
561
+ return false;
562
+ };
563
+ this.checkpointReceivedCallback = (checkpoint)=>{
564
+ this.logger.debug(`Handler not yet registered: Checkpoint received callback not set. Received checkpoint for slot ${checkpoint.slotNumber} from peer.`);
565
+ return Promise.resolve(undefined);
545
566
  };
546
567
  }
547
568
  updateConfig(config) {
@@ -574,7 +595,8 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
574
595
  const protocolVersion = compressComponentVersions(versions);
575
596
  const txTopic = createTopicString(TopicType.tx, protocolVersion);
576
597
  const blockProposalTopic = createTopicString(TopicType.block_proposal, protocolVersion);
577
- const blockAttestationTopic = createTopicString(TopicType.block_attestation, protocolVersion);
598
+ const checkpointProposalTopic = createTopicString(TopicType.checkpoint_proposal, protocolVersion);
599
+ const checkpointAttestationTopic = createTopicString(TopicType.checkpoint_attestation, protocolVersion);
578
600
  const preferredPeersEnrs = config.preferredPeers.map((enr)=>ENR.decodeTxt(enr));
579
601
  const directPeers = (await Promise.all(preferredPeersEnrs.map(async (enr)=>{
580
602
  const peerId = await enr.peerId();
@@ -698,12 +720,17 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
698
720
  invalidMessageDeliveriesWeight: -20,
699
721
  invalidMessageDeliveriesDecay: 0.5
700
722
  }),
701
- [blockAttestationTopic]: createTopicScoreParams({
723
+ [blockProposalTopic]: createTopicScoreParams({
702
724
  topicWeight: 1,
703
725
  invalidMessageDeliveriesWeight: -20,
704
726
  invalidMessageDeliveriesDecay: 0.5
705
727
  }),
706
- [blockProposalTopic]: createTopicScoreParams({
728
+ [checkpointProposalTopic]: createTopicScoreParams({
729
+ topicWeight: 1,
730
+ invalidMessageDeliveriesWeight: -20,
731
+ invalidMessageDeliveriesDecay: 0.5
732
+ }),
733
+ [checkpointAttestationTopic]: createTopicScoreParams({
707
734
  topicWeight: 1,
708
735
  invalidMessageDeliveriesWeight: -20,
709
736
  invalidMessageDeliveriesDecay: 0.5
@@ -739,15 +766,6 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
739
766
  throw new Error('Announce address not provided.');
740
767
  }
741
768
  const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
742
- await this.peerManager.initializePeers();
743
- if (!this.config.p2pDiscoveryDisabled) {
744
- await this.peerDiscoveryService.start();
745
- }
746
- await this.node.start();
747
- // Subscribe to standard GossipSub topics by default
748
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
749
- this.subscribeToTopic(this.topicStrings[topic]);
750
- }
751
769
  // Create request response protocol handlers
752
770
  const txHandler = reqRespTxHandler(this.mempools);
753
771
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
@@ -766,13 +784,6 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
766
784
  if (!this.config.disableTransactions) {
767
785
  requestResponseHandlers[ReqRespSubProtocol.TX] = txHandler.bind(this);
768
786
  }
769
- // add GossipSub listener
770
- this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
771
- // Start running promise for peer discovery and metrics collection
772
- this.discoveryRunningPromise = new RunningPromise(async ()=>{
773
- await this.peerManager.heartbeat();
774
- }, this.logger, this.config.peerCheckIntervalMS);
775
- this.discoveryRunningPromise.start();
776
787
  // Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
777
788
  const reqrespSubProtocolValidators = {
778
789
  ...DEFAULT_SUB_PROTOCOL_VALIDATORS,
@@ -780,7 +791,23 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
780
791
  [ReqRespSubProtocol.BLOCK_TXS]: this.validateRequestedBlockTxs.bind(this),
781
792
  [ReqRespSubProtocol.BLOCK]: this.validateRequestedBlock.bind(this)
782
793
  };
794
+ await this.peerManager.initializePeers();
783
795
  await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
796
+ await this.node.start();
797
+ // Subscribe to standard GossipSub topics by default
798
+ for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
799
+ this.subscribeToTopic(this.topicStrings[topic]);
800
+ }
801
+ // add GossipSub listener
802
+ this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.gossipSubEventHandler);
803
+ // Start running promise for peer discovery and metrics collection
804
+ if (!this.config.p2pDiscoveryDisabled) {
805
+ await this.peerDiscoveryService.start();
806
+ }
807
+ this.discoveryRunningPromise = new RunningPromise(async ()=>{
808
+ await this.peerManager.heartbeat();
809
+ }, this.logger, this.config.peerCheckIntervalMS);
810
+ this.discoveryRunningPromise.start();
784
811
  this.logger.info(`Started P2P service`, {
785
812
  listen: this.config.listenAddress,
786
813
  port: this.config.p2pPort,
@@ -844,6 +871,9 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
844
871
  registerBlockReceivedCallback(callback) {
845
872
  this.blockReceivedCallback = callback;
846
873
  }
874
+ registerCheckpointReceivedCallback(callback) {
875
+ this.checkpointReceivedCallback = callback;
876
+ }
847
877
  /**
848
878
  * Subscribes to a topic.
849
879
  * @param topic - The topic to subscribe to.
@@ -878,12 +908,15 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
878
908
  case this.topicStrings[TopicType.tx]:
879
909
  topicType = TopicType.tx;
880
910
  break;
881
- case this.topicStrings[TopicType.block_attestation]:
882
- topicType = TopicType.block_attestation;
883
- break;
884
911
  case this.topicStrings[TopicType.block_proposal]:
885
912
  topicType = TopicType.block_proposal;
886
913
  break;
914
+ case this.topicStrings[TopicType.checkpoint_proposal]:
915
+ topicType = TopicType.checkpoint_proposal;
916
+ break;
917
+ case this.topicStrings[TopicType.checkpoint_attestation]:
918
+ topicType = TopicType.checkpoint_attestation;
919
+ break;
887
920
  default:
888
921
  this.logger.error(`Received message on unknown topic: ${msg.topic}`);
889
922
  break;
@@ -940,23 +973,27 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
940
973
  // Determine topic type for attributes
941
974
  if (msg.topic === this.topicStrings[TopicType.tx]) {
942
975
  topicType = TopicType.tx;
943
- } else if (msg.topic === this.topicStrings[TopicType.block_attestation]) {
944
- topicType = TopicType.block_attestation;
976
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
977
+ topicType = TopicType.checkpoint_attestation;
945
978
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
946
979
  topicType = TopicType.block_proposal;
980
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
981
+ topicType = TopicType.checkpoint_proposal;
947
982
  }
948
983
  // Process the message, optionally within a linked span for trace propagation
949
984
  const processMessage = async ()=>{
950
985
  if (msg.topic === this.topicStrings[TopicType.tx]) {
951
986
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
952
- }
953
- if (msg.topic === this.topicStrings[TopicType.block_attestation]) {
987
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
954
988
  if (this.clientType === P2PClientType.Full) {
955
- await this.processAttestationFromPeer(p2pMessage.payload, msgId, source);
989
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
956
990
  }
957
- }
958
- if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
991
+ } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
959
992
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
993
+ } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
994
+ await this.handleGossipedCheckpointProposal(p2pMessage.payload, msgId, source);
995
+ } else {
996
+ this.logger.error(`Received message on unknown topic: ${msg.topic}`);
960
997
  }
961
998
  };
962
999
  const latency = p2pMessage.timestamp !== undefined ? msgReceivedTime - p2pMessage.timestamp.getTime() : undefined;
@@ -1061,24 +1098,22 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1061
1098
  ]);
1062
1099
  }
1063
1100
  /**
1064
- * Process Attestation From Peer
1065
- * When a proposal is received from a peer, we add it to the attestation pool, so it can be accessed by other services.
1066
- *
1067
- * @param attestation - The attestation to process.
1068
- */ async processAttestationFromPeer(payloadData, msgId, source) {
1101
+ * Process a checkpoint attestation from a peer.
1102
+ * Validates the attestation and adds it to the pool.
1103
+ */ async processCheckpointAttestationFromPeer(payloadData, msgId, source) {
1069
1104
  const validationFunc = async ()=>{
1070
- const attestation = BlockAttestation.fromBuffer(payloadData);
1105
+ const attestation = CheckpointAttestation.fromBuffer(payloadData);
1071
1106
  const pool = this.mempools.attestationPool;
1072
- const isValid = await this.validateAttestation(source, attestation);
1073
- const exists = isValid && await pool.hasAttestation(attestation);
1107
+ const isValid = await this.validateCheckpointAttestation(source, attestation);
1108
+ const exists = isValid && await pool.hasCheckpointAttestation(attestation);
1074
1109
  let canAdd = true;
1075
1110
  if (isValid && !exists) {
1076
1111
  const slot = attestation.payload.header.slotNumber;
1077
1112
  const { committee } = await this.epochCache.getCommittee(slot);
1078
1113
  const committeeSize = committee?.length ?? 0;
1079
- canAdd = await pool.canAddAttestation(attestation, committeeSize);
1114
+ canAdd = await pool.canAddCheckpointAttestation(attestation, committeeSize);
1080
1115
  }
1081
- this.logger.trace(`Validate propagated block attestation`, {
1116
+ this.logger.trace(`Validate propagated checkpoint attestation`, {
1082
1117
  isValid,
1083
1118
  exists,
1084
1119
  canAdd,
@@ -1095,7 +1130,7 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1095
1130
  obj: attestation
1096
1131
  };
1097
1132
  } else if (!canAdd) {
1098
- this.logger.warn(`Dropping block attestation due to per-(slot, proposalId) attestation cap`, {
1133
+ this.logger.warn(`Dropping checkpoint attestation due to per-(slot, proposalId) attestation cap`, {
1099
1134
  slot: attestation.payload.header.slotNumber.toString(),
1100
1135
  archive: attestation.archive.toString(),
1101
1136
  source: source.toString()
@@ -1111,17 +1146,17 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1111
1146
  };
1112
1147
  }
1113
1148
  };
1114
- const { result, obj: attestation } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.block_attestation);
1149
+ const { result, obj: attestation } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.checkpoint_attestation);
1115
1150
  if (result !== TopicValidatorResult.Accept || !attestation) {
1116
1151
  return;
1117
1152
  }
1118
- this.logger.debug(`Received attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`, {
1153
+ this.logger.debug(`Received checkpoint attestation for slot ${attestation.slotNumber} from external peer ${source.toString()}`, {
1119
1154
  p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
1120
1155
  slot: attestation.slotNumber,
1121
1156
  archive: attestation.archive.toString(),
1122
1157
  source: source.toString()
1123
1158
  });
1124
- await this.mempools.attestationPool.addAttestations([
1159
+ await this.mempools.attestationPool.addCheckpointAttestations([
1125
1160
  attestation
1126
1161
  ]);
1127
1162
  }
@@ -1136,7 +1171,7 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1136
1171
  isValid,
1137
1172
  exists,
1138
1173
  canAdd,
1139
- [Attributes.SLOT_NUMBER]: block.payload.header.slotNumber.toString(),
1174
+ [Attributes.SLOT_NUMBER]: block.slotNumber.toString(),
1140
1175
  [Attributes.P2P_ID]: source.toString()
1141
1176
  });
1142
1177
  if (!isValid) {
@@ -1172,18 +1207,16 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1172
1207
  await this.processValidBlockProposal(block, source);
1173
1208
  }
1174
1209
  // REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
1210
+ // REFACTOR(palla): This method should be moved to the p2p_client or to a separate component,
1211
+ // should not be here as it does not deal with p2p networking.
1175
1212
  async processValidBlockProposal(block, sender) {
1176
1213
  const slot = block.slotNumber;
1177
- const previousSlot = SlotNumber(slot - 1);
1178
1214
  this.logger.verbose(`Received block proposal for slot ${slot} from external peer ${sender.toString()}.`, {
1179
1215
  p2pMessageIdentifier: await block.p2pMessageLoggingIdentifier(),
1180
- slot: block.slotNumber,
1181
- archive: block.archive.toString(),
1182
- source: sender.toString()
1216
+ source: sender.toString(),
1217
+ ...block.toBlockInfo()
1183
1218
  });
1184
- const attestationsForPreviousSlot = await this.mempools.attestationPool.getAttestationsForSlot(previousSlot);
1185
- this.logger.verbose(`Received ${attestationsForPreviousSlot.length} attestations for slot ${previousSlot}`);
1186
- // Attempt to add proposal, then mark the txs in this proposal as non-evictable
1219
+ // Attempt to add proposal
1187
1220
  try {
1188
1221
  await this.mempools.attestationPool.addBlockProposal(block);
1189
1222
  } catch (err) {
@@ -1198,26 +1231,108 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1198
1231
  }
1199
1232
  throw err;
1200
1233
  }
1234
+ // Mark the txs in this proposal as non-evictable
1201
1235
  await this.mempools.txPool.markTxsAsNonEvictable(block.txHashes);
1202
- const attestations = await this.blockReceivedCallback(block, sender);
1203
- // TODO: fix up this pattern - the abstraction is not nice
1204
- // The attestation can be undefined if no handler is registered / the validator deems the block invalid / in fisherman mode
1205
- if (attestations?.length) {
1206
- for (const attestation of attestations){
1207
- this.logger.verbose(`Broadcasting attestation for slot ${attestation.slotNumber}`, {
1208
- p2pMessageIdentifier: await attestation.p2pMessageLoggingIdentifier(),
1209
- slot: attestation.slotNumber,
1210
- archive: attestation.archive.toString()
1236
+ // Call the block received callback to validate the proposal.
1237
+ // Note: Validators do NOT attest to individual blocks, only to checkpoint proposals.
1238
+ const isValid = await this.blockReceivedCallback(block, sender);
1239
+ if (!isValid) {
1240
+ this.logger.warn(`Block proposal validation failed for block ${block.blockNumber}`, block.toBlockInfo());
1241
+ }
1242
+ }
1243
+ /**
1244
+ * Handle a gossiped checkpoint proposal.
1245
+ * Validates and processes the checkpoint proposal, then triggers the callback for attestation.
1246
+ */ async handleGossipedCheckpointProposal(payloadData, msgId, source) {
1247
+ // TODO(palla/mbps): This pattern is repeated across multiple message handlers, consider abstracting it.
1248
+ const validationFunc = async ()=>{
1249
+ const checkpoint = CheckpointProposal.fromBuffer(payloadData);
1250
+ const isValid = await this.validateCheckpointProposal(source, checkpoint);
1251
+ const pool = this.mempools.attestationPool;
1252
+ const exists = isValid && await pool.hasCheckpointProposal(checkpoint);
1253
+ const canAdd = isValid && await pool.canAddCheckpointProposal(checkpoint);
1254
+ this.logger.trace(`Validate propagated checkpoint proposal`, {
1255
+ isValid,
1256
+ exists,
1257
+ canAdd,
1258
+ [Attributes.SLOT_NUMBER]: checkpoint.slotNumber.toString(),
1259
+ [Attributes.P2P_ID]: source.toString()
1260
+ });
1261
+ if (!isValid) {
1262
+ return {
1263
+ result: TopicValidatorResult.Reject
1264
+ };
1265
+ } else if (exists) {
1266
+ return {
1267
+ result: TopicValidatorResult.Ignore,
1268
+ obj: checkpoint
1269
+ };
1270
+ } else if (!canAdd) {
1271
+ this.peerManager.penalizePeer(source, PeerErrorSeverity.MidToleranceError);
1272
+ this.logger.warn(`Penalizing peer for checkpoint proposal exceeding per-slot cap`, {
1273
+ slot: checkpoint.slotNumber.toString(),
1274
+ archive: checkpoint.archive.toString(),
1275
+ source: source.toString()
1211
1276
  });
1212
- await this.broadcastAttestation(attestation);
1277
+ return {
1278
+ result: TopicValidatorResult.Reject
1279
+ };
1280
+ } else {
1281
+ return {
1282
+ result: TopicValidatorResult.Accept,
1283
+ obj: checkpoint
1284
+ };
1213
1285
  }
1286
+ };
1287
+ const { result, obj: checkpoint } = await this.validateReceivedMessage(validationFunc, msgId, source, TopicType.checkpoint_proposal);
1288
+ if (result !== TopicValidatorResult.Accept || !checkpoint) {
1289
+ return;
1214
1290
  }
1291
+ await this.processValidCheckpointProposal(checkpoint, source);
1215
1292
  }
1216
1293
  /**
1217
- * Broadcast an attestation to all peers.
1218
- * @param attestation - The attestation to broadcast.
1219
- */ async broadcastAttestation(attestation) {
1220
- await this.propagate(attestation);
1294
+ * Process a validated checkpoint proposal.
1295
+ * Extracts and processes the last block proposal (if present) first, then processes the checkpoint.
1296
+ * The block callback is invoked before the checkpoint callback.
1297
+ */ async processValidCheckpointProposal(checkpoint, sender) {
1298
+ const slot = checkpoint.slotNumber;
1299
+ this.logger.verbose(`Received checkpoint proposal for slot ${slot} from external peer ${sender.toString()}.`, {
1300
+ p2pMessageIdentifier: await checkpoint.p2pMessageLoggingIdentifier(),
1301
+ slot: checkpoint.slotNumber,
1302
+ archive: checkpoint.archive.toString(),
1303
+ source: sender.toString()
1304
+ });
1305
+ // Extract block proposal before adding to pool (pool stores them separately)
1306
+ const blockProposal = checkpoint.getBlockProposal();
1307
+ // Add proposal to the pool (this extracts and stores block proposal separately)
1308
+ await this.mempools.attestationPool.addCheckpointProposal(checkpoint);
1309
+ // Mark txs as non-evictable if present (from the last block)
1310
+ if (checkpoint.txHashes.length > 0) {
1311
+ await this.mempools.txPool.markTxsAsNonEvictable(checkpoint.txHashes);
1312
+ }
1313
+ // If there was a last block proposal, invoke the block callback first for validation.
1314
+ // Note: The block proposal is already stored in the pool by addCheckpointProposal.
1315
+ if (blockProposal) {
1316
+ const isValid = await this.blockReceivedCallback(blockProposal, sender);
1317
+ if (!isValid) {
1318
+ this.logger.warn(`Block proposal from checkpoint failed validation`, {
1319
+ slot: slot.toString(),
1320
+ archive: checkpoint.archive.toString(),
1321
+ blockNumber: blockProposal.blockNumber.toString()
1322
+ });
1323
+ return;
1324
+ }
1325
+ }
1326
+ // Call the checkpoint received callback with the core version (without lastBlock)
1327
+ // to validate and potentially generate attestations
1328
+ const attestations = await this.checkpointReceivedCallback(checkpoint.toCore(), sender);
1329
+ if (attestations && attestations.length > 0) {
1330
+ // If the callback returned attestations, add them to the pool and propagate them
1331
+ await this.mempools.attestationPool.addCheckpointAttestations(attestations);
1332
+ for (const attestation of attestations){
1333
+ await this.propagate(attestation);
1334
+ }
1335
+ }
1221
1336
  }
1222
1337
  /**
1223
1338
  * Propagates provided message to peers.
@@ -1525,13 +1640,14 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1525
1640
  return PeerErrorSeverity.HighToleranceError;
1526
1641
  }
1527
1642
  /**
1528
- * Validate an attestation.
1643
+ * Validate a checkpoint attestation.
1529
1644
  *
1530
- * @param attestation - The attestation to validate.
1531
- * @returns True if the attestation is valid, false otherwise.
1532
- */ async validateAttestation(peerId, attestation) {
1533
- const severity = await this.attestationValidator.validate(attestation);
1645
+ * @param attestation - The checkpoint attestation to validate.
1646
+ * @returns True if the checkpoint attestation is valid, false otherwise.
1647
+ */ async validateCheckpointAttestation(peerId, attestation) {
1648
+ const severity = await this.checkpointAttestationValidator.validate(attestation);
1534
1649
  if (severity) {
1650
+ this.logger.debug(`Penalizing peer ${peerId} for checkpoint attestation validation failure`);
1535
1651
  this.peerManager.penalizePeer(peerId, severity);
1536
1652
  return false;
1537
1653
  }
@@ -1551,6 +1667,20 @@ _dec = trackSpan('Libp2pService.processValidBlockProposal', async (block)=>({
1551
1667
  }
1552
1668
  return true;
1553
1669
  }
1670
+ /**
1671
+ * Validate a checkpoint proposal.
1672
+ *
1673
+ * @param checkpoint - The checkpoint proposal to validate.
1674
+ * @returns True if the checkpoint proposal is valid, false otherwise.
1675
+ */ async validateCheckpointProposal(peerId, checkpoint) {
1676
+ const severity = await this.checkpointProposalValidator.validate(checkpoint);
1677
+ if (severity) {
1678
+ this.logger.debug(`Penalizing peer ${peerId} for checkpoint proposal validation failure`);
1679
+ this.peerManager.penalizePeer(peerId, severity);
1680
+ return false;
1681
+ }
1682
+ return true;
1683
+ }
1554
1684
  getPeerScore(peerId) {
1555
1685
  return this.node.services.pubsub.score.score(peerId.toString());
1556
1686
  }
@@ -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 { BlockAttestation, BlockProposal, Gossipable } from '@aztec/stdlib/p2p';
3
+ import type { BlockProposal, CheckpointAttestation, CheckpointProposalCore, Gossipable } from '@aztec/stdlib/p2p';
4
4
  import type { Tx } from '@aztec/stdlib/tx';
5
5
  import type { PeerId } from '@libp2p/interface';
6
6
  import type { ENR } from '@nethermindeth/enr';
@@ -13,7 +13,19 @@ export declare enum PeerDiscoveryState {
13
13
  RUNNING = "running",
14
14
  STOPPED = "stopped"
15
15
  }
16
- export type P2PBlockReceivedCallback = (block: BlockProposal, sender: PeerId) => Promise<BlockAttestation[] | undefined>;
16
+ /**
17
+ * Callback for when a block proposal is received.
18
+ * Validators validate but DO NOT attest to individual blocks - attestations are only for checkpoints.
19
+ * @returns true if the proposal is valid, false otherwise
20
+ */
21
+ export type P2PBlockReceivedCallback = (block: BlockProposal, sender: PeerId) => Promise<boolean>;
22
+ /**
23
+ * Callback for when a checkpoint proposal is received.
24
+ * The checkpoint proposal is passed as CheckpointProposalCore (without lastBlock) since
25
+ * the lastBlock is extracted and stored separately as a BlockProposal, and the block
26
+ * callback is invoked and awaited before this checkpoint callback.
27
+ */
28
+ export type P2PCheckpointReceivedCallback = (checkpoint: CheckpointProposalCore, sender: PeerId) => Promise<CheckpointAttestation[] | undefined>;
17
29
  export type AuthReceivedCallback = (peerId: PeerId, authRequest: AuthRequest) => Promise<AuthResponse | undefined>;
18
30
  /**
19
31
  * The interface for a P2P service implementation.
@@ -43,6 +55,7 @@ export interface P2PService {
43
55
  */
44
56
  sendBatchRequest<Protocol extends ReqRespSubProtocol>(protocol: Protocol, requests: InstanceType<SubProtocolMap[Protocol]['request']>[], pinnedPeerId?: PeerId, timeoutMs?: number, maxPeers?: number, maxRetryAttempts?: number): Promise<InstanceType<SubProtocolMap[Protocol]['response']>[]>;
45
57
  registerBlockReceivedCallback(callback: P2PBlockReceivedCallback): void;
58
+ registerCheckpointReceivedCallback(callback: P2PCheckpointReceivedCallback): void;
46
59
  getEnr(): ENR | undefined;
47
60
  getPeers(includePending?: boolean): PeerInfo[];
48
61
  validate(txs: Tx[]): Promise<void>;
@@ -88,4 +101,4 @@ export interface PeerDiscoveryService extends EventEmitter {
88
101
  getEnr(): ENR | undefined;
89
102
  bootstrapNodeEnrs: ENR[];
90
103
  }
91
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3JGLE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTNDLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxZQUFZLE1BQU0sUUFBUSxDQUFDO0FBRXZDLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDeEQsT0FBTyxLQUFLLEVBQ1Ysa0JBQWtCLEVBQ2xCLHlCQUF5QixFQUN6Qiw0QkFBNEIsRUFDNUIsY0FBYyxFQUNmLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRTdFLG9CQUFZLGtCQUFrQjtJQUM1QixPQUFPLFlBQVk7SUFDbkIsT0FBTyxZQUFZO0NBQ3BCO0FBRUQsTUFBTSxNQUFNLHdCQUF3QixHQUFHLENBQ3JDLEtBQUssRUFBRSxhQUFhLEVBQ3BCLE1BQU0sRUFBRSxNQUFNLEtBQ1gsT0FBTyxDQUFDLGdCQUFnQixFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUM7QUFFN0MsTUFBTSxNQUFNLG9CQUFv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
104
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLHFCQUFxQixFQUFFLHNCQUFzQixFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xILE9BQU8sS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTNDLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxZQUFZLE1BQU0sUUFBUSxDQUFDO0FBRXZDLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDeEQsT0FBTyxLQUFLLEVBQ1Ysa0JBQWtCLEVBQ2xCLHlCQUF5QixFQUN6Qiw0QkFBNEIsRUFDNUIsY0FBYyxFQUNmLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRTdFLG9CQUFZLGtCQUFrQjtJQUM1QixPQUFPLFlBQVk7SUFDbkIsT0FBTyxZQUFZO0NBQ3BCO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sTUFBTSx3QkFBd0IsR0FBRyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLE1BQU0sS0FBSyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7QUFFbEc7Ozs7O0dBS0c7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
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/services/service.ts"],"names":[],"mappings":"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"}