@aztec/p2p 0.0.1-commit.7ac86ea28 → 0.0.1-commit.7b86788

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 (124) hide show
  1. package/dest/client/factory.d.ts +4 -5
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +15 -26
  4. package/dest/client/interface.d.ts +6 -13
  5. package/dest/client/interface.d.ts.map +1 -1
  6. package/dest/client/p2p_client.d.ts +5 -13
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +3 -58
  9. package/dest/client/test/tx_proposal_collector/proposal_tx_collector_worker.js +1 -2
  10. package/dest/config.d.ts +2 -5
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +0 -5
  13. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.js +1 -1
  14. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts +1 -1
  15. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.d.ts.map +1 -1
  16. package/dest/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.js +2 -0
  17. package/dest/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.js +2 -2
  18. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts +2 -2
  19. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.d.ts.map +1 -1
  20. package/dest/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.js +10 -6
  21. package/dest/mem_pools/tx_pool_v2/index.d.ts +2 -2
  22. package/dest/mem_pools/tx_pool_v2/index.d.ts.map +1 -1
  23. package/dest/mem_pools/tx_pool_v2/index.js +1 -1
  24. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +7 -5
  25. package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
  26. package/dest/mem_pools/tx_pool_v2/interfaces.js +2 -1
  27. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts +26 -4
  28. package/dest/mem_pools/tx_pool_v2/tx_metadata.d.ts.map +1 -1
  29. package/dest/mem_pools/tx_pool_v2/tx_metadata.js +48 -7
  30. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts +1 -1
  31. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.d.ts.map +1 -1
  32. package/dest/mem_pools/tx_pool_v2/tx_pool_indices.js +9 -10
  33. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts +2 -2
  34. package/dest/mem_pools/tx_pool_v2/tx_pool_v2.d.ts.map +1 -1
  35. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +2 -2
  36. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
  37. package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +173 -146
  38. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts +2 -2
  39. package/dest/msg_validators/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
  40. package/dest/msg_validators/tx_validator/aggregate_tx_validator.js +3 -3
  41. package/dest/msg_validators/tx_validator/factory.d.ts +114 -6
  42. package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
  43. package/dest/msg_validators/tx_validator/factory.js +219 -58
  44. package/dest/msg_validators/tx_validator/gas_validator.d.ts +58 -3
  45. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
  46. package/dest/msg_validators/tx_validator/gas_validator.js +73 -36
  47. package/dest/msg_validators/tx_validator/index.d.ts +2 -1
  48. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  49. package/dest/msg_validators/tx_validator/index.js +1 -0
  50. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts +14 -0
  51. package/dest/msg_validators/tx_validator/nullifier_cache.d.ts.map +1 -0
  52. package/dest/msg_validators/tx_validator/nullifier_cache.js +24 -0
  53. package/dest/services/dummy_service.d.ts +2 -3
  54. package/dest/services/dummy_service.d.ts.map +1 -1
  55. package/dest/services/dummy_service.js +1 -4
  56. package/dest/services/encoding.d.ts +2 -2
  57. package/dest/services/encoding.d.ts.map +1 -1
  58. package/dest/services/encoding.js +7 -7
  59. package/dest/services/libp2p/libp2p_service.d.ts +15 -13
  60. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  61. package/dest/services/libp2p/libp2p_service.js +64 -80
  62. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts +1 -1
  63. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.d.ts.map +1 -1
  64. package/dest/services/reqresp/batch-tx-requester/batch_tx_requester.js +14 -37
  65. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts +17 -11
  66. package/dest/services/reqresp/batch-tx-requester/peer_collection.d.ts.map +1 -1
  67. package/dest/services/reqresp/batch-tx-requester/peer_collection.js +49 -15
  68. package/dest/services/reqresp/batch-tx-requester/tx_validator.js +2 -2
  69. package/dest/services/reqresp/reqresp.d.ts +1 -1
  70. package/dest/services/reqresp/reqresp.d.ts.map +1 -1
  71. package/dest/services/reqresp/reqresp.js +2 -1
  72. package/dest/services/service.d.ts +2 -2
  73. package/dest/services/service.d.ts.map +1 -1
  74. package/dest/services/tx_provider.d.ts +3 -3
  75. package/dest/services/tx_provider.d.ts.map +1 -1
  76. package/dest/services/tx_provider.js +4 -4
  77. package/dest/test-helpers/make-test-p2p-clients.d.ts +5 -6
  78. package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
  79. package/dest/test-helpers/make-test-p2p-clients.js +1 -2
  80. package/dest/test-helpers/mock-pubsub.d.ts +2 -3
  81. package/dest/test-helpers/mock-pubsub.d.ts.map +1 -1
  82. package/dest/test-helpers/mock-pubsub.js +2 -2
  83. package/dest/test-helpers/reqresp-nodes.d.ts +2 -3
  84. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  85. package/dest/test-helpers/reqresp-nodes.js +2 -2
  86. package/dest/test-helpers/testbench-utils.d.ts +2 -2
  87. package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
  88. package/dest/testbench/p2p_client_testbench_worker.js +5 -5
  89. package/package.json +14 -14
  90. package/src/client/factory.ts +22 -46
  91. package/src/client/interface.ts +5 -19
  92. package/src/client/p2p_client.ts +4 -88
  93. package/src/client/test/tx_proposal_collector/proposal_tx_collector_worker.ts +1 -2
  94. package/src/config.ts +1 -9
  95. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_eviction_rule.ts +1 -1
  96. package/src/mem_pools/tx_pool_v2/eviction/fee_payer_balance_pre_add_rule.ts +3 -0
  97. package/src/mem_pools/tx_pool_v2/eviction/invalid_txs_after_reorg_rule.ts +2 -2
  98. package/src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.ts +10 -6
  99. package/src/mem_pools/tx_pool_v2/index.ts +1 -1
  100. package/src/mem_pools/tx_pool_v2/interfaces.ts +7 -4
  101. package/src/mem_pools/tx_pool_v2/tx_metadata.ts +65 -10
  102. package/src/mem_pools/tx_pool_v2/tx_pool_indices.ts +11 -11
  103. package/src/mem_pools/tx_pool_v2/tx_pool_v2.ts +1 -1
  104. package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +179 -148
  105. package/src/msg_validators/tx_validator/README.md +115 -0
  106. package/src/msg_validators/tx_validator/aggregate_tx_validator.ts +3 -3
  107. package/src/msg_validators/tx_validator/factory.ts +353 -77
  108. package/src/msg_validators/tx_validator/gas_validator.ts +90 -27
  109. package/src/msg_validators/tx_validator/index.ts +1 -0
  110. package/src/msg_validators/tx_validator/nullifier_cache.ts +30 -0
  111. package/src/services/dummy_service.ts +1 -5
  112. package/src/services/encoding.ts +5 -6
  113. package/src/services/libp2p/libp2p_service.ts +75 -90
  114. package/src/services/reqresp/batch-tx-requester/batch_tx_requester.ts +14 -42
  115. package/src/services/reqresp/batch-tx-requester/peer_collection.ts +63 -24
  116. package/src/services/reqresp/batch-tx-requester/tx_validator.ts +2 -2
  117. package/src/services/reqresp/reqresp.ts +3 -1
  118. package/src/services/service.ts +1 -1
  119. package/src/services/tx_provider.ts +2 -2
  120. package/src/test-helpers/make-test-p2p-clients.ts +0 -2
  121. package/src/test-helpers/mock-pubsub.ts +3 -6
  122. package/src/test-helpers/reqresp-nodes.ts +2 -5
  123. package/src/test-helpers/testbench-utils.ts +1 -1
  124. package/src/testbench/p2p_client_testbench_worker.ts +2 -6
