@aztec/p2p 0.60.0 → 0.62.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/client/index.js +2 -39
- package/dest/client/p2p_client.d.ts +33 -9
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +121 -30
- package/dest/config.d.ts +5 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +7 -2
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts +3 -2
- 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 +30 -5
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts +3 -2
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +26 -5
- package/dest/mem_pools/tx_pool/tx_pool.d.ts +8 -2
- package/dest/mem_pools/tx_pool/tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/tx_pool_test_suite.js +30 -3
- package/dest/mocks/index.d.ts +18 -2
- package/dest/mocks/index.d.ts.map +1 -1
- package/dest/mocks/index.js +79 -5
- package/dest/service/peer_scoring.js +5 -5
- package/dest/util.d.ts +3 -0
- package/dest/util.d.ts.map +1 -1
- package/dest/util.js +38 -1
- package/package.json +12 -7
- package/src/client/index.ts +1 -48
- package/src/client/p2p_client.ts +156 -40
- package/src/config.ts +11 -1
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +35 -6
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +32 -6
- package/src/mem_pools/tx_pool/tx_pool.ts +9 -2
- package/src/mem_pools/tx_pool/tx_pool_test_suite.ts +34 -2
- package/src/mocks/index.ts +123 -5
- package/src/service/peer_scoring.ts +4 -4
- package/src/util.ts +53 -0
package/src/mocks/index.ts
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type ClientProtocolCircuitVerifier,
|
|
3
|
+
type L2BlockSource,
|
|
4
|
+
type Tx,
|
|
5
|
+
type WorldStateSynchronizer,
|
|
6
|
+
} from '@aztec/circuit-types';
|
|
7
|
+
import { type DataStoreConfig } from '@aztec/kv-store/utils';
|
|
8
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
2
9
|
|
|
10
|
+
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
3
11
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
4
12
|
import { yamux } from '@chainsafe/libp2p-yamux';
|
|
5
13
|
import { bootstrap } from '@libp2p/bootstrap';
|
|
14
|
+
import { identify } from '@libp2p/identify';
|
|
15
|
+
import { type PeerId } from '@libp2p/interface';
|
|
6
16
|
import { tcp } from '@libp2p/tcp';
|
|
17
|
+
import getPort from 'get-port';
|
|
7
18
|
import { type Libp2p, type Libp2pOptions, createLibp2p } from 'libp2p';
|
|
8
19
|
|
|
20
|
+
import { BootstrapNode } from '../bootstrap/bootstrap.js';
|
|
21
|
+
import { type BootnodeConfig, type P2PConfig } from '../config.js';
|
|
22
|
+
import { type MemPools } from '../mem_pools/interface.js';
|
|
23
|
+
import { DiscV5Service } from '../service/discV5_service.js';
|
|
24
|
+
import { LibP2PService, createLibP2PPeerId } from '../service/libp2p_service.js';
|
|
9
25
|
import { type PeerManager } from '../service/peer_manager.js';
|
|
10
26
|
import { type P2PReqRespConfig } from '../service/reqresp/config.js';
|
|
11
27
|
import { pingHandler, statusHandler } from '../service/reqresp/handlers.js';
|
|
@@ -18,20 +34,35 @@ import {
|
|
|
18
34
|
noopValidator,
|
|
19
35
|
} from '../service/reqresp/interface.js';
|
|
20
36
|
import { ReqResp } from '../service/reqresp/reqresp.js';
|
|
37
|
+
import { type PubSubLibp2p } from '../util.js';
|
|
21
38
|
|
|
22
39
|
/**
|
|
23
40
|
* Creates a libp2p node, pre configured.
|
|
24
41
|
* @param boostrapAddrs - an optional list of bootstrap addresses
|
|
25
42
|
* @returns Lip2p node
|
|
26
43
|
*/
|
|
27
|
-
export async function createLibp2pNode(
|
|
44
|
+
export async function createLibp2pNode(
|
|
45
|
+
boostrapAddrs: string[] = [],
|
|
46
|
+
peerId?: PeerId,
|
|
47
|
+
port?: number,
|
|
48
|
+
enableGossipSub: boolean = false,
|
|
49
|
+
start: boolean = true,
|
|
50
|
+
): Promise<Libp2p> {
|
|
51
|
+
port = port ?? (await getPort());
|
|
28
52
|
const options: Libp2pOptions = {
|
|
53
|
+
start,
|
|
29
54
|
addresses: {
|
|
30
|
-
listen: [
|
|
55
|
+
listen: [`/ip4/0.0.0.0/tcp/${port}`],
|
|
56
|
+
announce: [`/ip4/0.0.0.0/tcp/${port}`],
|
|
31
57
|
},
|
|
32
58
|
connectionEncryption: [noise()],
|
|
33
59
|
streamMuxers: [yamux()],
|
|
34
60
|
transports: [tcp()],
|
|
61
|
+
services: {
|
|
62
|
+
identify: identify({
|
|
63
|
+
protocolPrefix: 'aztec',
|
|
64
|
+
}),
|
|
65
|
+
},
|
|
35
66
|
};
|
|
36
67
|
|
|
37
68
|
if (boostrapAddrs.length > 0) {
|
|
@@ -42,9 +73,65 @@ export async function createLibp2pNode(boostrapAddrs: string[] = []): Promise<Li
|
|
|
42
73
|
];
|
|
43
74
|
}
|
|
44
75
|
|
|
76
|
+
if (peerId) {
|
|
77
|
+
options.peerId = peerId;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (enableGossipSub) {
|
|
81
|
+
options.services!.pubsub = gossipsub({
|
|
82
|
+
allowPublishToZeroTopicPeers: true,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
45
86
|
return await createLibp2p(options);
|
|
46
87
|
}
|
|
47
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Test Libp2p service
|
|
91
|
+
* P2P functionality is operational, however everything else is default
|
|
92
|
+
*
|
|
93
|
+
* WORKTODO: more description
|
|
94
|
+
*/
|
|
95
|
+
export async function createTestLibP2PService(
|
|
96
|
+
boostrapAddrs: string[] = [],
|
|
97
|
+
l2BlockSource: L2BlockSource,
|
|
98
|
+
worldStateSynchronizer: WorldStateSynchronizer,
|
|
99
|
+
mempools: MemPools,
|
|
100
|
+
telemetry: TelemetryClient,
|
|
101
|
+
port: number = 0,
|
|
102
|
+
peerId?: PeerId,
|
|
103
|
+
) {
|
|
104
|
+
peerId = peerId ?? (await createLibP2PPeerId());
|
|
105
|
+
const config = {
|
|
106
|
+
tcpAnnounceAddress: `127.0.0.1:${port}`,
|
|
107
|
+
udpAnnounceAddress: `127.0.0.1:${port}`,
|
|
108
|
+
tcpListenAddress: `0.0.0.0:${port}`,
|
|
109
|
+
udpListenAddress: `0.0.0.0:${port}`,
|
|
110
|
+
bootstrapNodes: boostrapAddrs,
|
|
111
|
+
peerCheckIntervalMS: 1000,
|
|
112
|
+
minPeerCount: 1,
|
|
113
|
+
maxPeerCount: 5,
|
|
114
|
+
p2pEnabled: true,
|
|
115
|
+
peerIdPrivateKey: Buffer.from(peerId.privateKey!).toString('hex'),
|
|
116
|
+
} as P2PConfig & DataStoreConfig;
|
|
117
|
+
const discoveryService = new DiscV5Service(peerId, config);
|
|
118
|
+
const proofVerifier = new AlwaysTrueCircuitVerifier();
|
|
119
|
+
|
|
120
|
+
// No bootstrap nodes provided as the libp2p service will register them in the constructor
|
|
121
|
+
const p2pNode = await createLibp2pNode([], peerId, port, /*enable gossip */ true, /**start */ false);
|
|
122
|
+
|
|
123
|
+
return new LibP2PService(
|
|
124
|
+
config,
|
|
125
|
+
p2pNode as PubSubLibp2p,
|
|
126
|
+
discoveryService,
|
|
127
|
+
mempools,
|
|
128
|
+
l2BlockSource,
|
|
129
|
+
proofVerifier,
|
|
130
|
+
worldStateSynchronizer,
|
|
131
|
+
telemetry,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
48
135
|
/**
|
|
49
136
|
* A p2p / req resp node pairing the req node will always contain the p2p node.
|
|
50
137
|
* they are provided as a pair to allow access the p2p node directly
|
|
@@ -88,10 +175,12 @@ export const startNodes = async (
|
|
|
88
175
|
};
|
|
89
176
|
|
|
90
177
|
export const stopNodes = async (nodes: ReqRespNode[]): Promise<void> => {
|
|
178
|
+
const stopPromises = [];
|
|
91
179
|
for (const node of nodes) {
|
|
92
|
-
|
|
93
|
-
|
|
180
|
+
stopPromises.push(node.req.stop());
|
|
181
|
+
stopPromises.push(node.p2p.stop());
|
|
94
182
|
}
|
|
183
|
+
await Promise.all(stopPromises);
|
|
95
184
|
};
|
|
96
185
|
|
|
97
186
|
// Create a req resp node, exposing the underlying p2p node
|
|
@@ -132,3 +221,32 @@ export class AlwaysFalseCircuitVerifier implements ClientProtocolCircuitVerifier
|
|
|
132
221
|
return Promise.resolve(false);
|
|
133
222
|
}
|
|
134
223
|
}
|
|
224
|
+
|
|
225
|
+
// Bootnodes
|
|
226
|
+
export function createBootstrapNodeConfig(privateKey: string, port: number): BootnodeConfig {
|
|
227
|
+
return {
|
|
228
|
+
udpListenAddress: `0.0.0.0:${port}`,
|
|
229
|
+
udpAnnounceAddress: `127.0.0.1:${port}`,
|
|
230
|
+
peerIdPrivateKey: privateKey,
|
|
231
|
+
minPeerCount: 10,
|
|
232
|
+
maxPeerCount: 100,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function createBootstrapNodeFromPrivateKey(privateKey: string, port: number): Promise<BootstrapNode> {
|
|
237
|
+
const config = createBootstrapNodeConfig(privateKey, port);
|
|
238
|
+
return startBootstrapNode(config);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export async function createBootstrapNode(port: number): Promise<BootstrapNode> {
|
|
242
|
+
const peerId = await createLibP2PPeerId();
|
|
243
|
+
const config = createBootstrapNodeConfig(Buffer.from(peerId.privateKey!).toString('hex'), port);
|
|
244
|
+
|
|
245
|
+
return startBootstrapNode(config);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
async function startBootstrapNode(config: BootnodeConfig) {
|
|
249
|
+
const bootstrapNode = new BootstrapNode();
|
|
250
|
+
await bootstrapNode.start(config);
|
|
251
|
+
return bootstrapNode;
|
|
252
|
+
}
|
|
@@ -32,14 +32,14 @@ export class PeerScoring {
|
|
|
32
32
|
peerPenalties: { [key in PeerErrorSeverity]: number };
|
|
33
33
|
|
|
34
34
|
constructor(config: P2PConfig) {
|
|
35
|
-
const orderedValues = config.peerPenaltyValues
|
|
35
|
+
const orderedValues = config.peerPenaltyValues?.sort((a, b) => a - b);
|
|
36
36
|
this.peerPenalties = {
|
|
37
37
|
[PeerErrorSeverity.HighToleranceError]:
|
|
38
|
-
orderedValues[0] ?? DefaultPeerPenalties[PeerErrorSeverity.LowToleranceError],
|
|
38
|
+
orderedValues?.[0] ?? DefaultPeerPenalties[PeerErrorSeverity.LowToleranceError],
|
|
39
39
|
[PeerErrorSeverity.MidToleranceError]:
|
|
40
|
-
orderedValues[1] ?? DefaultPeerPenalties[PeerErrorSeverity.MidToleranceError],
|
|
40
|
+
orderedValues?.[1] ?? DefaultPeerPenalties[PeerErrorSeverity.MidToleranceError],
|
|
41
41
|
[PeerErrorSeverity.LowToleranceError]:
|
|
42
|
-
orderedValues[2] ?? DefaultPeerPenalties[PeerErrorSeverity.HighToleranceError],
|
|
42
|
+
orderedValues?.[2] ?? DefaultPeerPenalties[PeerErrorSeverity.HighToleranceError],
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
|
package/src/util.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { type DataStoreConfig } from '@aztec/kv-store/utils';
|
|
2
|
+
|
|
1
3
|
import type { GossipSub } from '@chainsafe/libp2p-gossipsub';
|
|
2
4
|
import { resolve } from 'dns/promises';
|
|
3
5
|
import type { Libp2p } from 'libp2p';
|
|
4
6
|
|
|
7
|
+
import { type P2PConfig } from './config.js';
|
|
8
|
+
|
|
5
9
|
export interface PubSubLibp2p extends Libp2p {
|
|
6
10
|
services: {
|
|
7
11
|
pubsub: GossipSub;
|
|
@@ -88,3 +92,52 @@ function addressToMultiAddressType(address: string): 'ip4' | 'ip6' | 'dns' {
|
|
|
88
92
|
return 'dns';
|
|
89
93
|
}
|
|
90
94
|
}
|
|
95
|
+
|
|
96
|
+
export async function configureP2PClientAddresses(
|
|
97
|
+
_config: P2PConfig & DataStoreConfig,
|
|
98
|
+
): Promise<P2PConfig & DataStoreConfig> {
|
|
99
|
+
const config = { ..._config };
|
|
100
|
+
const {
|
|
101
|
+
tcpAnnounceAddress: configTcpAnnounceAddress,
|
|
102
|
+
udpAnnounceAddress: configUdpAnnounceAddress,
|
|
103
|
+
queryForIp,
|
|
104
|
+
} = config;
|
|
105
|
+
|
|
106
|
+
config.tcpAnnounceAddress = configTcpAnnounceAddress
|
|
107
|
+
? await resolveAddressIfNecessary(configTcpAnnounceAddress)
|
|
108
|
+
: undefined;
|
|
109
|
+
config.udpAnnounceAddress = configUdpAnnounceAddress
|
|
110
|
+
? await resolveAddressIfNecessary(configUdpAnnounceAddress)
|
|
111
|
+
: undefined;
|
|
112
|
+
|
|
113
|
+
// create variable for re-use if needed
|
|
114
|
+
let publicIp;
|
|
115
|
+
|
|
116
|
+
// check if no announce IP was provided
|
|
117
|
+
const splitTcpAnnounceAddress = splitAddressPort(configTcpAnnounceAddress || '', true);
|
|
118
|
+
if (splitTcpAnnounceAddress.length == 2 && splitTcpAnnounceAddress[0] === '') {
|
|
119
|
+
if (queryForIp) {
|
|
120
|
+
publicIp = await getPublicIp();
|
|
121
|
+
const tcpAnnounceAddress = `${publicIp}:${splitTcpAnnounceAddress[1]}`;
|
|
122
|
+
config.tcpAnnounceAddress = tcpAnnounceAddress;
|
|
123
|
+
} else {
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Invalid announceTcpAddress provided: ${configTcpAnnounceAddress}. Expected format: <addr>:<port>`,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const splitUdpAnnounceAddress = splitAddressPort(configUdpAnnounceAddress || '', true);
|
|
131
|
+
if (splitUdpAnnounceAddress.length == 2 && splitUdpAnnounceAddress[0] === '') {
|
|
132
|
+
// If announceUdpAddress is not provided, use announceTcpAddress
|
|
133
|
+
if (!queryForIp && config.tcpAnnounceAddress) {
|
|
134
|
+
config.udpAnnounceAddress = config.tcpAnnounceAddress;
|
|
135
|
+
} else if (queryForIp) {
|
|
136
|
+
const udpPublicIp = publicIp || (await getPublicIp());
|
|
137
|
+
const udpAnnounceAddress = `${udpPublicIp}:${splitUdpAnnounceAddress[1]}`;
|
|
138
|
+
config.udpAnnounceAddress = udpAnnounceAddress;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
return config;
|
|
143
|
+
}
|