@aztec/p2p 0.38.0 → 0.40.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 (36) hide show
  1. package/dest/bootstrap/bootstrap.d.ts.map +1 -1
  2. package/dest/bootstrap/bootstrap.js +3 -1
  3. package/dest/config.d.ts +5 -0
  4. package/dest/config.d.ts.map +1 -1
  5. package/dest/config.js +4 -2
  6. package/dest/service/data_store.d.ts +27 -0
  7. package/dest/service/data_store.d.ts.map +1 -0
  8. package/dest/service/data_store.js +188 -0
  9. package/dest/service/discV5_service.d.ts +8 -6
  10. package/dest/service/discV5_service.d.ts.map +1 -1
  11. package/dest/service/discV5_service.js +35 -21
  12. package/dest/service/dummy_service.d.ts +3 -1
  13. package/dest/service/dummy_service.d.ts.map +1 -1
  14. package/dest/service/dummy_service.js +11 -1
  15. package/dest/service/libp2p_service.d.ts +28 -17
  16. package/dest/service/libp2p_service.d.ts.map +1 -1
  17. package/dest/service/libp2p_service.js +101 -174
  18. package/dest/service/peer_manager.d.ts +12 -0
  19. package/dest/service/peer_manager.d.ts.map +1 -0
  20. package/dest/service/peer_manager.js +22 -0
  21. package/dest/service/service.d.ts +5 -0
  22. package/dest/service/service.d.ts.map +1 -1
  23. package/dest/service/service.js +6 -2
  24. package/dest/service/tx_messages.d.ts +11 -57
  25. package/dest/service/tx_messages.d.ts.map +1 -1
  26. package/dest/service/tx_messages.js +14 -89
  27. package/package.json +29 -21
  28. package/src/bootstrap/bootstrap.ts +2 -0
  29. package/src/config.ts +9 -0
  30. package/src/service/data_store.ts +235 -0
  31. package/src/service/discV5_service.ts +37 -20
  32. package/src/service/dummy_service.ts +8 -1
  33. package/src/service/libp2p_service.ts +130 -194
  34. package/src/service/peer_manager.ts +26 -0
  35. package/src/service/service.ts +7 -0
  36. package/src/service/tx_messages.ts +18 -93
@@ -1,32 +1,18 @@
1
- import { EncryptedTxL2Logs, Tx, TxHash, UnencryptedTxL2Logs } from '@aztec/circuit-types';
1
+ import { EncryptedTxL2Logs, Tx, UnencryptedTxL2Logs } from '@aztec/circuit-types';
2
2
  import { PrivateKernelTailCircuitPublicInputs, Proof, PublicCallRequest } from '@aztec/circuits.js';
3
3
  import { numToUInt32BE } from '@aztec/foundation/serialize';