@@ -370,14 +370,14 @@ 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, _dec8, _dec9, _initProto;
373
+ var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _initProto;
374
374
  import { BlockNumber } from '@aztec/foundation/branded-types';
375
375
  import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
376
376
  import { RunningPromise } from '@aztec/foundation/running-promise';
377
377
  import { Timer } from '@aztec/foundation/timer';
378
378
  import { protocolContractsHash } from '@aztec/protocol-contracts';
379
379
  import { GasFees } from '@aztec/stdlib/gas';
380
- import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PClientType, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForClientAndConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
380
+ import { BlockProposal, CheckpointAttestation, CheckpointProposal, P2PMessage, PeerErrorSeverity, TopicType, createTopicString, getTopicsForConfig, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
381
381
  import { MerkleTreeId } from '@aztec/stdlib/trees';
382
382
  import { Tx } from '@aztec/stdlib/tx';
383
383
  import { compressComponentVersions } from '@aztec/stdlib/versioning';
@@ -396,7 +396,7 @@ import { ENR } from '@nethermindeth/enr';
396
396
  import { createLibp2p } from 'libp2p';
397
397
  import { BlockProposalValidator, CheckpointAttestationValidator, CheckpointProposalValidator, DoubleSpendTxValidator, FishermanAttestationValidator, getDefaultAllowedSetupFunctions } from '../../msg_validators/index.js';
398
398
  import { MessageSeenValidator } from '../../msg_validators/msg_seen_validator/msg_seen_validator.js';
399
- import { createTxMessageValidators, createTxReqRespValidator } from '../../msg_validators/tx_validator/factory.js';
399
+ import { createFirstStageTxValidationsForGossipedTransactions, createSecondStageTxValidationsForGossipedTransactions, createTxValidatorForBlockProposalReceivedTxs, createTxValidatorForReqResponseReceivedTxs } from '../../msg_validators/tx_validator/factory.js';
400
400
  import { GossipSubEvent } from '../../types/index.js';
401
401
  import { convertToMultiaddr } from '../../util.js';
402
402
  import { getVersions } from '../../versioning.js';
@@ -407,8 +407,7 @@ import { APP_SPECIFIC_WEIGHT, gossipScoreThresholds } from '../gossipsub/scoring
407
407
  import { createAllTopicScoreParams } from '../gossipsub/topic_score_params.js';
408
408
  import { PeerManager } from '../peer-manager/peer_manager.js';
409
409
  import { PeerScoring } from '../peer-manager/peer_scoring.js';
410
- import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError } from '../reqresp/index.js';
411
- import { pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
410
+ import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, ValidationError, pingHandler, reqGoodbyeHandler, reqRespBlockHandler, reqRespBlockTxsHandler, reqRespStatusHandler, reqRespTxHandler } from '../reqresp/index.js';
412
411
  import { ReqResp } from '../reqresp/reqresp.js';
413
412
  import { P2PInstrumentation } from './instrumentation.js';
