@aztec/p2p 0.42.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts +1 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +8 -4
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +22 -17
- package/dest/config.d.ts +9 -22
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +8 -9
- package/dest/service/discV5_service.d.ts.map +1 -1
- package/dest/service/discV5_service.js +14 -5
- package/dest/service/libp2p_service.d.ts +1 -2
- package/dest/service/libp2p_service.d.ts.map +1 -1
- package/dest/service/libp2p_service.js +18 -17
- package/dest/util.d.ts +21 -0
- package/dest/util.d.ts.map +1 -0
- package/dest/util.js +59 -0
- package/package.json +5 -5
- package/src/bootstrap/bootstrap.ts +11 -5
- package/src/client/index.ts +26 -17
- package/src/config.ts +19 -39
- package/src/service/discV5_service.ts +18 -5
- package/src/service/libp2p_service.ts +19 -18
- package/src/util.ts +62 -0
- package/dest/service/ip_query.d.ts +0 -2
- package/dest/service/ip_query.d.ts.map +0 -1
- package/dest/service/ip_query.js +0 -6
- package/src/service/ip_query.ts +0 -5
|
@@ -3,7 +3,7 @@ import { type P2PConfig } from '../config.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Required P2P config values for a bootstrap node.
|
|
5
5
|
*/
|
|
6
|
-
export type BootNodeConfig = Partial<P2PConfig> & Pick<P2PConfig, '
|
|
6
|
+
export type BootNodeConfig = Partial<P2PConfig> & Pick<P2PConfig, 'udpAnnounceAddress'> & Required<Pick<P2PConfig, 'udpListenAddress'>>;
|
|
7
7
|
/**
|
|
8
8
|
* Encapsulates a 'Bootstrap' node, used for the purpose of assisting new joiners in acquiring peers.
|
|
9
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/bootstrap/bootstrap.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/bootstrap/bootstrap.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAK9C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,GAC7C,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,GACrC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAEhD;;GAEG;AACH,qBAAa,aAAa;IAIZ,OAAO,CAAC,MAAM;IAH1B,OAAO,CAAC,IAAI,CAAC,CAAqB;IAClC,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEJ,MAAM,yCAA2C;IAErE;;;;OAIG;IACU,KAAK,CAAC,MAAM,EAAE,cAAc;IA8CzC;;;OAGG;IACU,IAAI;IAMjB;;;OAGG;IACI,SAAS;IAOT,MAAM;CAMd"}
|
|
@@ -4,6 +4,7 @@ import { SignableENR } from '@chainsafe/enr';
|
|
|
4
4
|
import { multiaddr } from '@multiformats/multiaddr';
|
|
5
5
|
import { AZTEC_ENR_KEY, AZTEC_NET } from '../service/discV5_service.js';
|
|
6
6
|
import { createLibP2PPeerId } from '../service/index.js';
|
|
7
|
+
import { convertToMultiaddr } from '../util.js';
|
|
7
8
|
/**
|
|
8
9
|
* Encapsulates a 'Bootstrap' node, used for the purpose of assisting new joiners in acquiring peers.
|
|
9
10
|
*/
|
|
@@ -18,12 +19,15 @@ export class BootstrapNode {
|
|
|
18
19
|
* @returns An empty promise.
|
|
19
20
|
*/
|
|
20
21
|
async start(config) {
|
|
21
|
-
const { peerIdPrivateKey,
|
|
22
|
+
const { peerIdPrivateKey, udpListenAddress, udpAnnounceAddress } = config;
|
|
22
23
|
const peerId = await createLibP2PPeerId(peerIdPrivateKey);
|
|
23
24
|
this.peerId = peerId;
|
|
24
25
|
const enr = SignableENR.createFromPeerId(peerId);
|
|
25
|
-
const listenAddrUdp = multiaddr(
|
|
26
|
-
|
|
26
|
+
const listenAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
|
|
27
|
+
if (!udpAnnounceAddress) {
|
|
28
|
+
throw new Error('You need to provide a UDP announce address.');
|
|
29
|
+
}
|
|
30
|
+
const publicAddr = multiaddr(convertToMultiaddr(udpAnnounceAddress, 'udp'));
|
|
27
31
|
enr.setLocationMultiaddr(publicAddr);
|
|
28
32
|
enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
|
|
29
33
|
this.logger.info(`Starting bootstrap node ${peerId}, listening on ${listenAddrUdp.toString()}`);
|
|
@@ -78,4 +82,4 @@ export class BootstrapNode {
|
|
|
78
82
|
return this.node?.enr.toENR();
|
|
79
83
|
}
|
|
80
84
|
}
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
85
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jvb3RzdHJhcC9ib290c3RyYXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFMUQsT0FBTyxFQUFFLE1BQU0sRUFBMkIsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsT0FBTyxFQUFrQixTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUdwRSxPQUFPLEVBQUUsYUFBYSxFQUFFLFNBQVMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3hFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQVNoRDs7R0FFRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBSXhCLFlBQW9CLFNBQVMsaUJBQWlCLENBQUMscUJBQXFCLENBQUM7UUFBakQsV0FBTSxHQUFOLE1BQU0sQ0FBMkM7UUFIN0QsU0FBSSxHQUFZLFNBQVMsQ0FBQztJQUdzQyxDQUFDO0lBRXpFOzs7O09BSUc7SUFDSSxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQXNCO1FBQ3ZDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsRUFBRSxrQkFBa0IsRUFBRSxHQUFHLE1BQU0sQ0FBQztRQUMxRSxNQUFNLE1BQU0sR0FBRyxNQUFNLGtCQUFrQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWpELE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsRUFBRSxLQUFLLENBQUMs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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD,cAAc,iBAAiB,CAAC;AAEhC,eAAO,MAAM,eAAe,UACnB,YAAY,UACX,SAAS,UACT,MAAM,iBACC,aAAa,uBAmD7B,CAAC"}
|
package/dest/client/index.js
CHANGED
|
@@ -2,39 +2,44 @@ import { P2PClient } from '../client/p2p_client.js';
|
|
|
2
2
|
import { DiscV5Service } from '../service/discV5_service.js';
|
|
3
3
|
import { DummyP2PService, DummyPeerDiscoveryService } from '../service/dummy_service.js';
|
|
4
4
|
import { LibP2PService, createLibP2PPeerId } from '../service/index.js';
|
|
5
|
-
import { getPublicIp } from '../
|
|
5
|
+
import { getPublicIp, splitAddressPort } from '../util.js';
|
|
6
6
|
export * from './p2p_client.js';
|
|
7
7
|
export const createP2PClient = async (store, config, txPool, l2BlockSource) => {
|
|
8
8
|
let discv5Service;
|
|
9
9
|
let p2pService;
|
|
10
10
|
if (config.p2pEnabled) {
|
|
11
|
-
// If
|
|
12
|
-
const {
|
|
13
|
-
if
|
|
11
|
+
// If announceTcpAddress or announceUdpAddress are not provided, query for public IP if config allows
|
|
12
|
+
const { tcpAnnounceAddress: configTcpAnnounceAddress, udpAnnounceAddress: configUdpAnnounceAddress, queryForIp, } = config;
|
|
13
|
+
// create variable for re-use if needed
|
|
14
|
+
let publicIp;
|
|
15
|
+
// check if no announce IP was provided
|
|
16
|
+
const splitTcpAnnounceAddress = splitAddressPort(configTcpAnnounceAddress || '', true);
|
|
17
|
+
if (splitTcpAnnounceAddress.length == 2 && splitTcpAnnounceAddress[0] === '') {
|
|
14
18
|
if (queryForIp) {
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
config.
|
|
19
|
+
publicIp = await getPublicIp();
|
|
20
|
+
const tcpAnnounceAddress = `${publicIp}:${splitTcpAnnounceAddress[1]}`;
|
|
21
|
+
config.tcpAnnounceAddress = tcpAnnounceAddress;
|
|
18
22
|
}
|
|
19
23
|
else {
|
|
20
|
-
throw new Error(
|
|
24
|
+
throw new Error(`Invalid announceTcpAddress provided: ${splitTcpAnnounceAddress}. Expected format: <addr>:<port>`);
|
|
21
25
|
}
|
|
22
26
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
const splitUdpAnnounceAddress = splitAddressPort(configUdpAnnounceAddress || '', true);
|
|
28
|
+
if (splitUdpAnnounceAddress.length == 2 && splitUdpAnnounceAddress[0] === '') {
|
|
29
|
+
// If announceUdpAddress is not provided, use announceTcpAddress
|
|
30
|
+
if (!queryForIp && config.tcpAnnounceAddress) {
|
|
31
|
+
config.udpAnnounceAddress = config.tcpAnnounceAddress;
|
|
27
32
|
}
|
|
28
33
|
else if (queryForIp) {
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
config.
|
|
34
|
+
const udpPublicIp = publicIp || (await getPublicIp());
|
|
35
|
+
const udpAnnounceAddress = `${udpPublicIp}:${splitUdpAnnounceAddress[1]}`;
|
|
36
|
+
config.udpAnnounceAddress = udpAnnounceAddress;
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
// Create peer discovery service
|
|
35
40
|
const peerId = await createLibP2PPeerId(config.peerIdPrivateKey);
|
|
36
41
|
discv5Service = new DiscV5Service(peerId, config);
|
|
37
|
-
p2pService = await LibP2PService.new(config, discv5Service, peerId, txPool
|
|
42
|
+
p2pService = await LibP2PService.new(config, discv5Service, peerId, txPool);
|
|
38
43
|
}
|
|
39
44
|
else {
|
|
40
45
|
p2pService = new DummyP2PService();
|
|
@@ -42,4 +47,4 @@ export const createP2PClient = async (store, config, txPool, l2BlockSource) => {
|
|
|
42
47
|
}
|
|
43
48
|
return new P2PClient(store, l2BlockSource, txPool, p2pService);
|
|
44
49
|
};
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
50
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xpZW50L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGVBQWUsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV4RSxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTNELGNBQWMsaUJBQWlCLENBQUM7QUFFaEMsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLEtBQUssRUFDbEMsS0FBbUIsRUFDbkIsTUFBaUIsRUFDakIsTUFBYyxFQUNkLGFBQTRCLEVBQzVCLEVBQUU7SUFDRixJQUFJLGFBQWEsQ0FBQztJQUNsQixJQUFJLFVBQVUsQ0FBQztJQUVmLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3RCLHFHQUFxRztRQUNyRyxNQUFNLEVBQ0osa0JBQWtCLEVBQUUsd0JBQXdCLEVBQzVDLGtCQUFrQixFQUFFLHdCQUF3QixFQUM1QyxVQUFVLEdBQ1gsR0FBRyxNQUFNLENBQUM7UUFFWCx1Q0FBdUM7UUFDdkMsSUFBSSxRQUFRLENBQUM7UUFFYix1Q0FBdUM7UUFDdkMsTUFBTSx1QkFBdUIsR0FBRyxnQkFBZ0IsQ0FBQyx3QkFBd0IsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkYsSUFBSSx1QkFBdUIsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLHVCQUF1QixDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQzdFLElBQUksVUFBVSxFQUFFLENBQUM7Z0JBQ2YsUUFBUSxHQUFHLE1BQU0sV0FBVyxFQUFFLENBQUM7Z0JBQy9CLE1BQU0sa0JBQWtCLEdBQUcsR0FBRyxRQUFRLElBQUksdUJBQXVCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDdkUsTUFBTSxDQUFDLGtCQUFrQixHQUFHLGtCQUFrQixDQUFDO1lBQ2pELENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLElBQUksS0FBSyxDQUNiLHdDQUF3Qyx1QkFBdUIsa0NBQWtDLENBQ2xHLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sdUJBQXVCLEdBQUcsZ0JBQWdCLENBQUMsd0JBQXdCLElBQUksRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3ZGLElBQUksdUJBQXVCLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUM3RSxnRUFBZ0U7WUFDaEUsSUFBSSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztnQkFDN0MsTUFBTSxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQztZQUN4RCxDQUFDO2lCQUFNLElBQUksVUFBVSxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sV0FBVyxHQUFHLFFBQVEsSUFBSSxDQUFDLE1BQU0sV0FBVyxFQUFFLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLFdBQVcsSUFBSSx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUMxRSxNQUFNLENBQUMsa0JBQWtCLEdBQUcsa0JBQWtCLENBQUM7WUFDakQsQ0FBQztRQUNILENBQUM7UUFFRCxnQ0FBZ0M7UUFDaEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNqRSxhQUFhLEdBQUcsSUFBSSxhQUFhLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2xELFVBQVUsR0FBRyxNQUFNLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDOUUsQ0FBQztTQUFNLENBQUM7UUFDTixVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUNuQyxhQUFhLEdBQUcsSUFBSSx5QkFBeUIsRUFBRSxDQUFDO0lBQ2xELENBQUM7SUFDRCxPQUFPLElBQUksU0FBUyxDQUFDLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2pFLENBQUMsQ0FBQyJ9
|
package/dest/config.d.ts
CHANGED
|
@@ -20,21 +20,21 @@ export interface P2PConfig {
|
|
|
20
20
|
*/
|
|
21
21
|
p2pL2QueueSize: number;
|
|
22
22
|
/**
|
|
23
|
-
* The
|
|
23
|
+
* The announce address for TCP.
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
tcpAnnounceAddress?: string;
|
|
26
26
|
/**
|
|
27
|
-
* The
|
|
27
|
+
* The announce address for UDP.
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
udpAnnounceAddress?: string;
|
|
30
30
|
/**
|
|
31
|
-
* The
|
|
31
|
+
* The listen address for TCP.
|
|
32
32
|
*/
|
|
33
|
-
|
|
33
|
+
tcpListenAddress: string;
|
|
34
34
|
/**
|
|
35
|
-
* The
|
|
35
|
+
* The listen address for UDP.
|
|
36
36
|
*/
|
|
37
|
-
|
|
37
|
+
udpListenAddress: string;
|
|
38
38
|
/**
|
|
39
39
|
* An optional peer id private key. If blank, will generate a random key.
|
|
40
40
|
*/
|
|
@@ -47,19 +47,6 @@ export interface P2PConfig {
|
|
|
47
47
|
* Protocol identifier for transaction gossiping.
|
|
48
48
|
*/
|
|
49
49
|
transactionProtocol: string;
|
|
50
|
-
/**
|
|
51
|
-
* TCP Hostname to announce.
|
|
52
|
-
*/
|
|
53
|
-
announceTcpHostname?: string;
|
|
54
|
-
/**
|
|
55
|
-
* UDP Hostname to announce.
|
|
56
|
-
* If not provided, will use the same hostname as TCP.
|
|
57
|
-
*/
|
|
58
|
-
announceUdpHostname?: string;
|
|
59
|
-
/**
|
|
60
|
-
* Port to announce.
|
|
61
|
-
*/
|
|
62
|
-
announcePort?: number;
|
|
63
50
|
/**
|
|
64
51
|
* Whether to enable NAT from libp2p (ignored for bootstrap node).
|
|
65
52
|
*/
|
|
@@ -81,7 +68,7 @@ export interface P2PConfig {
|
|
|
81
68
|
*/
|
|
82
69
|
txGossipVersion: SemVer;
|
|
83
70
|
/**
|
|
84
|
-
* If
|
|
71
|
+
* If announceUdpAddress or announceTcpAddress are not provided, query for the IP address of the machine. Default is false.
|
|
85
72
|
*/
|
|
86
73
|
queryForIp: boolean;
|
|
87
74
|
}
|
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,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAE/B;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;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;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,CA0C/C"}
|
package/dest/config.js
CHANGED
|
@@ -4,22 +4,21 @@ import { SemVer } from 'semver';
|
|
|
4
4
|
* @returns The config values for p2p client.
|
|
5
5
|
*/
|
|
6
6
|
export function getP2PConfigEnvVars() {
|
|
7
|
-
const { P2P_ENABLED, P2P_BLOCK_CHECK_INTERVAL_MS, P2P_PEER_CHECK_INTERVAL_MS, P2P_L2_BLOCK_QUEUE_SIZE,
|
|
7
|
+
const { P2P_ENABLED, P2P_BLOCK_CHECK_INTERVAL_MS, P2P_PEER_CHECK_INTERVAL_MS, P2P_L2_BLOCK_QUEUE_SIZE, P2P_TCP_LISTEN_ADDR, P2P_UDP_LISTEN_ADDR, P2P_TCP_ANNOUNCE_ADDR, P2P_UDP_ANNOUNCE_ADDR, PEER_ID_PRIVATE_KEY, BOOTSTRAP_NODES, P2P_NAT_ENABLED, P2P_MIN_PEERS, P2P_MAX_PEERS, DATA_DIRECTORY, TX_GOSSIP_VERSION, P2P_TX_PROTOCOL, P2P_QUERY_FOR_IP, } = process.env;
|
|
8
|
+
// P2P listen & announce addresses passed in format: <IP_ADDRESS>:<PORT>
|
|
9
|
+
// P2P announce multiaddrs passed in format: /ip4/<IP_ADDRESS>/<protocol>/<PORT>
|
|
8
10
|
const envVars = {
|
|
11
|
+
tcpAnnounceAddress: P2P_TCP_ANNOUNCE_ADDR,
|
|
12
|
+
udpAnnounceAddress: P2P_UDP_ANNOUNCE_ADDR,
|
|
13
|
+
tcpListenAddress: P2P_TCP_LISTEN_ADDR || '0.0.0.0:40400',
|
|
14
|
+
udpListenAddress: P2P_UDP_LISTEN_ADDR || '0.0.0.0:40400',
|
|
9
15
|
p2pEnabled: P2P_ENABLED === 'true',
|
|
10
16
|
p2pBlockCheckIntervalMS: P2P_BLOCK_CHECK_INTERVAL_MS ? +P2P_BLOCK_CHECK_INTERVAL_MS : 100,
|
|
11
17
|
p2pPeerCheckIntervalMS: P2P_PEER_CHECK_INTERVAL_MS ? +P2P_PEER_CHECK_INTERVAL_MS : 1000,
|
|
12
18
|
p2pL2QueueSize: P2P_L2_BLOCK_QUEUE_SIZE ? +P2P_L2_BLOCK_QUEUE_SIZE : 1000,
|
|
13
|
-
tcpListenPort: P2P_TCP_LISTEN_PORT ? +P2P_TCP_LISTEN_PORT : 40400,
|
|
14
|
-
tcpListenIp: P2P_TCP_LISTEN_IP ? P2P_TCP_LISTEN_IP : '0.0.0.0',
|
|
15
|
-
udpListenPort: P2P_UDP_LISTEN_PORT ? +P2P_UDP_LISTEN_PORT : 40400,
|
|
16
|
-
udpListenIp: P2P_UDP_LISTEN_IP ? P2P_UDP_LISTEN_IP : '0.0.0.0',
|
|
17
19
|
peerIdPrivateKey: PEER_ID_PRIVATE_KEY,
|
|
18
20
|
bootstrapNodes: BOOTSTRAP_NODES ? BOOTSTRAP_NODES.split(',') : [],
|
|
19
21
|
transactionProtocol: P2P_TX_PROTOCOL ? P2P_TX_PROTOCOL : '/aztec/0.1.0',
|
|
20
|
-
announceTcpHostname: P2P_ANNOUNCE_TCP_HOSTNAME,
|
|
21
|
-
announceUdpHostname: P2P_ANNOUNCE_UDP_HOSTNAME,
|
|
22
|
-
announcePort: P2P_ANNOUNCE_PORT ? +P2P_ANNOUNCE_PORT : undefined,
|
|
23
22
|
enableNat: P2P_NAT_ENABLED === 'true',
|
|
24
23
|
minPeerCount: P2P_MIN_PEERS ? +P2P_MIN_PEERS : 10,
|
|
25
24
|
maxPeerCount: P2P_MAX_PEERS ? +P2P_MAX_PEERS : 100,
|
|
@@ -29,4 +28,4 @@ export function getP2PConfigEnvVars() {
|
|
|
29
28
|
};
|
|
30
29
|
return envVars;
|
|
31
30
|
}
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBNEZoQzs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsbUJBQW1CO0lBQ2pDLE1BQU0sRUFDSixXQUFXLEVBQ1gsMkJBQTJCLEVBQzNCLDBCQUEwQixFQUMxQix1QkFBdUIsRUFDdkIsbUJBQW1CLEVBQ25CLG1CQUFtQixFQUNuQixxQkFBcUIsRUFDckIscUJBQXFCLEVBQ3JCLG1CQUFtQixFQUNuQixlQUFlLEVBQ2YsZUFBZSxFQUNmLGFBQWEsRUFDYixhQUFhLEVBQ2IsY0FBYyxFQUNkLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsZ0JBQWdCLEdBQ2pCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztJQUNoQix3RUFBd0U7SUFDeEUsZ0ZBQWdGO0lBQ2hGLE1BQU0sT0FBTyxHQUFjO1FBQ3pCLGtCQUFrQixFQUFFLHFCQUFxQjtRQUN6QyxrQkFBa0IsRUFBRSxxQkFBcUI7UUFDekMsZ0JBQWdCLEVBQUUsbUJBQW1CLElBQUksZUFBZTtRQUN4RCxnQkFBZ0IsRUFBRSxtQkFBbUIsSUFBSSxlQUFlO1FBQ3hELFVBQVUsRUFBRSxXQUFXLEtBQUssTUFBTTtRQUNsQyx1QkFBdUIsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDLENBQUMsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUMsR0FBRztRQUN6RixzQkFBc0IsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDLENBQUMsQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLENBQUMsSUFBSTtRQUN2RixjQUFjLEVBQUUsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLElBQUk7UUFDekUsZ0JBQWdCLEVBQUUsbUJBQW1CO1FBQ3JDLGNBQWMsRUFBRSxlQUFlLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDakUsbUJBQW1CLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLGNBQWM7UUFDdkUsU0FBUyxFQUFFLGVBQWUsS0FBSyxNQUFNO1FBQ3JDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFO1FBQ2pELFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxHQUFHO1FBQ2xELGFBQWEsRUFBRSxjQUFjO1FBQzdCLGVBQWUsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQ3hGLFVBQVUsRUFBRSxnQkFBZ0IsS0FBSyxNQUFNO0tBQ3hDLENBQUM7SUFDRixPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discV5_service.d.ts","sourceRoot":"","sources":["../../src/service/discV5_service.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"discV5_service.d.ts","sourceRoot":"","sources":["../../src/service/discV5_service.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,KAAK,GAAG,EAAe,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,KAAK,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE7E,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAE7C,oBAAY,QAAQ;IAClB,MAAM,IAAO;IACb,OAAO,IAAO;IACd,OAAO,IAAO;CACf;AAGD,eAAO,MAAM,SAAS,kBAAkB,CAAC;AAEzC;;GAEG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,oBAAoB;IAajE,OAAO,CAAC,MAAM;IAA6B,OAAO,CAAC,MAAM;IAZrE,0BAA0B;IAC1B,OAAO,CAAC,MAAM,CAAS;IAEvB,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAc;IAEzB,OAAO,CAAC,cAAc,CAAiB;IAEvC,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,cAAc,CAAW;gBAEb,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAU,MAAM,yCAA4C;IAkDpG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B5B,WAAW,IAAI,GAAG,EAAE;IAIpB,MAAM,IAAI,GAAG;IAIb,SAAS,IAAI,MAAM;IAInB,SAAS,IAAI,kBAAkB;IAIzB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC,OAAO,CAAC,YAAY;CAWrB"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
2
2
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
3
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
3
4
|
import { Discv5 } from '@chainsafe/discv5';
|
|
4
5
|
import { SignableENR } from '@chainsafe/enr';
|
|
5
6
|
import { multiaddr } from '@multiformats/multiaddr';
|
|
6
7
|
import EventEmitter from 'events';
|
|
8
|
+
import { convertToMultiaddr } from '../util.js';
|
|
7
9
|
import { PeerDiscoveryState } from './service.js';
|
|
8
10
|
export const AZTEC_ENR_KEY = 'aztec_network';
|
|
9
11
|
export var AztecENR;
|
|
@@ -23,15 +25,19 @@ export class DiscV5Service extends EventEmitter {
|
|
|
23
25
|
this.peerId = peerId;
|
|
24
26
|
this.logger = logger;
|
|
25
27
|
this.currentState = PeerDiscoveryState.STOPPED;
|
|
26
|
-
const {
|
|
28
|
+
const { tcpAnnounceAddress, udpAnnounceAddress, udpListenAddress, bootstrapNodes } = config;
|
|
27
29
|
this.bootstrapNodes = bootstrapNodes;
|
|
28
30
|
// create ENR from PeerId
|
|
29
31
|
this.enr = SignableENR.createFromPeerId(peerId);
|
|
30
32
|
// Add aztec identification to ENR
|
|
31
33
|
this.enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
if (!tcpAnnounceAddress) {
|
|
35
|
+
throw new Error('You need to provide at least a TCP announce address.');
|
|
36
|
+
}
|
|
37
|
+
const multiAddrTcp = multiaddr(`${convertToMultiaddr(tcpAnnounceAddress, 'tcp')}/p2p/${peerId.toString()}`);
|
|
38
|
+
// if no udp announce address is provided, use the tcp announce address
|
|
39
|
+
const multiAddrUdp = multiaddr(`${convertToMultiaddr(udpAnnounceAddress || tcpAnnounceAddress, 'udp')}/p2p/${peerId.toString()}`);
|
|
40
|
+
const listenMultiAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
|
|
35
41
|
// set location multiaddr in ENR record
|
|
36
42
|
this.enr.setLocationMultiaddr(multiAddrUdp);
|
|
37
43
|
this.enr.setLocationMultiaddr(multiAddrTcp);
|
|
@@ -76,6 +82,9 @@ export class DiscV5Service extends EventEmitter {
|
|
|
76
82
|
this.logger.error(`Error adding bootnode ENRs: ${e}`);
|
|
77
83
|
}
|
|
78
84
|
}
|
|
85
|
+
// First, wait some time before starting the peer discovery
|
|
86
|
+
// reference: https://github.com/ChainSafe/lodestar/issues/3423
|
|
87
|
+
await sleep(2000);
|
|
79
88
|
this.runningPromise.start();
|
|
80
89
|
}
|
|
81
90
|
getAllPeers() {
|
|
@@ -107,4 +116,4 @@ export class DiscV5Service extends EventEmitter {
|
|
|
107
116
|
}
|
|
108
117
|
}
|
|
109
118
|
}
|
|
110
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY1Y1X3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9kaXNjVjVfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbkUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRWhELE9BQU8sRUFBRSxNQUFNLEVBQTJCLE1BQU0sbUJBQW1CLENBQUM7QUFDcEUsT0FBTyxFQUFZLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXZELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLFlBQVksTUFBTSxRQUFRLENBQUM7QUFHbEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2hELE9BQU8sRUFBNkIsa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFN0UsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLGVBQWUsQ0FBQztBQUU3QyxNQUFNLENBQU4sSUFBWSxRQUlYO0FBSkQsV0FBWSxRQUFRO0lBQ2xCLDJDQUFhLENBQUE7SUFDYiw2Q0FBYyxDQUFBO0lBQ2QsNkNBQWMsQ0FBQTtBQUNoQixDQUFDLEVBSlcsUUFBUSxLQUFSLFFBQVEsUUFJbkI7QUFFRCw2QkFBNkI7QUFDN0IsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7QUFFekM7O0dBRUc7QUFDSCxNQUFNLE9BQU8sYUFBYyxTQUFRLFlBQVk7SUFhN0MsWUFBb0IsTUFBYyxFQUFFLE1BQWlCLEVBQVUsU0FBUyxpQkFBaUIsQ0FBQyxzQkFBc0IsQ0FBQztRQUMvRyxLQUFLLEVBQUUsQ0FBQztRQURVLFdBQU0sR0FBTixNQUFNLENBQVE7UUFBNkIsV0FBTSxH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
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type Tx, type TxHash } from '@aztec/circuit-types';
|
|
2
|
-
import { type AztecKVStore } from '@aztec/kv-store';
|
|
3
2
|
import { type GossipsubEvents } from '@chainsafe/libp2p-gossipsub';
|
|
4
3
|
import type { PeerId, PubSub } from '@libp2p/interface';
|
|
5
4
|
import '@libp2p/kad-dht';
|
|
@@ -50,7 +49,7 @@ export declare class LibP2PService implements P2PService {
|
|
|
50
49
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
51
50
|
* @returns The new service.
|
|
52
51
|
*/
|
|
53
|
-
static new(config: P2PConfig, peerDiscoveryService: PeerDiscoveryService, peerId: PeerId, txPool: TxPool
|
|
52
|
+
static new(config: P2PConfig, peerDiscoveryService: PeerDiscoveryService, peerId: PeerId, txPool: TxPool): Promise<LibP2PService>;
|
|
54
53
|
/**
|
|
55
54
|
* Subscribes to a topic.
|
|
56
55
|
* @param topic - The topic to subscribe to.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../src/service/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"libp2p_service.d.ts","sourceRoot":"","sources":["../../src/service/libp2p_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAM5D,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,6BAA6B,CAAC;AAI9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAU,MAAM,mBAAmB,CAAC;AAChE,OAAO,iBAAiB,CAAC;AAKzB,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,QAAQ,CAAC;AAEnD,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAKlD,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGrE,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;KACjC,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS7E;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,UAAU;IAM5C,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,oBAAoB;IAC5B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,MAAM;IAXhB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,WAAW,CAAc;gBAEvB,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,YAAY,EAClB,oBAAoB,EAAE,oBAAoB,EAC1C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,gBAAgB,GAAE,MAAM,EAAO,EAC/B,MAAM,yCAA4C;IAM5D;;;OAGG;IACU,KAAK;IAmDlB;;;OAGG;IACU,IAAI;IAQjB;;;;;OAKG;WACiB,GAAG,CACrB,MAAM,EAAE,SAAS,EACjB,oBAAoB,EAAE,oBAAoB,EAC1C,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM;IAkEhB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;;;;OAKG;YACW,cAAc;IAS5B;;;;OAIG;YACW,sBAAsB;IAUpC;;;OAGG;IACI,WAAW,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI;IAIhC;;;OAGG;IACI,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;YAI7B,OAAO;YAiCP,mBAAmB;YASnB,iBAAiB;YAOjB,aAAa;IAO3B,OAAO,CAAC,eAAe;CAGxB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
2
2
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
|
|
3
4
|
import { ENR } from '@chainsafe/enr';
|
|
4
5
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
5
6
|
import { noise } from '@chainsafe/libp2p-noise';
|
|
@@ -11,6 +12,7 @@ import { peerIdFromString } from '@libp2p/peer-id';
|
|
|
11
12
|
import { createFromJSON, createSecp256k1PeerId } from '@libp2p/peer-id-factory';
|
|
12
13
|
import { tcp } from '@libp2p/tcp';
|
|
13
14
|
import { createLibp2p } from 'libp2p';
|
|
15
|
+
import { convertToMultiaddr } from '../util.js';
|
|
14
16
|
import { AztecDatastore } from './data_store.js';
|
|
15
17
|
import { KnownTxLookup } from './known_txs.js';
|
|
16
18
|
import { PeerManager } from './peer_manager.js';
|
|
@@ -55,14 +57,13 @@ export class LibP2PService {
|
|
|
55
57
|
if (this.node.status === 'started') {
|
|
56
58
|
throw new Error('P2P service already started');
|
|
57
59
|
}
|
|
58
|
-
const {
|
|
59
|
-
this.logger.info(`Starting P2P node on ${
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
if (enableNat) {
|
|
64
|
-
this.logger.info(`Enabling NAT in libp2p module`);
|
|
60
|
+
const { tcpListenAddress, tcpAnnounceAddress } = this.config;
|
|
61
|
+
this.logger.info(`Starting P2P node on ${tcpListenAddress}`);
|
|
62
|
+
if (!tcpAnnounceAddress) {
|
|
63
|
+
throw new Error('Announce address not provided.');
|
|
65
64
|
}
|
|
65
|
+
const announceTcpMultiaddr = convertToMultiaddr(tcpAnnounceAddress, 'tcp');
|
|
66
|
+
this.logger.info(`Announcing at ${announceTcpMultiaddr}`);
|
|
66
67
|
// handle discovered peers from external discovery service
|
|
67
68
|
this.peerDiscoveryService.on('peer:discovered', async (enr) => {
|
|
68
69
|
await this.addPeer(enr);
|
|
@@ -74,10 +75,10 @@ export class LibP2PService {
|
|
|
74
75
|
this.node.addEventListener('peer:disconnect', async (evt) => {
|
|
75
76
|
const peerId = evt.detail;
|
|
76
77
|
if (this.isBootstrapPeer(peerId)) {
|
|
77
|
-
this.logger.
|
|
78
|
+
this.logger.info(`Disconnect from bootstrap peer ${peerId.toString()}`);
|
|
78
79
|
}
|
|
79
80
|
else {
|
|
80
|
-
this.logger.
|
|
81
|
+
this.logger.info(`Disconnected from transaction peer ${peerId.toString()}`);
|
|
81
82
|
await this.peerManager.updateDiscoveryService();
|
|
82
83
|
}
|
|
83
84
|
});
|
|
@@ -111,9 +112,10 @@ export class LibP2PService {
|
|
|
111
112
|
* @param txPool - The transaction pool to be accessed by the service.
|
|
112
113
|
* @returns The new service.
|
|
113
114
|
*/
|
|
114
|
-
static async new(config, peerDiscoveryService, peerId, txPool
|
|
115
|
-
const {
|
|
116
|
-
const bindAddrTcp =
|
|
115
|
+
static async new(config, peerDiscoveryService, peerId, txPool) {
|
|
116
|
+
const { tcpListenAddress, minPeerCount, maxPeerCount, transactionProtocol: protocolId } = config;
|
|
117
|
+
const bindAddrTcp = convertToMultiaddr(tcpListenAddress, 'tcp');
|
|
118
|
+
const datastore = new AztecDatastore(AztecLmdbStore.open());
|
|
117
119
|
// The autonat service seems quite problematic in that using it seems to cause a lot of attempts
|
|
118
120
|
// to dial ephemeral ports. I suspect that it works better if you can get the uPNPnat service to
|
|
119
121
|
// work as then you would have a permanent port to be dialled.
|
|
@@ -127,7 +129,6 @@ export class LibP2PService {
|
|
|
127
129
|
// });
|
|
128
130
|
// services.uPnPNAT = uPnPNATService();
|
|
129
131
|
// }
|
|
130
|
-
const datastore = new AztecDatastore(store);
|
|
131
132
|
const node = await createLibp2p({
|
|
132
133
|
start: false,
|
|
133
134
|
peerId,
|
|
@@ -240,7 +241,7 @@ export class LibP2PService {
|
|
|
240
241
|
stream = await this.node.dialProtocol(peerMultiAddr, this.protocolId);
|
|
241
242
|
}
|
|
242
243
|
catch (err) {
|
|
243
|
-
this.logger.
|
|
244
|
+
this.logger.debug(`Failed to dial peer ${peerIdStr}: ${err}`);
|
|
244
245
|
}
|
|
245
246
|
finally {
|
|
246
247
|
if (stream) {
|
|
@@ -251,10 +252,10 @@ export class LibP2PService {
|
|
|
251
252
|
}
|
|
252
253
|
async handleNewConnection(peerId) {
|
|
253
254
|
if (this.isBootstrapPeer(peerId)) {
|
|
254
|
-
this.logger.
|
|
255
|
+
this.logger.info(`Connected to bootstrap peer ${peerId.toString()}`);
|
|
255
256
|
}
|
|
256
257
|
else {
|
|
257
|
-
this.logger.
|
|
258
|
+
this.logger.info(`Connected to transaction peer ${peerId.toString()}`);
|
|
258
259
|
await this.peerManager.updateDiscoveryService();
|
|
259
260
|
}
|
|
260
261
|
}
|
|
@@ -274,4 +275,4 @@ export class LibP2PService {
|
|
|
274
275
|
return this.bootstrapPeerIds.some(bootstrapPeer => bootstrapPeer.equals(peer));
|
|
275
276
|
}
|
|
276
277
|
}
|
|
277
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHMUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFBd0IsU0FBUyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDOUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxpQkFBaUIsQ0FBQztBQUN6QixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxjQUFjLEVBQUUscUJBQXFCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xDLE9BQU8sRUFBZSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFJbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFaEQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBUXhFOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFV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
|
|
278
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlicDJwX3NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9saWJwMnBfc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXRELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyQyxPQUFPLEVBQXdCLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzlFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsY0FBYyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDaEYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQWUsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBSW5ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNoRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVoRCxP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
|
package/dest/util.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an address string to a multiaddr string.
|
|
3
|
+
* Example usage:
|
|
4
|
+
* const tcpAddr = '123.456.7.8:80' -> /ip4/123.456.7.8/tcp/80
|
|
5
|
+
* const udpAddr = '[2001:db8::1]:8080' -> /ip6/2001:db8::1/udp/8080
|
|
6
|
+
* const dnsAddr = 'example.com:443' -> /dns4/example.com/tcp/443
|
|
7
|
+
* @param address - The address string to convert. Has to be in the format <addr>:<port>.
|
|
8
|
+
* @param protocol - The protocol to use in the multiaddr string.
|
|
9
|
+
* @returns A multiaddr compliant string.
|
|
10
|
+
*/
|
|
11
|
+
export declare function convertToMultiaddr(address: string, protocol: 'tcp' | 'udp'): string;
|
|
12
|
+
/**
|
|
13
|
+
* Splits an <address>:<port> string into its components.
|
|
14
|
+
* @returns The ip6 or ip4 address & port separately
|
|
15
|
+
*/
|
|
16
|
+
export declare function splitAddressPort(address: string, allowEmptyAddress: boolean): [string, string];
|
|
17
|
+
/**
|
|
18
|
+
* Queries the public IP address of the machine.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getPublicIp(): Promise<string>;
|
|
21
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAgBnF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAoB9F;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAInD"}
|
package/dest/util.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an address string to a multiaddr string.
|
|
3
|
+
* Example usage:
|
|
4
|
+
* const tcpAddr = '123.456.7.8:80' -> /ip4/123.456.7.8/tcp/80
|
|
5
|
+
* const udpAddr = '[2001:db8::1]:8080' -> /ip6/2001:db8::1/udp/8080
|
|
6
|
+
* const dnsAddr = 'example.com:443' -> /dns4/example.com/tcp/443
|
|
7
|
+
* @param address - The address string to convert. Has to be in the format <addr>:<port>.
|
|
8
|
+
* @param protocol - The protocol to use in the multiaddr string.
|
|
9
|
+
* @returns A multiaddr compliant string.
|
|
10
|
+
*/
|
|
11
|
+
export function convertToMultiaddr(address, protocol) {
|
|
12
|
+
const [addr, port] = splitAddressPort(address, false);
|
|
13
|
+
let multiaddrPrefix;
|
|
14
|
+
if (addr.includes(':')) {
|
|
15
|
+
// IPv6 address
|
|
16
|
+
multiaddrPrefix = 'ip6';
|
|
17
|
+
}
|
|
18
|
+
else if (addr.match(/^[\d.]+$/)) {
|
|
19
|
+
// IPv4 address
|
|
20
|
+
multiaddrPrefix = 'ip4';
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
throw new Error('Invalid address format. Expected an IPv4 or IPv6 address.');
|
|
24
|
+
}
|
|
25
|
+
return `/${multiaddrPrefix}/${addr}/${protocol}/${port}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Splits an <address>:<port> string into its components.
|
|
29
|
+
* @returns The ip6 or ip4 address & port separately
|
|
30
|
+
*/
|
|
31
|
+
export function splitAddressPort(address, allowEmptyAddress) {
|
|
32
|
+
let addr;
|
|
33
|
+
let port;
|
|
34
|
+
if (address.startsWith('[')) {
|
|
35
|
+
// IPv6 address enclosed in square brackets
|
|
36
|
+
const match = address.match(/^\[([^\]]+)\]:(\d+)$/);
|
|
37
|
+
if (!match) {
|
|
38
|
+
throw new Error(`Invalid IPv6 address format:${address}. Expected format: [<addr>]:<port>`);
|
|
39
|
+
}
|
|
40
|
+
[, addr, port] = match;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// IPv4 address
|
|
44
|
+
[addr, port] = address.split(':');
|
|
45
|
+
if ((!addr && !allowEmptyAddress) || !port) {
|
|
46
|
+
throw new Error(`Invalid address format: ${address}. Expected format: <addr>:<port>`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return [addr, port];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Queries the public IP address of the machine.
|
|
53
|
+
*/
|
|
54
|
+
export async function getPublicIp() {
|
|
55
|
+
const resp = await fetch('http://checkip.amazonaws.com/');
|
|
56
|
+
const text = await resp.text();
|
|
57
|
+
return text.trim();
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxPQUFlLEVBQUUsUUFBdUI7SUFDekUsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFdEQsSUFBSSxlQUF1QixDQUFDO0lBRTVCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLGVBQWU7UUFDZixlQUFlLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7U0FBTSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUNsQyxlQUFlO1FBQ2YsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUMxQixDQUFDO1NBQU0sQ0FBQztRQUNOLE1BQU0sSUFBSSxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQztJQUMvRSxDQUFDO0lBRUQsT0FBTyxJQUFJLGVBQWUsSUFBSSxJQUFJLElBQUksUUFBUSxJQUFJLElBQUksRUFBRSxDQUFDO0FBQzNELENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsT0FBZSxFQUFFLGlCQUEwQjtJQUMxRSxJQUFJLElBQVksQ0FBQztJQUNqQixJQUFJLElBQVksQ0FBQztJQUVqQixJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUM1QiwyQ0FBMkM7UUFDM0MsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLE9BQU8sb0NBQW9DLENBQUMsQ0FBQztRQUM5RixDQUFDO1FBQ0QsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDekIsQ0FBQztTQUFNLENBQUM7UUFDTixlQUFlO1FBQ2YsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQyxJQUFJLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQywyQkFBMkIsT0FBTyxrQ0FBa0MsQ0FBQyxDQUFDO1FBQ3hGLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN0QixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFdBQVc7SUFDL0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztJQUMxRCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMvQixPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNyQixDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/p2p",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.43.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"typedocOptions": {
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"testTimeout": 15000
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@aztec/circuit-types": "0.
|
|
52
|
-
"@aztec/circuits.js": "0.
|
|
53
|
-
"@aztec/foundation": "0.
|
|
54
|
-
"@aztec/kv-store": "0.
|
|
51
|
+
"@aztec/circuit-types": "0.43.0",
|
|
52
|
+
"@aztec/circuits.js": "0.43.0",
|
|
53
|
+
"@aztec/foundation": "0.43.0",
|
|
54
|
+
"@aztec/kv-store": "0.43.0",
|
|
55
55
|
"@chainsafe/discv5": "9.0.0",
|
|
56
56
|
"@chainsafe/enr": "3.0.0",
|
|
57
57
|
"@chainsafe/libp2p-gossipsub": "13.0.0",
|
|
@@ -8,13 +8,14 @@ import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
|
|
|
8
8
|
import { type P2PConfig } from '../config.js';
|
|
9
9
|
import { AZTEC_ENR_KEY, AZTEC_NET } from '../service/discV5_service.js';
|
|
10
10
|
import { createLibP2PPeerId } from '../service/index.js';
|
|
11
|
+
import { convertToMultiaddr } from '../util.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Required P2P config values for a bootstrap node.
|
|
14
15
|
*/
|
|
15
16
|
export type BootNodeConfig = Partial<P2PConfig> &
|
|
16
|
-
Pick<P2PConfig, '
|
|
17
|
-
Required<Pick<P2PConfig, '
|
|
17
|
+
Pick<P2PConfig, 'udpAnnounceAddress'> &
|
|
18
|
+
Required<Pick<P2PConfig, 'udpListenAddress'>>;
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Encapsulates a 'Bootstrap' node, used for the purpose of assisting new joiners in acquiring peers.
|
|
@@ -31,13 +32,18 @@ export class BootstrapNode {
|
|
|
31
32
|
* @returns An empty promise.
|
|
32
33
|
*/
|
|
33
34
|
public async start(config: BootNodeConfig) {
|
|
34
|
-
const { peerIdPrivateKey,
|
|
35
|
+
const { peerIdPrivateKey, udpListenAddress, udpAnnounceAddress } = config;
|
|
35
36
|
const peerId = await createLibP2PPeerId(peerIdPrivateKey);
|
|
36
37
|
this.peerId = peerId;
|
|
37
38
|
const enr = SignableENR.createFromPeerId(peerId);
|
|
38
39
|
|
|
39
|
-
const listenAddrUdp = multiaddr(
|
|
40
|
-
|
|
40
|
+
const listenAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
|
|
41
|
+
|
|
42
|
+
if (!udpAnnounceAddress) {
|
|
43
|
+
throw new Error('You need to provide a UDP announce address.');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const publicAddr = multiaddr(convertToMultiaddr(udpAnnounceAddress, 'udp'));
|
|
41
47
|
enr.setLocationMultiaddr(publicAddr);
|
|
42
48
|
enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
|
|
43
49
|
|
package/src/client/index.ts
CHANGED
|
@@ -6,8 +6,8 @@ import { type P2PConfig } from '../config.js';
|
|
|
6
6
|
import { DiscV5Service } from '../service/discV5_service.js';
|
|
7
7
|
import { DummyP2PService, DummyPeerDiscoveryService } from '../service/dummy_service.js';
|
|
8
8
|
import { LibP2PService, createLibP2PPeerId } from '../service/index.js';
|
|
9
|
-
import { getPublicIp } from '../service/ip_query.js';
|
|
10
9
|
import { type TxPool } from '../tx_pool/index.js';
|
|
10
|
+
import { getPublicIp, splitAddressPort } from '../util.js';
|
|
11
11
|
|
|
12
12
|
export * from './p2p_client.js';
|
|
13
13
|
|
|
@@ -21,37 +21,46 @@ export const createP2PClient = async (
|
|
|
21
21
|
let p2pService;
|
|
22
22
|
|
|
23
23
|
if (config.p2pEnabled) {
|
|
24
|
-
// If
|
|
24
|
+
// If announceTcpAddress or announceUdpAddress are not provided, query for public IP if config allows
|
|
25
25
|
const {
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
tcpAnnounceAddress: configTcpAnnounceAddress,
|
|
27
|
+
udpAnnounceAddress: configUdpAnnounceAddress,
|
|
28
28
|
queryForIp,
|
|
29
29
|
} = config;
|
|
30
|
-
|
|
30
|
+
|
|
31
|
+
// create variable for re-use if needed
|
|
32
|
+
let publicIp;
|
|
33
|
+
|
|
34
|
+
// check if no announce IP was provided
|
|
35
|
+
const splitTcpAnnounceAddress = splitAddressPort(configTcpAnnounceAddress || '', true);
|
|
36
|
+
if (splitTcpAnnounceAddress.length == 2 && splitTcpAnnounceAddress[0] === '') {
|
|
31
37
|
if (queryForIp) {
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
config.
|
|
38
|
+
publicIp = await getPublicIp();
|
|
39
|
+
const tcpAnnounceAddress = `${publicIp}:${splitTcpAnnounceAddress[1]}`;
|
|
40
|
+
config.tcpAnnounceAddress = tcpAnnounceAddress;
|
|
35
41
|
} else {
|
|
36
|
-
throw new Error(
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Invalid announceTcpAddress provided: ${splitTcpAnnounceAddress}. Expected format: <addr>:<port>`,
|
|
44
|
+
);
|
|
37
45
|
}
|
|
38
46
|
}
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
const splitUdpAnnounceAddress = splitAddressPort(configUdpAnnounceAddress || '', true);
|
|
49
|
+
if (splitUdpAnnounceAddress.length == 2 && splitUdpAnnounceAddress[0] === '') {
|
|
50
|
+
// If announceUdpAddress is not provided, use announceTcpAddress
|
|
51
|
+
if (!queryForIp && config.tcpAnnounceAddress) {
|
|
52
|
+
config.udpAnnounceAddress = config.tcpAnnounceAddress;
|
|
44
53
|
} else if (queryForIp) {
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
config.
|
|
54
|
+
const udpPublicIp = publicIp || (await getPublicIp());
|
|
55
|
+
const udpAnnounceAddress = `${udpPublicIp}:${splitUdpAnnounceAddress[1]}`;
|
|
56
|
+
config.udpAnnounceAddress = udpAnnounceAddress;
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
// Create peer discovery service
|
|
52
61
|
const peerId = await createLibP2PPeerId(config.peerIdPrivateKey);
|
|
53
62
|
discv5Service = new DiscV5Service(peerId, config);
|
|
54
|
-
p2pService = await LibP2PService.new(config, discv5Service, peerId, txPool
|
|
63
|
+
p2pService = await LibP2PService.new(config, discv5Service, peerId, txPool);
|
|
55
64
|
} else {
|
|
56
65
|
p2pService = new DummyP2PService();
|
|
57
66
|
discv5Service = new DummyPeerDiscoveryService();
|
package/src/config.ts
CHANGED
|
@@ -25,24 +25,24 @@ export interface P2PConfig {
|
|
|
25
25
|
p2pL2QueueSize: number;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* The
|
|
28
|
+
* The announce address for TCP.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
tcpAnnounceAddress?: string;
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
|
-
* The
|
|
33
|
+
* The announce address for UDP.
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
udpAnnounceAddress?: string;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
|
-
* The
|
|
38
|
+
* The listen address for TCP.
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
tcpListenAddress: string;
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* The
|
|
43
|
+
* The listen address for UDP.
|
|
44
44
|
*/
|
|
45
|
-
|
|
45
|
+
udpListenAddress: string;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* An optional peer id private key. If blank, will generate a random key.
|
|
@@ -59,22 +59,6 @@ export interface P2PConfig {
|
|
|
59
59
|
*/
|
|
60
60
|
transactionProtocol: string;
|
|
61
61
|
|
|
62
|
-
/**
|
|
63
|
-
* TCP Hostname to announce.
|
|
64
|
-
*/
|
|
65
|
-
announceTcpHostname?: string;
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* UDP Hostname to announce.
|
|
69
|
-
* If not provided, will use the same hostname as TCP.
|
|
70
|
-
*/
|
|
71
|
-
announceUdpHostname?: string;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Port to announce.
|
|
75
|
-
*/
|
|
76
|
-
announcePort?: number;
|
|
77
|
-
|
|
78
62
|
/**
|
|
79
63
|
* Whether to enable NAT from libp2p (ignored for bootstrap node).
|
|
80
64
|
*/
|
|
@@ -101,7 +85,7 @@ export interface P2PConfig {
|
|
|
101
85
|
txGossipVersion: SemVer;
|
|
102
86
|
|
|
103
87
|
/**
|
|
104
|
-
* If
|
|
88
|
+
* If announceUdpAddress or announceTcpAddress are not provided, query for the IP address of the machine. Default is false.
|
|
105
89
|
*/
|
|
106
90
|
queryForIp: boolean;
|
|
107
91
|
}
|
|
@@ -116,15 +100,12 @@ export function getP2PConfigEnvVars(): P2PConfig {
|
|
|
116
100
|
P2P_BLOCK_CHECK_INTERVAL_MS,
|
|
117
101
|
P2P_PEER_CHECK_INTERVAL_MS,
|
|
118
102
|
P2P_L2_BLOCK_QUEUE_SIZE,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
103
|
+
P2P_TCP_LISTEN_ADDR,
|
|
104
|
+
P2P_UDP_LISTEN_ADDR,
|
|
105
|
+
P2P_TCP_ANNOUNCE_ADDR,
|
|
106
|
+
P2P_UDP_ANNOUNCE_ADDR,
|
|
123
107
|
PEER_ID_PRIVATE_KEY,
|
|
124
108
|
BOOTSTRAP_NODES,
|
|
125
|
-
P2P_ANNOUNCE_TCP_HOSTNAME,
|
|
126
|
-
P2P_ANNOUNCE_UDP_HOSTNAME,
|
|
127
|
-
P2P_ANNOUNCE_PORT,
|
|
128
109
|
P2P_NAT_ENABLED,
|
|
129
110
|
P2P_MIN_PEERS,
|
|
130
111
|
P2P_MAX_PEERS,
|
|
@@ -133,21 +114,20 @@ export function getP2PConfigEnvVars(): P2PConfig {
|
|
|
133
114
|
P2P_TX_PROTOCOL,
|
|
134
115
|
P2P_QUERY_FOR_IP,
|
|
135
116
|
} = process.env;
|
|
117
|
+
// P2P listen & announce addresses passed in format: <IP_ADDRESS>:<PORT>
|
|
118
|
+
// P2P announce multiaddrs passed in format: /ip4/<IP_ADDRESS>/<protocol>/<PORT>
|
|
136
119
|
const envVars: P2PConfig = {
|
|
120
|
+
tcpAnnounceAddress: P2P_TCP_ANNOUNCE_ADDR,
|
|
121
|
+
udpAnnounceAddress: P2P_UDP_ANNOUNCE_ADDR,
|
|
122
|
+
tcpListenAddress: P2P_TCP_LISTEN_ADDR || '0.0.0.0:40400',
|
|
123
|
+
udpListenAddress: P2P_UDP_LISTEN_ADDR || '0.0.0.0:40400',
|
|
137
124
|
p2pEnabled: P2P_ENABLED === 'true',
|
|
138
125
|
p2pBlockCheckIntervalMS: P2P_BLOCK_CHECK_INTERVAL_MS ? +P2P_BLOCK_CHECK_INTERVAL_MS : 100,
|
|
139
126
|
p2pPeerCheckIntervalMS: P2P_PEER_CHECK_INTERVAL_MS ? +P2P_PEER_CHECK_INTERVAL_MS : 1000,
|
|
140
127
|
p2pL2QueueSize: P2P_L2_BLOCK_QUEUE_SIZE ? +P2P_L2_BLOCK_QUEUE_SIZE : 1000,
|
|
141
|
-
tcpListenPort: P2P_TCP_LISTEN_PORT ? +P2P_TCP_LISTEN_PORT : 40400,
|
|
142
|
-
tcpListenIp: P2P_TCP_LISTEN_IP ? P2P_TCP_LISTEN_IP : '0.0.0.0',
|
|
143
|
-
udpListenPort: P2P_UDP_LISTEN_PORT ? +P2P_UDP_LISTEN_PORT : 40400,
|
|
144
|
-
udpListenIp: P2P_UDP_LISTEN_IP ? P2P_UDP_LISTEN_IP : '0.0.0.0',
|
|
145
128
|
peerIdPrivateKey: PEER_ID_PRIVATE_KEY,
|
|
146
129
|
bootstrapNodes: BOOTSTRAP_NODES ? BOOTSTRAP_NODES.split(',') : [],
|
|
147
130
|
transactionProtocol: P2P_TX_PROTOCOL ? P2P_TX_PROTOCOL : '/aztec/0.1.0',
|
|
148
|
-
announceTcpHostname: P2P_ANNOUNCE_TCP_HOSTNAME,
|
|
149
|
-
announceUdpHostname: P2P_ANNOUNCE_UDP_HOSTNAME,
|
|
150
|
-
announcePort: P2P_ANNOUNCE_PORT ? +P2P_ANNOUNCE_PORT : undefined,
|
|
151
131
|
enableNat: P2P_NAT_ENABLED === 'true',
|
|
152
132
|
minPeerCount: P2P_MIN_PEERS ? +P2P_MIN_PEERS : 10,
|
|
153
133
|
maxPeerCount: P2P_MAX_PEERS ? +P2P_MAX_PEERS : 100,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
2
2
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
3
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
3
4
|
|
|
4
5
|
import { Discv5, type Discv5EventEmitter } from '@chainsafe/discv5';
|
|
5
6
|
import { type ENR, SignableENR } from '@chainsafe/enr';
|
|
@@ -8,6 +9,7 @@ import { multiaddr } from '@multiformats/multiaddr';
|
|
|
8
9
|
import EventEmitter from 'events';
|
|
9
10
|
|
|
10
11
|
import type { P2PConfig } from '../config.js';
|
|
12
|
+
import { convertToMultiaddr } from '../util.js';
|
|
11
13
|
import { type PeerDiscoveryService, PeerDiscoveryState } from './service.js';
|
|
12
14
|
|
|
13
15
|
export const AZTEC_ENR_KEY = 'aztec_network';
|
|
@@ -39,18 +41,24 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
39
41
|
|
|
40
42
|
constructor(private peerId: PeerId, config: P2PConfig, private logger = createDebugLogger('aztec:discv5_service')) {
|
|
41
43
|
super();
|
|
42
|
-
const {
|
|
43
|
-
config;
|
|
44
|
+
const { tcpAnnounceAddress, udpAnnounceAddress, udpListenAddress, bootstrapNodes } = config;
|
|
44
45
|
this.bootstrapNodes = bootstrapNodes;
|
|
45
46
|
// create ENR from PeerId
|
|
46
47
|
this.enr = SignableENR.createFromPeerId(peerId);
|
|
47
48
|
// Add aztec identification to ENR
|
|
48
49
|
this.enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
if (!tcpAnnounceAddress) {
|
|
52
|
+
throw new Error('You need to provide at least a TCP announce address.');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const multiAddrTcp = multiaddr(`${convertToMultiaddr(tcpAnnounceAddress, 'tcp')}/p2p/${peerId.toString()}`);
|
|
56
|
+
// if no udp announce address is provided, use the tcp announce address
|
|
57
|
+
const multiAddrUdp = multiaddr(
|
|
58
|
+
`${convertToMultiaddr(udpAnnounceAddress || tcpAnnounceAddress, 'udp')}/p2p/${peerId.toString()}`,
|
|
59
|
+
);
|
|
52
60
|
|
|
53
|
-
const listenMultiAddrUdp = multiaddr(
|
|
61
|
+
const listenMultiAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
|
|
54
62
|
|
|
55
63
|
// set location multiaddr in ENR record
|
|
56
64
|
this.enr.setLocationMultiaddr(multiAddrUdp);
|
|
@@ -87,6 +95,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
87
95
|
}
|
|
88
96
|
this.logger.info('Starting DiscV5');
|
|
89
97
|
await this.discv5.start();
|
|
98
|
+
|
|
90
99
|
this.logger.info('DiscV5 started');
|
|
91
100
|
this.currentState = PeerDiscoveryState.RUNNING;
|
|
92
101
|
|
|
@@ -102,6 +111,10 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
102
111
|
}
|
|
103
112
|
}
|
|
104
113
|
|
|
114
|
+
// First, wait some time before starting the peer discovery
|
|
115
|
+
// reference: https://github.com/ChainSafe/lodestar/issues/3423
|
|
116
|
+
await sleep(2000);
|
|
117
|
+
|
|
105
118
|
this.runningPromise.start();
|
|
106
119
|
}
|
|
107
120
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Tx, type TxHash } from '@aztec/circuit-types';
|
|
2
2
|
import { SerialQueue } from '@aztec/foundation/fifo';
|
|
3
3
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
4
|
-
import {
|
|
4
|
+
import { AztecLmdbStore } from '@aztec/kv-store/lmdb';
|
|
5
5
|
|
|
6
6
|
import { ENR } from '@chainsafe/enr';
|
|
7
7
|
import { type GossipsubEvents, gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
@@ -18,6 +18,7 @@ import { type Libp2p, createLibp2p } from 'libp2p';
|
|
|
18
18
|
|
|
19
19
|
import { type P2PConfig } from '../config.js';
|
|
20
20
|
import { type TxPool } from '../tx_pool/index.js';
|
|
21
|
+
import { convertToMultiaddr } from '../util.js';
|
|
21
22
|
import { AztecDatastore } from './data_store.js';
|
|
22
23
|
import { KnownTxLookup } from './known_txs.js';
|
|
23
24
|
import { PeerManager } from './peer_manager.js';
|
|
@@ -75,15 +76,16 @@ export class LibP2PService implements P2PService {
|
|
|
75
76
|
if (this.node.status === 'started') {
|
|
76
77
|
throw new Error('P2P service already started');
|
|
77
78
|
}
|
|
78
|
-
const {
|
|
79
|
-
this.logger.info(`Starting P2P node on ${
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (enableNat) {
|
|
84
|
-
this.logger.info(`Enabling NAT in libp2p module`);
|
|
79
|
+
const { tcpListenAddress, tcpAnnounceAddress } = this.config;
|
|
80
|
+
this.logger.info(`Starting P2P node on ${tcpListenAddress}`);
|
|
81
|
+
|
|
82
|
+
if (!tcpAnnounceAddress) {
|
|
83
|
+
throw new Error('Announce address not provided.');
|
|
85
84
|
}
|
|
86
85
|
|
|
86
|
+
const announceTcpMultiaddr = convertToMultiaddr(tcpAnnounceAddress, 'tcp');
|
|
87
|
+
|
|
88
|
+
this.logger.info(`Announcing at ${announceTcpMultiaddr}`);
|
|
87
89
|
// handle discovered peers from external discovery service
|
|
88
90
|
this.peerDiscoveryService.on('peer:discovered', async (enr: ENR) => {
|
|
89
91
|
await this.addPeer(enr);
|
|
@@ -97,9 +99,9 @@ export class LibP2PService implements P2PService {
|
|
|
97
99
|
this.node.addEventListener('peer:disconnect', async evt => {
|
|
98
100
|
const peerId = evt.detail;
|
|
99
101
|
if (this.isBootstrapPeer(peerId)) {
|
|
100
|
-
this.logger.
|
|
102
|
+
this.logger.info(`Disconnect from bootstrap peer ${peerId.toString()}`);
|
|
101
103
|
} else {
|
|
102
|
-
this.logger.
|
|
104
|
+
this.logger.info(`Disconnected from transaction peer ${peerId.toString()}`);
|
|
103
105
|
await this.peerManager.updateDiscoveryService();
|
|
104
106
|
}
|
|
105
107
|
});
|
|
@@ -144,10 +146,11 @@ export class LibP2PService implements P2PService {
|
|
|
144
146
|
peerDiscoveryService: PeerDiscoveryService,
|
|
145
147
|
peerId: PeerId,
|
|
146
148
|
txPool: TxPool,
|
|
147
|
-
store: AztecKVStore,
|
|
148
149
|
) {
|
|
149
|
-
const {
|
|
150
|
-
const bindAddrTcp =
|
|
150
|
+
const { tcpListenAddress, minPeerCount, maxPeerCount, transactionProtocol: protocolId } = config;
|
|
151
|
+
const bindAddrTcp = convertToMultiaddr(tcpListenAddress, 'tcp');
|
|
152
|
+
|
|
153
|
+
const datastore = new AztecDatastore(AztecLmdbStore.open());
|
|
151
154
|
|
|
152
155
|
// The autonat service seems quite problematic in that using it seems to cause a lot of attempts
|
|
153
156
|
// to dial ephemeral ports. I suspect that it works better if you can get the uPNPnat service to
|
|
@@ -163,8 +166,6 @@ export class LibP2PService implements P2PService {
|
|
|
163
166
|
// services.uPnPNAT = uPnPNATService();
|
|
164
167
|
// }
|
|
165
168
|
|
|
166
|
-
const datastore = new AztecDatastore(store);
|
|
167
|
-
|
|
168
169
|
const node = await createLibp2p({
|
|
169
170
|
start: false,
|
|
170
171
|
peerId,
|
|
@@ -291,7 +292,7 @@ export class LibP2PService implements P2PService {
|
|
|
291
292
|
try {
|
|
292
293
|
stream = await this.node.dialProtocol(peerMultiAddr, this.protocolId);
|
|
293
294
|
} catch (err) {
|
|
294
|
-
this.logger.
|
|
295
|
+
this.logger.debug(`Failed to dial peer ${peerIdStr}: ${err}`);
|
|
295
296
|
} finally {
|
|
296
297
|
if (stream) {
|
|
297
298
|
await stream.close();
|
|
@@ -302,9 +303,9 @@ export class LibP2PService implements P2PService {
|
|
|
302
303
|
|
|
303
304
|
private async handleNewConnection(peerId: PeerId) {
|
|
304
305
|
if (this.isBootstrapPeer(peerId)) {
|
|
305
|
-
this.logger.
|
|
306
|
+
this.logger.info(`Connected to bootstrap peer ${peerId.toString()}`);
|
|
306
307
|
} else {
|
|
307
|
-
this.logger.
|
|
308
|
+
this.logger.info(`Connected to transaction peer ${peerId.toString()}`);
|
|
308
309
|
await this.peerManager.updateDiscoveryService();
|
|
309
310
|
}
|
|
310
311
|
}
|
package/src/util.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts an address string to a multiaddr string.
|
|
3
|
+
* Example usage:
|
|
4
|
+
* const tcpAddr = '123.456.7.8:80' -> /ip4/123.456.7.8/tcp/80
|
|
5
|
+
* const udpAddr = '[2001:db8::1]:8080' -> /ip6/2001:db8::1/udp/8080
|
|
6
|
+
* const dnsAddr = 'example.com:443' -> /dns4/example.com/tcp/443
|
|
7
|
+
* @param address - The address string to convert. Has to be in the format <addr>:<port>.
|
|
8
|
+
* @param protocol - The protocol to use in the multiaddr string.
|
|
9
|
+
* @returns A multiaddr compliant string.
|
|
10
|
+
*/
|
|
11
|
+
export function convertToMultiaddr(address: string, protocol: 'tcp' | 'udp'): string {
|
|
12
|
+
const [addr, port] = splitAddressPort(address, false);
|
|
13
|
+
|
|
14
|
+
let multiaddrPrefix: string;
|
|
15
|
+
|
|
16
|
+
if (addr.includes(':')) {
|
|
17
|
+
// IPv6 address
|
|
18
|
+
multiaddrPrefix = 'ip6';
|
|
19
|
+
} else if (addr.match(/^[\d.]+$/)) {
|
|
20
|
+
// IPv4 address
|
|
21
|
+
multiaddrPrefix = 'ip4';
|
|
22
|
+
} else {
|
|
23
|
+
throw new Error('Invalid address format. Expected an IPv4 or IPv6 address.');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return `/${multiaddrPrefix}/${addr}/${protocol}/${port}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Splits an <address>:<port> string into its components.
|
|
31
|
+
* @returns The ip6 or ip4 address & port separately
|
|
32
|
+
*/
|
|
33
|
+
export function splitAddressPort(address: string, allowEmptyAddress: boolean): [string, string] {
|
|
34
|
+
let addr: string;
|
|
35
|
+
let port: string;
|
|
36
|
+
|
|
37
|
+
if (address.startsWith('[')) {
|
|
38
|
+
// IPv6 address enclosed in square brackets
|
|
39
|
+
const match = address.match(/^\[([^\]]+)\]:(\d+)$/);
|
|
40
|
+
if (!match) {
|
|
41
|
+
throw new Error(`Invalid IPv6 address format:${address}. Expected format: [<addr>]:<port>`);
|
|
42
|
+
}
|
|
43
|
+
[, addr, port] = match;
|
|
44
|
+
} else {
|
|
45
|
+
// IPv4 address
|
|
46
|
+
[addr, port] = address.split(':');
|
|
47
|
+
if ((!addr && !allowEmptyAddress) || !port) {
|
|
48
|
+
throw new Error(`Invalid address format: ${address}. Expected format: <addr>:<port>`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return [addr, port];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Queries the public IP address of the machine.
|
|
57
|
+
*/
|
|
58
|
+
export async function getPublicIp(): Promise<string> {
|
|
59
|
+
const resp = await fetch('http://checkip.amazonaws.com/');
|
|
60
|
+
const text = await resp.text();
|
|
61
|
+
return text.trim();
|
|
62
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ip_query.d.ts","sourceRoot":"","sources":["../../src/service/ip_query.ts"],"names":[],"mappings":"AAAA,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAInD"}
|
package/dest/service/ip_query.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export async function getPublicIp() {
|
|
2
|
-
const resp = await fetch('http://checkip.amazonaws.com/');
|
|
3
|
-
const text = await resp.text();
|
|
4
|
-
return text.trim();
|
|
5
|
-
}
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXBfcXVlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZS9pcF9xdWVyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsS0FBSyxVQUFVLFdBQVc7SUFDL0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztJQUMxRCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMvQixPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztBQUNyQixDQUFDIn0=
|