4
- /**
5
- * Enumeration of P2P message types.
6
- */
7
- export var Messages;
8
- (function (Messages) {
9
- Messages[Messages["POOLED_TRANSACTIONS"] = 1] = "POOLED_TRANSACTIONS";
10
- Messages[Messages["POOLED_TRANSACTION_HASHES"] = 2] = "POOLED_TRANSACTION_HASHES";
11
- Messages[Messages["GET_TRANSACTIONS"] = 3] = "GET_TRANSACTIONS";
12
- })(Messages || (Messages = {}));
13
- /**
14
- * Create a P2P message from the message type and message data.
15
- * @param type - The type of the message.
16
- * @param messageData - The binary message data.
17
- * @returns The encoded message.
18
- */
19
- export function createMessage(type, messageData) {
20
- return Buffer.concat([numToUInt32BE(type), messageData]);
21
- }
22
- /**
23
- * Create a POOLED_TRANSACTIONS message from an array of transactions.
24
- * @param txs - The transactions to encoded into a message.
25
- * @returns The encoded message.
26
- */
27
- export function createTransactionsMessage(txs) {
28
- const messageData = txs.map(toTxMessage);
29
- return createMessage(Messages.POOLED_TRANSACTIONS, Buffer.concat(messageData));
4
+ export const TX_MESSAGE_TOPIC = '';
5
+ export class AztecTxMessageCreator {
6
+ constructor(version) {
7
+ this.topic = `/aztec/tx/${version.toString()}`;
8
+ }
9
+ createTxMessage(tx) {
10
+ const messageData = toTxMessage(tx);
11
+ return { topic: this.topic, data: messageData };
12
+ }
13
+ getTopic() {
14
+ return this.topic;
15
+ }
30
16
  }
31
17
  /**
32
18
  * Decode a POOLED_TRANSACTIONS message into the original transaction objects.
@@ -45,67 +31,6 @@ export function decodeTransactionsMessage(message) {
45
31
  }
46
32
  return txs;
47
33
  }
48
- /**
49
- * Create a POOLED_TRANSACTION_HASHES message.
50
- * @param hashes - The transaction hashes to be sent.
51
- * @returns The encoded message.
52
- */
53
- export function createTransactionHashesMessage(hashes) {
54
- const messageData = hashes.map(x => x.buffer);
55
- return createMessage(Messages.POOLED_TRANSACTION_HASHES, Buffer.concat(messageData));
56
- }
57
- /**
58
- * Decode a POOLED_TRANSACTION_HASHESs message ito the original transaction hash objects.
59
- * @param message - The binary message to be decoded.
60
- * @returns - The array of transaction hashes originally encoded into the message.
61
- */
62
- export function decodeTransactionHashesMessage(message) {
63
- let offset = 0;
64
- const txHashes = [];
65
- while (offset < message.length) {
66
- const slice = message.subarray(offset, offset + TxHash.SIZE);
67
- if (slice.length < TxHash.SIZE) {
68
- throw new Error(`Invalid message size when processing transaction hashes message`);
69
- }
70
- txHashes.push(new TxHash(slice));
71
- offset += TxHash.SIZE;
72
- }
73
- return txHashes;
74
- }
75
- /**
76
- * Create a GET_TRANSACTIONS message from an array of transaction hashes.
77
- * @param hashes - The hashes of the transactions to be requested.
78
- * @returns The encoded message.
79
- */
80
- export function createGetTransactionsRequestMessage(hashes) {
81
- const messageData = hashes.map(x => x.buffer);
82
- return createMessage(Messages.GET_TRANSACTIONS, Buffer.concat(messageData));
83
- }
84
- /**
85
- * Decode a GET_TRANSACTIONS message into the original transaction hash objects.
86
- * @param message - The binary message to be decoded.
87
- * @returns - The array of transaction hashes originally encoded into the message.
88
- */
89
- export function decodeGetTransactionsRequestMessage(message) {
90
- // for the time being this payload is effectively the same as the POOLED_TRANSACTION_HASHES message
91
- return decodeTransactionHashesMessage(message);
92
- }
93
- /**
94
- * Decode the message type from a received message.
95
- * @param message - The received message.
96
- * @returns The decoded MessageType.
97
- */
98
- export function decodeMessageType(message) {
99
- return message.readUInt32BE(0);
100
- }
101
- /**
102
- * Return the encoded message (minus the header) from received message buffer.
103
- * @param message - The complete received message.
104
- * @returns The encoded message, without the header.
105
- */
106
- export function getEncodedMessage(message) {
107
- return message.subarray(4);
108
- }
109
34
  /**
110
35
  * Creates a tx 'message' for sending to a peer.
111
36
  * @param tx - The transaction to convert to a message.
@@ -188,4 +113,4 @@ export function fromTxMessage(buffer) {
188
113
  const publicTeardownCall = toObject(publicCalls.remainingData, PublicCallRequest);
189
114
  return new Tx(publicInputs.obj, proof.obj, encryptedLogs.obj, unencryptedLogs.obj, publicCalls.objects, publicTeardownCall.obj);
190
115
  }
191
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfbWVzc2FnZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS90eF9tZXNzYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsRUFBRSxFQUFFLE1BQU0sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzFGLE9BQU8sRUFBRSxvQ0FBb0MsRUFBRSxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFNUQ7O0dBRUc7QUFDSCxNQUFNLENBQU4sSUFBWSxRQUlYO0FBSkQsV0FBWSxRQUFRO0lBQ2xCLHFFQUF1QixDQUFBO0lBQ3ZCLGlGQUE2QixDQUFBO0lBQzdCLCtEQUFvQixDQUFBO0FBQ3RCLENBQUMsRUFKVyxRQUFRLEtBQVIsUUFBUSxRQUluQjtBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBQyxJQUFjLEVBQUUsV0FBbUI7SUFDL0QsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUseUJBQXlCLENBQUMsR0FBUztJQUNqRCxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sYUFBYSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDakYsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUseUJBQXlCLENBQUMsT0FBZTtJQUN2RCxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUM7SUFDckIsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFD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
116
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfbWVzc2FnZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS90eF9tZXNzYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsRUFBRSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEYsT0FBTyxFQUFFLG9DQUFvQyxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3BHLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUk1RCxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7QUFFbkMsTUFBTSxPQUFPLHFCQUFxQjtJQUVoQyxZQUFZLE9BQWU7UUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxhQUFhLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDO0lBQ2pELENBQUM7SUFFRCxlQUFlLENBQUMsRUFBTTtRQUNwQixNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFcEMsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBRUQsUUFBUTtRQUNOLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUNwQixDQUFDO0NBQ0Y7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLHlCQUF5QixDQUFDLE9BQWU7SUFDdkQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQ3JCLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNmLE1BQU0sR0FBRyxHQUFTLEVBQUUsQ0FBQztJQUNyQixPQUFPLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDL0IsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/p2p",
3
- "version": "0.38.0",
3
+ "version": "0.40.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -44,30 +44,35 @@
44
44
  "summaryThreshold": 9999
45
45
  }
46
46
  ]
47
- ]
47
+ ],
48
+ "testTimeout": 15000
48
49
  },
49
50
  "dependencies": {
50
- "@aztec/circuit-types": "0.38.0",
51
- "@aztec/circuits.js": "0.38.0",
52
- "@aztec/foundation": "0.38.0",
53
- "@aztec/kv-store": "0.38.0",
54
- "@chainsafe/discv5": "^9.0.0",
55
- "@chainsafe/enr": "^3.0.0",
51
+ "@aztec/circuit-types": "0.40.0",
52
+ "@aztec/circuits.js": "0.40.0",
53
+ "@aztec/foundation": "0.40.0",
54
+ "@aztec/kv-store": "0.40.0",
55
+ "@chainsafe/discv5": "9.0.0",
56
+ "@chainsafe/enr": "3.0.0",
57
+ "@chainsafe/libp2p-gossipsub": "13.0.0",
56
58
  "@chainsafe/libp2p-noise": "^15.0.0",
57
59
  "@chainsafe/libp2p-yamux": "^6.0.2",
58
- "@libp2p/bootstrap": "^9.0.4",
59
- "@libp2p/crypto": "^4.0.3",
60
- "@libp2p/identify": "^1.0.15",
61
- "@libp2p/interface": "^1.1.4",
62
- "@libp2p/interface-libp2p": "^3.2.0",
63
- "@libp2p/kad-dht": "^10.0.4",
64
- "@libp2p/mplex": "^10.0.16",
65
- "@libp2p/peer-id": "^4.0.7",
66
- "@libp2p/peer-id-factory": "^4.0.7",
67
- "@libp2p/tcp": "^9.0.16",
68
- "@multiformats/multiaddr": "^12.1.14",
60
+ "@libp2p/bootstrap": "10.0.0",
61
+ "@libp2p/crypto": "4.0.3",
62
+ "@libp2p/identify": "1.0.18",
63
+ "@libp2p/interface": "1.3.1",
64
+ "@libp2p/kad-dht": "10.0.4",
65
+ "@libp2p/mplex": "10.0.16",
66
+ "@libp2p/peer-id": "4.0.7",
67
+ "@libp2p/peer-id-factory": "4.1.1",
68
+ "@libp2p/peer-store": "10.0.16",
69
+ "@libp2p/tcp": "9.0.24",
70
+ "@multiformats/multiaddr": "12.1.14",
71
+ "interface-datastore": "^8.2.11",
72
+ "interface-store": "^5.1.8",
69
73
  "it-pipe": "^3.0.1",
70
- "libp2p": "^1.2.4",
74
+ "libp2p": "1.5.0",
75
+ "semver": "^7.6.0",
71
76
  "sha3": "^2.1.4",
72
77
  "tslib": "^2.4.0"
73
78
  },
@@ -75,10 +80,13 @@
75
80
  "@jest/globals": "^29.5.0",
76
81
  "@types/jest": "^29.5.0",
77
82
  "@types/node": "^18.14.6",
83
+ "it-drain": "^3.0.5",
84
+ "it-length": "^3.0.6",
78
85
  "jest": "^29.5.0",
79
86
  "jest-mock-extended": "^3.0.4",
80
87
  "ts-node": "^10.9.1",
81
- "typescript": "^5.0.4"
88
+ "typescript": "^5.0.4",
89
+ "uint8arrays": "^5.0.3"
82
90
  },
83
91
  "files": [
84
92
  "dest",
@@ -6,6 +6,7 @@ import type { PeerId } from '@libp2p/interface';
6
6
  import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
7
7
 
8
8
  import { type P2PConfig } from '../config.js';
9
+ import { AZTEC_ENR_KEY, AZTEC_NET } from '../service/discV5_service.js';
9
10
  import { createLibP2PPeerId } from '../service/index.js';
10
11
 
11
12
  /**
@@ -38,6 +39,7 @@ export class BootstrapNode {
38
39
  const listenAddrUdp = multiaddr(`/ip4/${udpListenIp}/udp/${udpListenPort}`);
39
40
  const publicAddr = multiaddr(`${announceHostname}/udp/${announcePort}`);
40
41
  enr.setLocationMultiaddr(publicAddr);
42
+ enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
41
43
 
42
44
  this.logger.info(`Starting bootstrap node ${peerId}, listening on ${listenAddrUdp.toString()}`);
43
45
 
package/src/config.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { SemVer } from 'semver';
2
+
1
3
  /**
2
4
  * P2P client configuration values.
3
5
  */
@@ -86,6 +88,11 @@ export interface P2PConfig {
86
88
  * Data directory for peer & tx databases.
87
89
  */
88
90
  dataDirectory?: string;
91
+
92
+ /**
93
+ * The transaction gossiping message version.
94
+ */
95
+ txGossipVersion: SemVer;
89
96
  }
90
97
 
91
98
  /**
@@ -110,6 +117,7 @@ export function getP2PConfigEnvVars(): P2PConfig {
110
117
  P2P_MIN_PEERS,
111
118
  P2P_MAX_PEERS,
112
119
  DATA_DIRECTORY,
120
+ TX_GOSSIP_VERSION,
113
121
  } = process.env;
114
122
  const envVars: P2PConfig = {
115
123
  p2pEnabled: P2P_ENABLED === 'true',
@@ -129,6 +137,7 @@ export function getP2PConfigEnvVars(): P2PConfig {
129
137
  minPeerCount: P2P_MIN_PEERS ? +P2P_MIN_PEERS : 10,
130
138
  maxPeerCount: P2P_MAX_PEERS ? +P2P_MAX_PEERS : 100,
131
139
  dataDirectory: DATA_DIRECTORY,
140
+ txGossipVersion: TX_GOSSIP_VERSION ? new SemVer(TX_GOSSIP_VERSION) : new SemVer('0.1.0'),
132
141
  };
133
142
  return envVars;
134
143
  }
@@ -0,0 +1,235 @@
1
+ import { filter, map, sort, take } from '@aztec/foundation/iterable';
2
+ import type { AztecKVStore, AztecMap } from '@aztec/kv-store';
3
+
4
+ import { type Batch, type Datastore, Key, type KeyQuery, type Pair, type Query } from 'interface-datastore';
5
+ import type { AwaitIterable } from 'interface-store';
6
+
7
+ type MemoryItem = {
8
+ lastAccessedMs: number;
9
+ data: Uint8Array;
10
+ };
11
+
12
+ type BatchOp = {
13
+ type: 'put' | 'del';
14
+ key: Key;
15
+ value?: Uint8Array;
16
+ };
17
+
18
+ class KeyNotFoundError extends Error {
19
+ code: string;
20
+ constructor(message: string) {
21
+ super(message);
22
+ this.code = 'ERR_NOT_FOUND';
23
+ }
24
+ }
25
+
26
+ export class AztecDatastore implements Datastore {
27
+ #memoryDatastore: Map<string, MemoryItem>;
28
+ #dbDatastore: AztecMap<string, Uint8Array>;
29
+
30
+ #batchOps: BatchOp[] = [];
31
+
32
+ private maxMemoryItems: number;
33
+
34
+ constructor(db: AztecKVStore, { maxMemoryItems } = { maxMemoryItems: 50 }) {
35
+ this.#memoryDatastore = new Map();
36
+ this.#dbDatastore = db.openMap('p2p_datastore');
37
+
38
+ this.maxMemoryItems = maxMemoryItems;
39
+ }
40
+
41
+ has(key: Key): boolean {
42
+ return this.#memoryDatastore.has(key.toString()) || this.#dbDatastore.has(key.toString());
43
+ }
44
+
45
+ get(key: Key): Uint8Array {
46
+ const keyStr = key.toString();
47
+ const memoryItem = this.#memoryDatastore.get(keyStr);
48
+ if (memoryItem) {
49
+ memoryItem.lastAccessedMs = Date.now();
50
+ return memoryItem.data;
51
+ }
52
+ const dbItem = this.#dbDatastore.get(keyStr);
53
+
54
+ if (!dbItem) {
55
+ throw new KeyNotFoundError(`Key not found`);
56
+ }
57
+
58
+ return Uint8Array.from(dbItem);
59
+ }
60
+
61
+ put(key: Key, val: Uint8Array): Promise<Key> {
62
+ return this._put(key, val);
63
+ }
64
+
65
+ async *putMany(source: AwaitIterable<Pair>): AwaitIterable<Key> {
66
+ for await (const { key, value } of source) {
67
+ await this.put(key, value);
68
+ yield key;
69
+ }
70
+ }
71
+
72
+ async *getMany(source: AwaitIterable<Key>): AwaitIterable<Pair> {
73
+ for await (const key of source) {
74
+ yield {
75
+ key,
76
+ value: this.get(key),
77
+ };
78
+ }
79
+ }
80
+
81
+ async *deleteMany(source: AwaitIterable<Key>): AwaitIterable<Key> {
82
+ for await (const key of source) {
83
+ await this.delete(key);
84
+ yield key;
85
+ }
86
+ }
87
+
88
+ async delete(key: Key): Promise<void> {
89
+ this.#memoryDatastore.delete(key.toString());
90
+ await this.#dbDatastore.delete(key.toString());
91
+ }
92
+
93
+ batch(): Batch {
94
+ return {
95
+ put: (key, value) => {
96
+ this.#batchOps.push({
97
+ type: 'put',
98
+ key,
99
+ value,
100
+ });
101
+ },
102
+ delete: key => {
103
+ this.#batchOps.push({
104
+ type: 'del',
105
+ key,
106
+ });
107
+ },
108
+ commit: async () => {
109
+ for (const op of this.#batchOps) {
110
+ if (op.type === 'put' && op.value) {
111
+ await this.put(op.key, op.value);
112
+ } else if (op.type === 'del') {
113
+ await this.delete(op.key);
114
+ }
115
+ }
116
+ this.#batchOps = []; // Clear operations after commit
117
+ },
118
+ };
119
+ }
120
+
121
+ query(q: Query): AwaitIterable<Pair> {
122
+ let it = this.all(); //
123
+ const { prefix, filters, orders, offset, limit } = q;
124
+
125
+ if (prefix != null) {
126
+ it = filter(it, e => e.key.toString().startsWith(`${prefix}`));
127
+ }
128
+
129
+ if (Array.isArray(filters)) {
130
+ it = filters.reduce((it, f) => filter(it, f), it);
131
+ }
132
+
133
+ if (Array.isArray(orders)) {
134
+ it = orders.reduce((it, f) => sort(it, f), it);
135
+ }
136
+
137
+ if (offset != null) {
138
+ let i = 0;
139
+ it = filter(it, () => i++ >= offset);
140
+ }
141
+
142
+ if (limit != null) {
143
+ it = take(it, limit);
144
+ }
145
+
146
+ return it;
147
+ }
148
+
149
+ queryKeys(q: KeyQuery): AsyncIterable<Key> {
150
+ let it = map(this.all(), ({ key }) => key);
151
+ const { prefix, filters, orders, offset, limit } = q;
152
+ if (prefix != null) {
153
+ it = filter(it, e => e.toString().startsWith(`${prefix}`));
154
+ }
155
+
156
+ if (Array.isArray(filters)) {
157
+ it = filters.reduce((it, f) => filter(it, f), it);
158
+ }
159
+
160
+ if (Array.isArray(orders)) {
161
+ it = orders.reduce((it, f) => sort(it, f), it);
162
+ }
163
+
164
+ if (offset != null) {
165
+ let i = 0;
166
+ it = filter(it, () => i++ >= offset);
167
+ }
168
+
169
+ if (limit != null) {
170
+ it = take(it, limit);
171
+ }
172
+
173
+ return it;
174
+ }
175
+
176
+ private async _put(key: Key, val: Uint8Array): Promise<Key> {
177
+ const keyStr = key.toString();
178
+ while (this.#memoryDatastore.size >= this.maxMemoryItems) {
179
+ this.pruneMemoryDatastore();
180
+ }
181
+ const memoryItem = this.#memoryDatastore.get(keyStr);
182
+ if (memoryItem) {
183
+ // update existing
184
+ memoryItem.lastAccessedMs = Date.now();
185
+ memoryItem.data = val;
186
+ } else {
187
+ // new entry
188
+ this.#memoryDatastore.set(keyStr, { data: val, lastAccessedMs: Date.now() });
189
+ }
190
+
191
+ // Always add to DB
192
+ await this.#dbDatastore.set(keyStr, val);
193
+
194
+ return key;
195
+ }
196
+
197
+ private async *all(): AsyncIterable<Pair> {
198
+ for (const [key, value] of this.#memoryDatastore.entries()) {
199
+ yield {
200
+ key: new Key(key),
201
+ value: value.data,
202
+ };
203
+ }
204
+
205
+ for (const [key, value] of this.#dbDatastore.entries()) {
206
+ if (!this.#memoryDatastore.has(key)) {
207
+ yield {
208
+ key: new Key(key),
209
+ value,
210
+ };
211
+ }
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Prune memory store
217
+ */
218
+ private pruneMemoryDatastore(): void {
219
+ let oldestAccessedMs = Date.now() + 1000;
220
+ let oldestKey: string | undefined = undefined;
221
+ let oldestValue: Uint8Array | undefined = undefined;
222
+
223
+ for (const [key, value] of this.#memoryDatastore) {
224
+ if (value.lastAccessedMs < oldestAccessedMs) {
225
+ oldestAccessedMs = value.lastAccessedMs;
226
+ oldestKey = key;
227
+ oldestValue = value.data;
228
+ }
229
+ }
230
+
231
+ if (oldestKey && oldestValue) {
232
+ this.#memoryDatastore.delete(oldestKey);
233
+ }
234
+ }
235
+ }
@@ -8,13 +8,19 @@ import { multiaddr } from '@multiformats/multiaddr';
8
8
  import EventEmitter from 'events';
