@aztec/p2p 0.78.1 → 0.79.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/config.d.ts +5 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +6 -0
- package/dest/services/libp2p/libp2p_service.d.ts +1 -0
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +9 -3
- package/dest/services/peer-manager/metrics.d.ts +3 -1
- package/dest/services/peer-manager/metrics.d.ts.map +1 -1
- package/dest/services/peer-manager/metrics.js +11 -2
- package/dest/services/peer-manager/peer_manager.d.ts +21 -0
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +58 -8
- package/package.json +11 -11
- package/src/config.ts +11 -0
- package/src/services/libp2p/libp2p_service.ts +12 -2
- package/src/services/peer-manager/metrics.ts +13 -1
- package/src/services/peer-manager/peer_manager.ts +73 -9
package/dest/config.d.ts
CHANGED
|
@@ -124,6 +124,10 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
|
|
|
124
124
|
peerPenaltyValues: number[];
|
|
125
125
|
/** Limit of transactions to archive in the tx pool. Once the archived tx limit is reached, the oldest archived txs will be purged. */
|
|
126
126
|
archivedTxLimit: number;
|
|
127
|
+
/**
|
|
128
|
+
* A list of trusted peers.
|
|
129
|
+
*/
|
|
130
|
+
trustedPeers: string[];
|
|
127
131
|
}
|
|
128
132
|
export declare const p2pConfigMappings: ConfigMappingsType<P2PConfig>;
|
|
129
133
|
/**
|
|
@@ -176,5 +180,6 @@ export declare const bootnodeConfigMappings: ConfigMappingsType<Pick<{
|
|
|
176
180
|
gossipsubTxInvalidMessageDeliveriesDecay: unknown;
|
|
177
181
|
peerPenaltyValues: unknown;
|
|
178
182
|
archivedTxLimit: unknown;
|
|
183
|
+
trustedPeers: unknown;
|
|
179
184
|
}, "udpAnnounceAddress" | "udpListenAddress" | "peerIdPrivateKey" | "bootstrapNodes" | "l1ChainId" | "dataDirectory" | "dataStoreMapSizeKB">>;
|
|
180
185
|
//# sourceMappingURL=config.d.ts.map
|
package/dest/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAMxB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,KAAK,WAAW,EAAuB,MAAM,sBAAsB,CAAC;AAE7E,OAAO,EAAE,KAAK,gBAAgB,EAA4B,MAAM,8BAA8B,CAAC;AAE/F;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,gBAAgB,EAAE,WAAW;IAC9D;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,6BAA6B,EAAE,OAAO,CAAC;IAEvC;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IAEzB,sEAAsE;IACtE,4BAA4B,EAAE,OAAO,CAAC;IAEtC,iGAAiG;IACjG,yBAAyB,EAAE,OAAO,CAAC;IAEnC;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB,+HAA+H;IAC/H,sBAAsB,EAAE,MAAM,CAAC;IAE/B,+CAA+C;IAC/C,yBAAyB,EAAE,MAAM,CAAC;IAElC;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,kCAAkC,EAAE,MAAM,CAAC;IAE3C;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,yCAAyC,EAAE,MAAM,CAAC;IAElD;;OAEG;IACH,wCAAwC,EAAE,MAAM,CAAC;IAEjD;;OAEG;IACH,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAE5B,sIAAsI;IACtI,eAAe,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dest/config.js
CHANGED
|
@@ -165,6 +165,12 @@ export const p2pConfigMappings = {
|
|
|
165
165
|
description: 'The number of transactions that will be archived. If the limit is set to 0 then archiving will be disabled.',
|
|
166
166
|
...numberConfigHelper(0)
|
|
167
167
|
},
|
|
168
|
+
trustedPeers: {
|
|
169
|
+
env: 'P2P_TRUSTED_PEERS',
|
|
170
|
+
parseEnv: (val)=>val.split(','),
|
|
171
|
+
description: 'A list of trusted peers ENRs. Separated by commas.',
|
|
172
|
+
defaultValue: []
|
|
173
|
+
},
|
|
168
174
|
...p2pReqRespConfigMappings,
|
|
169
175
|
...chainConfigMappings
|
|
170
176
|
};
|
|
@@ -32,6 +32,7 @@ export declare class LibP2PService<T extends P2PClientType> extends WithTracer i
|
|
|
32
32
|
private attestationValidator;
|
|
33
33
|
private blockProposalValidator;
|
|
34
34
|
reqresp: ReqResp;
|
|
35
|
+
private trustedPeersIds;
|
|
35
36
|
/**
|
|
36
37
|
* Callback for when a block is received from a peer.
|
|
37
38
|
* @param block - The block received from the peer.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAK9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACvH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,UAAU,EACf,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAkC,KAAK,eAAe,EAAE,UAAU,EAAa,MAAM,yBAAyB,CAAC;AAEtH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAa1C,OAAO,EAAgB,KAAK,MAAM,EAAwB,MAAM,mBAAmB,CAAC;AAEpF,OAAO,iBAAiB,CAAC;AAKzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAS7D,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,eAAe,CAAC;AAMtE,OAAO,EAAmC,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGnH,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAiBtE;;GAEG;AACH,qBAAa,aAAa,CAAC,CAAC,SAAS,aAAa,CAAE,SAAQ,UAAW,YAAW,UAAU;
|
|
1
|
+
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../../src/services/libp2p/libp2p_service.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,13 +57,15 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
57
57
|
blockProposalValidator;
|
|
58
58
|
// Request and response sub service
|
|
59
59
|
reqresp;
|
|
60
|
+
// Trusted peers ids
|
|
61
|
+
trustedPeersIds;
|
|
60
62
|
/**
|
|
61
63
|
* Callback for when a block is received from a peer.
|
|
62
64
|
* @param block - The block received from the peer.
|
|
63
65
|
* @returns The attestation for the block, if any.
|
|
64
66
|
*/ blockReceivedCallback;
|
|
65
67
|
constructor(clientType, config, node, peerDiscoveryService, mempools, l2BlockSource, epochCache, proofVerifier, worldStateSynchronizer, telemetry, logger = createLogger('p2p:libp2p_service')){
|
|
66
|
-
super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.mempools = mempools, this.l2BlockSource = l2BlockSource, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.logger = logger, this.jobQueue = new SerialQueue();
|
|
68
|
+
super(telemetry, 'LibP2PService'), this.clientType = clientType, this.config = config, this.node = node, this.peerDiscoveryService = peerDiscoveryService, this.mempools = mempools, this.l2BlockSource = l2BlockSource, this.proofVerifier = proofVerifier, this.worldStateSynchronizer = worldStateSynchronizer, this.logger = logger, this.jobQueue = new SerialQueue(), this.trustedPeersIds = [];
|
|
67
69
|
const peerScoring = new PeerScoring(config);
|
|
68
70
|
this.reqresp = new ReqResp(config, node, peerScoring);
|
|
69
71
|
this.peerManager = new PeerManager(node, peerDiscoveryService, config, telemetry, createLogger(`${logger.module}:peer_manager`), peerScoring, this.reqresp);
|
|
@@ -93,11 +95,14 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
93
95
|
const announceAddrTcp = convertToMultiaddr(tcpAnnounceAddress, 'tcp');
|
|
94
96
|
const datastore = new AztecDatastore(store);
|
|
95
97
|
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
98
|
+
const bootstrapNodes = peerDiscoveryService.bootstrapNodes;
|
|
99
|
+
// If trusted peers are provided, also provide them to the p2p service
|
|
100
|
+
bootstrapNodes.push(...config.trustedPeers);
|
|
96
101
|
// If bootstrap nodes are provided, also provide them to the p2p service
|
|
97
102
|
const peerDiscovery = [];
|
|
98
|
-
if (
|
|
103
|
+
if (bootstrapNodes.length > 0) {
|
|
99
104
|
peerDiscovery.push(bootstrap({
|
|
100
|
-
list:
|
|
105
|
+
list: bootstrapNodes
|
|
101
106
|
}));
|
|
102
107
|
}
|
|
103
108
|
const node = await createLibp2p({
|
|
@@ -210,6 +215,7 @@ import { ReqResp } from '../reqresp/reqresp.js';
|
|
|
210
215
|
const announceTcpMultiaddr = convertToMultiaddr(tcpAnnounceAddress, 'tcp');
|
|
211
216
|
// Start job queue, peer discovery service and libp2p node
|
|
212
217
|
this.jobQueue.start();
|
|
218
|
+
await this.peerManager.initializeTrustedPeers();
|
|
213
219
|
await this.peerDiscoveryService.start();
|
|
214
220
|
await this.node.start();
|
|
215
221
|
// Subscribe to standard GossipSub topics by default
|
|
@@ -4,9 +4,11 @@ export declare class PeerManagerMetrics {
|
|
|
4
4
|
readonly telemetryClient: TelemetryClient;
|
|
5
5
|
private sentGoodbyes;
|
|
6
6
|
private receivedGoodbyes;
|
|
7
|
+
private peerCount;
|
|
7
8
|
readonly tracer: Tracer;
|
|
8
|
-
constructor(telemetryClient
|
|
9
|
+
constructor(telemetryClient?: TelemetryClient, name?: string);
|
|
9
10
|
recordGoodbyeSent(reason: GoodByeReason): void;
|
|
10
11
|
recordGoodbyeReceived(reason: GoodByeReason): void;
|
|
12
|
+
recordPeerCount(count: number): void;
|
|
11
13
|
}
|
|
12
14
|
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,MAAM,EAIZ,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,+BAA+B,CAAC;AAExF,qBAAa,kBAAkB;aAOD,eAAe,EAAE,eAAe;IAN5D,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,SAAS,CAAQ;IAEzB,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEH,eAAe,GAAE,eAAsC,EAAE,IAAI,SAAgB;IAqBlG,iBAAiB,CAAC,MAAM,EAAE,aAAa;IAIvC,qBAAqB,CAAC,MAAM,EAAE,aAAa;IAI3C,eAAe,CAAC,KAAK,EAAE,MAAM;CAGrC"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { Attributes, Metrics, ValueType } from '@aztec/telemetry-client';
|
|
1
|
+
import { Attributes, Metrics, ValueType, getTelemetryClient } from '@aztec/telemetry-client';
|
|
2
2
|
import { prettyGoodbyeReason } from '../reqresp/protocols/index.js';
|
|
3
3
|
export class PeerManagerMetrics {
|
|
4
4
|
telemetryClient;
|
|
5
5
|
sentGoodbyes;
|
|
6
6
|
receivedGoodbyes;
|
|
7
|
+
peerCount;
|
|
7
8
|
tracer;
|
|
8
|
-
constructor(telemetryClient, name = 'PeerManager'){
|
|
9
|
+
constructor(telemetryClient = getTelemetryClient(), name = 'PeerManager'){
|
|
9
10
|
this.telemetryClient = telemetryClient;
|
|
10
11
|
this.tracer = telemetryClient.getTracer(name);
|
|
11
12
|
const meter = telemetryClient.getMeter(name);
|
|
@@ -19,6 +20,11 @@ export class PeerManagerMetrics {
|
|
|
19
20
|
unit: 'peers',
|
|
20
21
|
valueType: ValueType.INT
|
|
21
22
|
});
|
|
23
|
+
this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT, {
|
|
24
|
+
description: 'Number of peers',
|
|
25
|
+
unit: 'peers',
|
|
26
|
+
valueType: ValueType.INT
|
|
27
|
+
});
|
|
22
28
|
}
|
|
23
29
|
recordGoodbyeSent(reason) {
|
|
24
30
|
this.sentGoodbyes.add(1, {
|
|
@@ -30,4 +36,7 @@ export class PeerManagerMetrics {
|
|
|
30
36
|
[Attributes.P2P_GOODBYE_REASON]: prettyGoodbyeReason(reason)
|
|
31
37
|
});
|
|
32
38
|
}
|
|
39
|
+
recordPeerCount(count) {
|
|
40
|
+
this.peerCount.record(count);
|
|
41
|
+
}
|
|
33
42
|
}
|
|
@@ -19,9 +19,17 @@ export declare class PeerManager {
|
|
|
19
19
|
private heartbeatCounter;
|
|
20
20
|
private displayPeerCountsPeerHeartbeat;
|
|
21
21
|
private timedOutPeers;
|
|
22
|
+
private trustedPeers;
|
|
23
|
+
private trustedPeersInitialized;
|
|
22
24
|
private metrics;
|
|
23
25
|
private discoveredPeerHandler;
|
|
24
26
|
constructor(libP2PNode: PubSubLibp2p, peerDiscoveryService: PeerDiscoveryService, config: P2PConfig, telemetryClient: TelemetryClient, logger: import("@aztec/foundation/log").Logger, peerScoring: PeerScoring, reqresp: ReqResp);
|
|
27
|
+
/**
|
|
28
|
+
* Initializes the trusted peers.
|
|
29
|
+
*
|
|
30
|
+
* This function is called when the peer manager is initialized.
|
|
31
|
+
*/
|
|
32
|
+
initializeTrustedPeers(): Promise<void>;
|
|
25
33
|
get tracer(): import("@aztec/telemetry-client").Tracer;
|
|
26
34
|
heartbeat(): void;
|
|
27
35
|
/**
|
|
@@ -42,6 +50,18 @@ export declare class PeerManager {
|
|
|
42
50
|
* @param e - The disconnected peer event.
|
|
43
51
|
*/
|
|
44
52
|
private handleDisconnectedPeerEvent;
|
|
53
|
+
/**
|
|
54
|
+
* Checks if a peer is trusted.
|
|
55
|
+
* @param peerId - The peer ID.
|
|
56
|
+
* @returns True if the peer is trusted, false otherwise.
|
|
57
|
+
* Note: This function will return false and log a warning if the trusted peers are not initialized.
|
|
58
|
+
*/
|
|
59
|
+
private isTrustedPeer;
|
|
60
|
+
/**
|
|
61
|
+
* Adds a peer to the trusted peers set.
|
|
62
|
+
* @param peerId - The peer ID to add to trusted peers.
|
|
63
|
+
*/
|
|
64
|
+
addTrustedPeer(peerId: PeerId): void;
|
|
45
65
|
/**
|
|
46
66
|
* Handles a goodbye received from a peer.
|
|
47
67
|
*
|
|
@@ -57,6 +77,7 @@ export declare class PeerManager {
|
|
|
57
77
|
* Discovers peers.
|
|
58
78
|
*/
|
|
59
79
|
private discover;
|
|
80
|
+
private onlyNotTrustedPeers;
|
|
60
81
|
private pruneUnhealthyPeers;
|
|
61
82
|
/**
|
|
62
83
|
* If the max peer count is reached, the lowest scoring peers will be pruned to satisfy the max peer count.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBrE,qBAAa,WAAW;
|
|
1
|
+
{"version":3,"file":"peer_manager.d.ts","sourceRoot":"","sources":["../../../src/services/peer-manager/peer_manager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAc,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,aAAa,EAAuB,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoBrE,qBAAa,WAAW;IAYpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,MAAM;IAEd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,OAAO;IAjBjB,OAAO,CAAC,WAAW,CAAsC;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,8BAA8B,CAAa;IACnD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,uBAAuB,CAAkB;IAEjD,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,qBAAqB,CAAC;gBAGpB,UAAU,EAAE,YAAY,EACxB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,SAAS,EACzB,eAAe,EAAE,eAAe,EACxB,MAAM,wCAAmC,EACzC,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,OAAO;IAoB1B;;;;OAIG;IACG,sBAAsB;IAU5B,IAAI,MAAM,6CAET;IAGM,SAAS;IAShB;;;;;;OAMG;IACH,OAAO,CAAC,sBAAsB;IAU9B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IASnC;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM3C;;;;;;OAMG;IACI,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAQrD,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB;IAIvD,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIpC,QAAQ,CAAC,cAAc,UAAQ,GAAG,QAAQ,EAAE;IAiCnD;;OAEG;IACH,OAAO,CAAC,QAAQ;IAiEhB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,mBAAmB;IAwB3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAwBvB;;;;;;;;OAQG;IACH,OAAO,CAAC,mBAAmB;YAuBb,wBAAwB;YAcxB,cAAc;IAQ5B;;;OAGG;YACW,oBAAoB;YA8DpB,QAAQ;IA2BtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,gBAAgB;IAsBxB;;;OAGG;IACU,IAAI;CAYlB"}
|
|
@@ -6,6 +6,7 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
6
6
|
}
|
|
7
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
8
|
import { trackSpan } from '@aztec/telemetry-client';
|
|
9
|
+
import { ENR } from '@chainsafe/enr';
|
|
9
10
|
import { inspect } from 'util';
|
|
10
11
|
import { PeerEvent } from '../../types/index.js';
|
|
11
12
|
import { ReqRespSubProtocol } from '../reqresp/interface.js';
|
|
@@ -27,6 +28,8 @@ export class PeerManager {
|
|
|
27
28
|
heartbeatCounter;
|
|
28
29
|
displayPeerCountsPeerHeartbeat;
|
|
29
30
|
timedOutPeers;
|
|
31
|
+
trustedPeers;
|
|
32
|
+
trustedPeersInitialized;
|
|
30
33
|
metrics;
|
|
31
34
|
discoveredPeerHandler;
|
|
32
35
|
constructor(libP2PNode, peerDiscoveryService, config, telemetryClient, logger = createLogger('p2p:peer-manager'), peerScoring, reqresp){
|
|
@@ -40,6 +43,8 @@ export class PeerManager {
|
|
|
40
43
|
this.heartbeatCounter = 0;
|
|
41
44
|
this.displayPeerCountsPeerHeartbeat = 0;
|
|
42
45
|
this.timedOutPeers = new Map();
|
|
46
|
+
this.trustedPeers = new Set();
|
|
47
|
+
this.trustedPeersInitialized = false;
|
|
43
48
|
this.metrics = new PeerManagerMetrics(telemetryClient, 'PeerManager');
|
|
44
49
|
// Handle new established connections
|
|
45
50
|
this.libP2PNode.addEventListener(PeerEvent.CONNECTED, this.handleConnectedPeerEvent.bind(this));
|
|
@@ -52,6 +57,16 @@ export class PeerManager {
|
|
|
52
57
|
// Display peer counts every 60 seconds
|
|
53
58
|
this.displayPeerCountsPeerHeartbeat = Math.floor(60_000 / this.config.peerCheckIntervalMS);
|
|
54
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Initializes the trusted peers.
|
|
62
|
+
*
|
|
63
|
+
* This function is called when the peer manager is initialized.
|
|
64
|
+
*/ async initializeTrustedPeers() {
|
|
65
|
+
const trustedPeersEnrs = this.config.trustedPeers.map((enr)=>ENR.decodeTxt(enr));
|
|
66
|
+
await Promise.all(trustedPeersEnrs.map((enr)=>enr.peerId())).then((peerIds)=>peerIds.forEach((peerId)=>this.trustedPeers.add(peerId))).finally(()=>{
|
|
67
|
+
this.trustedPeersInitialized = true;
|
|
68
|
+
}).catch((e)=>this.logger.error('Error initializing trusted peers', e));
|
|
69
|
+
}
|
|
55
70
|
get tracer() {
|
|
56
71
|
return this.metrics.tracer;
|
|
57
72
|
}
|
|
@@ -99,6 +114,26 @@ export class PeerManager {
|
|
|
99
114
|
}
|
|
100
115
|
}
|
|
101
116
|
/**
|
|
117
|
+
* Checks if a peer is trusted.
|
|
118
|
+
* @param peerId - The peer ID.
|
|
119
|
+
* @returns True if the peer is trusted, false otherwise.
|
|
120
|
+
* Note: This function will return false and log a warning if the trusted peers are not initialized.
|
|
121
|
+
*/ isTrustedPeer(peerId) {
|
|
122
|
+
if (!this.trustedPeersInitialized) {
|
|
123
|
+
this.logger.warn('Trusted peers not initialized, returning false');
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return this.trustedPeers.has(peerId);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Adds a peer to the trusted peers set.
|
|
130
|
+
* @param peerId - The peer ID to add to trusted peers.
|
|
131
|
+
*/ addTrustedPeer(peerId) {
|
|
132
|
+
this.trustedPeers.add(peerId);
|
|
133
|
+
this.trustedPeersInitialized = true;
|
|
134
|
+
this.logger.verbose(`Added trusted peer ${peerId.toString()}`);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
102
137
|
* Handles a goodbye received from a peer.
|
|
103
138
|
*
|
|
104
139
|
* Used as the reqresp handler when a peer sends us goodbye message.
|
|
@@ -149,9 +184,9 @@ export class PeerManager {
|
|
|
149
184
|
* Discovers peers.
|
|
150
185
|
*/ discover() {
|
|
151
186
|
const connections = this.libP2PNode.getConnections();
|
|
152
|
-
const healthyConnections = this.prioritizePeers(this.pruneUnhealthyPeers(this.pruneDuplicatePeers(connections)));
|
|
187
|
+
const healthyConnections = this.prioritizePeers(this.onlyNotTrustedPeers(this.pruneUnhealthyPeers(this.pruneDuplicatePeers(connections))));
|
|
153
188
|
// Calculate how many connections we're looking to make
|
|
154
|
-
const peersToConnect = this.config.maxPeerCount - healthyConnections.length;
|
|
189
|
+
const peersToConnect = this.config.maxPeerCount - healthyConnections.length - this.trustedPeers.size;
|
|
155
190
|
const logLevel = this.heartbeatCounter % this.displayPeerCountsPeerHeartbeat === 0 ? 'info' : 'debug';
|
|
156
191
|
this.logger[logLevel](`Connected to ${healthyConnections.length} peers`, {
|
|
157
192
|
connections: healthyConnections.length,
|
|
@@ -159,6 +194,7 @@ export class PeerManager {
|
|
|
159
194
|
cachedPeers: this.cachedPeers.size,
|
|
160
195
|
...this.peerScoring.getStats()
|
|
161
196
|
});
|
|
197
|
+
this.metrics.recordPeerCount(healthyConnections.length);
|
|
162
198
|
// Exit if no peers to connect
|
|
163
199
|
if (peersToConnect <= 0) {
|
|
164
200
|
return;
|
|
@@ -188,9 +224,16 @@ export class PeerManager {
|
|
|
188
224
|
void this.peerDiscoveryService.runRandomNodesQuery();
|
|
189
225
|
}
|
|
190
226
|
}
|
|
227
|
+
onlyNotTrustedPeers(connections) {
|
|
228
|
+
return connections.filter((conn)=>!this.isTrustedPeer(conn.remotePeer));
|
|
229
|
+
}
|
|
191
230
|
pruneUnhealthyPeers(connections) {
|
|
192
231
|
const connectedHealthyPeers = [];
|
|
193
232
|
for (const peer of connections){
|
|
233
|
+
if (this.isTrustedPeer(peer.remotePeer)) {
|
|
234
|
+
this.logger.debug(`Not pruning trusted peer ${peer.remotePeer.toString()}`);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
194
237
|
const score = this.peerScoring.getScoreState(peer.remotePeer.toString());
|
|
195
238
|
switch(score){
|
|
196
239
|
case PeerScoreState.Banned:
|
|
@@ -211,18 +254,21 @@ export class PeerManager {
|
|
|
211
254
|
* @param connections - The list of connections to prune low scoring peers above the max peer count from.
|
|
212
255
|
* @returns The pruned list of connections.
|
|
213
256
|
*/ prioritizePeers(connections) {
|
|
214
|
-
if (connections.length > this.config.maxPeerCount) {
|
|
215
|
-
// Sort the peer scores from
|
|
257
|
+
if (connections.length > this.config.maxPeerCount - this.trustedPeers.size) {
|
|
258
|
+
// Sort the regular peer scores from highest to lowest
|
|
216
259
|
const prioritizedConnections = connections.sort((connectionA, connectionB)=>{
|
|
217
260
|
const connectionScoreA = this.peerScoring.getScore(connectionA.remotePeer.toString());
|
|
218
261
|
const connectionScoreB = this.peerScoring.getScore(connectionB.remotePeer.toString());
|
|
219
262
|
return connectionScoreB - connectionScoreA;
|
|
220
263
|
});
|
|
221
|
-
//
|
|
222
|
-
|
|
264
|
+
// Calculate how many regular peers we can keep
|
|
265
|
+
const peersToKeep = Math.max(0, this.config.maxPeerCount - this.trustedPeers.size);
|
|
266
|
+
// Disconnect from the lowest scoring regular connections that exceed our limit
|
|
267
|
+
for (const conn of prioritizedConnections.slice(peersToKeep)){
|
|
223
268
|
void this.goodbyeAndDisconnectPeer(conn.remotePeer, GoodByeReason.MAX_PEERS);
|
|
224
269
|
}
|
|
225
|
-
|
|
270
|
+
// Return trusted connections plus the highest scoring regular connections up to the max peer count
|
|
271
|
+
return prioritizedConnections.slice(0, peersToKeep);
|
|
226
272
|
} else {
|
|
227
273
|
return connections;
|
|
228
274
|
}
|
|
@@ -383,7 +429,11 @@ export class PeerManager {
|
|
|
383
429
|
return;
|
|
384
430
|
}
|
|
385
431
|
// Remove the oldest peers
|
|
386
|
-
for (const key of this.cachedPeers.
|
|
432
|
+
for (const [key, value] of this.cachedPeers.entries()){
|
|
433
|
+
if (this.isTrustedPeer(value.peerId)) {
|
|
434
|
+
this.logger.debug(`Not pruning trusted peer ${key}`);
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
387
437
|
this.cachedPeers.delete(key);
|
|
388
438
|
this.logger.trace(`Pruning peer ${key} from cache`);
|
|
389
439
|
peersToDelete--;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/p2p",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.79.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -65,14 +65,14 @@
|
|
|
65
65
|
]
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"@aztec/constants": "0.
|
|
69
|
-
"@aztec/epoch-cache": "0.
|
|
70
|
-
"@aztec/foundation": "0.
|
|
71
|
-
"@aztec/kv-store": "0.
|
|
72
|
-
"@aztec/noir-protocol-circuits-types": "0.
|
|
73
|
-
"@aztec/protocol-contracts": "0.
|
|
74
|
-
"@aztec/stdlib": "0.
|
|
75
|
-
"@aztec/telemetry-client": "0.
|
|
68
|
+
"@aztec/constants": "0.79.0",
|
|
69
|
+
"@aztec/epoch-cache": "0.79.0",
|
|
70
|
+
"@aztec/foundation": "0.79.0",
|
|
71
|
+
"@aztec/kv-store": "0.79.0",
|
|
72
|
+
"@aztec/noir-protocol-circuits-types": "0.79.0",
|
|
73
|
+
"@aztec/protocol-contracts": "0.79.0",
|
|
74
|
+
"@aztec/stdlib": "0.79.0",
|
|
75
|
+
"@aztec/telemetry-client": "0.79.0",
|
|
76
76
|
"@chainsafe/discv5": "9.0.0",
|
|
77
77
|
"@chainsafe/enr": "3.0.0",
|
|
78
78
|
"@chainsafe/libp2p-gossipsub": "13.0.0",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"xxhash-wasm": "^1.1.0"
|
|
102
102
|
},
|
|
103
103
|
"devDependencies": {
|
|
104
|
-
"@aztec/archiver": "0.
|
|
104
|
+
"@aztec/archiver": "0.79.0",
|
|
105
105
|
"@jest/globals": "^29.5.0",
|
|
106
106
|
"@types/jest": "^29.5.0",
|
|
107
107
|
"@types/node": "^18.14.6",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
"ts-node": "^10.9.1",
|
|
114
114
|
"typescript": "^5.0.4",
|
|
115
115
|
"uint8arrays": "^5.0.3",
|
|
116
|
-
"viem": "2.
|
|
116
|
+
"viem": "2.23.7"
|
|
117
117
|
},
|
|
118
118
|
"files": [
|
|
119
119
|
"dest",
|
package/src/config.ts
CHANGED
|
@@ -164,6 +164,11 @@ export interface P2PConfig extends P2PReqRespConfig, ChainConfig {
|
|
|
164
164
|
|
|
165
165
|
/** Limit of transactions to archive in the tx pool. Once the archived tx limit is reached, the oldest archived txs will be purged. */
|
|
166
166
|
archivedTxLimit: number;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* A list of trusted peers.
|
|
170
|
+
*/
|
|
171
|
+
trustedPeers: string[];
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
|
|
@@ -331,6 +336,12 @@ export const p2pConfigMappings: ConfigMappingsType<P2PConfig> = {
|
|
|
331
336
|
'The number of transactions that will be archived. If the limit is set to 0 then archiving will be disabled.',
|
|
332
337
|
...numberConfigHelper(0),
|
|
333
338
|
},
|
|
339
|
+
trustedPeers: {
|
|
340
|
+
env: 'P2P_TRUSTED_PEERS',
|
|
341
|
+
parseEnv: (val: string) => val.split(','),
|
|
342
|
+
description: 'A list of trusted peers ENRs. Separated by commas.',
|
|
343
|
+
defaultValue: [],
|
|
344
|
+
},
|
|
334
345
|
...p2pReqRespConfigMappings,
|
|
335
346
|
...chainConfigMappings,
|
|
336
347
|
};
|
|
@@ -92,6 +92,9 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
92
92
|
// Request and response sub service
|
|
93
93
|
public reqresp: ReqResp;
|
|
94
94
|
|
|
95
|
+
// Trusted peers ids
|
|
96
|
+
private trustedPeersIds: PeerId[] = [];
|
|
97
|
+
|
|
95
98
|
/**
|
|
96
99
|
* Callback for when a block is received from a peer.
|
|
97
100
|
* @param block - The block received from the peer.
|
|
@@ -174,10 +177,15 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
174
177
|
|
|
175
178
|
const otelMetricsAdapter = new OtelMetricsAdapter(telemetry);
|
|
176
179
|
|
|
180
|
+
const bootstrapNodes = peerDiscoveryService.bootstrapNodes;
|
|
181
|
+
|
|
182
|
+
// If trusted peers are provided, also provide them to the p2p service
|
|
183
|
+
bootstrapNodes.push(...config.trustedPeers);
|
|
184
|
+
|
|
177
185
|
// If bootstrap nodes are provided, also provide them to the p2p service
|
|
178
186
|
const peerDiscovery = [];
|
|
179
|
-
if (
|
|
180
|
-
peerDiscovery.push(bootstrap({ list:
|
|
187
|
+
if (bootstrapNodes.length > 0) {
|
|
188
|
+
peerDiscovery.push(bootstrap({ list: bootstrapNodes }));
|
|
181
189
|
}
|
|
182
190
|
|
|
183
191
|
const node = await createLibp2p({
|
|
@@ -299,6 +307,8 @@ export class LibP2PService<T extends P2PClientType> extends WithTracer implement
|
|
|
299
307
|
|
|
300
308
|
// Start job queue, peer discovery service and libp2p node
|
|
301
309
|
this.jobQueue.start();
|
|
310
|
+
|
|
311
|
+
await this.peerManager.initializeTrustedPeers();
|
|
302
312
|
await this.peerDiscoveryService.start();
|
|
303
313
|
await this.node.start();
|
|
304
314
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Attributes,
|
|
3
|
+
type Gauge,
|
|
3
4
|
Metrics,
|
|
4
5
|
type TelemetryClient,
|
|
5
6
|
type Tracer,
|
|
6
7
|
type UpDownCounter,
|
|
7
8
|
ValueType,
|
|
9
|
+
getTelemetryClient,
|
|
8
10
|
} from '@aztec/telemetry-client';
|
|
9
11
|
|
|
10
12
|
import { type GoodByeReason, prettyGoodbyeReason } from '../reqresp/protocols/index.js';
|
|
@@ -12,10 +14,11 @@ import { type GoodByeReason, prettyGoodbyeReason } from '../reqresp/protocols/in
|
|
|
12
14
|
export class PeerManagerMetrics {
|
|
13
15
|
private sentGoodbyes: UpDownCounter;
|
|
14
16
|
private receivedGoodbyes: UpDownCounter;
|
|
17
|
+
private peerCount: Gauge;
|
|
15
18
|
|
|
16
19
|
public readonly tracer: Tracer;
|
|
17
20
|
|
|
18
|
-
constructor(public readonly telemetryClient: TelemetryClient, name = 'PeerManager') {
|
|
21
|
+
constructor(public readonly telemetryClient: TelemetryClient = getTelemetryClient(), name = 'PeerManager') {
|
|
19
22
|
this.tracer = telemetryClient.getTracer(name);
|
|
20
23
|
|
|
21
24
|
const meter = telemetryClient.getMeter(name);
|
|
@@ -29,6 +32,11 @@ export class PeerManagerMetrics {
|
|
|
29
32
|
unit: 'peers',
|
|
30
33
|
valueType: ValueType.INT,
|
|
31
34
|
});
|
|
35
|
+
this.peerCount = meter.createGauge(Metrics.PEER_MANAGER_PEER_COUNT, {
|
|
36
|
+
description: 'Number of peers',
|
|
37
|
+
unit: 'peers',
|
|
38
|
+
valueType: ValueType.INT,
|
|
39
|
+
});
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
public recordGoodbyeSent(reason: GoodByeReason) {
|
|
@@ -38,4 +46,8 @@ export class PeerManagerMetrics {
|
|
|
38
46
|
public recordGoodbyeReceived(reason: GoodByeReason) {
|
|
39
47
|
this.receivedGoodbyes.add(1, { [Attributes.P2P_GOODBYE_REASON]: prettyGoodbyeReason(reason) });
|
|
40
48
|
}
|
|
49
|
+
|
|
50
|
+
public recordPeerCount(count: number) {
|
|
51
|
+
this.peerCount.record(count);
|
|
52
|
+
}
|
|
41
53
|
}
|
|
@@ -3,7 +3,7 @@ import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
|
3
3
|
import type { PeerErrorSeverity } from '@aztec/stdlib/p2p';
|
|
4
4
|
import { type TelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import { ENR } from '@chainsafe/enr';
|
|
7
7
|
import type { Connection, PeerId } from '@libp2p/interface';
|
|
8
8
|
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
9
9
|
import { inspect } from 'util';
|
|
@@ -41,6 +41,8 @@ export class PeerManager {
|
|
|
41
41
|
private heartbeatCounter: number = 0;
|
|
42
42
|
private displayPeerCountsPeerHeartbeat: number = 0;
|
|
43
43
|
private timedOutPeers: Map<string, TimedOutPeer> = new Map();
|
|
44
|
+
private trustedPeers: Set<PeerId> = new Set();
|
|
45
|
+
private trustedPeersInitialized: boolean = false;
|
|
44
46
|
|
|
45
47
|
private metrics: PeerManagerMetrics;
|
|
46
48
|
private discoveredPeerHandler;
|
|
@@ -64,6 +66,7 @@ export class PeerManager {
|
|
|
64
66
|
// Handle Discovered peers
|
|
65
67
|
this.discoveredPeerHandler = (enr: ENR) =>
|
|
66
68
|
this.handleDiscoveredPeer(enr).catch(e => this.logger.error('Error handling discovered peer', e));
|
|
69
|
+
|
|
67
70
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
68
71
|
this.peerDiscoveryService.on(PeerEvent.DISCOVERED, this.discoveredPeerHandler);
|
|
69
72
|
|
|
@@ -71,6 +74,21 @@ export class PeerManager {
|
|
|
71
74
|
this.displayPeerCountsPeerHeartbeat = Math.floor(60_000 / this.config.peerCheckIntervalMS);
|
|
72
75
|
}
|
|
73
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Initializes the trusted peers.
|
|
79
|
+
*
|
|
80
|
+
* This function is called when the peer manager is initialized.
|
|
81
|
+
*/
|
|
82
|
+
async initializeTrustedPeers() {
|
|
83
|
+
const trustedPeersEnrs: ENR[] = this.config.trustedPeers.map(enr => ENR.decodeTxt(enr));
|
|
84
|
+
await Promise.all(trustedPeersEnrs.map(enr => enr.peerId()))
|
|
85
|
+
.then(peerIds => peerIds.forEach(peerId => this.trustedPeers.add(peerId)))
|
|
86
|
+
.finally(() => {
|
|
87
|
+
this.trustedPeersInitialized = true;
|
|
88
|
+
})
|
|
89
|
+
.catch(e => this.logger.error('Error initializing trusted peers', e));
|
|
90
|
+
}
|
|
91
|
+
|
|
74
92
|
get tracer() {
|
|
75
93
|
return this.metrics.tracer;
|
|
76
94
|
}
|
|
@@ -128,6 +146,30 @@ export class PeerManager {
|
|
|
128
146
|
}
|
|
129
147
|
}
|
|
130
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Checks if a peer is trusted.
|
|
151
|
+
* @param peerId - The peer ID.
|
|
152
|
+
* @returns True if the peer is trusted, false otherwise.
|
|
153
|
+
* Note: This function will return false and log a warning if the trusted peers are not initialized.
|
|
154
|
+
*/
|
|
155
|
+
private isTrustedPeer(peerId: PeerId): boolean {
|
|
156
|
+
if (!this.trustedPeersInitialized) {
|
|
157
|
+
this.logger.warn('Trusted peers not initialized, returning false');
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
return this.trustedPeers.has(peerId);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Adds a peer to the trusted peers set.
|
|
165
|
+
* @param peerId - The peer ID to add to trusted peers.
|
|
166
|
+
*/
|
|
167
|
+
public addTrustedPeer(peerId: PeerId): void {
|
|
168
|
+
this.trustedPeers.add(peerId);
|
|
169
|
+
this.trustedPeersInitialized = true;
|
|
170
|
+
this.logger.verbose(`Added trusted peer ${peerId.toString()}`);
|
|
171
|
+
}
|
|
172
|
+
|
|
131
173
|
/**
|
|
132
174
|
* Handles a goodbye received from a peer.
|
|
133
175
|
*
|
|
@@ -190,10 +232,12 @@ export class PeerManager {
|
|
|
190
232
|
private discover() {
|
|
191
233
|
const connections = this.libP2PNode.getConnections();
|
|
192
234
|
|
|
193
|
-
const healthyConnections = this.prioritizePeers(
|
|
235
|
+
const healthyConnections = this.prioritizePeers(
|
|
236
|
+
this.onlyNotTrustedPeers(this.pruneUnhealthyPeers(this.pruneDuplicatePeers(connections))),
|
|
237
|
+
);
|
|
194
238
|
|
|
195
239
|
// Calculate how many connections we're looking to make
|
|
196
|
-
const peersToConnect = this.config.maxPeerCount - healthyConnections.length;
|
|
240
|
+
const peersToConnect = this.config.maxPeerCount - healthyConnections.length - this.trustedPeers.size;
|
|
197
241
|
|
|
198
242
|
const logLevel = this.heartbeatCounter % this.displayPeerCountsPeerHeartbeat === 0 ? 'info' : 'debug';
|
|
199
243
|
this.logger[logLevel](`Connected to ${healthyConnections.length} peers`, {
|
|
@@ -203,6 +247,8 @@ export class PeerManager {
|
|
|
203
247
|
...this.peerScoring.getStats(),
|
|
204
248
|
});
|
|
205
249
|
|
|
250
|
+
this.metrics.recordPeerCount(healthyConnections.length);
|
|
251
|
+
|
|
206
252
|
// Exit if no peers to connect
|
|
207
253
|
if (peersToConnect <= 0) {
|
|
208
254
|
return;
|
|
@@ -248,10 +294,18 @@ export class PeerManager {
|
|
|
248
294
|
}
|
|
249
295
|
}
|
|
250
296
|
|
|
297
|
+
private onlyNotTrustedPeers(connections: Connection[]): Connection[] {
|
|
298
|
+
return connections.filter(conn => !this.isTrustedPeer(conn.remotePeer));
|
|
299
|
+
}
|
|
300
|
+
|
|
251
301
|
private pruneUnhealthyPeers(connections: Connection[]): Connection[] {
|
|
252
302
|
const connectedHealthyPeers: Connection[] = [];
|
|
253
303
|
|
|
254
304
|
for (const peer of connections) {
|
|
305
|
+
if (this.isTrustedPeer(peer.remotePeer)) {
|
|
306
|
+
this.logger.debug(`Not pruning trusted peer ${peer.remotePeer.toString()}`);
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
255
309
|
const score = this.peerScoring.getScoreState(peer.remotePeer.toString());
|
|
256
310
|
switch (score) {
|
|
257
311
|
case PeerScoreState.Banned:
|
|
@@ -275,19 +329,24 @@ export class PeerManager {
|
|
|
275
329
|
* @returns The pruned list of connections.
|
|
276
330
|
*/
|
|
277
331
|
private prioritizePeers(connections: Connection[]): Connection[] {
|
|
278
|
-
if (connections.length > this.config.maxPeerCount) {
|
|
279
|
-
// Sort the peer scores from
|
|
332
|
+
if (connections.length > this.config.maxPeerCount - this.trustedPeers.size) {
|
|
333
|
+
// Sort the regular peer scores from highest to lowest
|
|
280
334
|
const prioritizedConnections = connections.sort((connectionA, connectionB) => {
|
|
281
335
|
const connectionScoreA = this.peerScoring.getScore(connectionA.remotePeer.toString());
|
|
282
336
|
const connectionScoreB = this.peerScoring.getScore(connectionB.remotePeer.toString());
|
|
283
337
|
return connectionScoreB - connectionScoreA;
|
|
284
338
|
});
|
|
285
339
|
|
|
286
|
-
//
|
|
287
|
-
|
|
340
|
+
// Calculate how many regular peers we can keep
|
|
341
|
+
const peersToKeep = Math.max(0, this.config.maxPeerCount - this.trustedPeers.size);
|
|
342
|
+
|
|
343
|
+
// Disconnect from the lowest scoring regular connections that exceed our limit
|
|
344
|
+
for (const conn of prioritizedConnections.slice(peersToKeep)) {
|
|
288
345
|
void this.goodbyeAndDisconnectPeer(conn.remotePeer, GoodByeReason.MAX_PEERS);
|
|
289
346
|
}
|
|
290
|
-
|
|
347
|
+
|
|
348
|
+
// Return trusted connections plus the highest scoring regular connections up to the max peer count
|
|
349
|
+
return prioritizedConnections.slice(0, peersToKeep);
|
|
291
350
|
} else {
|
|
292
351
|
return connections;
|
|
293
352
|
}
|
|
@@ -458,7 +517,12 @@ export class PeerManager {
|
|
|
458
517
|
}
|
|
459
518
|
|
|
460
519
|
// Remove the oldest peers
|
|
461
|
-
for (const key of this.cachedPeers.
|
|
520
|
+
for (const [key, value] of this.cachedPeers.entries()) {
|
|
521
|
+
if (this.isTrustedPeer(value.peerId)) {
|
|
522
|
+
this.logger.debug(`Not pruning trusted peer ${key}`);
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
|
|
462
526
|
this.cachedPeers.delete(key);
|
|
463
527
|
this.logger.trace(`Pruning peer ${key} from cache`);
|
|
464
528
|
peersToDelete--;
|