414
413
  _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId, attestation)=>({
@@ -432,9 +431,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
432
431
  [Attributes.TX_HASH]: requestedTxHash.toString()
433
432
  })), _dec7 = trackSpan('Libp2pService.validateRequestedBlock', (requestedBlockNumber, _responseBlock)=>({
434
433
  [Attributes.BLOCK_NUMBER]: requestedBlockNumber.toString()
435
- })), _dec8 = trackSpan('Libp2pService.validatePropagatedTx', (tx)=>({
436
- [Attributes.TX_HASH]: tx.getTxHash().toString()
437
- })), _dec9 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
434
+ })), _dec8 = trackSpan('Libp2pService.validateCheckpointAttestation', async (_, attestation)=>({
438
435
  [Attributes.SLOT_NUMBER]: attestation.payload.header.slotNumber,
439
436
  [Attributes.BLOCK_ARCHIVE]: attestation.archive.toString(),
440
437
  [Attributes.P2P_ID]: await attestation.p2pMessageLoggingIdentifier().then((i)=>i.toString())
@@ -442,7 +439,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
442
439
  /**
443
440
  * Lib P2P implementation of the P2PService interface.
444
441
  */ export class LibP2PService extends WithTracer {
445
- clientType;
446
442
  config;
447
443
  node;
448
444
  peerDiscoveryService;
@@ -498,11 +494,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
498
494
  [
499
495
  _dec8,
500
496
  2,
501
- "validatePropagatedTx"
502
- ],
503
- [
504
- _dec9,
505
- 2,
506
497
  "validateCheckpointAttestation"
507
498
  ]
508
499
  ], []));
@@ -532,8 +523,8 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
532
523
  instrumentation;
533
524
  telemetry;
534
525
  logger;
535
- constructor(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
536
- super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.msgIdSeenValidators = (_initProto(this), {}), this.protocolVersion = '', this.topicStrings = {};
526
+ constructor(config, node, peerDiscoveryService, reqresp, peerManager, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
527
+ super(telemetry, 'LibP2PService'), this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.reqresp = reqresp, this.peerManager = peerManager, this.mempools = mempools, this.archiver = archiver, this.epochCache = epochCache, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.msgIdSeenValidators = (_initProto(this), {}), this.protocolVersion = '', this.topicStrings = {};
537
528
  this.telemetry = telemetry;
538
529
  // Create child logger with fisherman prefix if in fisherman mode
539
530
  this.logger = config.fishermanMode ? logger.createChild('[FISHERMAN]') : logger;
@@ -576,7 +567,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
576
567
  * @param config - The configuration to use when creating the service.
577
568
  * @param txPool - The transaction pool to be accessed by the service.
578
569
  * @returns The new service.
579
- */ static async new(clientType, config, peerId, deps) {
570
+ */ static async new(config, peerId, deps) {
580
571
  const { worldStateSynchronizer, epochCache, l2BlockSource, mempools, proofVerifier, peerStore, telemetry, logger, packageVersion } = deps;
581
572
  const { p2pPort, maxPeerCount, listenAddress } = config;
582
573
  const bindAddrTcp = convertToMultiaddr(listenAddress, p2pPort, 'tcp');
@@ -741,7 +732,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
741
732
  // Note: positive topic scores can offset penalties, so alignment is best-effort.
742
733
  node.services.pubsub.score.params.appSpecificWeight = APP_SPECIFIC_WEIGHT;
743
734
  node.services.pubsub.score.params.appSpecificScore = (peerId)=>peerManager.shouldDisableP2PGossip(peerId) ? -Infinity : peerManager.getPeerScore(peerId);
744
- return new LibP2PService(clientType, config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
735
+ return new LibP2PService(config, node, peerDiscoveryService, reqresp, peerManager, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger);
745
736
  }
746
737
  /**
747
738
  * Starts the LibP2P service.
@@ -786,7 +777,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
786
777
  await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
787
778
  await this.node.start();
788
779
  // Subscribe to standard GossipSub topics by default
789
- for (const topic of getTopicsForClientAndConfig(this.clientType, this.config.disableTransactions)){
780
+ for (const topic of getTopicsForConfig(this.config.disableTransactions)){
790
781
  this.subscribeToTopic(this.topicStrings[topic]);
791
782
  }
792
783
  // add GossipSub listener
@@ -995,9 +986,7 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
995
986
  if (msg.topic === this.topicStrings[TopicType.tx]) {
996
987
  await this.handleGossipedTx(p2pMessage.payload, msgId, source);
997
988
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_attestation]) {
998
- if (this.clientType === P2PClientType.Full) {
999
- await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
1000
- }
989
+ await this.processCheckpointAttestationFromPeer(p2pMessage.payload, msgId, source);
1001
990
  } else if (msg.topic === this.topicStrings[TopicType.block_proposal]) {
1002
991
  await this.processBlockFromPeer(p2pMessage.payload, msgId, source);
1003
992
  } else if (msg.topic === this.topicStrings[TopicType.checkpoint_proposal]) {
@@ -1065,16 +1054,45 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1065
1054
  async handleGossipedTx(payloadData, msgId, source) {
1066
1055
  const validationFunc = async ()=>{
1067
1056
  const tx = Tx.fromBuffer(payloadData);
1068
- const isValid = await this.validatePropagatedTx(tx, source);
1069
- if (!isValid) {
1070
- this.logger.trace(`Rejecting invalid propagated tx`, {
1071
- [Attributes.P2P_ID]: source.toString()
1072
- });
1057
+ const currentBlockNumber = await this.archiver.getBlockNumber();
1058
+ const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1059
+ // Stage 1: fast validators (metadata, data, timestamps, double-spend, gas, phases, block header)
1060
+ const firstStageValidators = await this.createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp);
1061
+ const firstStageOutcome = await this.runValidations(tx, firstStageValidators);
1062
+ if (!firstStageOutcome.allPassed) {
1063
+ const { name } = firstStageOutcome.failure;
1064
+ let { severity } = firstStageOutcome.failure;
1065
+ // Double spend validator has a special case handler. We perform more detailed examination
1066
+ // as to how recently the nullifier was entered into the tree and if the transaction should
1067
+ // have 'known' the nullifier existed. This determines the severity of the penalty applied to the peer.
1068
+ if (name === 'doubleSpendValidator') {
1069
+ const txBlockNumber = BlockNumber(currentBlockNumber + 1);
1070
+ severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1071
+ }
1072
+ this.peerManager.penalizePeer(source, severity);
1073
+ return {
1074
+ result: TopicValidatorResult.Reject
1075
+ };
1076
+ }
1077
+ // Pool pre-check: see if the pool would accept this tx before doing expensive proof verification
1078
+ const canAdd = await this.mempools.txPool.canAddPendingTx(tx);
1079
+ if (canAdd === 'ignored') {
1080
+ return {
1081
+ result: TopicValidatorResult.Ignore,
1082
+ obj: tx
1083
+ };
1084
+ }
1085
+ // Stage 2: expensive proof verification
1086
+ const secondStageValidators = this.createSecondStageMessageValidators();
1087
+ const secondStageOutcome = await this.runValidations(tx, secondStageValidators);
1088
+ if (!secondStageOutcome.allPassed) {
1089
+ const { severity } = secondStageOutcome.failure;
1090
+ this.peerManager.penalizePeer(source, severity);
1073
1091
  return {
1074
1092
  result: TopicValidatorResult.Reject
1075
1093
  };
1076
1094
  }
1077
- // Propagate only on pool acceptance
1095
+ // Pool add: persist the tx
1078
1096
  const txHash = tx.getTxHash();
1079
1097
  const addResult = await this.mempools.txPool.addPendingTxs([
1080
1098
  tx
@@ -1084,7 +1102,6 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1084
1102
  const wasAccepted = addResult.accepted.some((h)=>h.equals(txHash));
1085
1103
  const wasIgnored = addResult.ignored.some((h)=>h.equals(txHash));
1086
1104
  this.logger.trace(`Validate propagated tx`, {
1087
- isValid,
1088
1105
  wasAccepted,
1089
1106
  wasIgnored,
1090
1107
  [Attributes.P2P_ID]: source.toString()
@@ -1626,33 +1643,11 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1626
1643
  }
1627
1644
  }
1628
1645
  createRequestedTxValidator() {
1629
- return createTxReqRespValidator(this.proofVerifier, {
1646
+ return createTxValidatorForReqResponseReceivedTxs(this.proofVerifier, {
1630
1647
  l1ChainId: this.config.l1ChainId,
1631
1648
  rollupVersion: this.config.rollupVersion
1632
1649
  });
1633
1650
  }
1634
- async validatePropagatedTx(tx, peerId) {
1635
- const currentBlockNumber = await this.archiver.getBlockNumber();
1636
- // We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
1637
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1638
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1639
- for (const validator of messageValidators){
1640
- const outcome = await this.runValidations(tx, validator);
1641
- if (outcome.allPassed) {
1642
- continue;
1643
- }
1644
- const { name } = outcome.failure;
1645
- let { severity } = outcome.failure;
1646
- // Double spend validator has a special case handler
1647
- if (name === 'doubleSpendValidator') {
1648
- const txBlockNumber = BlockNumber(currentBlockNumber + 1); // tx is expected to be in the next block
1649
- severity = await this.handleDoubleSpendFailure(tx, txBlockNumber);
1650
- }
1651
- this.peerManager.penalizePeer(peerId, severity);
1652
- return false;
1653
- }
1654
- return true;
1655
- }
1656
1651
  async getGasFees(blockNumber) {
1657
1652
  if (blockNumber === this.feesCache?.blockNumber) {
1658
1653
  return this.feesCache.gasFees;
@@ -1679,38 +1674,27 @@ _dec = trackSpan('Libp2pService.validateAndStoreCheckpointAttestation', (_peerId
1679
1674
  peerScoring: this.peerManager
1680
1675
  };
1681
1676
  }
1682
- async validate(txs) {
1683
- const currentBlockNumber = await this.archiver.getBlockNumber();
1684
- // We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
1685
- const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1686
- const messageValidators = await this.createMessageValidators(currentBlockNumber, nextSlotTimestamp);
1687
- await Promise.all(txs.map(async (tx)=>{
1688
- for (const validator of messageValidators){
1689
- const outcome = await this.runValidations(tx, validator);
1690
- if (!outcome.allPassed) {
1691
- throw new Error('Invalid tx detected', {
1692
- cause: {
1693
- outcome
1694
- }
1695
- });
1696
- }
1697
- }
1677
+ async validateTxsReceivedInBlockProposal(txs) {
1678
+ const validator = createTxValidatorForBlockProposalReceivedTxs(this.proofVerifier, {
1679
+ l1ChainId: this.config.l1ChainId,
1680
+ rollupVersion: this.config.rollupVersion
1681
+ }, this.logger.getBindings());
1682
+ const results = await Promise.all(txs.map(async (tx)=>{
1683
+ const result = await validator.validateTx(tx);
1684
+ return result.result !== 'invalid';
1698
1685
  }));
1686
+ if (results.some((value)=>value === false)) {
1687
+ throw new Error('Invalid tx detected');
1688
+ }
1699
1689
  }
1700
- /**
1701
- * Create message validators for the given block number and timestamp.
1702
- *
1703
- * Each validator is a pair of a validator and a severity.
1704
- * If a validator fails, the peer is penalized with the severity of the validator.
1705
- *
1706
- * @param currentBlockNumber - The current synced block number.
1707
- * @param nextSlotTimestamp - The timestamp of the next slot (used to validate txs are not expired).
1708
- * @returns The message validators.
1709
- */ async createMessageValidators(currentBlockNumber, nextSlotTimestamp) {
1690
+ /** Creates the first stage (fast) validators for gossiped transactions. */ async createFirstStageMessageValidators(currentBlockNumber, nextSlotTimestamp) {
1710
1691
  const gasFees = await this.getGasFees(currentBlockNumber);
1711
1692
  const allowedInSetup = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
1712
- const blockNumberInWhichTheTxIsConsideredToBeIncluded = BlockNumber(currentBlockNumber + 1);
1713
- return createTxMessageValidators(nextSlotTimestamp, blockNumberInWhichTheTxIsConsideredToBeIncluded, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, this.proofVerifier, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings());
1693
+ const blockNumber = BlockNumber(currentBlockNumber + 1);
1694
+ return createFirstStageTxValidationsForGossipedTransactions(nextSlotTimestamp, blockNumber, this.worldStateSynchronizer, gasFees, this.config.l1ChainId, this.config.rollupVersion, protocolContractsHash, this.archiver, !this.config.disableTransactions, allowedInSetup, this.logger.getBindings());
1695
+ }
1696
+ /** Creates the second stage (expensive proof verification) validators for gossiped transactions. */ createSecondStageMessageValidators() {
1697
+ return createSecondStageTxValidationsForGossipedTransactions(this.proofVerifier, this.logger.getBindings());
1714
1698
  }
1715
1699
  /**
1716
1700
  * Run validations on a tx.
@@ -45,4 +45,4 @@ export declare class BatchTxRequester {
45
45
  private unlockSmartRequesterSemaphores;
46
46
  private sleepClampedToDeadline;
47
47
  }
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmF0Y2hfdHhfcmVxdWVzdGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc2VydmljZXMvcmVxcmVzcC9iYXRjaC10eC1yZXF1ZXN0ZXIvYmF0Y2hfdHhfcmVxdWVzdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxLQUFLLE1BQU0sRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUdsRSxPQUFPLEVBQUUsWUFBWSxFQUFrQixNQUFNLHlCQUF5QixDQUFDO0FBRXZFLE9BQU8sRUFBRSxFQUFFLEVBQW1CLE1BQU0sa0JBQWtCLENBQUM7QUFFdkQsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHaEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUVyRixPQUFPLEVBQXFDLEtBQUssY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFRakcsT0FBTyxLQUFLLEVBQUUsNkJBQTZCLEVBQUUsdUJBQXVCLEVBQXlCLE1BQU0sZ0JBQWdCLENBQUM7QUFzQnBILHFCQUFhLGdCQUFnQjtJQUMzQixPQUFPLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBaUI7SUFDaEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQXFCO0lBQ2hELE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFTO0lBQ25DLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFnQztJQUMzRCxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBUztJQUNoQyxPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBZTtJQUM1QyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBMEI7SUFDL0MsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQWtCO0lBQ3hDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUF3QjtJQUNwRCxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBUztJQUNsQyxPQUFPLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFhO0lBQ3JELE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFzQjtJQUM5QyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBMkI7SUFDdkQsT0FBTyxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBUztJQUNsRCxPQUFPLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFTO0lBQ2pELE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFTO0lBRXJDLFlBQ0UsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQ3JDLGNBQWMsRUFBRSxjQUFjLEVBQzlCLFVBQVUsRUFBRSxNQUFNLEdBQUcsU0FBUyxFQUM5QixTQUFTLEVBQUUsTUFBTSxFQUNqQixVQUFVLEVBQUUsNkJBQTZCLEVBQ3pDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFDZixZQUFZLENBQUMsRUFBRSxZQUFZLEVBQzNCLElBQUksQ0FBQyxFQUFFLHVCQUF1QixFQWtDL0I7SUFLYSxHQUFHLElBQUksY0FBYyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQTZDL0Q7SUFLRCxPQUFvQixhQUFhLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLFNBQVMsRUFBRSxPQUFPLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FTdkc7WUFVYSxtQkFBbUI7WUFrRG5CLGFBQWE7WUF5RGIsY0FBYztZQWdEZCxjQUFjO1lBd0NkLGVBQWU7WUFrRmYsY0FBYztJQW1DNUIsT0FBTyxDQUFDLDBCQUEwQjtZQWlCcEIsNkJBQTZCO1lBWTdCLGlCQUFpQjtJQXFEL0IsT0FBTyxDQUFDLG1CQUFtQjtJQWtDM0IsT0FBTyxDQUFDLG9CQUFvQjtJQU01QixPQUFPLENBQUMsMEJBQTBCO0lBS2xDLE9BQU8sQ0FBQyxjQUFjO0lBTXRCLE9BQU8sQ0FBQyxnQ0FBZ0M7SUFnQnhDLE9BQU8sQ0FBQyxxQkFBcUI7SUF1QjdCLE9BQU8sQ0FBQyxhQUFhO0lBYXJCLE9BQU8sQ0FBQyxVQUFVO0lBYWxCLE9BQU8sQ0FBQyw4QkFBOEI7WUFVeEIsc0JBQXNCO0NBT3JDIn0=
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmF0Y2hfdHhfcmVxdWVzdGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc2VydmljZXMvcmVxcmVzcC9iYXRjaC10eC1yZXF1ZXN0ZXIvYmF0Y2hfdHhfcmVxdWVzdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxLQUFLLE1BQU0sRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUdsRSxPQUFPLEVBQUUsWUFBWSxFQUFrQixNQUFNLHlCQUF5QixDQUFDO0FBRXZFLE9BQU8sRUFBRSxFQUFFLEVBQW1CLE1BQU0sa0JBQWtCLENBQUM7QUFFdkQsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFaEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUVyRixPQUFPLEVBQXFDLEtBQUssY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFRakcsT0FBTyxLQUFLLEVBQUUsNkJBQTZCLEVBQUUsdUJBQXVCLEVBQXlCLE1BQU0sZ0JBQWdCLENBQUM7QUFzQnBILHFCQUFhLGdCQUFnQjtJQUMzQixPQUFPLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBaUI7SUFDaEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQXFCO0lBQ2hELE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFTO0lBQ25DLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFnQztJQUMzRCxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBUztJQUNoQyxPQUFPLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBZTtJQUM1QyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBMEI7SUFDL0MsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQWtCO0lBQ3hDLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUF3QjtJQUNwRCxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBUztJQUNsQyxPQUFPLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFhO0lBQ3JELE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFzQjtJQUM5QyxPQUFPLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBMkI7SUFDdkQsT0FBTyxDQUFDLFFBQVEsQ0FBQyx3QkFBd0IsQ0FBUztJQUNsRCxPQUFPLENBQUMsUUFBUSxDQUFDLHVCQUF1QixDQUFTO0lBQ2pELE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFTO0lBRXJDLFlBQ0UsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQ3JDLGNBQWMsRUFBRSxjQUFjLEVBQzlCLFVBQVUsRUFBRSxNQUFNLEdBQUcsU0FBUyxFQUM5QixTQUFTLEVBQUUsTUFBTSxFQUNqQixVQUFVLEVBQUUsNkJBQTZCLEVBQ3pDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFDZixZQUFZLENBQUMsRUFBRSxZQUFZLEVBQzNCLElBQUksQ0FBQyxFQUFFLHVCQUF1QixFQWlDL0I7SUFLYSxHQUFHLElBQUksY0FBYyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQTZDL0Q7SUFLRCxPQUFvQixhQUFhLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLFNBQVMsRUFBRSxPQUFPLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FTdkc7WUFVYSxtQkFBbUI7WUFrRG5CLGFBQWE7WUFrRGIsY0FBYztZQWdEZCxjQUFjO1lBK0JkLGVBQWU7WUEwRWYsY0FBYztJQW1DNUIsT0FBTyxDQUFDLDBCQUEwQjtZQWlCcEIsNkJBQTZCO1lBWTdCLGlCQUFpQjtJQXFEL0IsT0FBTyxDQUFDLG1CQUFtQjtJQWdDM0IsT0FBTyxDQUFDLG9CQUFvQjtJQU01QixPQUFPLENBQUMsMEJBQTBCO0lBS2xDLE9BQU8sQ0FBQyxjQUFjO0lBTXRCLE9BQU8sQ0FBQyxnQ0FBZ0M7SUFnQnhDLE9BQU8sQ0FBQyxxQkFBcUI7SUF1QjdCLE9BQU8sQ0FBQyxhQUFhO0lBYXJCLE9BQU8sQ0FBQyxVQUFVO0lBYWxCLE9BQU8sQ0FBQyw4QkFBOEI7WUFVeEIsc0JBQXNCO0NBT3JDIn0=
@@ -1 +1 @@
1
- {"version":3,"file":"batch_tx_requester.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/batch-tx-requester/batch_tx_requester.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAkB,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,EAAE,EAAmB,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAErF,OAAO,EAAqC,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAQjG,OAAO,KAAK,EAAE,6BAA6B,EAAE,uBAAuB,EAAyB,MAAM,gBAAgB,CAAC;AAsBpH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IACvD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IAErC,YACE,iBAAiB,EAAE,kBAAkB,EACrC,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,6BAA6B,EACzC,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,YAAY,EAC3B,IAAI,CAAC,EAAE,uBAAuB,EAkC/B;IAKa,GAAG,IAAI,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,OAAO,CAAC,CA6C/D;IAKD,OAAoB,aAAa,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CASvG;YAUa,mBAAmB;YAkDnB,aAAa;YAyDb,cAAc;YAgDd,cAAc;YAwCd,eAAe;YAkFf,cAAc;IAmC5B,OAAO,CAAC,0BAA0B;YAiBpB,6BAA6B;YAY7B,iBAAiB;IAqD/B,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,0BAA0B;IAKlC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,gCAAgC;IAgBxC,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,8BAA8B;YAUxB,sBAAsB;CAOrC"}
1
+ {"version":3,"file":"batch_tx_requester.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/batch-tx-requester/batch_tx_requester.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAkB,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,EAAE,EAAmB,MAAM,kBAAkB,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAErF,OAAO,EAAqC,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAQjG,OAAO,KAAK,EAAE,6BAA6B,EAAE,uBAAuB,EAAyB,MAAM,gBAAgB,CAAC;AAsBpH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAa;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2B;IACvD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IAErC,YACE,iBAAiB,EAAE,kBAAkB,EACrC,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,6BAA6B,EACzC,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,YAAY,EAC3B,IAAI,CAAC,EAAE,uBAAuB,EAiC/B;IAKa,GAAG,IAAI,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,OAAO,CAAC,CA6C/D;IAKD,OAAoB,aAAa,CAAC,SAAS,EAAE,cAAc,CAAC,EAAE,EAAE,EAAE,GAAG,SAAS,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE,EAAE,CAAC,CASvG;YAUa,mBAAmB;YAkDnB,aAAa;YAkDb,cAAc;YAgDd,cAAc;YA+Bd,eAAe;YA0Ef,cAAc;IAmC5B,OAAO,CAAC,0BAA0B;YAiBpB,6BAA6B;YAY7B,iBAAiB;IAqD/B,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,0BAA0B;IAKlC,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,gCAAgC;IAgBxC,OAAO,CAAC,qBAAqB;IAuB7B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,8BAA8B;YAUxB,sBAAsB;CAOrC"}
@@ -6,7 +6,6 @@ import { sleep } from '@aztec/foundation/sleep';
6
6
  import { DateProvider, executeTimeout } from '@aztec/foundation/timer';
7
7
  import { PeerErrorSeverity } from '@aztec/stdlib/p2p';
8
8
  import { TxHash } from '@aztec/stdlib/tx';
9
- import { peerIdFromString } from '@libp2p/peer-id';
10
9
  import { ReqRespSubProtocol } from '.././interface.js';
11
10
  import { BlockTxsRequest, BlockTxsResponse } from '.././protocols/index.js';
12
11
  import { ReqRespStatus } from '.././status.js';
@@ -64,9 +63,8 @@ import { BatchRequestTxValidator } from './tx_validator.js';
64
63
  if (this.opts.peerCollection) {
65
64
  this.peers = this.opts.peerCollection;
66
65
  } else {
67
- const initialPeers = this.p2pService.connectionSampler.getPeerListSortedByConnectionCountAsc();
68
66
  const badPeerThreshold = this.opts.badPeerThreshold ?? DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD;
69
- this.peers = new PeerCollection(initialPeers, this.pinnedPeer, this.dateProvider, badPeerThreshold, this.p2pService.peerScoring);
67
+ this.peers = new PeerCollection(this.p2pService.connectionSampler, this.pinnedPeer, this.dateProvider, badPeerThreshold, this.p2pService.peerScoring);
70
68
  }
71
69
  this.txsMetadata = new MissingTxMetadataCollection(missingTxsTracker, this.txBatchSize);
72
70
  this.smartRequesterSemaphore = this.opts.semaphore ?? new Semaphore(0);
@@ -177,7 +175,6 @@ import { BatchRequestTxValidator } from './tx_validator.js';
177
175
  /*
178
176
  * Starts dumb worker loops
179
177
  * */ async dumbRequester() {
180
- const nextPeerIndex = this.makeRoundRobinIndexer();
181
178
  const nextBatchIndex = this.makeRoundRobinIndexer();
182
179
  // Chunk missing tx hashes into batches of txBatchSize, wrapping around to ensure no peer gets less than txBatchSize
183
180
  const txChunks = ()=>{
@@ -205,15 +202,10 @@ import { BatchRequestTxValidator } from './tx_validator.js';
205
202
  txs
206
203
  };
207
204
  };
208
- const nextPeer = ()=>{
209
- const peers = this.peers.getDumbPeersToQuery();
210
- const idx = nextPeerIndex(()=>peers.length);
211
- return idx === undefined ? undefined : peerIdFromString(peers[idx]);
212
- };
213
- const workerCount = Math.min(this.dumbParallelWorkerCount, this.peers.getAllPeers().size);
205
+ const workerCount = this.dumbParallelWorkerCount;
214
206
  const workers = Array.from({
215
207
  length: workerCount
216
- }, (_, index)=>this.dumbWorkerLoop(nextPeer, makeRequest, index + 1));
208
+ }, (_, index)=>this.dumbWorkerLoop(this.peers.nextDumbPeerToQuery.bind(this.peers), makeRequest, index + 1));
217
209
  await Promise.allSettled(workers);
218
210
  }
219
211
  /*
@@ -257,12 +249,6 @@ import { BatchRequestTxValidator } from './tx_validator.js';
257
249
  /*
258
250
  * Starts smart worker loops
259
251
  * */ async smartRequester() {
260
- const nextPeerIndex = this.makeRoundRobinIndexer();
261
- const nextPeer = ()=>{
262
- const peers = this.peers.getSmartPeersToQuery();
263
- const idx = nextPeerIndex(()=>peers.length);
264
- return idx === undefined ? undefined : peerIdFromString(peers[idx]);
265
- };
266
252
  const makeRequest = (pid)=>{
267
253
  const txs = this.txsMetadata.getTxsToRequestFromThePeer(pid);
268
254
  const blockRequest = BlockTxsRequest.fromTxsSourceAndMissingTxs(this.blockTxsSource, txs);
@@ -275,8 +261,8 @@ import { BatchRequestTxValidator } from './tx_validator.js';
275
261
  };
276
262
  };
277
263
  const workers = Array.from({
278
- length: Math.min(this.smartParallelWorkerCount, this.peers.getAllPeers().size)
279
- }, (_, index)=>this.smartWorkerLoop(nextPeer, makeRequest, index + 1));
264
+ length: this.smartParallelWorkerCount
265
+ }, (_, index)=>this.smartWorkerLoop(this.peers.nextSmartPeerToQuery.bind(this.peers), makeRequest, index + 1));
280
266
  await Promise.allSettled(workers);
281
267
  }