9
9
 
10
10
  import type { P2PConfig } from '../config.js';
11
- import type { PeerDiscoveryService } from './service.js';
11
+ import { type PeerDiscoveryService, PeerDiscoveryState } from './service.js';
12
12
 
13
- export enum PeerDiscoveryState {
14
- RUNNING = 'running',
15
- STOPPED = 'stopped',
13
+ export const AZTEC_ENR_KEY = 'aztec_network';
14
+
15
+ export enum AztecENR {
16
+ devnet = 0x01,
17
+ testnet = 0x02,
18
+ mainnet = 0x03,
16
19
  }
17
20
 
21
+ // TODO: Make this an env var
22
+ export const AZTEC_NET = AztecENR.devnet;
23
+
18
24
  /**
19
25
  * Peer discovery service using Discv5.
20
26
  */
@@ -25,18 +31,20 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
25
31
  /** This instance's ENR */
26
32
  private enr: SignableENR;
27
33
 
28
- /** The interval for checking for new peers */
29
- private discoveryInterval: NodeJS.Timeout | null = null;
30
-
31
34
  private runningPromise: RunningPromise;
32
35
 
33
36
  private currentState = PeerDiscoveryState.STOPPED;
34
37
 
38
+ private bootstrapNodes: string[];
39
+
35
40
  constructor(private peerId: PeerId, config: P2PConfig, private logger = createDebugLogger('aztec:discv5_service')) {
36
41
  super();
37
42
  const { announceHostname, tcpListenPort, udpListenIp, udpListenPort, bootstrapNodes } = config;
43
+ this.bootstrapNodes = bootstrapNodes;
38
44
  // create ENR from PeerId
39
45
  this.enr = SignableENR.createFromPeerId(peerId);
46
+ // Add aztec identification to ENR
47
+ this.enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
40
48
 
41
49
  const multiAddrUdp = multiaddr(`${announceHostname}/udp/${udpListenPort}/p2p/${peerId.toString()}`);
42
50
  const multiAddrTcp = multiaddr(`${announceHostname}/tcp/${tcpListenPort}/p2p/${peerId.toString()}`);
@@ -66,18 +74,6 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
66
74
  this.logger.debug(`ENR multiaddr: ${multiAddrTcp?.toString()}, ${multiAddrUdp?.toString()}`);
67
75
  });
