@aztec/p2p 0.65.2 → 0.66.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 (57) hide show
  1. package/dest/bootstrap/bootstrap.d.ts +3 -1
  2. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  3. package/dest/bootstrap/bootstrap.js +7 -6
  4. package/dest/client/index.d.ts.map +1 -1
  5. package/dest/client/index.js +5 -4
  6. package/dest/client/p2p_client.d.ts +2 -0
  7. package/dest/client/p2p_client.d.ts.map +1 -1
  8. package/dest/client/p2p_client.js +10 -2
  9. package/dest/config.d.ts +40 -2
  10. package/dest/config.d.ts.map +1 -1
  11. package/dest/config.js +10 -2
  12. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +8 -0
  13. package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
  14. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +1 -0
  15. package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
  16. package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +20 -1
  17. package/dest/mem_pools/instrumentation.d.ts +2 -7
  18. package/dest/mem_pools/instrumentation.d.ts.map +1 -1
  19. package/dest/mem_pools/instrumentation.js +3 -6
  20. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
  21. package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +2 -4
  22. package/dest/mocks/index.d.ts.map +1 -1
  23. package/dest/mocks/index.js +12 -6
  24. package/dest/service/encoding.d.ts +26 -0
  25. package/dest/service/encoding.d.ts.map +1 -0
  26. package/dest/service/encoding.js +49 -0
  27. package/dest/service/libp2p_service.d.ts +0 -6
  28. package/dest/service/libp2p_service.d.ts.map +1 -1
  29. package/dest/service/libp2p_service.js +10 -21
  30. package/dest/service/reqresp/handlers.d.ts +4 -2
  31. package/dest/service/reqresp/handlers.d.ts.map +1 -1
  32. package/dest/service/reqresp/handlers.js +3 -3
  33. package/dest/service/reqresp/interface.d.ts +1 -1
  34. package/dest/service/reqresp/interface.d.ts.map +1 -1
  35. package/dest/service/reqresp/interface.js +2 -2
  36. package/dest/service/reqresp/reqresp.d.ts +3 -0
  37. package/dest/service/reqresp/reqresp.d.ts.map +1 -1
  38. package/dest/service/reqresp/reqresp.js +8 -3
  39. package/dest/util.d.ts +20 -2
  40. package/dest/util.d.ts.map +1 -1
  41. package/dest/util.js +39 -3
  42. package/package.json +10 -8
  43. package/src/bootstrap/bootstrap.ts +11 -5
  44. package/src/client/index.ts +4 -3
  45. package/src/client/p2p_client.ts +15 -1
  46. package/src/config.ts +17 -2
  47. package/src/mem_pools/attestation_pool/attestation_pool.ts +9 -0
  48. package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +21 -0
  49. package/src/mem_pools/instrumentation.ts +3 -5
  50. package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +1 -3
  51. package/src/mocks/index.ts +11 -5
  52. package/src/service/encoding.ts +61 -0
  53. package/src/service/libp2p_service.ts +10 -22
  54. package/src/service/reqresp/handlers.ts +4 -4
  55. package/src/service/reqresp/interface.ts +3 -3
  56. package/src/service/reqresp/reqresp.ts +7 -2
  57. package/src/util.ts +48 -2
@@ -30,7 +30,6 @@ import { identify } from '@libp2p/identify';
30
30
  import type { PeerId } from '@libp2p/interface';
31
31
  import '@libp2p/kad-dht';
32
32
  import { mplex } from '@libp2p/mplex';
33
- import { createFromJSON, createSecp256k1PeerId } from '@libp2p/peer-id-factory';
34
33
  import { tcp } from '@libp2p/tcp';
35
34
  import { createLibp2p } from 'libp2p';
36
35
 
@@ -44,6 +43,7 @@ import {
44
43
  } from '../tx_validator/index.js';
45
44
  import { type PubSubLibp2p, convertToMultiaddr } from '../util.js';
