@aztec/p2p 0.83.1 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dest/client/factory.d.ts +2 -1
  2. package/dest/client/factory.d.ts.map +1 -1
  3. package/dest/client/factory.js +3 -3
  4. package/dest/client/p2p_client.d.ts +2 -1
  5. package/dest/client/p2p_client.d.ts.map +1 -1
  6. package/dest/config.d.ts +16 -1
  7. package/dest/config.d.ts.map +1 -1
  8. package/dest/config.js +53 -0
  9. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts +3 -0
  10. package/dest/msg_validators/tx_validator/allowed_public_setup.d.ts.map +1 -0
  11. package/dest/msg_validators/tx_validator/allowed_public_setup.js +27 -0
  12. package/dest/msg_validators/tx_validator/gas_validator.d.ts +10 -0
  13. package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -0
  14. package/dest/msg_validators/tx_validator/gas_validator.js +76 -0
  15. package/dest/msg_validators/tx_validator/index.d.ts +4 -0
  16. package/dest/msg_validators/tx_validator/index.d.ts.map +1 -1
  17. package/dest/msg_validators/tx_validator/index.js +4 -0
  18. package/dest/msg_validators/tx_validator/phases_validator.d.ts +13 -0
  19. package/dest/msg_validators/tx_validator/phases_validator.d.ts.map +1 -0
  20. package/dest/msg_validators/tx_validator/phases_validator.js +83 -0
  21. package/dest/msg_validators/tx_validator/test_utils.d.ts +17 -0
  22. package/dest/msg_validators/tx_validator/test_utils.d.ts.map +1 -0
  23. package/dest/msg_validators/tx_validator/test_utils.js +22 -0
  24. package/dest/services/libp2p/libp2p_service.d.ts +6 -3
  25. package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
  26. package/dest/services/libp2p/libp2p_service.js +36 -9
  27. package/dest/services/peer-manager/peer_manager.d.ts +1 -1
  28. package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
  29. package/dest/services/peer-manager/peer_manager.js +14 -9
  30. package/dest/test-helpers/reqresp-nodes.d.ts +2 -1
  31. package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
  32. package/dest/test-helpers/reqresp-nodes.js +2 -2
  33. package/package.json +12 -10
  34. package/src/client/factory.ts +4 -3
  35. package/src/client/p2p_client.ts +2 -1
  36. package/src/config.ts +64 -1
  37. package/src/msg_validators/tx_validator/allowed_public_setup.ts +35 -0
  38. package/src/msg_validators/tx_validator/gas_validator.ts +95 -0
  39. package/src/msg_validators/tx_validator/index.ts +4 -0
  40. package/src/msg_validators/tx_validator/phases_validator.ts +104 -0
  41. package/src/msg_validators/tx_validator/test_utils.ts +43 -0
  42. package/src/services/libp2p/libp2p_service.ts +42 -7
  43. package/src/services/peer-manager/peer_manager.ts +19 -11
  44. package/src/test-helpers/reqresp-nodes.ts +3 -2
@@ -8,8 +8,10 @@ import { Fr } from '@aztec/foundation/fields';
8
8
  import { createLibp2pComponentLogger, createLogger } from '@aztec/foundation/log';
9
9
  import { SerialQueue } from '@aztec/foundation/queue';
10
10
  import { RunningPromise } from '@aztec/foundation/running-promise';
11
+ import { ProtocolContractAddress } from '@aztec/protocol-contracts';
12
+ import { GasFees } from '@aztec/stdlib/gas';
11
13
  import { BlockAttestation, BlockProposal, P2PClientType, PeerErrorSeverity, TopicTypeMap, getTopicTypeForClientType, metricsTopicStrToLabels } from '@aztec/stdlib/p2p';
12
- import { MerkleTreeId } from '@aztec/stdlib/trees';
14
+ import { DatabasePublicStateSource, MerkleTreeId } from '@aztec/stdlib/trees';
13
15
  import { Tx } from '@aztec/stdlib/tx';
14
16
  import { Attributes, OtelMetricsAdapter, WithTracer, trackSpan } from '@aztec/telemetry-client';
15
17
  import { gossipsub } from '@chainsafe/libp2p-gossipsub';
@@ -25,7 +27,8 @@ import { mplex } from '@libp2p/mplex';
25
27
  import { tcp } from '@libp2p/tcp';
26
28
  import { createLibp2p } from 'libp2p';
27
29
  import { AttestationValidator, BlockProposalValidator } from '../../msg_validators/index.js';