68
76
 
69
- // Add bootnode ENR if provided
70
- if (bootstrapNodes?.length) {
71
- this.logger.info(`Adding bootstrap ENRs: ${bootstrapNodes.join(', ')}`);
72
- try {
73
- bootstrapNodes.forEach(enr => {
74
- this.discv5.addEnr(enr);
75
- });
76
- } catch (e) {
77
- this.logger.error(`Error adding bootnode ENRs: ${e}`);
78
- }
79
- }
80
-
81
77
  this.runningPromise = new RunningPromise(async () => {
82
78
  await this.discv5.findRandomNode();
83
79
  }, config.p2pPeerCheckIntervalMS);
@@ -91,6 +87,19 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
91
87
  await this.discv5.start();
92
88
  this.logger.info('DiscV5 started');
93
89
  this.currentState = PeerDiscoveryState.RUNNING;
90
+
91
+ // Add bootnode ENR if provided
92
+ if (this.bootstrapNodes?.length) {
93
+ this.logger.info(`Adding bootstrap ENRs: ${this.bootstrapNodes.join(', ')}`);
94
+ try {
95
+ this.bootstrapNodes.forEach(enr => {
96
+ this.discv5.addEnr(enr);
97
+ });
98
+ } catch (e) {
99
+ this.logger.error(`Error adding bootnode ENRs: ${e}`);
100
+ }
101
+ }
102
+
94
103
  this.runningPromise.start();
