@dignetwork/dig-sdk 0.0.1-alpha.150 → 0.0.1-alpha.152
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/dist/DigNetwork/DigNetwork.d.ts +3 -3
- package/dist/DigNetwork/DigNetwork.d.ts.map +1 -1
- package/dist/DigNetwork/DigNetwork.js +71 -88
- package/dist/blockchain/ServerCoin.js +1 -1
- package/dist/blockchain/StoreMonitorRegistry.js +1 -1
- package/dist/utils/PeerRanker.d.ts +2 -0
- package/dist/utils/PeerRanker.d.ts.map +1 -1
- package/dist/utils/PeerRanker.js +18 -2
- package/dist/utils/network.d.ts +1 -1
- package/dist/utils/network.d.ts.map +1 -1
- package/dist/utils/network.js +20 -21
- package/package.json +1 -1
|
@@ -7,17 +7,17 @@ export declare class DigNetwork {
|
|
|
7
7
|
private static networkSyncMap;
|
|
8
8
|
constructor(storeId: string);
|
|
9
9
|
static subscribeToStore(storeId: string): Promise<void>;
|
|
10
|
+
static getAllNetworkDataStoreIds(): string[];
|
|
10
11
|
static getUdiContent(udi: string): Promise<void>;
|
|
11
12
|
/**
|
|
12
|
-
* Find a peer that has the store key and root hash.
|
|
13
|
+
* Find a peer that has the store key and root hash, using ranked peers first and searching in groups of 5.
|
|
13
14
|
*
|
|
14
15
|
* @param {string} storeId - The ID of the store.
|
|
15
16
|
* @param {string} rootHash - The root hash of the store.
|
|
16
17
|
* @param {string} [key] - Optional key to check for in the store.
|
|
17
|
-
* @param {string[]} [initialBlackList] - Initial list of blacklisted peer IPs.
|
|
18
18
|
* @returns {Promise<DigPeer | null>} - A valid peer or null if none found.
|
|
19
19
|
*/
|
|
20
|
-
static findPeerWithStoreKey(storeId: string, rootHash: string, key?: string
|
|
20
|
+
static findPeerWithStoreKey(storeId: string, rootHash: string, key?: string): Promise<DigPeer | null>;
|
|
21
21
|
static unsubscribeFromStore(storeId: string): void;
|
|
22
22
|
static pingNetworkOfUpdate(storeId: string, rootHash: string): Promise<void>;
|
|
23
23
|
syncStoreFromPeers(prioritizedPeer?: DigPeer, maxRootsToProcess?: number): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DigNetwork.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/DigNetwork.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,MAAM,CAAC,cAAc,CAAmC;gBAEpD,OAAO,EAAE,MAAM;WAOP,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"DigNetwork.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/DigNetwork.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,MAAM,CAAC,cAAc,CAAmC;gBAEpD,OAAO,EAAE,MAAM;WAOP,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAQtD,yBAAyB,IAAI,MAAM,EAAE;WAI/B,aAAa,CAAC,GAAG,EAAE,MAAM;IAI7C;;;;;;;OAOG;WACiB,oBAAoB,CACtC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;WAsFZ,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;WAOrC,mBAAmB,CACrC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAcH,kBAAkB,CAC7B,eAAe,CAAC,EAAE,OAAO,EACzB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,IAAI,CAAC;IAqFH,mBAAmB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;CAUvD"}
|
|
@@ -44,74 +44,75 @@ class DigNetwork {
|
|
|
44
44
|
const digNetwork = new DigNetwork(storeId);
|
|
45
45
|
await digNetwork.syncStoreFromPeers();
|
|
46
46
|
}
|
|
47
|
+
static getAllNetworkDataStoreIds() {
|
|
48
|
+
throw new Error("Method not implemented.");
|
|
49
|
+
}
|
|
47
50
|
static async getUdiContent(udi) {
|
|
48
|
-
|
|
51
|
+
throw new Error("Method not implemented.");
|
|
49
52
|
}
|
|
50
53
|
/**
|
|
51
|
-
* Find a peer that has the store key and root hash.
|
|
54
|
+
* Find a peer that has the store key and root hash, using ranked peers first and searching in groups of 5.
|
|
52
55
|
*
|
|
53
56
|
* @param {string} storeId - The ID of the store.
|
|
54
57
|
* @param {string} rootHash - The root hash of the store.
|
|
55
58
|
* @param {string} [key] - Optional key to check for in the store.
|
|
56
|
-
* @param {string[]} [initialBlackList] - Initial list of blacklisted peer IPs.
|
|
57
59
|
* @returns {Promise<DigPeer | null>} - A valid peer or null if none found.
|
|
58
60
|
*/
|
|
59
|
-
static async findPeerWithStoreKey(storeId, rootHash, key
|
|
60
|
-
const peerBlackList = new Set(initialBlackList);
|
|
61
|
+
static async findPeerWithStoreKey(storeId, rootHash, key) {
|
|
61
62
|
const serverCoin = new blockchain_1.ServerCoin(storeId);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
63
|
+
try {
|
|
64
|
+
// Fetch all active peers for the current epoch
|
|
65
|
+
const digPeers = await serverCoin.getActiveEpochPeers();
|
|
66
|
+
// If no peers are returned, exit early
|
|
67
|
+
if (digPeers.length === 0) {
|
|
68
|
+
console.log("No peers found.");
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
// Initialize PeerRanker with the list of digPeers (IP addresses)
|
|
72
|
+
const peerRanker = new utils_1.PeerRanker(digPeers);
|
|
73
|
+
// Rank the peers based on latency and bandwidth
|
|
74
|
+
const rankedPeers = await peerRanker.rankPeers();
|
|
75
|
+
// If no peers are returned after ranking, exit early
|
|
76
|
+
if (rankedPeers.length === 0) {
|
|
77
|
+
console.log("No valid peers found after ranking.");
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
// Define the iterator function to process each peer
|
|
81
|
+
const iteratorFn = async (peerMetrics) => {
|
|
82
|
+
const peerIp = peerMetrics.ip;
|
|
83
|
+
try {
|
|
84
|
+
const digPeer = new DigPeer_1.DigPeer(peerIp, storeId);
|
|
85
|
+
// Wrap the store check with a 10-second timeout
|
|
86
|
+
const { storeExists, rootHashExists } = await (0, utils_1.withTimeout)(digPeer.propagationServer.checkStoreExists(rootHash), 10000, `Timeout while checking store on peer ${peerIp}`);
|
|
87
|
+
// Check if the store and root hash exist on the peer
|
|
88
|
+
if (storeExists && rootHashExists) {
|
|
89
|
+
console.log(`Found Peer at ${peerIp} for storeId: ${storeId}, root hash ${rootHash}`);
|
|
90
|
+
// If no key is provided, return the peer
|
|
91
|
+
if (!key) {
|
|
92
|
+
return digPeer;
|
|
90
93
|
}
|
|
91
|
-
|
|
92
|
-
|
|
94
|
+
// If key is provided, wrap key check with a 10-second timeout
|
|
95
|
+
const keyResponse = await (0, utils_1.withTimeout)(digPeer.contentServer.headKey(key, rootHash), 10000, `Timeout while checking key on peer ${peerIp}`);
|
|
96
|
+
if (keyResponse.headers?.["x-key-exists"] === "true") {
|
|
97
|
+
return digPeer;
|
|
93
98
|
}
|
|
94
|
-
|
|
95
|
-
resolve(null);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
// Wait for the first valid peer that resolves
|
|
99
|
-
const firstValidPeer = await Promise.race(peerPromises);
|
|
100
|
-
// If a valid peer is found, return it
|
|
101
|
-
if (firstValidPeer) {
|
|
102
|
-
return firstValidPeer;
|
|
99
|
+
}
|
|
103
100
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error(`Error connecting to DIG Peer ${peerIp}:`, error.message);
|
|
103
|
+
}
|
|
104
|
+
// If the peer does not meet the criteria, return null
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
// Use Promise.race to return the first valid peer found
|
|
108
|
+
const validPeer = await Promise.race(rankedPeers.map((peer) => iteratorFn(peer)));
|
|
109
|
+
// Return the first valid peer or null if none is found
|
|
110
|
+
return validPeer || null;
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error("Error sampling peers:", error);
|
|
114
|
+
return null;
|
|
112
115
|
}
|
|
113
|
-
// Return null if no valid peer was found after all attempts
|
|
114
|
-
return null;
|
|
115
116
|
}
|
|
116
117
|
static unsubscribeFromStore(storeId) {
|
|
117
118
|
fs.rmdirSync(path.join(config_1.DIG_FOLDER_PATH, "stores", storeId), {
|
|
@@ -135,7 +136,6 @@ class DigNetwork {
|
|
|
135
136
|
}
|
|
136
137
|
console.log("Starting network sync for store:", this.dataStore.StoreId);
|
|
137
138
|
DigNetwork.networkSyncMap.set(this.dataStore.StoreId, true);
|
|
138
|
-
let peerBlackList = [];
|
|
139
139
|
try {
|
|
140
140
|
const rootHistory = await this.dataStore.getRootHistory();
|
|
141
141
|
if (!rootHistory.length) {
|
|
@@ -156,41 +156,24 @@ class DigNetwork {
|
|
|
156
156
|
: rootHistoryFiltered;
|
|
157
157
|
// Process the root hashes sequentially
|
|
158
158
|
for (const rootInfo of rootsToProcess) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
selectedPeer = prioritizedPeer;
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
selectedPeer = await DigNetwork.findPeerWithStoreKey(this.dataStore.StoreId, rootInfo.root_hash, undefined, peerBlackList);
|
|
168
|
-
}
|
|
169
|
-
if (!selectedPeer) {
|
|
170
|
-
console.error(`No peer found with root hash ${rootInfo.root_hash}. Moving to next root.`);
|
|
171
|
-
break; // Exit the while loop to proceed to the next rootInfo
|
|
172
|
-
}
|
|
173
|
-
// Check if the selected peer has the store and root hash
|
|
174
|
-
const { storeExists, rootHashExists } = await selectedPeer.propagationServer.checkStoreExists(rootInfo.root_hash);
|
|
175
|
-
if (!storeExists || !rootHashExists) {
|
|
176
|
-
console.warn(`Peer ${selectedPeer.IpAddress} does not have the required store or root hash. Trying another peer...`);
|
|
177
|
-
peerBlackList.push(selectedPeer.IpAddress); // Blacklist and retry
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
// Download the store root and associated data
|
|
181
|
-
await selectedPeer.downloadStoreRoot(rootInfo.root_hash);
|
|
182
|
-
// Clear the blacklist upon successful download
|
|
183
|
-
peerBlackList = [];
|
|
184
|
-
// Break after successful download to proceed to next root hash
|
|
185
|
-
break;
|
|
159
|
+
try {
|
|
160
|
+
let selectedPeer = prioritizedPeer || null;
|
|
161
|
+
if (!selectedPeer) {
|
|
162
|
+
// Use the `findPeerWithStoreKey` method to find a peer with the store and root hash
|
|
163
|
+
selectedPeer = await DigNetwork.findPeerWithStoreKey(this.dataStore.StoreId, rootInfo.root_hash);
|
|
186
164
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (selectedPeer) {
|
|
191
|
-
peerBlackList.push(selectedPeer.IpAddress); // Blacklist and retry
|
|
192
|
-
}
|
|
165
|
+
if (!selectedPeer) {
|
|
166
|
+
console.error(`No peer found with root hash ${rootInfo.root_hash}. Moving to next root.`);
|
|
167
|
+
continue; // Move to the next rootInfo
|
|
193
168
|
}
|
|
169
|
+
// Download the store root and associated data
|
|
170
|
+
await selectedPeer.downloadStoreRoot(rootInfo.root_hash);
|
|
171
|
+
// Break after successful download to proceed to next root hash
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (error.message)
|
|
175
|
+
console.error(`Error downloading from peer ${prioritizedPeer?.IpAddress}. Retrying with another peer.`, error);
|
|
176
|
+
// Continue to next rootInfo in case of error
|
|
194
177
|
}
|
|
195
178
|
}
|
|
196
179
|
console.log("Syncing store complete.");
|
|
@@ -143,7 +143,7 @@ class ServerCoin {
|
|
|
143
143
|
// Sample server coins by epoch
|
|
144
144
|
async sampleServerCoinsByEpoch(epoch, sampleSize = 5, blacklist = []) {
|
|
145
145
|
// We dont want our own IP to be included
|
|
146
|
-
const myIp = await (0, network_1.
|
|
146
|
+
const myIp = await (0, network_1.getPublicHost)();
|
|
147
147
|
if (myIp) {
|
|
148
148
|
blacklist.push(myIp);
|
|
149
149
|
}
|
|
@@ -102,7 +102,7 @@ class StoreMonitorRegistry {
|
|
|
102
102
|
*/
|
|
103
103
|
async startMonitor(storeId, callback) {
|
|
104
104
|
let retryCount = 0;
|
|
105
|
-
const maxRetryDelay =
|
|
105
|
+
const maxRetryDelay = 1000; // 60 seconds
|
|
106
106
|
while (this.activeMonitors.has(storeId)) {
|
|
107
107
|
try {
|
|
108
108
|
await this.monitorStore(storeId, callback);
|
|
@@ -22,12 +22,14 @@ export declare class PeerRanker {
|
|
|
22
22
|
/**
|
|
23
23
|
* Measures the latency of a given IP address using an HTTPS request.
|
|
24
24
|
* Tries HEAD first, then falls back to GET if HEAD is not supported.
|
|
25
|
+
* If the latency is cached, returns the cached value.
|
|
25
26
|
* @param ip - The IP address of the peer.
|
|
26
27
|
* @returns Promise resolving to the latency in milliseconds or rejecting if the peer fails.
|
|
27
28
|
*/
|
|
28
29
|
private measureLatency;
|
|
29
30
|
/**
|
|
30
31
|
* Measures the upload bandwidth of a given IP address by sending random data.
|
|
32
|
+
* If the bandwidth is cached, returns the cached value.
|
|
31
33
|
* @param ip - The IP address of the peer.
|
|
32
34
|
* @returns Promise resolving to the upload bandwidth in bytes per second or rejecting if the peer fails.
|
|
33
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PeerRanker.d.ts","sourceRoot":"","sources":["../../src/utils/PeerRanker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PeerRanker.d.ts","sourceRoot":"","sources":["../../src/utils/PeerRanker.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAChC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAS;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAS;IAG/B,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,YAAY,CAAa;IAEjC;;;OAGG;gBACS,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,MAAa,EAAE,cAAc,GAAE,MAAoB;IAW/F;;;;;;OAMG;YACW,cAAc;IAkD5B;;;;;OAKG;YACW,gBAAgB;IA4C9B;;;;;OAKG;IACU,SAAS,CAAC,QAAQ,GAAE,MAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAmCtE;;;;OAIG;IACI,eAAe,IAAI,WAAW,GAAG,IAAI;IAW5C;;OAEG;IACI,aAAa,IAAI,IAAI;CAG7B"}
|
package/dist/utils/PeerRanker.js
CHANGED
|
@@ -7,8 +7,11 @@ exports.PeerRanker = void 0;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const https_1 = __importDefault(require("https"));
|
|
10
|
+
const node_cache_1 = __importDefault(require("node-cache")); // Import node-cache
|
|
10
11
|
const ssl_1 = require("./ssl");
|
|
11
12
|
const promiseUtils_1 = require("./promiseUtils");
|
|
13
|
+
// Cache with TTL of 1 day (86400 seconds)
|
|
14
|
+
const peerCache = new node_cache_1.default({ stdTTL: 86400 });
|
|
12
15
|
/**
|
|
13
16
|
* Utility class to rank peers based on latency and upload bandwidth using HTTPS with mTLS.
|
|
14
17
|
*/
|
|
@@ -32,10 +35,15 @@ class PeerRanker {
|
|
|
32
35
|
/**
|
|
33
36
|
* Measures the latency of a given IP address using an HTTPS request.
|
|
34
37
|
* Tries HEAD first, then falls back to GET if HEAD is not supported.
|
|
38
|
+
* If the latency is cached, returns the cached value.
|
|
35
39
|
* @param ip - The IP address of the peer.
|
|
36
40
|
* @returns Promise resolving to the latency in milliseconds or rejecting if the peer fails.
|
|
37
41
|
*/
|
|
38
42
|
async measureLatency(ip) {
|
|
43
|
+
const cachedMetrics = peerCache.get(ip);
|
|
44
|
+
if (cachedMetrics && cachedMetrics.latency) {
|
|
45
|
+
return cachedMetrics.latency;
|
|
46
|
+
}
|
|
39
47
|
const url = `https://${ip}:4159/diagnostics/ping`;
|
|
40
48
|
const configHead = {
|
|
41
49
|
url: url,
|
|
@@ -69,19 +77,26 @@ class PeerRanker {
|
|
|
69
77
|
await (0, axios_1.default)(configGet);
|
|
70
78
|
}
|
|
71
79
|
const latency = Date.now() - startTime;
|
|
80
|
+
// Cache the latency for the IP
|
|
81
|
+
peerCache.set(ip, { ...cachedMetrics, latency });
|
|
72
82
|
return latency;
|
|
73
83
|
}
|
|
74
84
|
catch (error) {
|
|
75
|
-
console.error(`Latency measurement failed for IP ${ip}:`, error.message);
|
|
76
85
|
throw new Error(`Latency measurement failed for IP ${ip}`);
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
88
|
/**
|
|
80
89
|
* Measures the upload bandwidth of a given IP address by sending random data.
|
|
90
|
+
* If the bandwidth is cached, returns the cached value.
|
|
81
91
|
* @param ip - The IP address of the peer.
|
|
82
92
|
* @returns Promise resolving to the upload bandwidth in bytes per second or rejecting if the peer fails.
|
|
83
93
|
*/
|
|
84
94
|
async measureBandwidth(ip) {
|
|
95
|
+
const cachedMetrics = peerCache.get(ip);
|
|
96
|
+
if (cachedMetrics && cachedMetrics.bandwidth) {
|
|
97
|
+
console.log(`Bandwidth for IP ${ip} retrieved from cache.`);
|
|
98
|
+
return cachedMetrics.bandwidth;
|
|
99
|
+
}
|
|
85
100
|
const url = `https://${ip}:4159/diagnostics/bandwidth`;
|
|
86
101
|
const randomData = Buffer.alloc(this.uploadTestSize, 'a');
|
|
87
102
|
const config = {
|
|
@@ -106,10 +121,11 @@ class PeerRanker {
|
|
|
106
121
|
await (0, axios_1.default)(config);
|
|
107
122
|
const timeElapsed = (Date.now() - startTime) / 1000;
|
|
108
123
|
const bandwidth = this.uploadTestSize / timeElapsed;
|
|
124
|
+
// Cache the bandwidth for the IP
|
|
125
|
+
peerCache.set(ip, { ...cachedMetrics, bandwidth });
|
|
109
126
|
return bandwidth;
|
|
110
127
|
}
|
|
111
128
|
catch (error) {
|
|
112
|
-
console.error(`Bandwidth measurement failed for IP ${ip}:`, error.message);
|
|
113
129
|
throw new Error(`Bandwidth measurement failed for IP ${ip}`);
|
|
114
130
|
}
|
|
115
131
|
}
|
package/dist/utils/network.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/utils/network.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,aAAa,QAAa,OAAO,CAAC,MAAM,GAAG,SAAS,CA+ChE,CAAC;AAIF,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,MAUzC,CAAC"}
|
package/dist/utils/network.js
CHANGED
|
@@ -3,29 +3,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.formatHost = exports.
|
|
7
|
-
/*
|
|
8
|
-
* Stopgap until better solution for finding public IPS found
|
|
9
|
-
*/
|
|
6
|
+
exports.formatHost = exports.getPublicHost = void 0;
|
|
10
7
|
const superagent_1 = __importDefault(require("superagent"));
|
|
11
8
|
const Environment_1 = require("./Environment");
|
|
12
9
|
const MAX_RETRIES = 5;
|
|
13
10
|
const RETRY_DELAY = 2000; // in milliseconds
|
|
14
11
|
// Regular expression for validating both IPv4 and IPv6 addresses
|
|
15
12
|
const ipv4Regex = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
16
|
-
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)|(([0-9a-fA-F]{1,
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
|
|
13
|
+
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7}([0-9a-fA-F]{1,4}|:)|(([0-9a-fA-F]{1,7}|:):){1,7}([0-9a-fA-F]{1,4}|:))$/;
|
|
14
|
+
// Regular expression for validating hostnames
|
|
15
|
+
const hostnameRegex = /^(([a-zA-Z0-9](-*[a-zA-Z0-9])*)\.)*[a-zA-Z]{2,}$/;
|
|
16
|
+
// Helper function to validate the IP address or hostname
|
|
17
|
+
const isValidHost = (host) => {
|
|
18
|
+
return ipv4Regex.test(host) || ipv6Regex.test(host) || hostnameRegex.test(host);
|
|
20
19
|
};
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
console.log("Public IP
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
20
|
+
const getPublicHost = async () => {
|
|
21
|
+
const publicHost = Environment_1.Environment.PUBLIC_IP;
|
|
22
|
+
if (publicHost) {
|
|
23
|
+
console.log("Public IP/Hostname from env:", publicHost);
|
|
24
|
+
if (isValidHost(publicHost)) {
|
|
25
|
+
return publicHost;
|
|
27
26
|
}
|
|
28
|
-
console.error("Invalid public IP
|
|
27
|
+
console.error("Invalid public IP/Hostname in environment variable");
|
|
29
28
|
return undefined;
|
|
30
29
|
}
|
|
31
30
|
let attempt = 0;
|
|
@@ -34,24 +33,24 @@ const getPublicIpAddress = async () => {
|
|
|
34
33
|
const response = await superagent_1.default.get("https://api.datalayer.storage/user/v1/get_user_ip");
|
|
35
34
|
if (response.body && response.body.success) {
|
|
36
35
|
const ipAddress = response.body.ip_address;
|
|
37
|
-
if (
|
|
36
|
+
if (isValidHost(ipAddress)) {
|
|
38
37
|
return ipAddress;
|
|
39
38
|
}
|
|
40
|
-
throw new Error("Invalid IP address format received");
|
|
39
|
+
throw new Error("Invalid IP address or hostname format received");
|
|
41
40
|
}
|
|
42
|
-
throw new Error("Failed to retrieve public
|
|
41
|
+
throw new Error("Failed to retrieve public host");
|
|
43
42
|
}
|
|
44
43
|
catch (error) {
|
|
45
44
|
attempt++;
|
|
46
|
-
console.error(`Error fetching public
|
|
45
|
+
console.error(`Error fetching public host (Attempt ${attempt}):`, error.message);
|
|
47
46
|
if (attempt >= MAX_RETRIES) {
|
|
48
|
-
throw new Error("Could not retrieve public
|
|
47
|
+
throw new Error("Could not retrieve public host after several attempts");
|
|
49
48
|
}
|
|
50
49
|
await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY));
|
|
51
50
|
}
|
|
52
51
|
}
|
|
53
52
|
};
|
|
54
|
-
exports.
|
|
53
|
+
exports.getPublicHost = getPublicHost;
|
|
55
54
|
// Helper function to wrap IPv6 addresses in brackets
|
|
56
55
|
const formatHost = (host) => {
|
|
57
56
|
const ipv6Pattern = /^[a-fA-F0-9:]+$/; // Simple regex to match raw IPv6 addresses (without brackets)
|