282
268
  /*
@@ -301,24 +287,17 @@ import { BatchRequestTxValidator } from './tx_validator.js';
301
287
  const weRanOutOfPeersToQuery = peerId === undefined;
302
288
  if (weRanOutOfPeersToQuery) {
303
289
  this.logger.debug(`Worker loop smart: No more peers to query`);
304
- // If there are no more dumb peers to query then none of our peers can become smart,
305
- // thus we can simply exit this worker
306
- const noMoreDumbPeersToQuery = this.peers.getDumbPeersToQuery().length === 0;
307
- if (noMoreDumbPeersToQuery) {
308
- // These might be either smart peers that will get unblocked after _some time_
309
- const nextSmartPeerDelay = this.peers.getNextSmartPeerAvailabilityDelayMs();
310
- const thereAreSomeRateLimitedSmartPeers = nextSmartPeerDelay !== undefined;
311
- if (thereAreSomeRateLimitedSmartPeers) {
312
- await this.sleepClampedToDeadline(nextSmartPeerDelay);
313
- continue;
314
- }
315
- this.logger.debug(`Worker loop smart: No more smart peers to query killing ${workerIndex}`);
316
- break;
290
+ // If we have rate limited peers wait for them.
291
+ const nextSmartPeerDelay = this.peers.getNextSmartPeerAvailabilityDelayMs();
292
+ const thereAreSomeRateLimitedSmartPeers = nextSmartPeerDelay !== undefined;
293
+ if (thereAreSomeRateLimitedSmartPeers) {
294
+ await this.sleepClampedToDeadline(nextSmartPeerDelay);
295
+ continue;
317
296
  }
318
- // Otherwise there are still some dumb peers that could become smart.
319
297
  // We end up here when all known smart peers became temporarily unavailable via combination of
320
298
  // (bad, in-flight, or rate-limited) or in some weird scenario all current smart peers turn bad which is permanent
321
- // but dumb peers still exist that could become smart.
299
+ // but there are dumb peers that could be promoted
300
+ // or new peer can join as dumb and be promoted later
322
301
  //
323
302
  // When a dumb peer responds with valid txIndices, it gets
324
303
  // promoted to smart and releases the semaphore, waking this worker.
@@ -473,9 +452,7 @@ import { BatchRequestTxValidator } from './tx_validator.js';
473
452
  this.peers.markPeerSmart(peerId);
474
453
  this.markTxsPeerHas(peerId, response);
475
454
  // Unblock smart workers
476
- if (this.peers.getSmartPeersToQuery().length <= this.smartParallelWorkerCount) {
477
- this.smartRequesterSemaphore.release();
478
- }
455
+ this.smartRequesterSemaphore.release();
479
456
  }
480
457
  isBlockResponseValid(response) {
481
458
  const archiveRootsMatch = this.blockTxsSource.archive.toString() === response.archiveRoot.toString();
@@ -1,14 +1,15 @@
1
1
  import type { DateProvider } from '@aztec/foundation/timer';
2
2
  import type { PeerErrorSeverity } from '@aztec/stdlib/p2p';
3
3
  import type { PeerId } from '@libp2p/interface';
4
+ import type { ConnectionSampler } from '../connection-sampler/connection_sampler.js';
4
5
  import type { IPeerPenalizer } from './interface.js';
5
6
  export declare const RATE_LIMIT_EXCEEDED_PEER_CACHE_TTL = 1000;
6
7
  export interface IPeerCollection {
7
- getAllPeers(): Set<string>;
8
- getSmartPeers(): Set<string>;
9
8
  markPeerSmart(peerId: PeerId): void;
10
- getSmartPeersToQuery(): Array<string>;
11
- getDumbPeersToQuery(): Array<string>;
9
+ /** Sample next peer in round-robin fashion. No smart peers if returns undefined */
10
+ nextSmartPeerToQuery(): PeerId | undefined;
11
+ /** Sample next peer in round-robin fashion. No dumb peers if returns undefined */
12
+ nextDumbPeerToQuery(): PeerId | undefined;
12
13
  thereAreSomeDumbRatelimitExceededPeers(): boolean;