95
104
  }
96
105
 
@@ -117,6 +126,14 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
117
126
  }
118
127
 
119
128
  private onDiscovered(enr: ENR) {
120
- this.emit('peer:discovered', enr);
129
+ // check the peer is an aztec peer
130
+ const value = enr.kvs.get(AZTEC_ENR_KEY);
131
+ if (value) {
132
+ const network = value[0];
133
+ // check if the peer is on the same network
134
+ if (network === AZTEC_NET) {
135
+ this.emit('peer:discovered', enr);
136
+ }
137
+ }
121
138
  }
122
139
  }
@@ -2,7 +2,7 @@ import { type Tx, type TxHash } from '@aztec/circuit-types';
2
2
 
3
3
  import EventEmitter from 'events';
4
4
 
5
- import type { P2PService, PeerDiscoveryService } from './service.js';
5
+ import { type P2PService, type PeerDiscoveryService, PeerDiscoveryState } from './service.js';
6
6
 
7
7
  /**
8
8
  * A dummy implementation of the P2P Service.
@@ -41,11 +41,13 @@ export class DummyP2PService implements P2PService {
41
41
  * A dummy implementation of the Peer Discovery Service.
42
42
  */
43
43
  export class DummyPeerDiscoveryService extends EventEmitter implements PeerDiscoveryService {
44
+ private currentState = PeerDiscoveryState.STOPPED;
44
45
  /**
45
46
  * Starts the dummy implementation.
46
47
  * @returns A resolved promise.
47
48
  */
48
49
  public start() {
50
+ this.currentState = PeerDiscoveryState.RUNNING;
49
51
  return Promise.resolve();
50
52
  }
51
53
  /**
@@ -53,6 +55,7 @@ export class DummyPeerDiscoveryService extends EventEmitter implements PeerDisco
53
55
  * @returns A resolved promise.
54
56
  */
55
57
  public stop() {
58
+ this.currentState = PeerDiscoveryState.STOPPED;
56
59
  return Promise.resolve();
57
60
  }
58
61
  /**
@@ -62,4 +65,8 @@ export class DummyPeerDiscoveryService extends EventEmitter implements PeerDisco
62
65
  public getAllPeers() {
63
66
  return [];
64
67
  }
68
+
69
+ public getStatus(): PeerDiscoveryState {
70
+ return this.currentState;
71
+ }
65
72
  }