@aztec/p2p 0.85.0-alpha-testnet.2 → 0.85.0-nightly.20250417

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.
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/bootstrap/bootstrap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAInF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD;;GAEG;AACH,qBAAa,aAAc,YAAW,eAAe;IAKjD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,IAAI,CAAC,CAA0C;IACvD,OAAO,CAAC,MAAM,CAAC,CAAS;gBAGd,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,eAAe,EAC1B,MAAM,yCAAgC;IAGhD;;;;OAIG;IACU,KAAK,CAAC,MAAM,EAAE,cAAc;IAoEzC;;;OAGG;IACU,IAAI;IAOjB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IAMpB;;;OAGG;IACI,SAAS;IAKT,MAAM;IAKN,aAAa;IAKb,eAAe;CAIvB"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/bootstrap/bootstrap.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAInF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAInD;;GAEG;AACH,qBAAa,aAAc,YAAW,eAAe;IAKjD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,IAAI,CAAC,CAA0C;IACvD,OAAO,CAAC,MAAM,CAAC,CAAS;gBAGd,KAAK,EAAE,iBAAiB,EACxB,SAAS,EAAE,eAAe,EAC1B,MAAM,yCAAgC;IAGhD;;;;OAIG;IACU,KAAK,CAAC,MAAM,EAAE,cAAc;IAwEzC;;;OAGG;IACU,IAAI;IAOjB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IAMpB;;;OAGG;IACI,SAAS;IAKT,MAAM;IAKN,aAAa;IAKb,eAAe;CAIvB"}
@@ -24,13 +24,16 @@ import { convertToMultiaddr, getPeerIdPrivateKey } from '../util.js';
24
24
  * @param config - A partial P2P configuration. No need for TCP values as well as aztec node specific values.
25
25
  * @returns An empty promise.
26
26
  */ async start(config) {
27
- const { p2pIp, p2pPort, listenAddress } = config;
28
- const listenAddrUdp = multiaddr(convertToMultiaddr(listenAddress, p2pPort, 'udp'));
27
+ const { p2pIp, p2pPort, listenAddress, p2pBroadcastPort } = config;
29
28
  if (!p2pIp) {
30
29
  throw new Error('You need to provide a P2P IP address.');
31
30
  }
31
+ if (!p2pBroadcastPort) {
32
+ config.p2pBroadcastPort = p2pPort;
33
+ }
34
+ const listenAddrUdp = multiaddr(convertToMultiaddr(listenAddress, config.p2pBroadcastPort, 'udp'));
32
35
  const peerIdPrivateKey = await getPeerIdPrivateKey(config, this.store, this.logger);
33
- const { enr: ourEnr, peerId } = await createBootnodeENRandPeerId(peerIdPrivateKey, p2pIp, p2pPort, config.l1ChainId);
36
+ const { enr: ourEnr, peerId } = await createBootnodeENRandPeerId(peerIdPrivateKey, p2pIp, config.p2pBroadcastPort, config.l1ChainId);
34
37
  this.peerId = peerId;
35
38
  this.logger.debug(`Starting bootstrap node ${peerId} listening on ${listenAddrUdp.toString()}`);
36
39
  const metricsRegistry = new OtelMetricsAdapter(this.telemetry);
package/dest/config.d.ts CHANGED
@@ -34,6 +34,10 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
34
34
  * The port for the P2P service.
35
35
  */
36
36
  p2pPort: number;
37
+ /**
38
+ * The port to broadcast the P2P service on (included in the node's ENR).
39
+ */
40
+ p2pBroadcastPort?: number;
37
41
  /**
38
42
  * The IP address for the P2P service.
39
43
  */
@@ -130,6 +134,10 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
130
134
  * A list of trusted peers.
131
135
  */
132
136
  trustedPeers: string[];
137
+ /**
138
+ * A list of private peers.
139
+ */
140
+ privatePeers: string[];
133
141
  /**
134
142
  * The maximum possible size of the P2P DB in KB. Overwrites the general dataStoreMapSizeKB.
135
143
  */
@@ -141,6 +149,7 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
141
149
  */
142
150
  maxTxPoolSize: number;
143
151
  }
152
+ export declare const DEFAULT_P2P_PORT = 40400;
144
153
  export declare const p2pConfigMappings: ConfigMappingsType<P2PConfig>;
145
154
  /**
146
155
  * Gets the config values for p2p client from environment variables.
@@ -151,7 +160,7 @@ export declare function getP2PDefaultConfig(): P2PConfig;
151
160
  /**
152
161
  * Required P2P config values for a bootstrap node.
153
162
  */