13
14
  penalisePeer(peerId: PeerId, severity: PeerErrorSeverity): void;
14
15
  unMarkPeerAsBad(peerId: PeerId): void;
@@ -22,22 +23,25 @@ export interface IPeerCollection {
22
23
  getNextSmartPeerAvailabilityDelayMs(): number | undefined;
23
24
  }
24
25
  export declare class PeerCollection implements IPeerCollection {
26
+ private readonly connectionSampler;
25
27
  private readonly pinnedPeerId;
26
28
  private readonly dateProvider;
27
29
  private readonly badPeerThreshold;
28
30
  private readonly peerPenalizer?;
29
- private readonly peers;
30
31
  private readonly smartPeers;
31
32
  private readonly inFlightPeers;
32
33
  private readonly rateLimitExceededPeers;
33
34
  private readonly peerPenaltyCounters;
34
35
  private readonly badPeers;
35
- constructor(initialPeers: PeerId[], pinnedPeerId: PeerId | undefined, dateProvider: DateProvider, badPeerThreshold?: number, peerPenalizer?: IPeerPenalizer | undefined);
36
- getAllPeers(): Set<string>;
37
- getSmartPeers(): Set<string>;
36
+ constructor(connectionSampler: Pick<ConnectionSampler, 'getPeerListSortedByConnectionCountAsc'>, pinnedPeerId: PeerId | undefined, dateProvider: DateProvider, badPeerThreshold?: number, peerPenalizer?: IPeerPenalizer | undefined);
38
37
  markPeerSmart(peerId: PeerId): void;
39
- getSmartPeersToQuery(): Array<string>;
40
- getDumbPeersToQuery(): Array<string>;
38
+ private queriedSmartPeers;
39
+ private queriedDumbPeers;
40
+ private static nextPeer;
41
+ nextSmartPeerToQuery(): PeerId | undefined;
42
+ nextDumbPeerToQuery(): PeerId | undefined;
43
+ private get availableSmartPeers();
44
+ private get availableDumbPeers();
41
45
  thereAreSomeDumbRatelimitExceededPeers(): boolean;
42
46
  markPeerInFlight(peerId: PeerId): void;
43
47
  unMarkPeerInFlight(peerId: PeerId): void;
@@ -50,5 +54,7 @@ export declare class PeerCollection implements IPeerCollection {
50
54
  getNextDumbPeerAvailabilityDelayMs(): number | undefined;
51
55
  getNextSmartPeerAvailabilityDelayMs(): number | undefined;
52
56
  private getNextRateLimitDelayMs;
57
+ private orderedPeers;
58
+ private get peers();
53
59
  }
54
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9jb2xsZWN0aW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc2VydmljZXMvcmVxcmVzcC9iYXRjaC10eC1yZXF1ZXN0ZXIvcGVlcl9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0QsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHaEQsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFckQsZUFBTyxNQUFNLGtDQUFrQyxPQUFPLENBQUM7QUFFdkQsTUFBTSxXQUFXLGVBQWU7SUFDOUIsV0FBVyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzQixhQUFhLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdCLGFBQWEsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQztJQUNwQyxvQkFBb0IsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdEMsbUJBQW1CLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JDLHNDQUFzQyxJQUFJLE9BQU8sQ0FBQztJQUNsRCxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0lBQ2hFLGVBQWUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQztJQUN0QyxXQUFXLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNCLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3ZDLGtCQUFrQixDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3pDLHlCQUF5QixDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ2hELHlCQUF5QixJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6Qyx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLE1BQU0sR0FBRyxTQUFTLENBQUM7SUFDNUQsa0NBQWtDLElBQUksTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUN6RCxtQ0FBbUMsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUFDO0NBQzNEO0FBRUQscUJBQWEsY0FBZSxZQUFXLGVBQWU7SUFXbEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxZQUFZO0lBQzdCLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWTtJQUM3QixPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQjtJQUNqQyxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQztJQWJqQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztJQUV2QixPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBcUI7SUFDaEQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQXFCO0lBQ25ELE9BQU8sQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQTZCO0lBQ3BFLE9BQU8sQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQTZCO0lBQ2pFLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFxQjtJQUU5QyxZQUNFLFlBQVksRUFBRSxNQUFNLEVBQUUsRUFDTCxZQUFZLEVBQUUsTUFBTSxHQUFHLFNBQVMsRUFDaEMsWUFBWSxFQUFFLFlBQVksRUFDMUIsZ0JBQWdCLEdBQUUsTUFBc0QsRUFDeEUsYUFBYSxDQUFDLDRCQUFnQixFQVdoRDtJQUVNLFdBQVcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBRWhDO0lBRU0sYUFBYSxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FFbEM7SUFFTSxhQUFhLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBRXpDO0lBRU0sb0JBQW9CLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUkzQztJQUVNLG1CQUFtQixJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FNMUM7SUFFTSxzQ0FBc0MsSUFBSSxPQUFPLENBS3ZEO0lBRU0sZ0JBQWdCLENBQUMsTUFBTSxFQUFFLE1BQU0sUUFFckM7SUFFTSxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxRQU12QztJQUVNLHlCQUF5QixDQUFDLE1BQU0sRUFBRSxNQUFNLFFBRzlDO0lBRU0seUJBQXlCLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQWE5QztJQUVNLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsR0FBRyxJQUFJLENBUXJFO0lBRU0sZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNLFFBSXBDO0lBRU0sV0FBVyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FFaEM7SUFFTSx1QkFBdUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxHQUFHLE1BQU0sR0FBRyxTQUFTLENBZWpFO0lBRU0sa0NBQWtDLElBQUksTUFBTSxHQUFHLFNBQVMsQ0FXOUQ7SUFFTSxtQ0FBbUMsSUFBSSxNQUFNLEdBQUcsU0FBUyxDQUsvRDtJQUVELE9BQU8sQ0FBQyx1QkFBdUI7Q0EwQmhDIn0=
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVlcl9jb2xsZWN0aW9uLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvc2VydmljZXMvcmVxcmVzcC9iYXRjaC10eC1yZXF1ZXN0ZXIvcGVlcl9jb2xsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFlBQVksRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0QsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHaEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUVyRixPQUFPLEtBQUssRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyRCxlQUFPLE1BQU0sa0NBQWtDLE9BQU8sQ0FBQztBQUV2RCxNQUFNLFdBQVcsZUFBZTtJQUM5QixhQUFhLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFFcEMsbUZBQW1GO0lBQ25GLG9CQUFvQixJQUFJLE1BQU0sR0FBRyxTQUFTLENBQUM7SUFDM0Msa0ZBQWtGO0lBQ2xGLG1CQUFtQixJQUFJLE1BQU0sR0FBRyxTQUFTLENBQUM7SUFFMUMsc0NBQXNDLElBQUksT0FBTyxDQUFDO0lBQ2xELFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxpQkFBaUIsR0FBRyxJQUFJLENBQUM7SUFDaEUsZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3RDLFdBQVcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDM0IsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDdkMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDekMseUJB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
@@ -1 +1 @@
1
- {"version":3,"file":"peer_collection.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/batch-tx-requester/peer_collection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"peer_collection.d.ts","sourceRoot":"","sources":["../../../../src/services/reqresp/batch-tx-requester/peer_collection.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,19 @@
1
+ import { peerIdFromString } from '@libp2p/peer-id';
1
2
  import { DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD } from './config.js';
2
3
  export const RATE_LIMIT_EXCEEDED_PEER_CACHE_TTL = 1000; // 1s
3
4
  export class PeerCollection {
5
+ connectionSampler;
4
6
  pinnedPeerId;
5
7
  dateProvider;
6
8
  badPeerThreshold;
7
9
  peerPenalizer;
8
- peers;
9
10
  smartPeers;
10
11
  inFlightPeers;
11
12
  rateLimitExceededPeers;
12
13
  peerPenaltyCounters;
13
14
  badPeers;
14
- constructor(initialPeers, pinnedPeerId, dateProvider, badPeerThreshold = DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD, peerPenalizer){
15
+ constructor(connectionSampler, pinnedPeerId, dateProvider, badPeerThreshold = DEFAULT_BATCH_TX_REQUESTER_BAD_PEER_THRESHOLD, peerPenalizer){
16
+ this.connectionSampler = connectionSampler;
15
17
  this.pinnedPeerId = pinnedPeerId;
16
18
  this.dateProvider = dateProvider;
17
19
  this.badPeerThreshold = badPeerThreshold;
@@ -21,29 +23,47 @@ export class PeerCollection {
21
23
  this.rateLimitExceededPeers = new Map();
22
24
  this.peerPenaltyCounters = new Map();
23
25
  this.badPeers = new Set();
24
- this.peers = new Set(initialPeers.map((peer)=>peer.toString()));
25
- // Pinned peer is treaded specially, always mark it as in-flight
26
+ this.queriedSmartPeers = new Set();
27
+ this.queriedDumbPeers = new Set();
28
+ this.orderedPeers = new Set();
29
+ // Pinned peer is treated specially, always mark it as in-flight
26
30
  // and never return it as part of smart/dumb peers
27
31
  if (this.pinnedPeerId) {
28
32
  const peerIdStr = this.pinnedPeerId.toString();
29
33
  this.inFlightPeers.add(peerIdStr);
30
- this.peers.delete(peerIdStr);
31
34
  }
32
35
  }
33
- getAllPeers() {
34
- return this.peers;
35
- }
36
- getSmartPeers() {
37
- return this.smartPeers;
38
- }
39
36
  markPeerSmart(peerId) {
40
37
  this.smartPeers.add(peerId.toString());
41
38
  }
42
- getSmartPeersToQuery() {
43
- return Array.from(this.smartPeers.difference(this.getBadPeers().union(this.inFlightPeers).union(this.getRateLimitExceededPeers())));
39
+ // We keep track of all peers that are queried for peer sampling algorithm
40
+ queriedSmartPeers;
41
+ queriedDumbPeers;
42
+ static nextPeer(allPeers, queried) {
43
+ if (allPeers.size === 0) {
44
+ return undefined;
45
+ }
46
+ const availablePeers = allPeers.difference(queried);
47
+ let [first] = availablePeers;
48
+ if (first === undefined) {
49
+ // We queried all peers. Start over
50
+ [first] = allPeers;
51
+ queried.clear();
52
+ }
53
+ queried.add(first);
54
+ return peerIdFromString(first);
55
+ }
56
+ nextSmartPeerToQuery() {
57
+ return PeerCollection.nextPeer(this.availableSmartPeers, this.queriedSmartPeers);
44
58
  }
45
- getDumbPeersToQuery() {
46
- return Array.from(this.peers.difference(this.smartPeers.union(this.getBadPeers()).union(this.inFlightPeers).union(this.getRateLimitExceededPeers())));
59
+ nextDumbPeerToQuery() {
60
+ return PeerCollection.nextPeer(this.availableDumbPeers, this.queriedDumbPeers);
61
+ }
62
+ get availableSmartPeers() {
63
+ return this.peers.intersection(this.smartPeers.difference(this.getBadPeers().union(this.inFlightPeers).union(this.getRateLimitExceededPeers())));
64
+ }
65
+ get availableDumbPeers() {
66
+ return this.peers.difference(this.smartPeers.union(this.getBadPeers()).union(this.inFlightPeers).union(this.getRateLimitExceededPeers()));
47
67
  }
48
68
  thereAreSomeDumbRatelimitExceededPeers() {
49
69
  return this.getRateLimitExceededPeers().difference(this.smartPeers.union(this.badPeers).union(this.inFlightPeers)).size > 0;
@@ -136,4 +156,18 @@ export class PeerCollection {
136
156
  }
137
157
  return minExpiry - now;
138
158
  }
159
+ orderedPeers;
160
+ get peers() {
161
+ const pinnedStr = this.pinnedPeerId?.toString();
162
+ const currentlyConnected = new Set(this.connectionSampler.getPeerListSortedByConnectionCountAsc().map((p)=>p.toString()).filter((p)=>p !== pinnedStr));
163
+ // Remove disconnected peers, preserving order of the rest.
164
+ this.orderedPeers = this.orderedPeers.intersection(currentlyConnected);
165
+ // Append newly connected peers at the end (lowest priority).
166
+ for (const peer of currentlyConnected){
167
+ if (!this.orderedPeers.has(peer)) {
168
+ this.orderedPeers.add(peer);
169
+ }
170
+ }
171
+ return this.orderedPeers;
172
+ }
139
173
  }
@@ -1,4 +1,4 @@
1
- import { createTxReqRespValidator } from '../../../msg_validators/tx_validator/factory.js';
1
+ import { createTxValidatorForReqResponseReceivedTxs } from '../../../msg_validators/index.js';
2
2
  export class BatchRequestTxValidator {
3
3
  config;
4
4
  txValidator;
@@ -13,7 +13,7 @@ export class BatchRequestTxValidator {
13
13
  return await Promise.all(txs.map((tx)=>this.validateRequestedTx(tx)));
14
14
  }
15
15
  static createRequestedTxValidator(config) {
16
- return createTxReqRespValidator(config.proofVerifier, {
16
+ return createTxValidatorForReqResponseReceivedTxs(config.proofVerifier, {
17
17
  l1ChainId: config.l1ChainId,
18
18
  rollupVersion: config.rollupVersion
19
19
  });