46
45
  import { AztecDatastore } from './data_store.js';
46
+ import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from './encoding.js';
47
47
  import { PeerManager } from './peer_manager.js';
48
48
  import { PeerErrorSeverity } from './peer_scoring.js';
49
49
  import { pingHandler, statusHandler } from './reqresp/handlers.js';
@@ -60,22 +60,6 @@ import {
60
60
  import { ReqResp } from './reqresp/reqresp.js';
61
61
  import type { P2PService, PeerDiscoveryService } from './service.js';
62
62
 
63
- /**
64
- * Create a libp2p peer ID from the private key if provided, otherwise creates a new random ID.
65
- * @param privateKey - Optional peer ID private key as hex string
66
- * @returns The peer ID.
67
- */
68
- export async function createLibP2PPeerId(privateKey?: string): Promise<PeerId> {
69
- if (!privateKey?.length) {
70
- return await createSecp256k1PeerId();
71
- }
72
- const base64 = Buffer.from(privateKey, 'hex').toString('base64');
73
- return await createFromJSON({
74
- id: '',
75
- privKey: base64,
76
- });
77
- }
78
-
79
63
  /**
80
64
  * Lib P2P implementation of the P2PService interface.
81
65
  */
@@ -156,7 +140,7 @@ export class LibP2PService extends WithTracer implements P2PService {
156
140
  // add GossipSub listener
157
141
  this.node.services.pubsub.addEventListener('gossipsub:message', async e => {
158
142
  const { msg, propagationSource: peerId } = e.detail;
159
- this.logger.debug(`Received PUBSUB message.`);
143
+ this.logger.trace(`Received PUBSUB message.`);
160
144
 
161
145
  await this.jobQueue.put(() => this.handleNewGossipMessage(msg, peerId));
162
146
  });
@@ -259,6 +243,10 @@ export class LibP2PService extends WithTracer implements P2PService {
259
243
  heartbeatInterval: config.gossipsubInterval,
260
244
  mcacheLength: config.gossipsubMcacheLength,
261
245
  mcacheGossip: config.gossipsubMcacheGossip,
246
+ msgIdFn: getMsgIdFn,
247
+ msgIdToStrFn: msgIdToStrFn,
248
+ fastMsgIdFn: fastMsgIdFn,
249
+ dataTransform: new SnappyTransform(),
262
250
  metricsRegister: otelMetricsAdapter,
263
251
  metricsTopicStrToLabel: metricsTopicStrToLabels(),
264
252
  scoreParams: createPeerScoreParams({
@@ -295,11 +283,11 @@ export class LibP2PService extends WithTracer implements P2PService {
295
283
  * @param msg - the tx request message
296
284
  * @returns the tx response message
297
285
  */
298
- const txHandler = (msg: Buffer): Promise<Uint8Array> => {
286
+ const txHandler = (msg: Buffer): Promise<Buffer> => {
299
287
  const txHash = TxHash.fromBuffer(msg);
300
288
  const foundTx = mempools.txPool.getTxByHash(txHash);
301
- const asUint8Array = Uint8Array.from(foundTx ? foundTx.toBuffer() : Buffer.alloc(0));
302
- return Promise.resolve(asUint8Array);
289
+ const buf = foundTx ? foundTx.toBuffer() : Buffer.alloc(0);
290
+ return Promise.resolve(buf);
303
291
  };
304
292
 
305
293
  const requestResponseHandlers = {
@@ -468,7 +456,7 @@ export class LibP2PService extends WithTracer implements P2PService {
468
456
  * @param message - The message to propagate.
469
457
  */
470
458
  public propagate<T extends Gossipable>(message: T): void {
471
- this.logger.debug(`[${message.p2pMessageIdentifier()}] queued`);
459
+ this.logger.trace(`[${message.p2pMessageIdentifier()}] queued`);
472
460
  void this.jobQueue.put(async () => {
473
461
  await this.sendToPeers(message);
474
462
  });
@@ -3,8 +3,8 @@
3
3
  * @param _msg - The ping request message.
4
4
  * @returns A resolved promise with the pong response.
5
5
  */
6
- export function pingHandler(_msg: any): Promise<Uint8Array> {
7
- return Promise.resolve(Uint8Array.from(Buffer.from('pong')));
6
+ export function pingHandler(_msg: any): Promise<Buffer> {
7
+ return Promise.resolve(Buffer.from('pong'));
8
8
  }
9
9
 
10
10
  /**
@@ -12,6 +12,6 @@ export function pingHandler(_msg: any): Promise<Uint8Array> {
12
12
  * @param _msg - The status request message.
13
13
  * @returns A resolved promise with the ok response.
14
14
  */
15
- export function statusHandler(_msg: any): Promise<Uint8Array> {
16
- return Promise.resolve(Uint8Array.from(Buffer.from('ok')));
15
+ export function statusHandler(_msg: any): Promise<Buffer> {
16
+ return Promise.resolve(Buffer.from('ok'));
17
17
  }
@@ -16,7 +16,7 @@ export type ReqRespSubProtocol = typeof PING_PROTOCOL | typeof STATUS_PROTOCOL |
16
16
  * A handler for a sub protocol
17
17
  * The message will arrive as a buffer, and the handler must return a buffer
18
18
  */
19
- export type ReqRespSubProtocolHandler = (msg: Buffer) => Promise<Uint8Array>;
19
+ export type ReqRespSubProtocolHandler = (msg: Buffer) => Promise<Buffer>;
20
20
 
21
21
  /**
22
22
  * A type mapping from supprotocol to it's rate limits
@@ -83,8 +83,8 @@ export type SubProtocolMap = {
83
83
  * Default handler for unimplemented sub protocols, this SHOULD be overwritten
84
84
  * by the service, but is provided as a fallback
85
85
  */
86
- const defaultHandler = (_msg: any): Promise<Uint8Array> => {
87
- return Promise.resolve(Uint8Array.from(Buffer.from('unimplemented')));
86
+ const defaultHandler = (_msg: any): Promise<Buffer> => {
87
+ return Promise.resolve(Buffer.from('unimplemented'));
88
88
  };
89
89
 
90
90
  /**
@@ -5,6 +5,7 @@ import { executeTimeoutWithCustomError } from '@aztec/foundation/timer';
5
5
  import { type IncomingStreamData, type PeerId, type Stream } from '@libp2p/interface';
6
6
  import { pipe } from 'it-pipe';
7
7
  import { type Libp2p } from 'libp2p';
8
+ import { compressSync, uncompressSync } from 'snappy';
8
9
  import { type Uint8ArrayList } from 'uint8arraylist';
9
10
 
10
11
  import { CollectiveReqRespTimeoutError, IndiviualReqRespTimeoutError } from '../../errors/reqresp.error.js';
@@ -31,6 +32,9 @@ import { RequestResponseRateLimiter } from './rate_limiter/rate_limiter.js';
31
32
  * This service implements the request response sub protocol, it is heavily inspired from
32
33
  * ethereum implementations of the same name.
33
34
  *
35
+ * Note, responses get compressed in streamHandler
36
+ * so they get decompressed in readMessage
37
+ *
34
38
  * see: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md#the-reqresp-domain
35
39
  */
36
40
  export class ReqResp {
@@ -232,7 +236,7 @@ export class ReqResp {
232
236
  chunks.push(chunk.subarray());
233
237
  }
234
238
  const messageData = chunks.concat();
235
- return Buffer.concat(messageData);
239
+ return uncompressSync(Buffer.concat(messageData), { asBuffer: true }) as Buffer;
236
240
  }
237
241
 
238
242
  /**
@@ -269,7 +273,8 @@ export class ReqResp {
269
273
  async function* (source: any) {
270
274
  for await (const chunkList of source) {
271
275
  const msg = Buffer.from(chunkList.subarray());
272
- yield handler(msg);
276
+ const response = await handler(msg);
277
+ yield new Uint8Array(compressSync(response));
273
278
  }
274
279
  },
275
280
  stream,
package/src/util.ts CHANGED
@@ -1,6 +1,10 @@
1
+ import { type AztecKVStore, type AztecSingleton } from '@aztec/kv-store';
1
2
  import { type DataStoreConfig } from '@aztec/kv-store/config';
2
3
 
3
4
  import type { GossipSub } from '@chainsafe/libp2p-gossipsub';
5
+ import { generateKeyPair, marshalPrivateKey, unmarshalPrivateKey } from '@libp2p/crypto/keys';
6
+ import { type PeerId, type PrivateKey } from '@libp2p/interface';
7
+ import { createFromPrivKey } from '@libp2p/peer-id-factory';
4
8
  import { resolve } from 'dns/promises';
5
9
  import type { Libp2p } from 'libp2p';
6
10
 
@@ -19,8 +23,7 @@ export interface PubSubLibp2p extends Libp2p {
19
23
  * const udpAddr = '[2001:db8::1]:8080' -> /ip6/2001:db8::1/udp/8080
20
24
  * @param address - The address string to convert. Has to be in the format <addr>:<port>.
21
25
  * @param protocol - The protocol to use in the multiaddr string.
22
- * @returns A multiaddr compliant string.
23
- */
26
+ * @returns A multiaddr compliant string. */
24
27
  export function convertToMultiaddr(address: string, protocol: 'tcp' | 'udp'): string {
25
28
  const [addr, port] = splitAddressPort(address, false);
26
29
 
@@ -141,3 +144,46 @@ export async function configureP2PClientAddresses(
141
144
 
142
145
  return config;
143
146
  }
147
+
148
+ /**
149
+ * Get the peer id private key
150
+ *
151
+ * 1. Check if we have a peer id private key in the config
152
+ * 2. If not, check we have a peer id private key persisted in the node
153
+ * 3. If not, create a new one, then persist it in the node
154
+ *
155
+ */
156
+ export async function getPeerIdPrivateKey(config: { peerIdPrivateKey?: string }, store: AztecKVStore): Promise<string> {
157
+ const peerIdPrivateKeySingleton: AztecSingleton<string> = store.openSingleton('peerIdPrivateKey');
158
+ if (config.peerIdPrivateKey) {
159
+ await peerIdPrivateKeySingleton.set(config.peerIdPrivateKey);
160
+ return config.peerIdPrivateKey;
161
+ }
162
+
163
+ const storedPeerIdPrivateKey = peerIdPrivateKeySingleton.get();
164
+ if (storedPeerIdPrivateKey) {
165
+ return storedPeerIdPrivateKey;
166
+ }
167
+
168
+ const newPeerIdPrivateKey = await generateKeyPair('secp256k1');
169
+ const privateKeyString = Buffer.from(marshalPrivateKey(newPeerIdPrivateKey)).toString('hex');
170
+
171
+ await peerIdPrivateKeySingleton.set(privateKeyString);
172
+ return privateKeyString;
173
+ }
174
+
175
+ /**
176
+ * Create a libp2p peer ID from the private key.
177
+ * @param privateKey - peer ID private key as hex string
178
+ * @returns The peer ID.
179
+ */
180
+ export async function createLibP2PPeerIdFromPrivateKey(privateKey: string): Promise<PeerId> {
181
+ if (!privateKey?.length) {
182
+ throw new Error('No peer private key provided');
183
+ }
184
+
185
+ const asLibp2pPrivateKey: PrivateKey<'secp256k1'> = await unmarshalPrivateKey(
186
+ new Uint8Array(Buffer.from(privateKey, 'hex')),
187
+ );
188
+ return await createFromPrivKey(asLibp2pPrivateKey);
189
+ }