28
- import { DataTxValidator, DoubleSpendTxValidator, MetadataTxValidator, TxProofValidator } from '../../msg_validators/tx_validator/index.js';
30
+ import { getDefaultAllowedSetupFunctions } from '../../msg_validators/tx_validator/allowed_public_setup.js';
31
+ import { DataTxValidator, DoubleSpendTxValidator, GasTxValidator, MetadataTxValidator, PhasesTxValidator, TxProofValidator } from '../../msg_validators/tx_validator/index.js';
29
32
  import { GossipSubEvent } from '../../types/index.js';
30
33
  import { convertToMultiaddr } from '../../util.js';
31
34
  import { AztecDatastore } from '../data_store.js';
@@ -45,7 +48,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
45
48
  node;
46
49
  peerDiscoveryService;
47
50
  mempools;
48
- l2BlockSource;
51
+ archiver;
49
52
  proofVerifier;
50
53
  worldStateSynchronizer;
51
54
  logger;
@@ -59,14 +62,15 @@ import { ReqResp } from '../reqresp/reqresp.js';
59
62
  reqresp;
60
63
  // Trusted peers ids
61
64
  trustedPeersIds;
65
+ feesCache;
62
66
  /**
63
67
  * Callback for when a block is received from a peer.
64
68
  * @param block - The block received from the peer.
65
69
  * @returns The attestation for the block, if any.
66
70
  */ blockReceivedCallback;
67
71
  gossipSubEventHandler;
68
- constructor(clientType, config, node, peerDiscoveryService, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
69
- super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.mempools = mempools, this.l2BlockSource = l2BlockSource, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.logger = logger, this.jobQueue = new SerialQueue(), this.trustedPeersIds = [];
72
+ constructor(clientType, config, node, peerDiscoveryService, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
73
+ super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.mempools = mempools, this.archiver = archiver, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.logger = logger, this.jobQueue = new SerialQueue(), this.trustedPeersIds = [];
70
74
  const peerScoring = new PeerScoring(config);
71
75
  this.reqresp = new ReqResp(config, node, peerScoring);
72
76
  this.peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, this.reqresp);
@@ -223,7 +227,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
223
227
  // Create request response protocol handlers
224
228
  const txHandler = reqRespTxHandler(this.mempools);
225
229
  const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
226
- const blockHandler = reqRespBlockHandler(this.l2BlockSource);
230
+ const blockHandler = reqRespBlockHandler(this.archiver);
227
231
  const requestResponseHandlers = {
228
232
  [ReqRespSubProtocol.PING]: pingHandler,
229
233
  [ReqRespSubProtocol.STATUS]: statusHandler,
@@ -509,8 +513,8 @@ import { ReqResp } from '../reqresp/reqresp.js';
509
513
  return true;
510
514
  }
511
515
  async validatePropagatedTx(tx, peerId) {
512
- const blockNumber = await this.l2BlockSource.getBlockNumber() + 1;
513
- const messageValidators = this.createMessageValidators(blockNumber);
516
+ const blockNumber = await this.archiver.getBlockNumber() + 1;
517
+ const messageValidators = await this.createMessageValidators(blockNumber);
514
518
  const outcome = await this.runValidations(tx, messageValidators);
515
519
  if (outcome.allPassed) {
516
520
  return true;
@@ -524,6 +528,18 @@ import { ReqResp } from '../reqresp/reqresp.js';
524
528
  this.peerManager.penalizePeer(peerId, severity);
525
529
  return false;
526
530
  }
531
+ async getGasFees(blockNumber) {
532
+ if (blockNumber === this.feesCache?.blockNumber) {
533
+ return this.feesCache.gasFees;
534
+ }
535
+ const header = await this.archiver.getBlockHeader(blockNumber);
536
+ const gasFees = header?.globalVariables.gasFees ?? GasFees.empty();
537
+ this.feesCache = {
538
+ blockNumber,
539
+ gasFees
540
+ };
541
+ return gasFees;
542
+ }
527
543
  /**
528
544
  * Create message validators for the given block number.
529
545
  *
@@ -532,7 +548,10 @@ import { ReqResp } from '../reqresp/reqresp.js';
532
548
  *
533
549
  * @param blockNumber - The block number to create validators for.
534
550
  * @returns The message validators.
535
- */ createMessageValidators(blockNumber) {
551
+ */ async createMessageValidators(blockNumber) {
552
+ const merkleTree = this.worldStateSynchronizer.getCommitted();
553
+ const gasFees = await this.getGasFees(blockNumber - 1);
554
+ const allowedInSetup = this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
536
555
  return {
537
556
  dataValidator: {
538
557
  validator: new DataTxValidator(),
@@ -555,6 +574,14 @@ import { ReqResp } from '../reqresp/reqresp.js';
555
574
  }
556
575
  }),
557
576
  severity: PeerErrorSeverity.HighToleranceError
577
+ },
578
+ gasValidator: {
579
+ validator: new GasTxValidator(new DatabasePublicStateSource(merkleTree), ProtocolContractAddress.FeeJuice, gasFees),
580
+ severity: PeerErrorSeverity.HighToleranceError
581
+ },
582
+ phasesValidator: {
583
+ validator: new PhasesTxValidator(this.archiver, allowedInSetup, blockNumber),
584
+ severity: PeerErrorSeverity.MidToleranceError
558
585
  }
559
586
  };
560
587
  }
