@aztec/p2p 0.49.2 → 0.50.1
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/attestation_pool/attestation_pool.d.ts +39 -0
- package/dest/attestation_pool/attestation_pool.d.ts.map +1 -0
- package/dest/attestation_pool/attestation_pool.js +2 -0
- package/dest/attestation_pool/index.d.ts +3 -0
- package/dest/attestation_pool/index.d.ts.map +1 -0
- package/dest/attestation_pool/index.js +3 -0
- package/dest/attestation_pool/memory_attestation_pool.d.ts +12 -0
- package/dest/attestation_pool/memory_attestation_pool.d.ts.map +1 -0
- package/dest/attestation_pool/memory_attestation_pool.js +56 -0
- package/dest/attestation_pool/mocks.d.ts +16 -0
- package/dest/attestation_pool/mocks.d.ts.map +1 -0
- package/dest/attestation_pool/mocks.js +29 -0
- package/dest/client/index.d.ts +2 -1
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +4 -4
- package/dest/client/p2p_client.d.ts +27 -2
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +17 -5
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/service/dummy_service.d.ts +8 -4
- package/dest/service/dummy_service.d.ts.map +1 -1
- package/dest/service/dummy_service.js +8 -4
- package/dest/service/libp2p_service.d.ts +23 -6
- package/dest/service/libp2p_service.d.ts.map +1 -1
- package/dest/service/libp2p_service.js +52 -10
- package/dest/service/service.d.ts +4 -3
- package/dest/service/service.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/attestation_pool/attestation_pool.ts +42 -0
- package/src/attestation_pool/index.ts +2 -0
- package/src/attestation_pool/memory_attestation_pool.ts +70 -0
- package/src/attestation_pool/mocks.ts +33 -0
- package/src/client/index.ts +4 -2
- package/src/client/p2p_client.ts +52 -3
- package/src/index.ts +1 -0
- package/src/service/dummy_service.ts +9 -4
- package/src/service/libp2p_service.ts +69 -7
- package/src/service/service.ts +6 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TopicType, TopicTypeMap, Tx } from '@aztec/circuit-types';
|
|
1
|
+
import { BlockAttestation, BlockProposal, TopicType, TopicTypeMap, Tx, } from '@aztec/circuit-types';
|
|
2
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { SerialQueue } from '@aztec/foundation/queue';
|
|
4
4
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
@@ -33,14 +33,19 @@ export async function createLibP2PPeerId(privateKey) {
|
|
|
33
33
|
* Lib P2P implementation of the P2PService interface.
|
|
34
34
|
*/
|
|
35
35
|
export class LibP2PService {
|
|
36
|
-
constructor(config, node, peerDiscoveryService, txPool, logger = createDebugLogger('aztec:libp2p_service')) {
|
|
36
|
+
constructor(config, node, peerDiscoveryService, txPool, attestationPool, logger = createDebugLogger('aztec:libp2p_service')) {
|
|
37
37
|
this.config = config;
|
|
38
38
|
this.node = node;
|
|
39
39
|
this.peerDiscoveryService = peerDiscoveryService;
|
|
40
40
|
this.txPool = txPool;
|
|
41
|
+
this.attestationPool = attestationPool;
|
|
41
42
|
this.logger = logger;
|
|
42
43
|
this.jobQueue = new SerialQueue();
|
|
43
44
|
this.peerManager = new PeerManager(node, peerDiscoveryService, config, logger);
|
|
45
|
+
this.blockReceivedCallback = (block) => {
|
|
46
|
+
this.logger.verbose(`[WARNING] handler not yet registered: Block received callback not set. Received block ${block.p2pMessageIdentifier()} from peer.`);
|
|
47
|
+
return Promise.resolve(undefined);
|
|
48
|
+
};
|
|
44
49
|
}
|
|
45
50
|
/**
|
|
46
51
|
* Starts the LibP2P service.
|
|
@@ -101,7 +106,7 @@ export class LibP2PService {
|
|
|
101
106
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
102
107
|
* @returns The new service.
|
|
103
108
|
*/
|
|
104
|
-
static async new(config, peerDiscoveryService, peerId, txPool, store) {
|
|
109
|
+
static async new(config, peerDiscoveryService, peerId, txPool, attestationPool, store) {
|
|
105
110
|
const { tcpListenAddress, tcpAnnounceAddress, minPeerCount, maxPeerCount } = config;
|
|
106
111
|
const bindAddrTcp = convertToMultiaddr(tcpListenAddress, 'tcp');
|
|
107
112
|
// We know tcpAnnounceAddress cannot be null here because we set it or throw when setting up the service.
|
|
@@ -149,7 +154,11 @@ export class LibP2PService {
|
|
|
149
154
|
}),
|
|
150
155
|
},
|
|
151
156
|
});
|
|
152
|
-
return new LibP2PService(config, node, peerDiscoveryService, txPool);
|
|
157
|
+
return new LibP2PService(config, node, peerDiscoveryService, txPool, attestationPool);
|
|
158
|
+
}
|
|
159
|
+
registerBlockReceivedCallback(callback) {
|
|
160
|
+
this.blockReceivedCallback = callback;
|
|
161
|
+
this.logger.verbose('Block received callback registered');
|
|
153
162
|
}
|
|
154
163
|
/**
|
|
155
164
|
* Subscribes to a topic.
|
|
@@ -184,14 +193,47 @@ export class LibP2PService {
|
|
|
184
193
|
const tx = Tx.fromBuffer(Buffer.from(message.data));
|
|
185
194
|
await this.processTxFromPeer(tx);
|
|
186
195
|
}
|
|
196
|
+
if (message.topic === BlockAttestation.p2pTopic) {
|
|
197
|
+
const attestation = BlockAttestation.fromBuffer(Buffer.from(message.data));
|
|
198
|
+
await this.processAttestationFromPeer(attestation);
|
|
199
|
+
}
|
|
200
|
+
if (message.topic == BlockProposal.p2pTopic) {
|
|
201
|
+
const block = BlockProposal.fromBuffer(Buffer.from(message.data));
|
|
202
|
+
await this.processBlockFromPeer(block);
|
|
203
|
+
}
|
|
187
204
|
return;
|
|
188
205
|
}
|
|
206
|
+
/**Process Attestation From Peer
|
|
207
|
+
* When a proposal is received from a peer, we add it to the attestation pool, so it can be accessed by other services.
|
|
208
|
+
*
|
|
209
|
+
* @param attestation - The attestation to process.
|
|
210
|
+
*/
|
|
211
|
+
async processAttestationFromPeer(attestation) {
|
|
212
|
+
this.logger.verbose(`Received attestation ${attestation.p2pMessageIdentifier()} from external peer.`);
|
|
213
|
+
await this.attestationPool.addAttestations([attestation]);
|
|
214
|
+
}
|
|
215
|
+
/**Process block from peer
|
|
216
|
+
*
|
|
217
|
+
* Pass the received block to the validator client
|
|
218
|
+
*
|
|
219
|
+
* @param block - The block to process.
|
|
220
|
+
*/
|
|
221
|
+
// REVIEW: callback pattern https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
222
|
+
async processBlockFromPeer(block) {
|
|
223
|
+
this.logger.verbose(`Received block ${block.p2pMessageIdentifier()} from external peer.`);
|
|
224
|
+
const attestation = await this.blockReceivedCallback(block);
|
|
225
|
+
// TODO: fix up this pattern - the abstraction is not nice
|
|
226
|
+
// The attestation can be undefined if no handler is registered / the validator deems the block invalid
|
|
227
|
+
if (attestation != undefined) {
|
|
228
|
+
this.propagate(attestation);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
189
231
|
/**
|
|
190
|
-
* Propagates
|
|
191
|
-
* @param
|
|
232
|
+
* Propagates provided message to peers.
|
|
233
|
+
* @param message - The message to propagate.
|
|
192
234
|
*/
|
|
193
|
-
|
|
194
|
-
void this.jobQueue.put(() => Promise.resolve(this.sendToPeers(
|
|
235
|
+
propagate(message) {
|
|
236
|
+
void this.jobQueue.put(() => Promise.resolve(this.sendToPeers(message)));
|
|
195
237
|
}
|
|
196
238
|
async processTxFromPeer(tx) {
|
|
197
239
|
const txHash = tx.getTxHash();
|
|
@@ -202,7 +244,7 @@ export class LibP2PService {
|
|
|
202
244
|
async sendToPeers(message) {
|
|
203
245
|
const parent = message.constructor;
|
|
204
246
|
const identifier = message.p2pMessageIdentifier().toString();
|
|
205
|
-
this.logger.verbose(`Sending
|
|
247
|
+
this.logger.verbose(`Sending message ${identifier} to peers`);
|
|
206
248
|
const recipientsNum = await this.publishToTopic(parent.p2pTopic, message.toBuffer());
|
|
207
249
|
this.logger.verbose(`Sent tx ${identifier} to ${recipientsNum} peers`);
|
|
208
250
|
}
|
|
@@ -221,4 +263,4 @@ export class LibP2PService {
|
|
|
221
263
|
}
|
|
222
264
|
}
|
|
223
265
|
}
|
|
224
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQTBDLFNBQVMsRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDM0csT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUduRSxPQUFPLEVBQXdCLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzlFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEVBQUUsY0FBYyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQWUsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBSW5ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBUWhEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGtCQUFrQixDQUFDLFVBQW1CO0lBQzFELElBQUksQ0FBQyxV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
|
|
266
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGFBQWEsRUFHYixTQUFTLEVBQ1QsWUFBWSxFQUNaLEVBQUUsR0FDSCxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzFELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFHbkUsT0FBTyxFQUF3QixTQUFTLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM5RSxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUU1QyxPQUFPLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hGLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxFQUFlLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUtuRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDaEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQVFoRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxrQkFBa0IsQ0FBQyxV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
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import type {
|
|
2
|
+
import type { BlockAttestation, BlockProposal, Gossipable } from '@aztec/circuit-types';
|
|
3
3
|
import type { ENR } from '@chainsafe/enr';
|
|
4
4
|
import type { PeerId } from '@libp2p/interface';
|
|
5
5
|
import type EventEmitter from 'events';
|
|
@@ -23,9 +23,10 @@ export interface P2PService {
|
|
|
23
23
|
stop(): Promise<void>;
|
|
24
24
|
/**
|
|
25
25
|
* Called to have the given transaction propagated through the P2P network.
|
|
26
|
-
* @param
|
|
26
|
+
* @param message - The message to be propagated.
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
propagate<T extends Gossipable>(message: T): void;
|
|
29
|
+
registerBlockReceivedCallback(callback: (block: BlockProposal) => Promise<BlockAttestation>): void;
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* The interface for a peer discovery service implementation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/service/service.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAExF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,oBAAY,kBAAkB;IAC5B,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,SAAS,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;IAGlD,6BAA6B,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC;CACpG;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,YAAY;IACxD;;SAEK;IACL,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;SAEK;IACL,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;OAGG;IACH,WAAW,IAAI,GAAG,EAAE,CAAC;IAErB;;OAEG;IACH,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC;;;;OAIG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,iBAAiB,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;IAElD,SAAS,IAAI,kBAAkB,CAAC;CACjC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/p2p",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.50.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"typedocOptions": {
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"testTimeout": 15000
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@aztec/circuit-types": "0.
|
|
60
|
-
"@aztec/circuits.js": "0.
|
|
61
|
-
"@aztec/foundation": "0.
|
|
62
|
-
"@aztec/kv-store": "0.
|
|
63
|
-
"@aztec/telemetry-client": "0.
|
|
59
|
+
"@aztec/circuit-types": "0.50.1",
|
|
60
|
+
"@aztec/circuits.js": "0.50.1",
|
|
61
|
+
"@aztec/foundation": "0.50.1",
|
|
62
|
+
"@aztec/kv-store": "0.50.1",
|
|
63
|
+
"@aztec/telemetry-client": "0.50.1",
|
|
64
64
|
"@chainsafe/discv5": "9.0.0",
|
|
65
65
|
"@chainsafe/enr": "3.0.0",
|
|
66
66
|
"@chainsafe/libp2p-gossipsub": "13.0.0",
|
|
@@ -95,7 +95,8 @@
|
|
|
95
95
|
"jest-mock-extended": "^3.0.4",
|
|
96
96
|
"ts-node": "^10.9.1",
|
|
97
97
|
"typescript": "^5.0.4",
|
|
98
|
-
"uint8arrays": "^5.0.3"
|
|
98
|
+
"uint8arrays": "^5.0.3",
|
|
99
|
+
"viem": "^2.7.15"
|
|
99
100
|
},
|
|
100
101
|
"files": [
|
|
101
102
|
"dest",
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type BlockAttestation } from '@aztec/circuit-types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An Attestation Pool contains attestations collected by a validator
|
|
5
|
+
*
|
|
6
|
+
* Attestations that are observed via the p2p network are stored for requests
|
|
7
|
+
* from the validator to produce a block, or to serve to other peers.
|
|
8
|
+
*/
|
|
9
|
+
export interface AttestationPool {
|
|
10
|
+
/**
|
|
11
|
+
* AddAttestation
|
|
12
|
+
*
|
|
13
|
+
* @param attestations - Attestations to add into the pool
|
|
14
|
+
*/
|
|
15
|
+
addAttestations(attestations: BlockAttestation[]): Promise<void>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* DeleteAttestation
|
|
19
|
+
*
|
|
20
|
+
* @param attestations - Attestations to remove from the pool
|
|
21
|
+
*/
|
|
22
|
+
deleteAttestations(attestations: BlockAttestation[]): Promise<void>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Delete Attestations for slot
|
|
26
|
+
*
|
|
27
|
+
* Removes all attestations associated with a slot
|
|
28
|
+
*
|
|
29
|
+
* @param slot - The slot to delete.
|
|
30
|
+
*/
|
|
31
|
+
deleteAttestationsForSlot(slot: bigint): Promise<void>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get Attestations for slot
|
|
35
|
+
*
|
|
36
|
+
* Retrieve all of the attestations observed pertaining to a given slot
|
|
37
|
+
*
|
|
38
|
+
* @param slot - The slot to query
|
|
39
|
+
* @return BlockAttestations
|
|
40
|
+
*/
|
|
41
|
+
getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]>;
|
|
42
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type BlockAttestation } from '@aztec/circuit-types';
|
|
2
|
+
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
+
|
|
4
|
+
import { type AttestationPool } from './attestation_pool.js';
|
|
5
|
+
|
|
6
|
+
export class InMemoryAttestationPool implements AttestationPool {
|
|
7
|
+
private attestations: Map</*slot=*/ bigint, Map</*address=*/ string, BlockAttestation>>;
|
|
8
|
+
|
|
9
|
+
constructor(private log = createDebugLogger('aztec:attestation_pool')) {
|
|
10
|
+
this.attestations = new Map();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]> {
|
|
14
|
+
const slotAttestationMap = this.attestations.get(slot);
|
|
15
|
+
if (slotAttestationMap) {
|
|
16
|
+
return Promise.resolve(Array.from(slotAttestationMap.values()));
|
|
17
|
+
} else {
|
|
18
|
+
return Promise.resolve([]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public async addAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
23
|
+
for (const attestation of attestations) {
|
|
24
|
+
// Perf: order and group by slot before insertion
|
|
25
|
+
const slotNumber = attestation.header.globalVariables.slotNumber;
|
|
26
|
+
|
|
27
|
+
const address = await attestation.getSender();
|
|
28
|
+
|
|
29
|
+
const slotAttestationMap = getSlotOrDefault(this.attestations, slotNumber.toBigInt());
|
|
30
|
+
slotAttestationMap.set(address.toString(), attestation);
|
|
31
|
+
|
|
32
|
+
this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public deleteAttestationsForSlot(slot: bigint): Promise<void> {
|
|
37
|
+
// TODO(md): check if this will free the memory of the inner hash map
|
|
38
|
+
this.attestations.delete(slot);
|
|
39
|
+
this.log.verbose(`Removed attestation for slot ${slot}`);
|
|
40
|
+
return Promise.resolve();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
44
|
+
for (const attestation of attestations) {
|
|
45
|
+
const slotNumber = attestation.header.globalVariables.slotNumber;
|
|
46
|
+
const slotAttestationMap = this.attestations.get(slotNumber.toBigInt());
|
|
47
|
+
if (slotAttestationMap) {
|
|
48
|
+
const address = await attestation.getSender();
|
|
49
|
+
slotAttestationMap.delete(address.toString());
|
|
50
|
+
this.log.verbose(`Deleted attestation for slot ${slotNumber} from ${address}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return Promise.resolve();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get Slot or Default
|
|
59
|
+
*
|
|
60
|
+
* Fetch the slot mapping, if it does not exist, then create a mapping and return it
|
|
61
|
+
*/
|
|
62
|
+
function getSlotOrDefault(
|
|
63
|
+
map: Map<bigint, Map<string, BlockAttestation>>,
|
|
64
|
+
slot: bigint,
|
|
65
|
+
): Map<string, BlockAttestation> {
|
|
66
|
+
if (!map.has(slot)) {
|
|
67
|
+
map.set(slot, new Map<string, BlockAttestation>());
|
|
68
|
+
}
|
|
69
|
+
return map.get(slot)!;
|
|
70
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BlockAttestation, Signature } from '@aztec/circuit-types';
|
|
2
|
+
import { makeHeader } from '@aztec/circuits.js/testing';
|
|
3
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
4
|
+
|
|
5
|
+
import { type PrivateKeyAccount } from 'viem';
|
|
6
|
+
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
|
|
7
|
+
|
|
8
|
+
/** Generate Account
|
|
9
|
+
*
|
|
10
|
+
* Create a random signer
|
|
11
|
+
* @returns A random viem signer
|
|
12
|
+
*/
|
|
13
|
+
export const generateAccount = () => {
|
|
14
|
+
const privateKey = generatePrivateKey();
|
|
15
|
+
return privateKeyToAccount(privateKey);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** Mock Attestation
|
|
19
|
+
*
|
|
20
|
+
* @param signer A viem signer to create a signature
|
|
21
|
+
* @param slot The slot number the attestation is for
|
|
22
|
+
* @returns A Block Attestation
|
|
23
|
+
*/
|
|
24
|
+
export const mockAttestation = async (signer: PrivateKeyAccount, slot: number = 0): Promise<BlockAttestation> => {
|
|
25
|
+
// Use arbitrary numbers for all other than slot
|
|
26
|
+
const header = makeHeader(1, 2, slot);
|
|
27
|
+
const archive = Fr.random();
|
|
28
|
+
const message = archive.toString();
|
|
29
|
+
const sigString = await signer.signMessage({ message });
|
|
30
|
+
|
|
31
|
+
const signature = Signature.from0xString(sigString);
|
|
32
|
+
return new BlockAttestation(header, archive, signature);
|
|
33
|
+
};
|
package/src/client/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type L2BlockSource } from '@aztec/circuit-types';
|
|
2
2
|
import { type AztecKVStore } from '@aztec/kv-store';
|
|
3
3
|
|
|
4
|
+
import { type AttestationPool } from '../attestation_pool/attestation_pool.js';
|
|
4
5
|
import { P2PClient } from '../client/p2p_client.js';
|
|
5
6
|
import { type P2PConfig } from '../config.js';
|
|
6
7
|
import { DiscV5Service } from '../service/discV5_service.js';
|
|
@@ -15,6 +16,7 @@ export const createP2PClient = async (
|
|
|
15
16
|
config: P2PConfig,
|
|
16
17
|
store: AztecKVStore,
|
|
17
18
|
txPool: TxPool,
|
|
19
|
+
attestationsPool: AttestationPool,
|
|
18
20
|
l2BlockSource: L2BlockSource,
|
|
19
21
|
) => {
|
|
20
22
|
let p2pService;
|
|
@@ -59,9 +61,9 @@ export const createP2PClient = async (
|
|
|
59
61
|
// Create peer discovery service
|
|
60
62
|
const peerId = await createLibP2PPeerId(config.peerIdPrivateKey);
|
|
61
63
|
const discoveryService = new DiscV5Service(peerId, config);
|
|
62
|
-
p2pService = await LibP2PService.new(config, discoveryService, peerId, txPool, store);
|
|
64
|
+
p2pService = await LibP2PService.new(config, discoveryService, peerId, txPool, attestationsPool, store);
|
|
63
65
|
} else {
|
|
64
66
|
p2pService = new DummyP2PService();
|
|
65
67
|
}
|
|
66
|
-
return new P2PClient(store, l2BlockSource, txPool, p2pService, config.keepProvenTxsInPoolFor);
|
|
68
|
+
return new P2PClient(store, l2BlockSource, txPool, attestationsPool, p2pService, config.keepProvenTxsInPoolFor);
|
|
67
69
|
};
|
package/src/client/p2p_client.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type BlockAttestation,
|
|
3
|
+
type BlockProposal,
|
|
4
|
+
type L2Block,
|
|
5
|
+
L2BlockDownloader,
|
|
6
|
+
type L2BlockSource,
|
|
7
|
+
type Tx,
|
|
8
|
+
type TxHash,
|
|
9
|
+
} from '@aztec/circuit-types';
|
|
2
10
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
|
|
3
11
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
12
|
import { type AztecKVStore, type AztecSingleton } from '@aztec/kv-store';
|
|
5
13
|
|
|
14
|
+
import { type AttestationPool } from '../attestation_pool/attestation_pool.js';
|
|
6
15
|
import { getP2PConfigEnvVars } from '../config.js';
|
|
7
16
|
import type { P2PService } from '../service/service.js';
|
|
8
17
|
import { type TxPool } from '../tx_pool/index.js';
|
|
@@ -35,6 +44,31 @@ export interface P2PSyncState {
|
|
|
35
44
|
* Interface of a P2P client.
|
|
36
45
|
**/
|
|
37
46
|
export interface P2P {
|
|
47
|
+
/**
|
|
48
|
+
* Broadcasts a block proposal to other peers.
|
|
49
|
+
*
|
|
50
|
+
* @param proposal - the block proposal
|
|
51
|
+
*/
|
|
52
|
+
broadcastProposal(proposal: BlockProposal): void;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Queries the Attestation pool for attestations for the given slot
|
|
56
|
+
*
|
|
57
|
+
* @param slot - the slot to query
|
|
58
|
+
* @returns BlockAttestations
|
|
59
|
+
*/
|
|
60
|
+
getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Registers a callback from the validator client that determines how to behave when
|
|
64
|
+
* foreign block proposals are received
|
|
65
|
+
*
|
|
66
|
+
* @param handler - A function taking a received block proposal and producing an attestation
|
|
67
|
+
*/
|
|
68
|
+
// REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
69
|
+
// ^ This pattern is not my favorite (md)
|
|
70
|
+
registerBlockProposalHandler(handler: (block: BlockProposal) => Promise<BlockAttestation>): void;
|
|
71
|
+
|
|
38
72
|
/**
|
|
39
73
|
* Verifies the 'tx' and, if valid, adds it to local tx pool and forwards it to other peers.
|
|
40
74
|
* @param tx - The transaction.
|
|
@@ -130,6 +164,7 @@ export class P2PClient implements P2P {
|
|
|
130
164
|
store: AztecKVStore,
|
|
131
165
|
private l2BlockSource: L2BlockSource,
|
|
132
166
|
private txPool: TxPool,
|
|
167
|
+
private attestationPool: AttestationPool,
|
|
133
168
|
private p2pService: P2PService,
|
|
134
169
|
private keepProvenTxsFor: number,
|
|
135
170
|
private log = createDebugLogger('aztec:p2p'),
|
|
@@ -220,6 +255,20 @@ export class P2PClient implements P2P {
|
|
|
220
255
|
this.log.info('P2P client stopped.');
|
|
221
256
|
}
|
|
222
257
|
|
|
258
|
+
public broadcastProposal(proposal: BlockProposal): void {
|
|
259
|
+
return this.p2pService.propagate(proposal);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
public getAttestationsForSlot(slot: bigint): Promise<BlockAttestation[]> {
|
|
263
|
+
return Promise.resolve(this.attestationPool.getAttestationsForSlot(slot));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
267
|
+
// ^ This pattern is not my favorite (md)
|
|
268
|
+
public registerBlockProposalHandler(handler: (block: BlockProposal) => Promise<BlockAttestation>): void {
|
|
269
|
+
this.p2pService.registerBlockReceivedCallback(handler);
|
|
270
|
+
}
|
|
271
|
+
|
|
223
272
|
/**
|
|
224
273
|
* Returns all transactions in the transaction pool.
|
|
225
274
|
* @returns An array of Txs.
|
|
@@ -263,7 +312,7 @@ export class P2PClient implements P2P {
|
|
|
263
312
|
throw new Error('P2P client not ready');
|
|
264
313
|
}
|
|
265
314
|
await this.txPool.addTxs([tx]);
|
|
266
|
-
this.p2pService.
|
|
315
|
+
this.p2pService.propagate(tx);
|
|
267
316
|
}
|
|
268
317
|
|
|
269
318
|
/**
|
|
@@ -425,7 +474,7 @@ export class P2PClient implements P2P {
|
|
|
425
474
|
const txs = this.txPool.getAllTxs();
|
|
426
475
|
if (txs.length > 0) {
|
|
427
476
|
this.log.debug(`Publishing ${txs.length} previously stored txs`);
|
|
428
|
-
await Promise.all(txs.map(tx => this.p2pService.
|
|
477
|
+
await Promise.all(txs.map(tx => this.p2pService.propagate(tx)));
|
|
429
478
|
}
|
|
430
479
|
}
|
|
431
480
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BlockAttestation, BlockProposal, Gossipable, TxHash } from '@aztec/circuit-types';
|
|
2
2
|
|
|
3
3
|
import type { PeerId } from '@libp2p/interface';
|
|
4
4
|
import EventEmitter from 'events';
|
|
@@ -26,16 +26,21 @@ export class DummyP2PService implements P2PService {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* Called to have the given
|
|
30
|
-
* @param _ - The
|
|
29
|
+
* Called to have the given message propagated through the P2P network.
|
|
30
|
+
* @param _ - The message to be propagated.
|
|
31
31
|
*/
|
|
32
|
-
public
|
|
32
|
+
public propagate<T extends Gossipable>(_: T) {}
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Called upon receipt of settled transactions.
|
|
36
36
|
* @param _ - The hashes of the settled transactions.
|
|
37
37
|
*/
|
|
38
38
|
public settledTxs(_: TxHash[]) {}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Register a callback into the validator client for when a block proposal is received
|
|
42
|
+
*/
|
|
43
|
+
public registerBlockReceivedCallback(_: (block: BlockProposal) => Promise<BlockAttestation>) {}
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
/**
|