@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.
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +3 -1
- package/dest/config.d.ts +5 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +4 -2
- package/dest/service/data_store.d.ts +27 -0
- package/dest/service/data_store.d.ts.map +1 -0
- package/dest/service/data_store.js +188 -0
- package/dest/service/discV5_service.d.ts +8 -6
- package/dest/service/discV5_service.d.ts.map +1 -1
- package/dest/service/discV5_service.js +35 -21
- package/dest/service/dummy_service.d.ts +3 -1
- package/dest/service/dummy_service.d.ts.map +1 -1
- package/dest/service/dummy_service.js +11 -1
- package/dest/service/libp2p_service.d.ts +28 -17
- package/dest/service/libp2p_service.d.ts.map +1 -1
- package/dest/service/libp2p_service.js +101 -174
- package/dest/service/peer_manager.d.ts +12 -0
- package/dest/service/peer_manager.d.ts.map +1 -0
- package/dest/service/peer_manager.js +22 -0
- package/dest/service/service.d.ts +5 -0
- package/dest/service/service.d.ts.map +1 -1
- package/dest/service/service.js +6 -2
- package/dest/service/tx_messages.d.ts +11 -57
- package/dest/service/tx_messages.d.ts.map +1 -1
- package/dest/service/tx_messages.js +14 -89
- package/package.json +29 -21
- package/src/bootstrap/bootstrap.ts +2 -0
- package/src/config.ts +9 -0
- package/src/service/data_store.ts +235 -0
- package/src/service/discV5_service.ts +37 -20
- package/src/service/dummy_service.ts +8 -1
- package/src/service/libp2p_service.ts +130 -194
- package/src/service/peer_manager.ts +26 -0
- package/src/service/service.ts +7 -0
- package/src/service/tx_messages.ts +18 -93
|
@@ -1,32 +1,18 @@
|
|
|
1
|
-
import { EncryptedTxL2Logs, Tx,
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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,
|
|
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.
|
|
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.
|
|
51
|
-
"@aztec/circuits.js": "0.
|
|
52
|
-
"@aztec/foundation": "0.
|
|
53
|
-
"@aztec/kv-store": "0.
|
|
54
|
-
"@chainsafe/discv5": "
|
|
55
|
-
"@chainsafe/enr": "
|
|
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": "
|
|
59
|
-
"@libp2p/crypto": "
|
|
60
|
-
"@libp2p/identify": "
|
|
61
|
-
"@libp2p/interface": "
|
|
62
|
-
"@libp2p/
|
|
63
|
-
"@libp2p/
|
|
64
|
-
"@libp2p/
|
|
65
|
-
"@libp2p/peer-id": "
|
|
66
|
-
"@libp2p/peer-
|
|
67
|
-
"@libp2p/tcp": "
|
|
68
|
-
"@multiformats/multiaddr": "
|
|
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": "
|
|
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
|
|
11
|
+
import { type PeerDiscoveryService, PeerDiscoveryState } from './service.js';
|
|
12
12
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
|
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
|
}
|