@aztec/p2p 0.70.0 → 0.72.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/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +6 -5
- package/dest/client/p2p_client.d.ts +16 -2
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +22 -12
- package/dest/config.d.ts +3 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +3 -2
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +3 -2
- package/dest/mem_pools/attestation_pool/mocks.d.ts +2 -1
- package/dest/mem_pools/attestation_pool/mocks.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/mocks.js +1 -1
- package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts +1 -1
- package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.d.ts.map +1 -1
- package/dest/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.js +3 -2
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +20 -5
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +72 -9
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +2 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +6 -2
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +6 -0
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mocks/index.d.ts +3 -3
- package/dest/mocks/index.d.ts.map +1 -1
- package/dest/mocks/index.js +22 -21
- package/dest/services/discv5/discV5_service.d.ts +1 -1
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +3 -3
- package/dest/services/dummy_service.d.ts +7 -0
- package/dest/services/dummy_service.d.ts.map +1 -1
- package/dest/services/dummy_service.js +10 -1
- package/dest/services/libp2p/libp2p_service.d.ts +17 -13
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +109 -101
- package/dest/services/peer-manager/metrics.d.ts +12 -0
- package/dest/services/peer-manager/metrics.d.ts.map +1 -0
- package/dest/services/peer-manager/metrics.js +26 -0
- package/dest/services/{peer_manager.d.ts → peer-manager/peer_manager.d.ts} +23 -8
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -0
- package/dest/services/peer-manager/peer_manager.js +392 -0
- package/dest/services/{peer-scoring → peer-manager}/peer_scoring.d.ts +3 -0
- package/dest/services/peer-manager/peer_scoring.d.ts.map +1 -0
- package/dest/services/peer-manager/peer_scoring.js +84 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts +45 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.d.ts.map +1 -0
- package/dest/services/reqresp/connection-sampler/batch_connection_sampler.js +81 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts +61 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.d.ts.map +1 -0
- package/dest/services/reqresp/connection-sampler/connection_sampler.js +175 -0
- package/dest/services/reqresp/interface.d.ts +17 -4
- package/dest/services/reqresp/interface.d.ts.map +1 -1
- package/dest/services/reqresp/interface.js +34 -11
- package/dest/services/reqresp/metrics.d.ts +15 -0
- package/dest/services/reqresp/metrics.d.ts.map +1 -0
- package/dest/services/reqresp/metrics.js +42 -0
- package/dest/services/reqresp/protocols/block.d.ts +4 -0
- package/dest/services/reqresp/protocols/block.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/block.js +9 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts +51 -0
- package/dest/services/reqresp/protocols/goodbye.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/goodbye.js +92 -0
- package/dest/services/reqresp/protocols/index.d.ts +9 -0
- package/dest/services/reqresp/protocols/index.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/index.js +9 -0
- package/dest/services/reqresp/protocols/ping.d.ts +9 -0
- package/dest/services/reqresp/protocols/ping.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/ping.js +9 -0
- package/dest/services/reqresp/{handlers.d.ts → protocols/status.d.ts} +1 -7
- package/dest/services/reqresp/protocols/status.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/status.js +9 -0
- package/dest/services/reqresp/protocols/tx.d.ts +13 -0
- package/dest/services/reqresp/protocols/tx.d.ts.map +1 -0
- package/dest/services/reqresp/protocols/tx.js +23 -0
- package/dest/services/reqresp/rate-limiter/index.d.ts.map +1 -0
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/index.js +1 -1
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.d.ts +3 -3
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.d.ts.map +1 -1
- package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.js +4 -4
- package/dest/services/reqresp/rate-limiter/rate_limits.d.ts.map +1 -0
- package/dest/services/reqresp/rate-limiter/rate_limits.js +55 -0
- package/dest/services/reqresp/reqresp.d.ts +33 -6
- package/dest/services/reqresp/reqresp.d.ts.map +1 -1
- package/dest/services/reqresp/reqresp.js +414 -249
- package/dest/services/service.d.ts +8 -0
- package/dest/services/service.d.ts.map +1 -1
- package/dest/util.d.ts +4 -0
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +1 -1
- package/package.json +8 -8
- package/src/client/factory.ts +5 -13
- package/src/client/p2p_client.ts +32 -11
- package/src/config.ts +9 -0
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +2 -2
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +2 -2
- package/src/mem_pools/attestation_pool/mocks.ts +2 -2
- package/src/mem_pools/epoch_proof_quote_pool/memory_epoch_proof_quote_pool.ts +2 -2
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +92 -7
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +6 -2
- package/src/mem_pools/tx_pool/tx_pool.ts +7 -0
- package/src/mocks/index.ts +22 -24
- package/src/services/discv5/discV5_service.ts +2 -2
- package/src/services/dummy_service.ts +13 -0
- package/src/services/libp2p/libp2p_service.ts +143 -128
- package/src/services/peer-manager/metrics.ts +41 -0
- package/src/services/{peer_manager.ts → peer-manager/peer_manager.ts} +67 -22
- package/src/services/{peer-scoring → peer-manager}/peer_scoring.ts +16 -3
- package/src/services/reqresp/connection-sampler/batch_connection_sampler.ts +94 -0
- package/src/services/reqresp/connection-sampler/connection_sampler.ts +211 -0
- package/src/services/reqresp/interface.ts +39 -16
- package/src/services/reqresp/metrics.ts +57 -0
- package/src/services/reqresp/protocols/block.ts +15 -0
- package/src/services/reqresp/protocols/goodbye.ts +101 -0
- package/src/services/reqresp/protocols/index.ts +8 -0
- package/src/services/reqresp/protocols/ping.ts +8 -0
- package/src/services/reqresp/{handlers.ts → protocols/status.ts} +0 -9
- package/src/services/reqresp/protocols/tx.ts +29 -0
- package/src/services/reqresp/{rate_limiter → rate-limiter}/rate_limiter.ts +3 -3
- package/src/services/reqresp/{rate_limiter → rate-limiter}/rate_limits.ts +24 -4
- package/src/services/reqresp/reqresp.ts +224 -25
- package/src/services/service.ts +12 -0
- package/src/util.ts +4 -0
- package/dest/services/peer-scoring/peer_scoring.d.ts.map +0 -1
- package/dest/services/peer-scoring/peer_scoring.js +0 -75
- package/dest/services/peer_manager.d.ts.map +0 -1
- package/dest/services/peer_manager.js +0 -358
- package/dest/services/reqresp/handlers.d.ts.map +0 -1
- package/dest/services/reqresp/handlers.js +0 -17
- package/dest/services/reqresp/rate_limiter/index.d.ts.map +0 -1
- package/dest/services/reqresp/rate_limiter/rate_limits.d.ts.map +0 -1
- package/dest/services/reqresp/rate_limiter/rate_limits.js +0 -35
- /package/dest/services/reqresp/{rate_limiter → rate-limiter}/index.d.ts +0 -0
- /package/dest/services/reqresp/{rate_limiter → rate-limiter}/rate_limits.d.ts +0 -0
- /package/src/services/reqresp/{rate_limiter → rate-limiter}/index.ts +0 -0
package/src/mocks/index.ts
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
type WorldStateSynchronizer,
|
|
7
7
|
} from '@aztec/circuit-types';
|
|
8
8
|
import { type EpochCache } from '@aztec/epoch-cache';
|
|
9
|
+
import { timesParallel } from '@aztec/foundation/collection';
|
|
9
10
|
import { type DataStoreConfig } from '@aztec/kv-store/config';
|
|
10
11
|
import { openTmpStore } from '@aztec/kv-store/lmdb';
|
|
11
|
-
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
12
|
-
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
12
|
+
import { type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
13
13
|
|
|
14
14
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
15
15
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
@@ -27,17 +27,15 @@ import { type BootnodeConfig, type P2PConfig } from '../config.js';
|
|
|
27
27
|
import { type MemPools } from '../mem_pools/interface.js';
|
|
28
28
|
import { DiscV5Service } from '../services/discv5/discV5_service.js';
|
|
29
29
|
import { LibP2PService } from '../services/libp2p/libp2p_service.js';
|
|
30
|
-
import { type
|
|
30
|
+
import { type PeerScoring } from '../services/peer-manager/peer_scoring.js';
|
|
31
31
|
import { type P2PReqRespConfig } from '../services/reqresp/config.js';
|
|
32
|
-
import { pingHandler, statusHandler } from '../services/reqresp/handlers.js';
|
|
33
32
|
import {
|
|
34
|
-
|
|
33
|
+
ReqRespSubProtocol,
|
|
35
34
|
type ReqRespSubProtocolHandlers,
|
|
36
35
|
type ReqRespSubProtocolValidators,
|
|
37
|
-
STATUS_PROTOCOL,
|
|
38
|
-
TX_REQ_PROTOCOL,
|
|
39
36
|
noopValidator,
|
|
40
37
|
} from '../services/reqresp/interface.js';
|
|
38
|
+
import { pingHandler, statusHandler } from '../services/reqresp/protocols/index.js';
|
|
41
39
|
import { ReqResp } from '../services/reqresp/reqresp.js';
|
|
42
40
|
import { type PubSubLibp2p } from '../util.js';
|
|
43
41
|
|
|
@@ -152,25 +150,29 @@ export type ReqRespNode = {
|
|
|
152
150
|
|
|
153
151
|
// Mock sub protocol handlers
|
|
154
152
|
export const MOCK_SUB_PROTOCOL_HANDLERS: ReqRespSubProtocolHandlers = {
|
|
155
|
-
[
|
|
156
|
-
[
|
|
157
|
-
[
|
|
153
|
+
[ReqRespSubProtocol.PING]: pingHandler,
|
|
154
|
+
[ReqRespSubProtocol.STATUS]: statusHandler,
|
|
155
|
+
[ReqRespSubProtocol.TX]: (_msg: any) => Promise.resolve(Buffer.from('tx')),
|
|
156
|
+
[ReqRespSubProtocol.GOODBYE]: (_msg: any) => Promise.resolve(Buffer.from('goodbye')),
|
|
157
|
+
[ReqRespSubProtocol.BLOCK]: (_msg: any) => Promise.resolve(Buffer.from('block')),
|
|
158
158
|
};
|
|
159
159
|
|
|
160
160
|
// By default, all requests are valid
|
|
161
161
|
// If you want to test an invalid response, you can override the validator
|
|
162
162
|
export const MOCK_SUB_PROTOCOL_VALIDATORS: ReqRespSubProtocolValidators = {
|
|
163
|
-
[
|
|
164
|
-
[
|
|
165
|
-
[
|
|
163
|
+
[ReqRespSubProtocol.PING]: noopValidator,
|
|
164
|
+
[ReqRespSubProtocol.STATUS]: noopValidator,
|
|
165
|
+
[ReqRespSubProtocol.TX]: noopValidator,
|
|
166
|
+
[ReqRespSubProtocol.GOODBYE]: noopValidator,
|
|
167
|
+
[ReqRespSubProtocol.BLOCK]: noopValidator,
|
|
166
168
|
};
|
|
167
169
|
|
|
168
170
|
/**
|
|
169
171
|
* @param numberOfNodes - the number of nodes to create
|
|
170
172
|
* @returns An array of the created nodes
|
|
171
173
|
*/
|
|
172
|
-
export const createNodes =
|
|
173
|
-
return
|
|
174
|
+
export const createNodes = (peerScoring: PeerScoring, numberOfNodes: number): Promise<ReqRespNode[]> => {
|
|
175
|
+
return timesParallel(numberOfNodes, () => createReqResp(peerScoring));
|
|
174
176
|
};
|
|
175
177
|
|
|
176
178
|
export const startNodes = async (
|
|
@@ -184,22 +186,18 @@ export const startNodes = async (
|
|
|
184
186
|
};
|
|
185
187
|
|
|
186
188
|
export const stopNodes = async (nodes: ReqRespNode[]): Promise<void> => {
|
|
187
|
-
const stopPromises = [];
|
|
188
|
-
for (const node of nodes) {
|
|
189
|
-
stopPromises.push(node.req.stop());
|
|
190
|
-
stopPromises.push(node.p2p.stop());
|
|
191
|
-
}
|
|
189
|
+
const stopPromises = nodes.flatMap(node => [node.req.stop(), node.p2p.stop()]);
|
|
192
190
|
await Promise.all(stopPromises);
|
|
193
191
|
};
|
|
194
192
|
|
|
195
193
|
// Create a req resp node, exposing the underlying p2p node
|
|
196
|
-
export const createReqResp = async (
|
|
194
|
+
export const createReqResp = async (peerScoring: PeerScoring): Promise<ReqRespNode> => {
|
|
197
195
|
const p2p = await createLibp2pNode();
|
|
198
196
|
const config: P2PReqRespConfig = {
|
|
199
197
|
overallRequestTimeoutMs: 4000,
|
|
200
198
|
individualRequestTimeoutMs: 2000,
|
|
201
199
|
};
|
|
202
|
-
const req = new ReqResp(config, p2p,
|
|
200
|
+
const req = new ReqResp(config, p2p, peerScoring);
|
|
203
201
|
return {
|
|
204
202
|
p2p,
|
|
205
203
|
req,
|
|
@@ -247,7 +245,7 @@ export function createBootstrapNodeConfig(privateKey: string, port: number): Boo
|
|
|
247
245
|
export function createBootstrapNodeFromPrivateKey(
|
|
248
246
|
privateKey: string,
|
|
249
247
|
port: number,
|
|
250
|
-
telemetry: TelemetryClient =
|
|
248
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
251
249
|
): Promise<BootstrapNode> {
|
|
252
250
|
const config = createBootstrapNodeConfig(privateKey, port);
|
|
253
251
|
return startBootstrapNode(config, telemetry);
|
|
@@ -255,7 +253,7 @@ export function createBootstrapNodeFromPrivateKey(
|
|
|
255
253
|
|
|
256
254
|
export async function createBootstrapNode(
|
|
257
255
|
port: number,
|
|
258
|
-
telemetry: TelemetryClient =
|
|
256
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
259
257
|
): Promise<BootstrapNode> {
|
|
260
258
|
const peerId = await createSecp256k1PeerId();
|
|
261
259
|
const config = createBootstrapNodeConfig(Buffer.from(peerId.privateKey!).toString('hex'), port);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/foundation/log';
|
|
2
2
|
import { sleep } from '@aztec/foundation/sleep';
|
|
3
|
-
import { OtelMetricsAdapter, type TelemetryClient } from '@aztec/telemetry-client';
|
|
3
|
+
import { OtelMetricsAdapter, type TelemetryClient, getTelemetryClient } from '@aztec/telemetry-client';
|
|
4
4
|
|
|
5
5
|
import { Discv5, type Discv5EventEmitter } from '@chainsafe/discv5';
|
|
6
6
|
import { ENR, SignableENR } from '@chainsafe/enr';
|
|
@@ -38,7 +38,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
38
38
|
constructor(
|
|
39
39
|
private peerId: PeerId,
|
|
40
40
|
config: P2PConfig,
|
|
41
|
-
telemetry: TelemetryClient,
|
|
41
|
+
telemetry: TelemetryClient = getTelemetryClient(),
|
|
42
42
|
private logger = createLogger('p2p:discv5_service'),
|
|
43
43
|
) {
|
|
44
44
|
super();
|
|
@@ -61,6 +61,19 @@ export class DummyP2PService implements P2PService {
|
|
|
61
61
|
return Promise.resolve(undefined);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Sends a batch request to a peer.
|
|
66
|
+
* @param _protocol - The protocol to send the request on.
|
|
67
|
+
* @param _requests - The requests to send.
|
|
68
|
+
* @returns The responses from the peer, otherwise undefined.
|
|
69
|
+
*/
|
|
70
|
+
public sendBatchRequest<Protocol extends ReqRespSubProtocol>(
|
|
71
|
+
_protocol: Protocol,
|
|
72
|
+
_requests: InstanceType<SubProtocolMap[Protocol]['request']>[],
|
|
73
|
+
): Promise<InstanceType<SubProtocolMap[Protocol]['response']>[]> {
|
|
74
|
+
return Promise.resolve([]);
|
|
75
|
+
}
|
|
76
|
+
|
|
64
77
|
/**
|
|
65
78
|
* Returns the ENR of the peer.
|
|
66
79
|
* @returns The ENR of the peer, otherwise undefined.
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type RawGossipMessage,
|
|
13
13
|
TopicTypeMap,
|
|
14
14
|
Tx,
|
|
15
|
-
TxHash,
|
|
15
|
+
type TxHash,
|
|
16
16
|
type TxValidationResult,
|
|
17
17
|
type WorldStateSynchronizer,
|
|
18
18
|
getTopicTypeForClientType,
|
|
@@ -38,6 +38,7 @@ import { noise } from '@chainsafe/libp2p-noise';
|
|
|
38
38
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
39
39
|
import { identify } from '@libp2p/identify';
|
|
40
40
|
import { type Message, type PeerId, TopicValidatorResult } from '@libp2p/interface';
|
|
41
|
+
import { type ConnectionManager } from '@libp2p/interface-internal';
|
|
41
42
|
import '@libp2p/kad-dht';
|
|
42
43
|
import { mplex } from '@libp2p/mplex';
|
|
43
44
|
import { tcp } from '@libp2p/tcp';
|
|
@@ -56,18 +57,11 @@ import {
|
|
|
56
57
|
import { type PubSubLibp2p, convertToMultiaddr } from '../../util.js';
|
|
57
58
|
import { AztecDatastore } from '../data_store.js';
|
|
58
59
|
import { SnappyTransform, fastMsgIdFn, getMsgIdFn, msgIdToStrFn } from '../encoding.js';
|
|
59
|
-
import { PeerManager } from '../peer_manager.js';
|
|
60
|
-
import {
|
|
61
|
-
import {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
PING_PROTOCOL,
|
|
65
|
-
type ReqRespSubProtocol,
|
|
66
|
-
type ReqRespSubProtocolHandlers,
|
|
67
|
-
STATUS_PROTOCOL,
|
|
68
|
-
type SubProtocolMap,
|
|
69
|
-
TX_REQ_PROTOCOL,
|
|
70
|
-
} from '../reqresp/interface.js';
|
|
60
|
+
import { PeerManager } from '../peer-manager/peer_manager.js';
|
|
61
|
+
import { PeerScoring } from '../peer-manager/peer_scoring.js';
|
|
62
|
+
import { DEFAULT_SUB_PROTOCOL_VALIDATORS, ReqRespSubProtocol, type SubProtocolMap } from '../reqresp/interface.js';
|
|
63
|
+
import { reqGoodbyeHandler } from '../reqresp/protocols/goodbye.js';
|
|
64
|
+
import { pingHandler, reqRespBlockHandler, reqRespTxHandler, statusHandler } from '../reqresp/protocols/index.js';
|
|
71
65
|
import { ReqResp } from '../reqresp/reqresp.js';
|
|
72
66
|
import type { P2PService, PeerDiscoveryService } from '../service.js';
|
|
73
67
|
import { GossipSubEvent } from '../types.js';
|
|
@@ -117,21 +111,32 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
117
111
|
private peerDiscoveryService: PeerDiscoveryService,
|
|
118
112
|
private mempools: MemPools<T>,
|
|
119
113
|
private l2BlockSource: L2BlockSource,
|
|
120
|
-
|
|
114
|
+
epochCache: EpochCache,
|
|
121
115
|
private proofVerifier: ClientProtocolCircuitVerifier,
|
|
122
116
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
123
|
-
|
|
124
|
-
private requestResponseHandlers: ReqRespSubProtocolHandlers = DEFAULT_SUB_PROTOCOL_HANDLERS,
|
|
117
|
+
telemetry: TelemetryClient,
|
|
125
118
|
private logger = createLogger('p2p:libp2p_service'),
|
|
126
119
|
) {
|
|
127
120
|
super(telemetry, 'LibP2PService');
|
|
128
121
|
|
|
129
|
-
|
|
122
|
+
const peerScoring = new PeerScoring(config);
|
|
123
|
+
this.reqresp = new ReqResp(config, node, peerScoring);
|
|
124
|
+
|
|
125
|
+
this.peerManager = new PeerManager(
|
|
126
|
+
node,
|
|
127
|
+
peerDiscoveryService,
|
|
128
|
+
config,
|
|
129
|
+
telemetry,
|
|
130
|
+
logger,
|
|
131
|
+
peerScoring,
|
|
132
|
+
this.reqresp,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// Update gossipsub score params
|
|
130
136
|
this.node.services.pubsub.score.params.appSpecificScore = (peerId: string) => {
|
|
131
137
|
return this.peerManager.getPeerScore(peerId);
|
|
132
138
|
};
|
|
133
139
|
this.node.services.pubsub.score.params.appSpecificWeight = 10;
|
|
134
|
-
this.reqresp = new ReqResp(config, node, this.peerManager);
|
|
135
140
|
|
|
136
141
|
this.attestationValidator = new AttestationValidator(epochCache);
|
|
137
142
|
this.blockProposalValidator = new BlockProposalValidator(epochCache);
|
|
@@ -145,95 +150,6 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
145
150
|
};
|
|
146
151
|
}
|
|
147
152
|
|
|
148
|
-
/**
|
|
149
|
-
* Starts the LibP2P service.
|
|
150
|
-
* @returns An empty promise.
|
|
151
|
-
*/
|
|
152
|
-
public async start() {
|
|
153
|
-
// Check if service is already started
|
|
154
|
-
if (this.node.status === 'started') {
|
|
155
|
-
throw new Error('P2P service already started');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Get listen & announce addresses for logging
|
|
159
|
-
const { tcpListenAddress, tcpAnnounceAddress } = this.config;
|
|
160
|
-
if (!tcpAnnounceAddress) {
|
|
161
|
-
throw new Error('Announce address not provided.');
|
|
162
|
-
}
|
|
163
|
-
const announceTcpMultiaddr = convertToMultiaddr(tcpAnnounceAddress, 'tcp');
|
|
164
|
-
|
|
165
|
-
// Start job queue, peer discovery service and libp2p node
|
|
166
|
-
this.jobQueue.start();
|
|
167
|
-
await this.peerDiscoveryService.start();
|
|
168
|
-
await this.node.start();
|
|
169
|
-
|
|
170
|
-
// Subscribe to standard GossipSub topics by default
|
|
171
|
-
for (const topic of getTopicTypeForClientType(this.clientType)) {
|
|
172
|
-
this.subscribeToTopic(TopicTypeMap[topic].p2pTopic);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
// Add p2p topic validators
|
|
176
|
-
// As they are stored within a kv pair, there is no need to register them conditionally
|
|
177
|
-
// based on the client type
|
|
178
|
-
const topicValidators = {
|
|
179
|
-
[Tx.p2pTopic]: this.validatePropagatedTxFromMessage.bind(this),
|
|
180
|
-
[BlockAttestation.p2pTopic]: this.validatePropagatedAttestationFromMessage.bind(this),
|
|
181
|
-
[BlockProposal.p2pTopic]: this.validatePropagatedBlockFromMessage.bind(this),
|
|
182
|
-
[EpochProofQuote.p2pTopic]: this.validatePropagatedEpochProofQuoteFromMessage.bind(this),
|
|
183
|
-
};
|
|
184
|
-
for (const [topic, validator] of Object.entries(topicValidators)) {
|
|
185
|
-
this.node.services.pubsub.topicValidators.set(topic, validator);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// add GossipSub listener
|
|
189
|
-
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.handleGossipSubEvent.bind(this));
|
|
190
|
-
|
|
191
|
-
// Start running promise for peer discovery
|
|
192
|
-
this.discoveryRunningPromise = new RunningPromise(
|
|
193
|
-
() => this.peerManager.heartbeat(),
|
|
194
|
-
this.logger,
|
|
195
|
-
this.config.peerCheckIntervalMS,
|
|
196
|
-
);
|
|
197
|
-
this.discoveryRunningPromise.start();
|
|
198
|
-
|
|
199
|
-
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
200
|
-
const reqrespSubProtocolValidators = {
|
|
201
|
-
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
202
|
-
[TX_REQ_PROTOCOL]: this.validateRequestedTx.bind(this),
|
|
203
|
-
};
|
|
204
|
-
await this.reqresp.start(this.requestResponseHandlers, reqrespSubProtocolValidators);
|
|
205
|
-
this.logger.info(`Started P2P service`, {
|
|
206
|
-
listen: tcpListenAddress,
|
|
207
|
-
announce: announceTcpMultiaddr,
|
|
208
|
-
peerId: this.node.peerId.toString(),
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Stops the LibP2P service.
|
|
214
|
-
* @returns An empty promise.
|
|
215
|
-
*/
|
|
216
|
-
public async stop() {
|
|
217
|
-
// Remove gossip sub listener
|
|
218
|
-
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.handleGossipSubEvent.bind(this));
|
|
219
|
-
|
|
220
|
-
// Stop peer manager
|
|
221
|
-
this.logger.debug('Stopping peer manager...');
|
|
222
|
-
this.peerManager.stop();
|
|
223
|
-
|
|
224
|
-
this.logger.debug('Stopping job queue...');
|
|
225
|
-
await this.jobQueue.end();
|
|
226
|
-
this.logger.debug('Stopping running promise...');
|
|
227
|
-
await this.discoveryRunningPromise?.stop();
|
|
228
|
-
this.logger.debug('Stopping peer discovery service...');
|
|
229
|
-
await this.peerDiscoveryService.stop();
|
|
230
|
-
this.logger.debug('Request response service stopped...');
|
|
231
|
-
await this.reqresp.stop();
|
|
232
|
-
this.logger.debug('Stopping LibP2P...');
|
|
233
|
-
await this.stopLibP2P();
|
|
234
|
-
this.logger.info('LibP2P service stopped');
|
|
235
|
-
}
|
|
236
|
-
|
|
237
153
|
/**
|
|
238
154
|
* Creates an instance of the LibP2P service.
|
|
239
155
|
* @param config - The configuration to use when creating the service.
|
|
@@ -333,28 +249,12 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
333
249
|
},
|
|
334
250
|
}),
|
|
335
251
|
}) as (components: GossipSubComponents) => GossipSub,
|
|
252
|
+
components: (components: { connectionManager: ConnectionManager }) => ({
|
|
253
|
+
connectionManager: components.connectionManager,
|
|
254
|
+
}),
|
|
336
255
|
},
|
|
337
256
|
});
|
|
338
257
|
|
|
339
|
-
// Create request response protocol handlers
|
|
340
|
-
/**
|
|
341
|
-
* Handler for tx requests
|
|
342
|
-
* @param msg - the tx request message
|
|
343
|
-
* @returns the tx response message
|
|
344
|
-
*/
|
|
345
|
-
const txHandler = (msg: Buffer): Promise<Buffer> => {
|
|
346
|
-
const txHash = TxHash.fromBuffer(msg);
|
|
347
|
-
const foundTx = mempools.txPool.getTxByHash(txHash);
|
|
348
|
-
const buf = foundTx ? foundTx.toBuffer() : Buffer.alloc(0);
|
|
349
|
-
return Promise.resolve(buf);
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
const requestResponseHandlers = {
|
|
353
|
-
[PING_PROTOCOL]: pingHandler,
|
|
354
|
-
[STATUS_PROTOCOL]: statusHandler,
|
|
355
|
-
[TX_REQ_PROTOCOL]: txHandler,
|
|
356
|
-
};
|
|
357
|
-
|
|
358
258
|
return new LibP2PService(
|
|
359
259
|
clientType,
|
|
360
260
|
config,
|
|
@@ -366,10 +266,112 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
366
266
|
proofVerifier,
|
|
367
267
|
worldStateSynchronizer,
|
|
368
268
|
telemetry,
|
|
369
|
-
requestResponseHandlers,
|
|
370
269
|
);
|
|
371
270
|
}
|
|
372
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Starts the LibP2P service.
|
|
274
|
+
* @returns An empty promise.
|
|
275
|
+
*/
|
|
276
|
+
public async start() {
|
|
277
|
+
// Check if service is already started
|
|
278
|
+
if (this.node.status === 'started') {
|
|
279
|
+
throw new Error('P2P service already started');
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Get listen & announce addresses for logging
|
|
283
|
+
const { tcpListenAddress, tcpAnnounceAddress } = this.config;
|
|
284
|
+
if (!tcpAnnounceAddress) {
|
|
285
|
+
throw new Error('Announce address not provided.');
|
|
286
|
+
}
|
|
287
|
+
const announceTcpMultiaddr = convertToMultiaddr(tcpAnnounceAddress, 'tcp');
|
|
288
|
+
|
|
289
|
+
// Start job queue, peer discovery service and libp2p node
|
|
290
|
+
this.jobQueue.start();
|
|
291
|
+
await this.peerDiscoveryService.start();
|
|
292
|
+
await this.node.start();
|
|
293
|
+
|
|
294
|
+
// Subscribe to standard GossipSub topics by default
|
|
295
|
+
for (const topic of getTopicTypeForClientType(this.clientType)) {
|
|
296
|
+
this.subscribeToTopic(TopicTypeMap[topic].p2pTopic);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Create request response protocol handlers
|
|
300
|
+
const txHandler = reqRespTxHandler(this.mempools);
|
|
301
|
+
const goodbyeHandler = reqGoodbyeHandler(this.peerManager);
|
|
302
|
+
const blockHandler = reqRespBlockHandler(this.l2BlockSource);
|
|
303
|
+
|
|
304
|
+
const requestResponseHandlers = {
|
|
305
|
+
[ReqRespSubProtocol.PING]: pingHandler,
|
|
306
|
+
[ReqRespSubProtocol.STATUS]: statusHandler,
|
|
307
|
+
[ReqRespSubProtocol.TX]: txHandler.bind(this),
|
|
308
|
+
[ReqRespSubProtocol.GOODBYE]: goodbyeHandler.bind(this),
|
|
309
|
+
[ReqRespSubProtocol.BLOCK]: blockHandler.bind(this),
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
// Add p2p topic validators
|
|
313
|
+
// As they are stored within a kv pair, there is no need to register them conditionally
|
|
314
|
+
// based on the client type
|
|
315
|
+
const topicValidators = {
|
|
316
|
+
[Tx.p2pTopic]: this.validatePropagatedTxFromMessage.bind(this),
|
|
317
|
+
[BlockAttestation.p2pTopic]: this.validatePropagatedAttestationFromMessage.bind(this),
|
|
318
|
+
[BlockProposal.p2pTopic]: this.validatePropagatedBlockFromMessage.bind(this),
|
|
319
|
+
[EpochProofQuote.p2pTopic]: this.validatePropagatedEpochProofQuoteFromMessage.bind(this),
|
|
320
|
+
};
|
|
321
|
+
for (const [topic, validator] of Object.entries(topicValidators)) {
|
|
322
|
+
this.node.services.pubsub.topicValidators.set(topic, validator);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// add GossipSub listener
|
|
326
|
+
this.node.services.pubsub.addEventListener(GossipSubEvent.MESSAGE, this.handleGossipSubEvent.bind(this));
|
|
327
|
+
|
|
328
|
+
// Start running promise for peer discovery
|
|
329
|
+
this.discoveryRunningPromise = new RunningPromise(
|
|
330
|
+
() => this.peerManager.heartbeat(),
|
|
331
|
+
this.logger,
|
|
332
|
+
this.config.peerCheckIntervalMS,
|
|
333
|
+
);
|
|
334
|
+
this.discoveryRunningPromise.start();
|
|
335
|
+
|
|
336
|
+
// Define the sub protocol validators - This is done within this start() method to gain a callback to the existing validateTx function
|
|
337
|
+
const reqrespSubProtocolValidators = {
|
|
338
|
+
...DEFAULT_SUB_PROTOCOL_VALIDATORS,
|
|
339
|
+
// TODO(#11336): A request validator for blocks
|
|
340
|
+
[ReqRespSubProtocol.TX]: this.validateRequestedTx.bind(this),
|
|
341
|
+
};
|
|
342
|
+
await this.reqresp.start(requestResponseHandlers, reqrespSubProtocolValidators);
|
|
343
|
+
this.logger.info(`Started P2P service`, {
|
|
344
|
+
listen: tcpListenAddress,
|
|
345
|
+
announce: announceTcpMultiaddr,
|
|
346
|
+
peerId: this.node.peerId.toString(),
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Stops the LibP2P service.
|
|
352
|
+
* @returns An empty promise.
|
|
353
|
+
*/
|
|
354
|
+
public async stop() {
|
|
355
|
+
// Remove gossip sub listener
|
|
356
|
+
this.node.services.pubsub.removeEventListener(GossipSubEvent.MESSAGE, this.handleGossipSubEvent.bind(this));
|
|
357
|
+
|
|
358
|
+
// Stop peer manager
|
|
359
|
+
this.logger.debug('Stopping peer manager...');
|
|
360
|
+
await this.peerManager.stop();
|
|
361
|
+
|
|
362
|
+
this.logger.debug('Stopping job queue...');
|
|
363
|
+
await this.jobQueue.end();
|
|
364
|
+
this.logger.debug('Stopping running promise...');
|
|
365
|
+
await this.discoveryRunningPromise?.stop();
|
|
366
|
+
this.logger.debug('Stopping peer discovery service...');
|
|
367
|
+
await this.peerDiscoveryService.stop();
|
|
368
|
+
this.logger.debug('Request response service stopped...');
|
|
369
|
+
await this.reqresp.stop();
|
|
370
|
+
this.logger.debug('Stopping LibP2P...');
|
|
371
|
+
await this.stopLibP2P();
|
|
372
|
+
this.logger.info('LibP2P service stopped');
|
|
373
|
+
}
|
|
374
|
+
|
|
373
375
|
public getPeers(includePending?: boolean): PeerInfo[] {
|
|
374
376
|
return this.peerManager.getPeers(includePending);
|
|
375
377
|
}
|
|
@@ -398,6 +400,19 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
398
400
|
return this.reqresp.sendRequest(protocol, request);
|
|
399
401
|
}
|
|
400
402
|
|
|
403
|
+
/**
|
|
404
|
+
* Send a batch of requests to peers, and return the responses
|
|
405
|
+
* @param protocol - The request response protocol to use
|
|
406
|
+
* @param requests - The requests to send to the peers
|
|
407
|
+
* @returns The responses to the requests
|
|
408
|
+
*/
|
|
409
|
+
sendBatchRequest<SubProtocol extends ReqRespSubProtocol>(
|
|
410
|
+
protocol: SubProtocol,
|
|
411
|
+
requests: InstanceType<SubProtocolMap[SubProtocol]['request']>[],
|
|
412
|
+
): Promise<InstanceType<SubProtocolMap[SubProtocol]['response']>[] | undefined> {
|
|
413
|
+
return this.reqresp.sendBatchRequest(protocol, requests);
|
|
414
|
+
}
|
|
415
|
+
|
|
401
416
|
/**
|
|
402
417
|
* Get the ENR of the node
|
|
403
418
|
* @returns The ENR of the node
|
|
@@ -548,7 +563,7 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
548
563
|
* In order to perform this check, the tx proof must be verified.
|
|
549
564
|
*
|
|
550
565
|
* Note: This function is called from within `ReqResp.sendRequest` as part of the
|
|
551
|
-
*
|
|
566
|
+
* ReqRespSubProtocol.TX subprotocol validation.
|
|
552
567
|
*
|
|
553
568
|
* @param requestedTxHash - The hash of the tx that was requested.
|
|
554
569
|
* @param responseTx - The tx that was received as a response to the request.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Attributes,
|
|
3
|
+
Metrics,
|
|
4
|
+
type TelemetryClient,
|
|
5
|
+
type Tracer,
|
|
6
|
+
type UpDownCounter,
|
|
7
|
+
ValueType,
|
|
8
|
+
} from '@aztec/telemetry-client';
|
|
9
|
+
|
|
10
|
+
import { type GoodByeReason, prettyGoodbyeReason } from '../reqresp/protocols/index.js';
|
|
11
|
+
|
|
12
|
+
export class PeerManagerMetrics {
|
|
13
|
+
private sentGoodbyes: UpDownCounter;
|
|
14
|
+
private receivedGoodbyes: UpDownCounter;
|
|
15
|
+
|
|
16
|
+
public readonly tracer: Tracer;
|
|
17
|
+
|
|
18
|
+
constructor(public readonly telemetryClient: TelemetryClient, name = 'PeerManager') {
|
|
19
|
+
this.tracer = telemetryClient.getTracer(name);
|
|
20
|
+
|
|
21
|
+
const meter = telemetryClient.getMeter(name);
|
|
22
|
+
this.sentGoodbyes = meter.createUpDownCounter(Metrics.PEER_MANAGER_GOODBYES_SENT, {
|
|
23
|
+
description: 'Number of goodbyes sent to peers',
|
|
24
|
+
unit: 'peers',
|
|
25
|
+
valueType: ValueType.INT,
|
|
26
|
+
});
|
|
27
|
+
this.receivedGoodbyes = meter.createUpDownCounter(Metrics.PEER_MANAGER_GOODBYES_RECEIVED, {
|
|
28
|
+
description: 'Number of goodbyes received from peers',
|
|
29
|
+
unit: 'peers',
|
|
30
|
+
valueType: ValueType.INT,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public recordGoodbyeSent(reason: GoodByeReason) {
|
|
35
|
+
this.sentGoodbyes.add(1, { [Attributes.P2P_GOODBYE_REASON]: prettyGoodbyeReason(reason) });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public recordGoodbyeReceived(reason: GoodByeReason) {
|
|
39
|
+
this.receivedGoodbyes.add(1, { [Attributes.P2P_GOODBYE_REASON]: prettyGoodbyeReason(reason) });
|
|
40
|
+
}
|
|
41
|
+
}
|