154
- export type BootnodeConfig = Pick<P2PConfig, 'p2pIp' | 'p2pPort' | 'peerIdPrivateKey' | 'peerIdPrivateKeyPath' | 'bootstrapNodes' | 'listenAddress'> & Required<Pick<P2PConfig, 'p2pIp' | 'p2pPort'>> & Pick<DataStoreConfig, 'dataDirectory' | 'dataStoreMapSizeKB'> & Pick<ChainConfig, 'l1ChainId'>;
163
+ export type BootnodeConfig = Pick<P2PConfig, 'p2pIp' | 'p2pPort' | 'p2pBroadcastPort' | 'peerIdPrivateKey' | 'peerIdPrivateKeyPath' | 'bootstrapNodes' | 'listenAddress'> & Required<Pick<P2PConfig, 'p2pIp' | 'p2pPort'>> & Pick<DataStoreConfig, 'dataDirectory' | 'dataStoreMapSizeKB'> & Pick<ChainConfig, 'l1ChainId'>;
155
164
  export declare const bootnodeConfigMappings: ConfigMappingsType<Pick<{
156
165
  l1ChainId: unknown;
157
166
  rollupVersion: unknown;
@@ -167,6 +176,7 @@ export declare const bootnodeConfigMappings: ConfigMappingsType<Pick<{
167
176
  peerCheckIntervalMS: unknown;
168
177
  l2QueueSize: unknown;
169
178
  p2pPort: unknown;
179
+ p2pBroadcastPort: unknown;
170
180
  p2pIp: unknown;
171
181
  listenAddress: unknown;
172
182
  peerIdPrivateKey: unknown;
@@ -193,10 +203,11 @@ export declare const bootnodeConfigMappings: ConfigMappingsType<Pick<{
193
203
  peerPenaltyValues: unknown;
194
204
  archivedTxLimit: unknown;
195
205
  trustedPeers: unknown;
206
+ privatePeers: unknown;
196
207
  p2pStoreMapSizeKb: unknown;
197
208
  txPublicSetupAllowList: unknown;
198
209
  maxTxPoolSize: unknown;
199
- }, "p2pPort" | "p2pIp" | "listenAddress" | "peerIdPrivateKey" | "peerIdPrivateKeyPath" | "bootstrapNodes" | "l1ChainId" | "dataDirectory" | "dataStoreMapSizeKB">>;
210
+ }, "p2pPort" | "p2pBroadcastPort" | "p2pIp" | "listenAddress" | "peerIdPrivateKey" | "peerIdPrivateKeyPath" | "bootstrapNodes" | "l1ChainId" | "dataDirectory" | "dataStoreMapSizeKB">>;
200
211
  /**
201
212
  * Parses a string to a list of allowed elements.
202
213
  * Each encoded is expected to be of one of the following formats
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dest/config.js CHANGED
@@ -5,6 +5,7 @@ import { FunctionSelector } from '@aztec/stdlib/abi';
5
5
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
6
6
  import { chainConfigMappings } from '@aztec/stdlib/config';
7
7
  import { p2pReqRespConfigMappings } from './services/reqresp/config.js';
8
+ export const DEFAULT_P2P_PORT = 40400;
8
9
  export const p2pConfigMappings = {
9
10
  p2pEnabled: {
10
11
  env: 'P2P_ENABLED',
@@ -38,8 +39,12 @@ export const p2pConfigMappings = {
38
39
  },
39
40
  p2pPort: {
40
41
  env: 'P2P_PORT',
41
- description: 'The port for the P2P service.',
42
- ...numberConfigHelper(40400)
42
+ description: `The port for the P2P service. Defaults to ${DEFAULT_P2P_PORT}`,
43
+ ...numberConfigHelper(DEFAULT_P2P_PORT)
44
+ },
45
+ p2pBroadcastPort: {
46
+ env: 'P2P_BROADCAST_PORT',
47
+ description: `The port to broadcast the P2P service on (included in the node's ENR). Defaults to P2P_PORT.`
43
48
  },
44
49
  p2pIp: {
45
50
  env: 'P2P_IP',
@@ -172,7 +177,13 @@ export const p2pConfigMappings = {
172
177
  trustedPeers: {
173
178
  env: 'P2P_TRUSTED_PEERS',
174
179
  parseEnv: (val)=>val.split(','),
175
- description: 'A list of trusted peers ENRs. Separated by commas.',
180
+ description: 'A list of trusted peer ENRs that will always be persisted. Separated by commas.',
181
+ defaultValue: []
182
+ },
183
+ privatePeers: {
184
+ env: 'P2P_PRIVATE_PEERS',
185
+ parseEnv: (val)=>val.split(','),
186
+ description: 'A list of private peer ENRs that will always be persisted and not be used for discovery. Separated by commas.',
176
187
  defaultValue: []
177
188
  },
178
189
  p2pStoreMapSizeKb: {
@@ -206,6 +217,7 @@ export function getP2PDefaultConfig() {
206
217
  const bootnodeConfigKeys = [
207
218
  'p2pIp',
208
219
  'p2pPort',
220
+ 'p2pBroadcastPort',
209
221
  'listenAddress',
210
222
  'peerIdPrivateKey',
211
223
  'peerIdPrivateKeyPath',
@@ -1,7 +1,7 @@
1
1
  import type { LogFn } from '@aztec/foundation/log';
2
2
  import { SignableENR } from '@chainsafe/enr';
3
3
  import type { PeerId } from '@libp2p/interface';
4
- export declare function createBootnodeENRandPeerId(privateKey: string, p2pIp: string, p2pPort: number, l1ChainId: number): Promise<{
4
+ export declare function createBootnodeENRandPeerId(privateKey: string, p2pIp: string, p2pBroadcastPort: number, l1ChainId: number): Promise<{
5
5
  enr: SignableENR;
6
6
  peerId: PeerId;
7
7
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"generate-enr.d.ts","sourceRoot":"","sources":["../../src/enr/generate-enr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAO,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAOhD,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAa/C;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,iBAQrD"}
1
+ {"version":3,"file":"generate-enr.d.ts","sourceRoot":"","sources":["../../src/enr/generate-enr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAO,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAOhD,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,gBAAgB,EAAE,MAAM,EACxB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAa/C;AAED,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,iBAQrD"}
@@ -4,10 +4,10 @@ import { multiaddr } from '@multiformats/multiaddr';
4
4
  import { AZTEC_ENR_KEY } from '../types/index.js';
5
5
  import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey } from '../util.js';
6
6
  import { setAztecEnrKey } from '../versioning.js';
7
- export async function createBootnodeENRandPeerId(privateKey, p2pIp, p2pPort, l1ChainId) {
7
+ export async function createBootnodeENRandPeerId(privateKey, p2pIp, p2pBroadcastPort, l1ChainId) {
8
8
  const peerId = await createLibP2PPeerIdFromPrivateKey(privateKey);
9
9
  const enr = SignableENR.createFromPeerId(peerId);
10
- const publicAddr = multiaddr(convertToMultiaddr(p2pIp, p2pPort, 'udp'));
10
+ const publicAddr = multiaddr(convertToMultiaddr(p2pIp, p2pBroadcastPort, 'udp'));
11
11
  enr.setLocationMultiaddr(publicAddr);
12
12
  const config = {
13
13
  ...emptyChainConfig,
@@ -22,6 +22,7 @@ export declare class DiscV5Service extends EventEmitter implements PeerDiscovery
22
22
  private currentState;
23
23
  private bootstrapNodePeerIds;
24
24
  bootstrapNodeEnrs: ENR[];
25
+ private trustedPeerEnrs;
25
26
  private startTime;
26
27
  private handlers;
27
28
  constructor(peerId: PeerId, config: P2PConfig, telemetry?: TelemetryClient, logger?: import("@aztec/foundation/log").Logger, configOverrides?: Partial<IDiscv5CreateOptions>);
@@ -1 +1 @@
1
- {"version":3,"file":"discV5_service.d.ts","sourceRoot":"","sources":["../../../src/services/discv5/discV5_service.ts"],"names":[],"mappings":";AAGA,OAAO,EAAsB,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAEvG,OAAO,EAAmC,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,GAAG,EAAe,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,OAAO,EAAE,KAAK,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAI9E;;GAEG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,oBAAoB;IAwB3E,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IA1BhB,0BAA0B;IAC1B,OAAO,CAAC,MAAM,CAA8B;IAE5C,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAc;IAEzB,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAqB;IAErC,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,oBAAoB,CAAgB;IACrC,iBAAiB,EAAE,GAAG,EAAE,CAAM;IAErC,OAAO,CAAC,SAAS,CAAK;IAEtB,OAAO,CAAC,QAAQ,CAId;gBAGQ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACzB,SAAS,GAAE,eAAsC,EACzC,MAAM,yCAAqC,EACnD,eAAe,GAAE,OAAO,CAAC,oBAAoB,CAAM;IA+DrD,OAAO,CAAC,kBAAkB;IAOb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2CtB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB1C,WAAW,IAAI,GAAG,EAAE;IAIpB,MAAM,IAAI,GAAG;IAIb,SAAS,IAAI,MAAM;IAInB,SAAS,IAAI,kBAAkB;IAI/B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAUpB,UAAU;IAOxB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,WAAW;CA0BpB"}
1
+ {"version":3,"file":"discV5_service.d.ts","sourceRoot":"","sources":["../../../src/services/discv5/discV5_service.ts"],"names":[],"mappings":";AAGA,OAAO,EAAsB,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAEvG,OAAO,EAAmC,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,GAAG,EAAe,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,OAAO,EAAE,KAAK,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAI9E;;GAEG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,oBAAoB;IAyB3E,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IA3BhB,0BAA0B;IAC1B,OAAO,CAAC,MAAM,CAA8B;IAE5C,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAc;IAEzB,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAqB;IAErC,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,oBAAoB,CAAgB;IACrC,iBAAiB,EAAE,GAAG,EAAE,CAAM;IACrC,OAAO,CAAC,eAAe,CAAa;IAEpC,OAAO,CAAC,SAAS,CAAK;IAEtB,OAAO,CAAC,QAAQ,CAId;gBAGQ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACzB,SAAS,GAAE,eAAsC,EACzC,MAAM,yCAAqC,EACnD,eAAe,GAAE,OAAO,CAAC,oBAAoB,CAAM;IAyErD,OAAO,CAAC,kBAAkB;IAQb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuDtB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB1C,WAAW,IAAI,GAAG,EAAE;IAIpB,MAAM,IAAI,GAAG;IAIb,SAAS,IAAI,MAAM;IAInB,SAAS,IAAI,kBAAkB;IAI/B,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAUpB,UAAU;IAOxB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,WAAW;CA0BpB"}
@@ -23,27 +23,33 @@ const delayBeforeStart = 2000; // 2sec
23
23
  currentState;
24
24
  bootstrapNodePeerIds;
25
25
  bootstrapNodeEnrs;
26
+ trustedPeerEnrs;
26
27
  startTime;
27
28
  handlers;
28
29
  constructor(peerId, config, telemetry = getTelemetryClient(), logger = createLogger('p2p:discv5_service'), configOverrides = {}){
29
- super(), this.peerId = peerId, this.config = config, this.logger = logger, this.currentState = PeerDiscoveryState.STOPPED, this.bootstrapNodePeerIds = [], this.bootstrapNodeEnrs = [], this.startTime = 0, this.handlers = {
30
+ super(), this.peerId = peerId, this.config = config, this.logger = logger, this.currentState = PeerDiscoveryState.STOPPED, this.bootstrapNodePeerIds = [], this.bootstrapNodeEnrs = [], this.trustedPeerEnrs = [], this.startTime = 0, this.handlers = {
30
31
  onMultiaddrUpdated: this.onMultiaddrUpdated.bind(this),
31
32
  onDiscovered: this.onDiscovered.bind(this),
32
33
  onEnrAdded: this.onEnrAdded.bind(this)
33
34
  };
34
- const { p2pIp, p2pPort, bootstrapNodes } = config;
35
+ const { p2pIp, p2pPort, p2pBroadcastPort, bootstrapNodes, trustedPeers, privatePeers } = config;
35
36
  this.bootstrapNodeEnrs = bootstrapNodes.map((x)=>ENR.decodeTxt(x));
37
+ const privatePeerEnrs = new Set(privatePeers);
38
+ this.trustedPeerEnrs = trustedPeers.filter((x)=>!privatePeerEnrs.has(x)).map((x)=>ENR.decodeTxt(x));
36
39
  // create ENR from PeerId
37
40
  this.enr = SignableENR.createFromPeerId(peerId);
38
41
  // Add aztec identification to ENR
39
42
  this.versions = setAztecEnrKey(this.enr, config);
43
+ // If no overridden broadcast port is provided, use the p2p port as the broadcast port
44
+ if (!p2pBroadcastPort) {
45
+ config.p2pBroadcastPort = p2pPort;
46
+ }
40
47
  const bindAddrs = {
41
48
  ip4: multiaddr(convertToMultiaddr(config.listenAddress, p2pPort, 'udp'))
42
49
  };
43
50
  if (p2pIp) {
44
- const multiAddrTcp = multiaddr(`${convertToMultiaddr(p2pIp, p2pPort, 'tcp')}/p2p/${peerId.toString()}`);
45
- // if no udp announce address is provided, use the tcp announce address
46
- const multiAddrUdp = multiaddr(`${convertToMultiaddr(p2pIp, p2pPort, 'udp')}/p2p/${peerId.toString()}`);
51
+ const multiAddrTcp = multiaddr(`${convertToMultiaddr(p2pIp, config.p2pBroadcastPort, 'tcp')}/p2p/${peerId.toString()}`);
52
+ const multiAddrUdp = multiaddr(`${convertToMultiaddr(p2pIp, config.p2pBroadcastPort, 'udp')}/p2p/${peerId.toString()}`);
47
53
  // set location multiaddr in ENR record
48
54
  this.enr.setLocationMultiaddr(multiAddrUdp);
49
55
  this.enr.setLocationMultiaddr(multiAddrTcp);
@@ -86,7 +92,8 @@ const delayBeforeStart = 2000; // 2sec
86
92
  }
87
93
  onMultiaddrUpdated(m) {
88
94
  // We want to update our tcp port to match the udp port
89
- const multiAddrTcp = multiaddr(convertToMultiaddr(m.nodeAddress().address, this.config.p2pPort, 'tcp'));
95
+ // p2pBroadcastPort is optional on config, however it is set to default within the p2p client factory
96
+ const multiAddrTcp = multiaddr(convertToMultiaddr(m.nodeAddress().address, this.config.p2pBroadcastPort, 'tcp'));
90
97
  this.enr.setLocationMultiaddr(multiAddrTcp);
91
98
  this.logger.info('Multiaddr updated', {
92
99
  multiaddr: multiAddrTcp.toString()
@@ -127,6 +134,13 @@ const delayBeforeStart = 2000; // 2sec
127
134
  }
128
135
  }
129
136
  }
137
+ // Add trusted peer ENRs if provided
138
+ if (this.trustedPeerEnrs?.length) {
139
+ this.logger.info(`Adding ${this.trustedPeerEnrs.length} trusted peer ENRs: ${this.trustedPeerEnrs.map((enr)=>enr.encodeTxt()).join(', ')}`);
140
+ for (const enr of this.trustedPeerEnrs){
141
+ this.discv5.addEnr(enr);
142
+ }
143
+ }
130
144
  }
131
145
  async runRandomNodesQuery() {
132
146
  if (this.currentState !== PeerDiscoveryState.RUNNING) {
@@ -217,7 +217,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
217
217
  const announceTcpMultiaddr = convertToMultiaddr(p2pIp, p2pPort, 'tcp');
218
218
  // Start job queue, peer discovery service and libp2p node
219
219
  this.jobQueue.start();
220
- await this.peerManager.initializeTrustedPeers();
220
+ await this.peerManager.initializePeers();
221
221
  await this.peerDiscoveryService.start();
222
222
  await this.node.start();
223
223
  // Subscribe to standard GossipSub topics by default
@@ -21,6 +21,8 @@ export declare class PeerManager {
21
21
  private timedOutPeers;
22
22
  private trustedPeers;
23
23
  private trustedPeersInitialized;
24
+ private privatePeers;
25
+ private privatePeersInitialized;
24
26
  private metrics;
25
27
  private handlers;
26
28
  constructor(libP2PNode: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, config: P2PConfig, telemetryClient: TelemetryClient, logger: import("@aztec/foundation/log").Logger, peerScoring: PeerScoring, reqresp: ReqResp);
@@ -29,7 +31,7 @@ export declare class PeerManager {
29
31
  *
30
32
  * This function is called when the peer manager is initialized.
31
33
  */
32
- initializeTrustedPeers(): Promise<void>;
34
+ initializePeers(): Promise<void>;
33
35
  get tracer(): import("@aztec/telemetry-client").Tracer;
34
36
  heartbeat(): void;
35
37
  /**
@@ -62,6 +64,23 @@ export declare class PeerManager {
62
64
  * @param peerId - The peer ID to add to trusted peers.
63
65
  */
64
66
  addTrustedPeer(peerId: PeerId): void;
67
+ /**
68
+ * Adds a peer to the private peers set.
69
+ * @param peerId - The peer ID to add to private peers.
70
+ */
71
+ addPrivatePeer(peerId: PeerId): void;
72
+ /**
73
+ * Checks if a peer is private.
74
+ * @param peerId - The peer ID.
75
+ * @returns True if the peer is private, false otherwise.
76
+ */
77
+ private isPrivatePeer;
78
+ /**
79
+ * Checks if a peer is protected (either trusted or private).
80
+ * @param peerId - The peer ID.
81
+ * @returns True if the peer is protected, false otherwise.
82
+ */
83
+ private isProtectedPeer;
65
84
  /**
66
85
  * Handles a goodbye received from a peer.
67
86
  *
@@ -77,7 +96,7 @@ export declare class PeerManager {
77
96
  * Discovers peers.
78
97
  */
79
98
  private discover;
80
- private onlyNotTrustedPeers;
99
+ private getNonProtectedPeers;
81
100
  private pruneUnhealthyPeers;
82
101
  /**
83
102
  * If the max peer count is reached, the lowest scoring peers will be pruned to satisfy the max peer count.
@@ -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;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,CAId;gBAGQ,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"}
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;IAkBpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IAvBjB,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;IACjD,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAId;gBAGQ,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,eAAe;IA8BrB,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;IAQ3C;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAU3C;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAQrB;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;;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;IAkEhB,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,mBAAmB;IAoB3B;;;;;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"}
@@ -30,6 +30,8 @@ export class PeerManager {
30
30
  timedOutPeers;
31
31
  trustedPeers;
32
32
  trustedPeersInitialized;
33
+ privatePeers;
34
+ privatePeersInitialized;
33
35
  metrics;
34
36
  handlers;
35
37
  constructor(libP2PNode, peerDiscoveryService, config, telemetryClient, logger = createLogger('p2p:peer-manager'), peerScoring, reqresp){
@@ -45,6 +47,8 @@ export class PeerManager {
45
47
  this.timedOutPeers = new Map();
46
48
  this.trustedPeers = new Set();
47
49
  this.trustedPeersInitialized = false;
50
+ this.privatePeers = new Set();
51
+ this.privatePeersInitialized = false;
48
52
  this.metrics = new PeerManagerMetrics(telemetryClient, 'PeerManager');
49
53
  // Handle Discovered peers
50
54
  this.handlers = {
@@ -65,11 +69,25 @@ export class PeerManager {
65
69
  * Initializes the trusted peers.
66
70
  *
67
71
  * This function is called when the peer manager is initialized.
68
- */ async initializeTrustedPeers() {
69
- const trustedPeersEnrs = this.config.trustedPeers.map((enr)=>ENR.decodeTxt(enr));
70
- await Promise.all(trustedPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.trustedPeers.add(peerId))).finally(()=>{
71
- this.trustedPeersInitialized = true;
72
- }).catch((e)=>this.logger.error('Error initializing trusted peers', e));
72
+ */ async initializePeers() {
73
+ if (this.config.trustedPeers) {
74
+ const trustedPeersEnrs = this.config.trustedPeers.map((enr)=>ENR.decodeTxt(enr));
75
+ await Promise.all(trustedPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.trustedPeers.add(peerId.toString()))).finally(()=>{
76
+ this.trustedPeersInitialized = true;
77
+ }).catch((e)=>this.logger.error('Error initializing trusted peers', e));
78
+ }
79
+ if (this.config.privatePeers) {
80
+ const privatePeersEnrs = this.config.privatePeers.map((enr)=>ENR.decodeTxt(enr));
81
+ await Promise.all(privatePeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>{
82
+ this.trustedPeers.add(peerId.toString());
83
+ this.privatePeers.add(peerId.toString());
84
+ })).finally(()=>{
85
+ if (!this.config.trustedPeers) {
86
+ this.trustedPeersInitialized = true;
87
+ }
88
+ this.privatePeersInitialized = true;
89
+ }).catch((e)=>this.logger.error('Error initializing private peers', e));
90
+ }
73
91
  }