@@ -22,7 +22,7 @@ export declare class PeerManager {
22
22
  private trustedPeers;
23
23
  private trustedPeersInitialized;
24
24
  private metrics;
25
- private discoveredPeerHandler;
25
+ private handlers;
26
26
  constructor(libP2PNode: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, config: P2PConfig, telemetryClient: TelemetryClient, logger: import("@aztec/foundation/log").Logger, peerScoring: PeerScoring, reqresp: ReqResp);
27
27
  /**
28
28
  * Initializes the trusted peers.
@@ -1 +1 @@
1
- {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBrE,qBAAa,WAAW;IAYpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IAjBjB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,8BAA8B,CAAa;IACnD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,qBAAqB,CAAC;gBAGpB,UAAU,EAAE,YAAY,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACzB,eAAe,EAAE,eAAe,EACxB,MAAM,wCAAmC,EACzC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO;IAoB1B;;;;OAIG;IACG,sBAAsB;IAU5B,IAAI,MAAM,6CAET;IAGM,SAAS;IAShB;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IASnC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;;OAMG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAQrD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAIvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,QAAQ,CAAC,cAAc,UAAQ,GAAG,QAAQ,EAAE;IAiCnD;;OAEG;IACH,OAAO,CAAC,QAAQ;IAiEhB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;IAwB3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;YAuBb,wBAAwB;YAcxB,cAAc;IAQ5B;;;OAGG;YACW,oBAAoB;YA8DpB,QAAQ;IA2BtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,gBAAgB;IAsBxB;;;OAGG;IACU,IAAI;CAYlB"}
1
+ {"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBrE,qBAAa,WAAW;IAgBpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IArBjB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,8BAA8B,CAAa;IACnD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAIF;gBAGJ,UAAU,EAAE,YAAY,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACzB,eAAe,EAAE,eAAe,EACxB,MAAM,wCAAmC,EACzC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO;IAwB1B;;;;OAIG;IACG,sBAAsB;IAU5B,IAAI,MAAM,6CAET;IAGM,SAAS;IAShB;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IASnC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;;OAMG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAQrD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAIvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,QAAQ,CAAC,cAAc,UAAQ,GAAG,QAAQ,EAAE;IAiCnD;;OAEG;IACH,OAAO,CAAC,QAAQ;IAiEhB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;IAwB3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;YAuBb,wBAAwB;YAcxB,cAAc;IAQ5B;;;OAGG;YACW,oBAAoB;YA8DpB,QAAQ;IA2BtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,gBAAgB;IAsBxB;;;OAGG;IACU,IAAI;CAYlB"}
@@ -31,7 +31,7 @@ export class PeerManager {
31
31
  trustedPeers;
32
32
  trustedPeersInitialized;
33
33
  metrics;
34
- discoveredPeerHandler;
34
+ handlers;
35
35
  constructor(libP2PNode, peerDiscoveryService, config, telemetryClient, logger = createLogger('p2p:peer-manager'), peerScoring, reqresp){
36
36
  this.libP2PNode = libP2PNode;
37
37
  this.peerDiscoveryService = peerDiscoveryService;
@@ -45,15 +45,20 @@ export class PeerManager {
45
45
  this.timedOutPeers = new Map();
46
46
  this.trustedPeers = new Set();
47
47
  this.trustedPeersInitialized = false;
48
+ this.handlers = {};
48
49
  this.metrics = new PeerManagerMetrics(telemetryClient, 'PeerManager');
50
+ // Handle Discovered peers
51
+ this.handlers = {
52
+ handleConnectedPeerEvent: this.handleConnectedPeerEvent.bind(this),
53
+ handleDisconnectedPeerEvent: this.handleDisconnectedPeerEvent.bind(this),
54
+ handleDiscoveredPeer: (enr)=>this.handleDiscoveredPeer(enr).catch((e)=>this.logger.error('Error handling discovered peer', e))
55
+ };
49
56
  // Handle new established connections
50
- this.libP2PNode.addEventListener(PeerEvent.CONNECTED, this.handleConnectedPeerEvent.bind(this));
57
+ this.libP2PNode.addEventListener(PeerEvent.CONNECTED, this.handlers.handleConnectedPeerEvent);
51
58
  // Handle lost connections
52
- this.libP2PNode.addEventListener(PeerEvent.DISCONNECTED, this.handleDisconnectedPeerEvent.bind(this));
53
- // Handle Discovered peers
54
- this.discoveredPeerHandler = (enr)=>this.handleDiscoveredPeer(enr).catch((e)=>this.logger.error('Error handling discovered peer', e));
59
+ this.libP2PNode.addEventListener(PeerEvent.DISCONNECTED, this.handlers.handleDisconnectedPeerEvent);
55
60
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
56
- this.peerDiscoveryService.on(PeerEvent.DISCOVERED, this.discoveredPeerHandler);
61
+ this.peerDiscoveryService.on(PeerEvent.DISCOVERED, this.handlers.handleDiscoveredPeer);
57
62
  // Display peer counts every 60 seconds
58
63
  this.displayPeerCountsPeerHeartbeat = Math.floor(60_000 / this.config.peerCheckIntervalMS);
59
64
  }
@@ -447,11 +452,11 @@ export class PeerManager {
447
452
  * Removing all event listeners.
448
453
  */ async stop() {
449
454
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
450
- this.peerDiscoveryService.off(PeerEvent.DISCOVERED, this.discoveredPeerHandler);
455
+ this.peerDiscoveryService.off(PeerEvent.DISCOVERED, this.handlers.handleDiscoveredPeer);
451
456
  // Send goodbyes to all peers
452
457
  await Promise.all(this.libP2PNode.getPeers().map((peer)=>this.goodbyeAndDisconnectPeer(peer, GoodByeReason.SHUTDOWN)));
453
- this.libP2PNode.removeEventListener(PeerEvent.CONNECTED, this.handleConnectedPeerEvent);
454
- this.libP2PNode.removeEventListener(PeerEvent.DISCONNECTED, this.handleDisconnectedPeerEvent);
458
+ this.libP2PNode.removeEventListener(PeerEvent.CONNECTED, this.handlers.handleConnectedPeerEvent);
459
+ this.libP2PNode.removeEventListener(PeerEvent.DISCONNECTED, this.handlers.handleDisconnectedPeerEvent);
455
460
  }
456
461
  }