74
92
  get tracer() {
75
93
  return this.metrics.tracer;
@@ -127,15 +145,45 @@ export class PeerManager {
127
145
  this.logger.warn('Trusted peers not initialized, returning false');
128
146
  return false;
129
147
  }
130
- return this.trustedPeers.has(peerId);
148
+ return this.trustedPeers.has(peerId.toString());
131
149
  }
132
150
  /**
133
151
  * Adds a peer to the trusted peers set.
134
152
  * @param peerId - The peer ID to add to trusted peers.
135
153
  */ addTrustedPeer(peerId) {
136
- this.trustedPeers.add(peerId);
154
+ const peerIdStr = peerId.toString();
155
+ this.trustedPeers.add(peerIdStr);
156
+ this.trustedPeersInitialized = true;
157
+ this.logger.verbose(`Added trusted peer ${peerIdStr}`);
158
+ }
159
+ /**
160
+ * Adds a peer to the private peers set.
161
+ * @param peerId - The peer ID to add to private peers.
162
+ */ addPrivatePeer(peerId) {
163
+ const peerIdStr = peerId.toString();
164
+ this.trustedPeers.add(peerIdStr);
165
+ this.privatePeers.add(peerIdStr);
137
166
  this.trustedPeersInitialized = true;
138
- this.logger.verbose(`Added trusted peer ${peerId.toString()}`);
167
+ this.privatePeersInitialized = true;
168
+ this.logger.verbose(`Added private peer ${peerIdStr}`);
169
+ }
170
+ /**
171
+ * Checks if a peer is private.
172
+ * @param peerId - The peer ID.
173
+ * @returns True if the peer is private, false otherwise.
174
+ */ isPrivatePeer(peerId) {
175
+ if (!this.privatePeersInitialized) {
176
+ this.logger.warn('Private peers not initialized, returning false');
177
+ return false;
178
+ }
179
+ return this.privatePeers.has(peerId.toString());
180
+ }
181
+ /**
182
+ * Checks if a peer is protected (either trusted or private).
183
+ * @param peerId - The peer ID.
184
+ * @returns True if the peer is protected, false otherwise.
185
+ */ isProtectedPeer(peerId) {
186
+ return this.isTrustedPeer(peerId) || this.isPrivatePeer(peerId);
139
187
  }
140
188
  /**
141
189
  * Handles a goodbye received from a peer.
@@ -188,12 +236,13 @@ export class PeerManager {
188
236
  * Discovers peers.
189
237
  */ discover() {
190
238
  const connections = this.libP2PNode.getConnections();
191
- const healthyConnections = this.prioritizePeers(this.onlyNotTrustedPeers(this.pruneUnhealthyPeers(this.pruneDuplicatePeers(connections))));
239
+ const healthyConnections = this.prioritizePeers(this.pruneUnhealthyPeers(this.getNonProtectedPeers(this.pruneDuplicatePeers(connections))));
192
240
  // Calculate how many connections we're looking to make
193
241
  const peersToConnect = this.config.maxPeerCount - healthyConnections.length - this.trustedPeers.size;
194
242
  const logLevel = this.heartbeatCounter % this.displayPeerCountsPeerHeartbeat === 0 ? 'info' : 'debug';
195
- this.logger[logLevel](`Connected to ${healthyConnections.length} peers`, {
196
- connections: healthyConnections.length,
243
+ this.logger[logLevel](`Connected to ${healthyConnections.length + this.trustedPeers.size} peers`, {
244
+ discoveredConnections: healthyConnections.length,
245
+ protectedConnections: this.trustedPeers.size,
197
246
  maxPeerCount: this.config.maxPeerCount,
198
247
  cachedPeers: this.cachedPeers.size,
199
248
  ...this.peerScoring.getStats()
@@ -228,16 +277,12 @@ export class PeerManager {
228
277
  void this.peerDiscoveryService.runRandomNodesQuery();
229
278
  }
230
279
  }
231
- onlyNotTrustedPeers(connections) {
232
- return connections.filter((conn)=>!this.isTrustedPeer(conn.remotePeer));
280
+ getNonProtectedPeers(connections) {
281
+ return connections.filter((conn)=>!this.isProtectedPeer(conn.remotePeer));
233
282
  }
234
283
  pruneUnhealthyPeers(connections) {
235
284
  const connectedHealthyPeers = [];
236
285
  for (const peer of connections){
237
- if (this.isTrustedPeer(peer.remotePeer)) {
238
- this.logger.debug(`Not pruning trusted peer ${peer.remotePeer.toString()}`);
239
- continue;
240
- }
241
286
  const score = this.peerScoring.getScoreState(peer.remotePeer.toString());
242
287
  switch(score){
243
288
  case PeerScoreState.Banned:
@@ -434,7 +479,7 @@ export class PeerManager {
434
479
  }
435
480
  // Remove the oldest peers
436
481
  for (const [key, value] of this.cachedPeers.entries()){
437
- if (this.isTrustedPeer(value.peerId)) {
482
+ if (this.isProtectedPeer(value.peerId)) {
438
483
  this.logger.debug(`Not pruning trusted peer ${key}`);
439
484
  continue;
440
485
  }
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAuB,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,QAAQ,EAAE;QACR,MAAM,EAAE,SAAS,CAAC;QAClB,UAAU,EAAE;YACV,iBAAiB,EAAE,iBAAiB,CAAC;SACtC,CAAC;KACH,CAAC;CACH;AAED;;;;;;;6CAO6C;AAC7C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAOjG;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAInD;AAED,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9F;AAcD,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,SAAS,GAAG,eAAe,GACnC,OAAO,CAAC,SAAS,GAAG,eAAe,CAAC,CActC;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5F,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CA2DjB;AAED;;;;GAIG;AACH,wBAAsB,gCAAgC,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS1F"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAuB,MAAM,iBAAiB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAIpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGrC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,QAAQ,EAAE;QACR,MAAM,EAAE,SAAS,CAAC;QAClB,UAAU,EAAE;YACV,iBAAiB,EAAE,iBAAiB,CAAC;SACtC,CAAC;KACH,CAAC;CACH;AAED;;;;;;;6CAO6C;AAC7C,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAOjG;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAInD;AAED,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9F;AAcD,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,SAAS,GAAG,eAAe,GACnC,OAAO,CAAC,SAAS,GAAG,eAAe,CAAC,CAmBtC;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE;IAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5F,KAAK,EAAE,iBAAiB,EACxB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CA2DjB;AAED;;;;GAIG;AACH,wBAAsB,gCAAgC,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS1F"}
package/dest/util.js CHANGED
@@ -52,7 +52,11 @@ export async function configureP2PClientAddresses(_config) {
52
52
  const config = {
53
53
  ..._config
54
54
  };
55
- const { p2pIp, queryForIp } = config;
55
+ const { p2pIp, queryForIp, p2pBroadcastPort, p2pPort } = config;
56
+ // If no broadcast port is provided, use the given p2p port as the broadcast port
57
+ if (!p2pBroadcastPort) {
58
+ config.p2pBroadcastPort = p2pPort;
59
+ }
56
60
  // check if no announce IP was provided
57
61
  if (!p2pIp) {
58
62
  if (queryForIp) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.85.0-alpha-testnet.2",
3
+ "version": "0.85.0-nightly.20250417",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -22,8 +22,6 @@
22
22
  "build": "yarn clean && tsc -b",
23
23
  "build:dev": "tsc -b --watch",
24
24
  "clean": "rm -rf ./dest .tsbuildinfo",
25
- "formatting": "run -T prettier --check ./src && run -T eslint ./src",
26
- "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
27
25
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}",
28
26
  "start": "node ./dest",
29
27
  "start:dev": "tsc-watch -p tsconfig.json --onSuccess 'yarn start'"
@@ -65,16 +63,16 @@
65
63
  ]
66
64
  },
67
65
  "dependencies": {
68
- "@aztec/constants": "0.85.0-alpha-testnet.2",
69
- "@aztec/epoch-cache": "0.85.0-alpha-testnet.2",
70
- "@aztec/foundation": "0.85.0-alpha-testnet.2",
71
- "@aztec/kv-store": "0.85.0-alpha-testnet.2",
72
- "@aztec/noir-contracts.js": "0.85.0-alpha-testnet.2",
73
- "@aztec/noir-protocol-circuits-types": "0.85.0-alpha-testnet.2",
74
- "@aztec/protocol-contracts": "0.85.0-alpha-testnet.2",
75
- "@aztec/simulator": "0.85.0-alpha-testnet.2",
76
- "@aztec/stdlib": "0.85.0-alpha-testnet.2",
77
- "@aztec/telemetry-client": "0.85.0-alpha-testnet.2",
66
+ "@aztec/constants": "0.85.0-nightly.20250417",
67
+ "@aztec/epoch-cache": "0.85.0-nightly.20250417",
68
+ "@aztec/foundation": "0.85.0-nightly.20250417",
69
+ "@aztec/kv-store": "0.85.0-nightly.20250417",
70
+ "@aztec/noir-contracts.js": "0.85.0-nightly.20250417",
71
+ "@aztec/noir-protocol-circuits-types": "0.85.0-nightly.20250417",
72
+ "@aztec/protocol-contracts": "0.85.0-nightly.20250417",
73
+ "@aztec/simulator": "0.85.0-nightly.20250417",
74
+ "@aztec/stdlib": "0.85.0-nightly.20250417",
75
+ "@aztec/telemetry-client": "0.85.0-nightly.20250417",
78
76
  "@chainsafe/discv5": "9.0.0",
79
77
  "@chainsafe/enr": "3.0.0",
80
78
  "@chainsafe/libp2p-gossipsub": "13.0.0",
@@ -103,7 +101,7 @@
103
101
  "xxhash-wasm": "^1.1.0"
104
102
  },
105
103
  "devDependencies": {
106
- "@aztec/archiver": "0.85.0-alpha-testnet.2",
104
+ "@aztec/archiver": "0.85.0-nightly.20250417",
107
105
  "@jest/globals": "^29.5.0",
108
106
  "@types/jest": "^29.5.0",
109
107
  "@types/node": "^18.14.6",
@@ -31,19 +31,23 @@ export class BootstrapNode implements P2PBootstrapApi {
31
31
  * @returns An empty promise.
32
32
  */
33
33
  public async start(config: BootnodeConfig) {
34
- const { p2pIp, p2pPort, listenAddress } = config;
35
- const listenAddrUdp = multiaddr(convertToMultiaddr(listenAddress, p2pPort, 'udp'));
36
-
34
+ const { p2pIp, p2pPort, listenAddress, p2pBroadcastPort } = config;
37
35
  if (!p2pIp) {
38
36
  throw new Error('You need to provide a P2P IP address.');
39
37
  }
40
38
 
39
+ if (!p2pBroadcastPort) {
40
+ config.p2pBroadcastPort = p2pPort;
41
+ }
42
+
43
+ const listenAddrUdp = multiaddr(convertToMultiaddr(listenAddress, config.p2pBroadcastPort!, 'udp'));
44
+
41
45
  const peerIdPrivateKey = await getPeerIdPrivateKey(config, this.store, this.logger);
42
46
 
43
47
  const { enr: ourEnr, peerId } = await createBootnodeENRandPeerId(
44
48
  peerIdPrivateKey,
45
49
  p2pIp,
46
- p2pPort,
50
+ config.p2pBroadcastPort!,
47
51
  config.l1ChainId,
48
52
  );
49
53
  this.peerId = peerId;
package/src/config.ts CHANGED
@@ -53,6 +53,11 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
53
53
  */
54
54
  p2pPort: number;
55
55
 
56
+ /**
57
+ * The port to broadcast the P2P service on (included in the node's ENR).
58
+ */
59
+ p2pBroadcastPort?: number;
60
+
56
61
  /**
57
62
  * The IP address for the P2P service.
58
63
  */
@@ -175,6 +180,11 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
175
180
  */
176
181
  trustedPeers: string[];
177
182
 
183
+ /**
184
+ * A list of private peers.
185
+ */
186
+ privatePeers: string[];
187
+
178
188
  /**
179
189
  * The maximum possible size of the P2P DB in KB. Overwrites the general dataStoreMapSizeKB.
180
190
  */
@@ -189,6 +199,8 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
189
199
  maxTxPoolSize: number;
190
200
  }
191
201
 
202
+ export const DEFAULT_P2P_PORT = 40400;
203
+
192
204
  export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
193
205
  p2pEnabled: {
194
206
  env: 'P2P_ENABLED',
@@ -222,8 +234,12 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
222
234
  },
223
235
  p2pPort: {
224
236
  env: 'P2P_PORT',
225
- description: 'The port for the P2P service.',
226
- ...numberConfigHelper(40400),
237
+ description: `The port for the P2P service. Defaults to ${DEFAULT_P2P_PORT}`,
238
+ ...numberConfigHelper(DEFAULT_P2P_PORT),
239
+ },
240
+ p2pBroadcastPort: {
241
+ env: 'P2P_BROADCAST_PORT',
242
+ description: `The port to broadcast the P2P service on (included in the node's ENR). Defaults to P2P_PORT.`,
227
243
  },
228
244
  p2pIp: {
229
245
  env: 'P2P_IP',
@@ -357,7 +373,14 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
357
373
  trustedPeers: {
358
374
  env: 'P2P_TRUSTED_PEERS',
359
375
  parseEnv: (val: string) => val.split(','),
360
- description: 'A list of trusted peers ENRs. Separated by commas.',
376
+ description: 'A list of trusted peer ENRs that will always be persisted. Separated by commas.',
377
+ defaultValue: [],
378
+ },
379
+ privatePeers: {
380
+ env: 'P2P_PRIVATE_PEERS',
381
+ parseEnv: (val: string) => val.split(','),
382
+ description:
383
+ 'A list of private peer ENRs that will always be persisted and not be used for discovery. Separated by commas.',
361
384
  defaultValue: [],
362
385
  },
363
386
  p2pStoreMapSizeKb: {
@@ -398,7 +421,13 @@ export function getP2PDefaultConfig(): P2PConfig {
398
421
  */
399
422
  export type BootnodeConfig = Pick<
400
423
  P2PConfig,
401
- 'p2pIp' | 'p2pPort' | 'peerIdPrivateKey' | 'peerIdPrivateKeyPath' | 'bootstrapNodes' | 'listenAddress'
424
+ | 'p2pIp'
425
+ | 'p2pPort'
426
+ | 'p2pBroadcastPort'
427
+ | 'peerIdPrivateKey'
428
+ | 'peerIdPrivateKeyPath'
429
+ | 'bootstrapNodes'
430
+ | 'listenAddress'
402
431
  > &
403
432
  Required<Pick<P2PConfig, 'p2pIp' | 'p2pPort'>> &
404
433
  Pick<DataStoreConfig, 'dataDirectory' | 'dataStoreMapSizeKB'> &
@@ -407,6 +436,7 @@ export type BootnodeConfig = Pick<
407
436
  const bootnodeConfigKeys: (keyof BootnodeConfig)[] = [
408
437
  'p2pIp',
409
438
  'p2pPort',
439
+ 'p2pBroadcastPort',
410
440
  'listenAddress',
411
441
  'peerIdPrivateKey',
412
442
  'peerIdPrivateKeyPath',
@@ -12,12 +12,12 @@ import { setAztecEnrKey } from '../versioning.js';
12
12
  export async function createBootnodeENRandPeerId(
13
13
  privateKey: string,
14
14
  p2pIp: string,
15
- p2pPort: number,
15
+ p2pBroadcastPort: number,
16
16
  l1ChainId: number,
17
17
  ): Promise<{ enr: SignableENR; peerId: PeerId }> {
18
18
  const peerId = await createLibP2PPeerIdFromPrivateKey(privateKey);
19
19
  const enr = SignableENR.createFromPeerId(peerId);
20
- const publicAddr = multiaddr(convertToMultiaddr(p2pIp, p2pPort, 'udp'));
20
+ const publicAddr = multiaddr(convertToMultiaddr(p2pIp, p2pBroadcastPort, 'udp'));
21
21
  enr.setLocationMultiaddr(publicAddr);
22
22
 
23
23
  const config: ChainConfig = {
@@ -34,6 +34,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
34
34
 
35
35
  private bootstrapNodePeerIds: PeerId[] = [];
36
36
  public bootstrapNodeEnrs: ENR[] = [];
37
+ private trustedPeerEnrs: ENR[] = [];
37
38
 
38
39
  private startTime = 0;
39
40
 
@@ -51,21 +52,31 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
51
52
  configOverrides: Partial<IDiscv5CreateOptions> = {},
52
53
  ) {
53
54
  super();
54
- const { p2pIp, p2pPort, bootstrapNodes } = config;
55
+ const { p2pIp, p2pPort, p2pBroadcastPort, bootstrapNodes, trustedPeers, privatePeers } = config;
55
56
  this.bootstrapNodeEnrs = bootstrapNodes.map(x => ENR.decodeTxt(x));
57
+ const privatePeerEnrs = new Set(privatePeers);
58
+ this.trustedPeerEnrs = trustedPeers.filter(x => !privatePeerEnrs.has(x)).map(x => ENR.decodeTxt(x));
56
59
  // create ENR from PeerId
57
60
  this.enr = SignableENR.createFromPeerId(peerId);
58
61
  // Add aztec identification to ENR
59
62
  this.versions = setAztecEnrKey(this.enr, config);
60
63
 
64
+ // If no overridden broadcast port is provided, use the p2p port as the broadcast port
65
+ if (!p2pBroadcastPort) {
66
+ config.p2pBroadcastPort = p2pPort;
67
+ }
68
+
61
69
  const bindAddrs: any = {
62
70
  ip4: multiaddr(convertToMultiaddr(config.listenAddress, p2pPort, 'udp')),
63
71
  };
64
72
 
65
73
  if (p2pIp) {
66
- const multiAddrTcp = multiaddr(`${convertToMultiaddr(p2pIp!, p2pPort, 'tcp')}/p2p/${peerId.toString()}`);
67
- // if no udp announce address is provided, use the tcp announce address
68
- const multiAddrUdp = multiaddr(`${convertToMultiaddr(p2pIp!, p2pPort, 'udp')}/p2p/${peerId.toString()}`);
74
+ const multiAddrTcp = multiaddr(
75
+ `${convertToMultiaddr(p2pIp!, config.p2pBroadcastPort!, 'tcp')}/p2p/${peerId.toString()}`,
76
+ );
77
+ const multiAddrUdp = multiaddr(
78
+ `${convertToMultiaddr(p2pIp!, config.p2pBroadcastPort!, 'udp')}/p2p/${peerId.toString()}`,
79
+ );
69
80
 
70
81
  // set location multiaddr in ENR record
71
82
  this.enr.setLocationMultiaddr(multiAddrUdp);
@@ -113,7 +124,8 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
113
124
 
114
125
  private onMultiaddrUpdated(m: Multiaddr) {
115
126
  // We want to update our tcp port to match the udp port
116
- const multiAddrTcp = multiaddr(convertToMultiaddr(m.nodeAddress().address, this.config.p2pPort, 'tcp'));
127
+ // p2pBroadcastPort is optional on config, however it is set to default within the p2p client factory
128
+ const multiAddrTcp = multiaddr(convertToMultiaddr(m.nodeAddress().address, this.config.p2pBroadcastPort!, 'tcp'));
117
129
  this.enr.setLocationMultiaddr(multiAddrTcp);
118
130
  this.logger.info('Multiaddr updated', { multiaddr: multiAddrTcp.toString() });
119
131
  }
@@ -159,6 +171,18 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
159
171
  }
160
172
  }
161
173
  }
174
+
175
+ // Add trusted peer ENRs if provided
176
+ if (this.trustedPeerEnrs?.length) {
177
+ this.logger.info(
178
+ `Adding ${this.trustedPeerEnrs.length} trusted peer ENRs: ${this.trustedPeerEnrs
179
+ .map(enr => enr.encodeTxt())
180
+ .join(', ')}`,
181
+ );
182
+ for (const enr of this.trustedPeerEnrs) {
183
+ this.discv5.addEnr(enr);
184
+ }
185
+ }
162
186
  }
163
187
 
164
188
  public async runRandomNodesQuery(): Promise<void> {
@@ -318,7 +318,7 @@ export class LibP2PService<T extends P2PClientType = P2PClientType.Full> extends
318
318
  // Start job queue, peer discovery service and libp2p node
319
319
  this.jobQueue.start();
320
320
 
321
- await this.peerManager.initializeTrustedPeers();
321
+ await this.peerManager.initializePeers();
322
322
  await this.peerDiscoveryService.start();
323
323
  await this.node.start();
324
324
 
@@ -41,8 +41,10 @@ export class PeerManager {
41
41
  private heartbeatCounter: number = 0;
42
42
  private displayPeerCountsPeerHeartbeat: number = 0;
43
43
  private timedOutPeers: Map<string, TimedOutPeer> = new Map();
44
- private trustedPeers: Set<PeerId> = new Set();
44
+ private trustedPeers: Set<string> = new Set();
45
45
  private trustedPeersInitialized: boolean = false;
46
+ private privatePeers: Set<string> = new Set();
47
+ private privatePeersInitialized: boolean = false;
46
48
 
47
49
  private metrics: PeerManagerMetrics;
48
50
  private handlers: {
@@ -87,14 +89,34 @@ export class PeerManager {
87
89
  *
88
90
  * This function is called when the peer manager is initialized.
89
91
  */
90
- async initializeTrustedPeers() {
91
- const trustedPeersEnrs: ENR[] = this.config.trustedPeers.map(enr => ENR.decodeTxt(enr));
92
- await Promise.all(trustedPeersEnrs.map(enr => enr.peerId()))
93
- .then(peerIds => peerIds.forEach(peerId => this.trustedPeers.add(peerId)))
94
- .finally(() => {
95
- this.trustedPeersInitialized = true;
96
- })
97
- .catch(e => this.logger.error('Error initializing trusted peers', e));
92
+ async initializePeers() {
93
+ if (this.config.trustedPeers) {
94
+ const trustedPeersEnrs: ENR[] = this.config.trustedPeers.map(enr => ENR.decodeTxt(enr));
95
+ await Promise.all(trustedPeersEnrs.map(enr => enr.peerId()))
96
+ .then(peerIds => peerIds.forEach(peerId => this.trustedPeers.add(peerId.toString())))
97
+ .finally(() => {
98
+ this.trustedPeersInitialized = true;
99
+ })
100
+ .catch(e => this.logger.error('Error initializing trusted peers', e));
101
+ }
102
+
103
+ if (this.config.privatePeers) {
104
+ const privatePeersEnrs: ENR[] = this.config.privatePeers.map(enr => ENR.decodeTxt(enr));
105
+ await Promise.all(privatePeersEnrs.map(enr => enr.peerId()))
106
+ .then(peerIds =>
107
+ peerIds.forEach(peerId => {
108
+ this.trustedPeers.add(peerId.toString());
109
+ this.privatePeers.add(peerId.toString());
110
+ }),
111
+ )
112
+ .finally(() => {
113
+ if (!this.config.trustedPeers) {
114
+ this.trustedPeersInitialized = true;
115
+ }
116
+ this.privatePeersInitialized = true;
117
+ })
118
+ .catch(e => this.logger.error('Error initializing private peers', e));
119
+ }
98
120
  }
99
121
 
100
122
  get tracer() {
@@ -165,7 +187,7 @@ export class PeerManager {
165
187
  this.logger.warn('Trusted peers not initialized, returning false');
166
188
  return false;
167
189
  }
168
- return this.trustedPeers.has(peerId);
190
+ return this.trustedPeers.has(peerId.toString());
169
191
  }
170
192
 
171
193
  /**
@@ -173,9 +195,47 @@ export class PeerManager {
173
195
  * @param peerId - The peer ID to add to trusted peers.
174
196
  */
175
197
  public addTrustedPeer(peerId: PeerId): void {
176
- this.trustedPeers.add(peerId);
198
+ const peerIdStr = peerId.toString();
199
+
200
+ this.trustedPeers.add(peerIdStr);
201
+ this.trustedPeersInitialized = true;
202
+ this.logger.verbose(`Added trusted peer ${peerIdStr}`);
203
+ }
204
+
205
+ /**
206
+ * Adds a peer to the private peers set.
207
+ * @param peerId - The peer ID to add to private peers.
208
+ */
209
+ public addPrivatePeer(peerId: PeerId): void {
210
+ const peerIdStr = peerId.toString();
211
+
212
+ this.trustedPeers.add(peerIdStr);
213
+ this.privatePeers.add(peerIdStr);
177
214
  this.trustedPeersInitialized = true;
178
- this.logger.verbose(`Added trusted peer ${peerId.toString()}`);
215
+ this.privatePeersInitialized = true;
216
+ this.logger.verbose(`Added private peer ${peerIdStr}`);
217
+ }
218
+
219
+ /**
220
+ * Checks if a peer is private.
221
+ * @param peerId - The peer ID.
222
+ * @returns True if the peer is private, false otherwise.
223
+ */
224
+ private isPrivatePeer(peerId: PeerId): boolean {
225
+ if (!this.privatePeersInitialized) {
226
+ this.logger.warn('Private peers not initialized, returning false');
227
+ return false;
228
+ }
229
+ return this.privatePeers.has(peerId.toString());
230
+ }
231
+
232
+ /**
233
+ * Checks if a peer is protected (either trusted or private).
234
+ * @param peerId - The peer ID.
235
+ * @returns True if the peer is protected, false otherwise.
236
+ */
237
+ private isProtectedPeer(peerId: PeerId): boolean {
238
+ return this.isTrustedPeer(peerId) || this.isPrivatePeer(peerId);
179
239
  }
180
240
 
181
241
  /**
@@ -241,15 +301,16 @@ export class PeerManager {
241
301
  const connections = this.libP2PNode.getConnections();
242
302
 
243
303
  const healthyConnections = this.prioritizePeers(
244
- this.onlyNotTrustedPeers(this.pruneUnhealthyPeers(this.pruneDuplicatePeers(connections))),
304
+ this.pruneUnhealthyPeers(this.getNonProtectedPeers(this.pruneDuplicatePeers(connections))),
245
305
  );
246
306
 
247
307
  // Calculate how many connections we're looking to make
248
308
  const peersToConnect = this.config.maxPeerCount - healthyConnections.length - this.trustedPeers.size;
249
309
 
250
310
  const logLevel = this.heartbeatCounter % this.displayPeerCountsPeerHeartbeat === 0 ? 'info' : 'debug';
251
- this.logger[logLevel](`Connected to ${healthyConnections.length} peers`, {
252
- connections: healthyConnections.length,
311
+ this.logger[logLevel](`Connected to ${healthyConnections.length + this.trustedPeers.size} peers`, {
312
+ discoveredConnections: healthyConnections.length,
313
+ protectedConnections: this.trustedPeers.size,
253
314
  maxPeerCount: this.config.maxPeerCount,
254
315
  cachedPeers: this.cachedPeers.size,
255
316
  ...this.peerScoring.getStats(),
@@ -302,18 +363,14 @@ export class PeerManager {
302
363
  }
303
364
  }
304
365
 
305
- private onlyNotTrustedPeers(connections: Connection[]): Connection[] {
306
- return connections.filter(conn => !this.isTrustedPeer(conn.remotePeer));
366
+ private getNonProtectedPeers(connections: Connection[]): Connection[] {
367
+ return connections.filter(conn => !this.isProtectedPeer(conn.remotePeer));
307
368
  }
308
369
 
309
370
  private pruneUnhealthyPeers(connections: Connection[]): Connection[] {
310
371
  const connectedHealthyPeers: Connection[] = [];
311
372
 
312
373
  for (const peer of connections) {
313
- if (this.isTrustedPeer(peer.remotePeer)) {
314
- this.logger.debug(`Not pruning trusted peer ${peer.remotePeer.toString()}`);
315
- continue;
316
- }
317
374
  const score = this.peerScoring.getScoreState(peer.remotePeer.toString());
318
375
  switch (score) {
319
376
  case PeerScoreState.Banned:
@@ -526,7 +583,7 @@ export class PeerManager {
526
583
 
527
584
  // Remove the oldest peers
528
585
  for (const [key, value] of this.cachedPeers.entries()) {
529
- if (this.isTrustedPeer(value.peerId)) {
586
+ if (this.isProtectedPeer(value.peerId)) {
530
587
  this.logger.debug(`Not pruning trusted peer ${key}`);
531
588
  continue;
532
589
  }
package/src/util.ts CHANGED
@@ -80,7 +80,12 @@ export async function configureP2PClientAddresses(
80
80
  _config: P2PConfig & DataStoreConfig,
81
81
  ): Promise<P2PConfig & DataStoreConfig> {
82
82
  const config = { ..._config };
83
- const { p2pIp, queryForIp } = config;
83
+ const { p2pIp, queryForIp, p2pBroadcastPort, p2pPort } = config;
84
+
85
+ // If no broadcast port is provided, use the given p2p port as the broadcast port
86
+ if (!p2pBroadcastPort) {
87
+ config.p2pBroadcastPort = p2pPort;
88
+ }
84
89
 
85
90
  // check if no announce IP was provided
86
91
  if (!p2pIp) {