457
462
  _ts_decorate([
@@ -1,6 +1,7 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
2
  import type { L2BlockSource } from '@aztec/stdlib/block';
3
3
  import { type ChainConfig } from '@aztec/stdlib/config';
4
+ import type { ContractDataSource } from '@aztec/stdlib/contract';
4
5
  import type { ClientProtocolCircuitVerifier, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
5
6
  import type { P2PClientType } from '@aztec/stdlib/p2p';
6
7
  import type { Tx } from '@aztec/stdlib/tx';
@@ -27,7 +28,7 @@ export declare function createLibp2pNode(boostrapAddrs?: string[], peerId?: Peer
27
28
  *
28
29
  *
29
30
  */
30
- export declare function createTestLibP2PService<T extends P2PClientType>(clientType: T, boostrapAddrs: string[] | undefined, l2BlockSource: L2BlockSource, worldStateSynchronizer: WorldStateSynchronizer, epochCache: EpochCache, mempools: MemPools<T>, telemetry: TelemetryClient, port?: number, peerId?: PeerId, chainConfig?: ChainConfig): Promise<LibP2PService<T>>;
31
+ export declare function createTestLibP2PService<T extends P2PClientType>(clientType: T, boostrapAddrs: string[] | undefined, archiver: L2BlockSource & ContractDataSource, worldStateSynchronizer: WorldStateSynchronizer, epochCache: EpochCache, mempools: MemPools<T>, telemetry: TelemetryClient, port?: number, peerId?: PeerId, chainConfig?: ChainConfig): Promise<LibP2PService<T>>;
31
32
  /**
32
33
  * A p2p / req resp node pairing the req node will always contain the p2p node.
33
34
  * they are provided as a pair to allow access the p2p node directly
@@ -1 +1 @@
1
- {"version":3,"file":"reqresp-nodes.d.ts","sourceRoot":"","sources":["../../src/test-helpers/reqresp-nodes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reqresp-nodes.d.ts","sourceRoot":"","sources":["../../src/test-helpers/reqresp-nodes.ts"],"names":[],"mappings":"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"}
@@ -73,7 +73,7 @@ import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js
73
73
  * P2P functionality is operational, however everything else is default
74
74
  *
75
75
  *
76
- */ export async function createTestLibP2PService(clientType, boostrapAddrs = [], l2BlockSource, worldStateSynchronizer, epochCache, mempools, telemetry, port = 0, peerId, chainConfig = emptyChainConfig) {
76
+ */ export async function createTestLibP2PService(clientType, boostrapAddrs = [], archiver, worldStateSynchronizer, epochCache, mempools, telemetry, port = 0, peerId, chainConfig = emptyChainConfig) {
77
77
  peerId = peerId ?? await createSecp256k1PeerId();
78
78
  const config = {
79
79
  p2pIp: `127.0.0.1`,
@@ -90,7 +90,7 @@ import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js
90
90
  const proofVerifier = new AlwaysTrueCircuitVerifier();
91
91
  // No bootstrap nodes provided as the libp2p service will register them in the constructor
92
92
  const p2pNode = await createLibp2pNode([], peerId, port, /*enable gossip */ true, /**start */ false);
93
- return new LibP2PService(clientType, config, p2pNode, discoveryService, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry);
93
+ return new LibP2PService(clientType, config, p2pNode, discoveryService, mempools, archiver, epochCache, proofVerifier, worldStateSynchronizer, telemetry);
94
94
  }
95
95
  // Mock sub protocol handlers
96
96
  export const MOCK_SUB_PROTOCOL_HANDLERS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.83.1",
3
+ "version": "0.84.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -65,14 +65,16 @@
65
65
  ]
66
66
  },
67
67
  "dependencies": {
68
- "@aztec/constants": "0.83.1",
69
- "@aztec/epoch-cache": "0.83.1",
70
- "@aztec/foundation": "0.83.1",
71
- "@aztec/kv-store": "0.83.1",
72
- "@aztec/noir-protocol-circuits-types": "0.83.1",
73
- "@aztec/protocol-contracts": "0.83.1",
74
- "@aztec/stdlib": "0.83.1",
75
- "@aztec/telemetry-client": "0.83.1",
68
+ "@aztec/constants": "0.84.0",
69
+ "@aztec/epoch-cache": "0.84.0",
70
+ "@aztec/foundation": "0.84.0",
71
+ "@aztec/kv-store": "0.84.0",
72
+ "@aztec/noir-contracts.js": "0.84.0",
73
+ "@aztec/noir-protocol-circuits-types": "0.84.0",
74
+ "@aztec/protocol-contracts": "0.84.0",
75
+ "@aztec/simulator": "0.84.0",
76
+ "@aztec/stdlib": "0.84.0",
77
+ "@aztec/telemetry-client": "0.84.0",
76
78
  "@chainsafe/discv5": "9.0.0",
77
79
  "@chainsafe/enr": "3.0.0",
78
80
  "@chainsafe/libp2p-gossipsub": "13.0.0",
@@ -101,7 +103,7 @@
101
103
  "xxhash-wasm": "^1.1.0"
102
104
  },
103
105
  "devDependencies": {
104
- "@aztec/archiver": "0.83.1",
106
+ "@aztec/archiver": "0.84.0",
105
107
  "@jest/globals": "^29.5.0",
106
108
  "@types/jest": "^29.5.0",
107
109
  "@types/node": "^18.14.6",
@@ -4,6 +4,7 @@ import type { AztecAsyncKVStore } from '@aztec/kv-store';
4
4
  import type { DataStoreConfig } from '@aztec/kv-store/config';
5
5
  import { createStore } from '@aztec/kv-store/lmdb-v2';
6
6
  import type { L2BlockSource } from '@aztec/stdlib/block';
7
+ import type { ContractDataSource } from '@aztec/stdlib/contract';
7
8
  import type { ClientProtocolCircuitVerifier, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
8
9
  import { P2PClientType } from '@aztec/stdlib/p2p';
9
10
  import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
@@ -29,7 +30,7 @@ type P2PClientDeps<T extends P2PClientType> = {
29
30
  export const createP2PClient = async <T extends P2PClientType>(
30
31
  clientType: T,
31
32
  _config: P2PConfig & DataStoreConfig,
32
- l2BlockSource: L2BlockSource,
33
+ archiver: L2BlockSource & ContractDataSource,
33
34
  proofVerifier: ClientProtocolCircuitVerifier,
34
35
  worldStateSynchronizer: WorldStateSynchronizer,
35
36
  epochCache: EpochCacheInterface,
@@ -73,7 +74,7 @@ export const createP2PClient = async <T extends P2PClientType>(
73
74
  discoveryService,
74
75
  peerId,
75
76
  mempools,
76
- l2BlockSource,
77
+ archiver,
77
78
  epochCache,
78
79
  proofVerifier,
79
80
  worldStateSynchronizer,
@@ -85,5 +86,5 @@ export const createP2PClient = async <T extends P2PClientType>(
85
86
  logger.verbose('P2P is disabled. Using dummy P2P service');
86
87
  p2pService = new DummyP2PService();
87
88
  }
88
- return new P2PClient(clientType, store, l2BlockSource, mempools, p2pService, config, telemetry);
89
+ return new P2PClient(clientType, store, archiver, mempools, p2pService, config, telemetry);
89
90
  };
@@ -9,6 +9,7 @@ import type {
9
9
  L2Tips,
10
10
  PublishedL2Block,
11
11
  } from '@aztec/stdlib/block';
12
+ import type { ContractDataSource } from '@aztec/stdlib/contract';
12
13
  import type { P2PApi, PeerInfo, ProverCoordination } from '@aztec/stdlib/interfaces/server';
13
14
  import { BlockAttestation, type BlockProposal, ConsensusPayload, type P2PClientType } from '@aztec/stdlib/p2p';
14
15
  import type { Tx, TxHash } from '@aztec/stdlib/tx';
@@ -211,7 +212,7 @@ export class P2PClient<T extends P2PClientType = P2PClientType.Full>
211
212
  constructor(
212
213
  _clientType: T,
213
214
  store: AztecAsyncKVStore,
214
- private l2BlockSource: L2BlockSource,
215
+ private l2BlockSource: L2BlockSource & ContractDataSource,
215
216
  mempools: MemPools<T>,
216
217
  private p2pService: P2PService,
217
218
  config: Partial<P2PConfig> = {},
package/src/config.ts CHANGED
@@ -6,8 +6,11 @@ import {
6
6
  numberConfigHelper,
7
7
  pickConfigMappings,
8
8
  } from '@aztec/foundation/config';
9
+ import { Fr } from '@aztec/foundation/fields';
9
10
  import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
10
- import { type ChainConfig, chainConfigMappings } from '@aztec/stdlib/config';
11
+ import { FunctionSelector } from '@aztec/stdlib/abi';
12
+ import { AztecAddress } from '@aztec/stdlib/aztec-address';
13
+ import { type AllowedElement, type ChainConfig, chainConfigMappings } from '@aztec/stdlib/config';
11
14
 
12
15
  import { type P2PReqRespConfig, p2pReqRespConfigMappings } from './services/reqresp/config.js';
13
16
 
@@ -169,6 +172,9 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
169
172
  * The maximum possible size of the P2P DB in KB. Overwrites the general dataStoreMapSizeKB.
170
173
  */
171
174
  p2pStoreMapSizeKb?: number;
175
+
176
+ /** Which calls are allowed in the public setup phase of a tx. */
177
+ txPublicSetupAllowList: AllowedElement[];
172
178
  }
173
179
 
174
180
  export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
@@ -341,6 +347,13 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
341
347
  parseEnv: (val: string | undefined) => (val ? +val : undefined),
342
348
  description: 'The maximum possible size of the P2P DB in KB. Overwrites the general dataStoreMapSizeKB.',
343
349
  },
350
+ txPublicSetupAllowList: {
351
+ env: 'TX_PUBLIC_SETUP_ALLOWLIST',
352
+ parseEnv: (val: string) => parseAllowList(val),
353
+ description: 'The list of functions calls allowed to run in setup',
354
+ printDefault: () =>
355
+ 'AuthRegistry, FeeJuice.increase_public_balance, Token.increase_public_balance, FPC.prepare_fee',
356
+ },
344
357
  ...p2pReqRespConfigMappings,
345
358
  ...chainConfigMappings,
346
359
  };
@@ -383,3 +396,53 @@ export const bootnodeConfigMappings = pickConfigMappings(
383
396
  { ...p2pConfigMappings, ...dataConfigMappings, ...chainConfigMappings },
384
397
  bootnodeConfigKeys,
385
398
  );
399
+
400
+ /**
401
+ * Parses a string to a list of allowed elements.
402
+ * Each encoded is expected to be of one of the following formats
403
+ * `I:${address}`
404
+ * `I:${address}:${selector}`
405
+ * `C:${classId}`
406
+ * `C:${classId}:${selector}`
407
+ *
408
+ * @param value The string to parse
409
+ * @returns A list of allowed elements
410
+ */
411
+ export function parseAllowList(value: string): AllowedElement[] {
412
+ const entries: AllowedElement[] = [];
413
+
414
+ if (!value) {
415
+ return entries;
416
+ }
417
+
418
+ for (const val of value.split(',')) {
419
+ const [typeString, identifierString, selectorString] = val.split(':');
420
+ const selector = selectorString !== undefined ? FunctionSelector.fromString(selectorString) : undefined;
421
+
422
+ if (typeString === 'I') {
423
+ if (selector) {
424
+ entries.push({
425
+ address: AztecAddress.fromString(identifierString),
426
+ selector,
427
+ });
428
+ } else {
429
+ entries.push({
430
+ address: AztecAddress.fromString(identifierString),
431
+ });
432
+ }
433
+ } else if (typeString === 'C') {
434
+ if (selector) {
435
+ entries.push({
436
+ classId: Fr.fromHexString(identifierString),
437
+ selector,
438
+ });
439
+ } else {
440
+ entries.push({
441
+ classId: Fr.fromHexString(identifierString),
442
+ });
443
+ }
444
+ }
445
+ }
446
+
447
+ return entries;
448
+ }
@@ -0,0 +1,35 @@
1
+ import { FPCContract } from '@aztec/noir-contracts.js/FPC';
2
+ import { TokenContractArtifact } from '@aztec/noir-contracts.js/Token';
3
+ import { ProtocolContractAddress } from '@aztec/protocol-contracts';
4
+ import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
5
+ import type { AllowedElement } from '@aztec/stdlib/interfaces/server';
6
+
7
+ let defaultAllowedSetupFunctions: AllowedElement[] | undefined = undefined;
8
+ export async function getDefaultAllowedSetupFunctions(): Promise<AllowedElement[]> {
9
+ if (defaultAllowedSetupFunctions === undefined) {
10
+ defaultAllowedSetupFunctions = [
11
+ // needed for authwit support
12
+ {
13
+ address: ProtocolContractAddress.AuthRegistry,
14
+ },
15
+ // needed for claiming on the same tx as a spend
16
+ {
17
+ address: ProtocolContractAddress.FeeJuice,
18
+ // We can't restrict the selector because public functions get routed via dispatch.
19
+ // selector: FunctionSelector.fromSignature('_increase_public_balance((Field),u128)'),
20
+ },
21
+ // needed for private transfers via FPC
22
+ {
23
+ classId: (await getContractClassFromArtifact(TokenContractArtifact)).id,
24
+ // We can't restrict the selector because public functions get routed via dispatch.
25
+ // selector: FunctionSelector.fromSignature('_increase_public_balance((Field),u128)'),
26
+ },
27
+ {
28
+ classId: (await getContractClassFromArtifact(FPCContract.artifact)).id,
29
+ // We can't restrict the selector because public functions get routed via dispatch.
30
+ // selector: FunctionSelector.fromSignature('prepare_fee((Field),Field,(Field),Field)'),
31
+ },
32
+ ];
33
+ }
34
+ return defaultAllowedSetupFunctions;
35
+ }
@@ -0,0 +1,95 @@
1
+ import { createLogger } from '@aztec/foundation/log';
2
+ import { computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
3
+ import { getCallRequestsWithCalldataByPhase } from '@aztec/simulator/server';
4
+ import { FunctionSelector } from '@aztec/stdlib/abi';
5
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
6
+ import type { GasFees } from '@aztec/stdlib/gas';
7
+ import type { PublicStateSource } from '@aztec/stdlib/trees';
8
+ import { type Tx, TxExecutionPhase, type TxValidationResult, type TxValidator } from '@aztec/stdlib/tx';
9
+
10
+ export class GasTxValidator implements TxValidator<Tx> {
11
+ #log = createLogger('sequencer:tx_validator:tx_gas');
12
+ #publicDataSource: PublicStateSource;
13
+ #feeJuiceAddress: AztecAddress;
14
+ #gasFees: GasFees;
15
+
16
+ constructor(publicDataSource: PublicStateSource, feeJuiceAddress: AztecAddress, gasFees: GasFees) {
17
+ this.#publicDataSource = publicDataSource;
18
+ this.#feeJuiceAddress = feeJuiceAddress;
19
+ this.#gasFees = gasFees;
20
+ }
21
+
22
+ async validateTx(tx: Tx): Promise<TxValidationResult> {
23
+ if (await this.#shouldSkip(tx)) {
24
+ return Promise.resolve({ result: 'skipped', reason: ['Insufficient fee per gas'] });
25
+ }
26
+ return this.#validateTxFee(tx);
27
+ }
28
+
29
+ /**
30
+ * Check whether the tx's max fees are valid for the current block, and skip if not.
31
+ * We skip instead of invalidating since the tx may become eligible later.
32
+ * Note that circuits check max fees even if fee payer is unset, so we
33
+ * keep this validation even if the tx does not pay fees.
34
+ */
35
+ async #shouldSkip(tx: Tx): Promise<boolean> {
36
+ const gasSettings = tx.data.constants.txContext.gasSettings;
37
+
38
+ // Skip the tx if its max fees are not enough for the current block's gas fees.
39
+ const maxFeesPerGas = gasSettings.maxFeesPerGas;
40
+ const notEnoughMaxFees =
41
+ maxFeesPerGas.feePerDaGas.lt(this.#gasFees.feePerDaGas) ||
42
+ maxFeesPerGas.feePerL2Gas.lt(this.#gasFees.feePerL2Gas);
43
+
44
+ if (notEnoughMaxFees) {
45
+ this.#log.warn(`Skipping transaction ${await tx.getTxHash()} due to insufficient fee per gas`, {
46
+ txMaxFeesPerGas: maxFeesPerGas.toInspect(),
47
+ currentGasFees: this.#gasFees.toInspect(),
48
+ });
49
+ }
50
+ return notEnoughMaxFees;
51
+ }
52
+
53
+ async #validateTxFee(tx: Tx): Promise<TxValidationResult> {
54
+ const feePayer = tx.data.feePayer;
55
+
56
+ // Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
57
+ const feeLimit = tx.data.constants.txContext.gasSettings.getFeeLimit();
58
+
59
+ // Read current balance of the feePayer
60
+ const initialBalance = await this.#publicDataSource.storageRead(
61
+ this.#feeJuiceAddress,
62
+ await computeFeePayerBalanceStorageSlot(feePayer),
63
+ );
64
+
65
+ // If there is a claim in this tx that increases the fee payer balance in Fee Juice, add it to balance
66
+ const setupFns = getCallRequestsWithCalldataByPhase(tx, TxExecutionPhase.SETUP);
67
+ const increasePublicBalanceSelector = await FunctionSelector.fromSignature(
68
+ '_increase_public_balance((Field),u128)',
69
+ );
70
+
71
+ // Arguments of the claim function call:
72
+ // - args[0]: Amount recipient.
73
+ // - args[1]: Amount being claimed.
74
+ const claimFunctionCall = setupFns.find(
75
+ fn =>
76
+ fn.request.contractAddress.equals(this.#feeJuiceAddress) &&
77
+ fn.request.msgSender.equals(this.#feeJuiceAddress) &&
78
+ fn.calldata.length > 2 &&
79
+ fn.functionSelector.equals(increasePublicBalanceSelector) &&
80
+ fn.args[0].equals(feePayer.toField()) &&
81
+ !fn.request.isStaticCall,
82
+ );
83
+
84
+ const balance = claimFunctionCall ? initialBalance.add(claimFunctionCall.args[1]) : initialBalance;
85
+ if (balance.lt(feeLimit)) {
86
+ this.#log.warn(`Rejecting transaction due to not enough fee payer balance`, {
87
+ feePayer,
88
+ balance: balance.toBigInt(),
89
+ feeLimit: feeLimit.toBigInt(),
90
+ });
91
+ return { result: 'invalid', reason: ['Insufficient fee payer balance'] };
92
+ }
93
+ return { result: 'valid' };
94
+ }
95
+ }
@@ -4,3 +4,7 @@ export * from './double_spend_validator.js';
4
4
  export * from './metadata_validator.js';
5
5
  export * from './tx_proof_validator.js';
6
6
  export * from './block_header_validator.js';
7
+ export * from './gas_validator.js';
8
+ export * from './phases_validator.js';
9
+ export * from './test_utils.js';
10
+ export * from './allowed_public_setup.js';