@dignetwork/dig-sdk 0.0.1-alpha.159 → 0.0.1-alpha.161
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PropagationServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/PropagationServer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAuBrC,qBAAa,iBAAiB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAQ;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;gBAErC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAY9C;;OAEG;IACG,gBAAgB;IAOtB;;OAEG;IACH,gBAAgB;IAQhB;;;OAGG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"PropagationServer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/PropagationServer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,MAAM,OAAO,CAAC;AAY1B,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAuBrC,qBAAa,iBAAiB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAQ;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;gBAErC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAY9C;;OAEG;IACG,gBAAgB;IAOtB;;OAEG;IACH,gBAAgB;IAQhB;;;OAGG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BpD;;;;OAIG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkDjD;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM;IAyB3D;;;;;;OAMG;IACU,gBAAgB,CAC3B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IAgE7D;;OAEG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM;IAyDzC;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IA2BlD;;;OAGG;IACG,UAAU,CACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,OAAe;IAsH7B;;OAEG;IACG,mBAAmB;IAkCzB;;OAEG;WACU,WAAW,CACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;IA0DnB;;;OAGG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmFlD;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IA4B7C;;;OAGG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM;IA4GjB;;OAEG;WACU,aAAa,CACxB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM;CA2FpB"}
|
|
@@ -106,11 +106,9 @@ class PropagationServer {
|
|
|
106
106
|
};
|
|
107
107
|
try {
|
|
108
108
|
const response = await axios_1.default.get(url, config);
|
|
109
|
-
console.log((0, colorette_1.green)(`✔ Successfully pinged peer: ${this.ipAddress}`));
|
|
110
109
|
return response.data;
|
|
111
110
|
}
|
|
112
111
|
catch (error) {
|
|
113
|
-
console.error((0, colorette_1.red)(`✖ Failed to ping peer: ${this.ipAddress}`));
|
|
114
112
|
console.error((0, colorette_1.red)(error.message));
|
|
115
113
|
throw error;
|
|
116
114
|
}
|
|
@@ -154,7 +152,7 @@ class PropagationServer {
|
|
|
154
152
|
return response.data;
|
|
155
153
|
}
|
|
156
154
|
catch (error) {
|
|
157
|
-
console.error((0, colorette_1.red)(`✖ Failed to ping peer: ${this.ipAddress}`));
|
|
155
|
+
console.error((0, colorette_1.red)(`✖ Failed to ping peer: ${this.ipAddress}`), error.message);
|
|
158
156
|
console.error((0, colorette_1.red)(error.message));
|
|
159
157
|
throw error;
|
|
160
158
|
}
|
|
@@ -5,13 +5,14 @@ import { Peer } from "@dignetwork/datalayer-driver";
|
|
|
5
5
|
export declare class FullNodePeer {
|
|
6
6
|
private peer;
|
|
7
7
|
private static instance;
|
|
8
|
-
private static cachedPeer;
|
|
9
8
|
private static cooldownCache;
|
|
9
|
+
private static failedDNSCache;
|
|
10
10
|
private static peerWeights;
|
|
11
11
|
private static prioritizedPeers;
|
|
12
12
|
private static peerInfos;
|
|
13
13
|
private static peerIPCache;
|
|
14
14
|
private static peerLimiters;
|
|
15
|
+
private static roundRobinIndex;
|
|
15
16
|
private constructor();
|
|
16
17
|
/**
|
|
17
18
|
* Retrieves the singleton instance of FullNodePeer.
|
|
@@ -66,11 +67,10 @@ export declare class FullNodePeer {
|
|
|
66
67
|
*/
|
|
67
68
|
private static initializePeerWeights;
|
|
68
69
|
/**
|
|
69
|
-
* Selects
|
|
70
|
-
* Prioritized peers have higher weights.
|
|
70
|
+
* Selects the next peer based on round-robin selection.
|
|
71
71
|
* @returns {string} The selected peer IP.
|
|
72
72
|
*/
|
|
73
|
-
private static
|
|
73
|
+
private static selectPeerRoundRobin;
|
|
74
74
|
/**
|
|
75
75
|
* Retrieves all reachable peer IPs, excluding those in cooldown.
|
|
76
76
|
* @returns {Promise<string[]>} An array of reachable peer IPs.
|
|
@@ -82,7 +82,7 @@ export declare class FullNodePeer {
|
|
|
82
82
|
*/
|
|
83
83
|
private static setupPeers;
|
|
84
84
|
/**
|
|
85
|
-
* Connects to the best available peer based on
|
|
85
|
+
* Connects to the best available peer based on round-robin selection and reliability.
|
|
86
86
|
* @returns {Promise<Peer>} The connected Peer instance.
|
|
87
87
|
*/
|
|
88
88
|
private getBestPeer;
|
|
@@ -91,7 +91,7 @@ export declare class FullNodePeer {
|
|
|
91
91
|
* Handles peer disconnection by marking it in cooldown and updating internal states.
|
|
92
92
|
* @param {string} peerIP - The IP address of the disconnected peer.
|
|
93
93
|
*/
|
|
94
|
-
handlePeerDisconnection(peerIP: string): void;
|
|
94
|
+
static handlePeerDisconnection(peerIP: string): void;
|
|
95
95
|
/**
|
|
96
96
|
* Extracts the IP address from a Peer instance.
|
|
97
97
|
* @param {Peer} peer - The Peer instance.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullNodePeer.d.ts","sourceRoot":"","sources":["../../src/blockchain/FullNodePeer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"FullNodePeer.d.ts","sourceRoot":"","sources":["../../src/blockchain/FullNodePeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAO,MAAM,8BAA8B,CAAC;AAiCzD;;GAEG;AACH,qBAAa,YAAY;IA6BH,OAAO,CAAC,IAAI;IA3BhC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IAGpD,OAAO,CAAC,MAAM,CAAC,aAAa,CAAuD;IAGnF,OAAO,CAAC,MAAM,CAAC,cAAc,CAAuD;IAGpF,OAAO,CAAC,MAAM,CAAC,WAAW,CAAkC;IAG5D,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAgB;IAG/C,OAAO,CAAC,MAAM,CAAC,SAAS,CAAoC;IAG5D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAoD;IAG9E,OAAO,CAAC,MAAM,CAAC,YAAY,CAAsC;IAGjE,OAAO,CAAC,MAAM,CAAC,eAAe,CAAa;IAG3C,OAAO;IAEP;;;OAGG;WACW,WAAW,IAAI,YAAY;IAOzC;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAaxC;;;;OAIG;WACiB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAuB9B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IASjC;;;;OAIG;mBACkB,eAAe;IA4FpC;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAS3B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAgBpC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAenC;;;OAGG;mBACkB,UAAU;IAK/B;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;IAIzB;;;OAGG;YACW,WAAW;IAuEzB,OAAO,CAAC,eAAe;IAkDvB;;;OAGG;WACW,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAqB3D;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAS5B;;;;OAIG;WACiB,mBAAmB,CACrC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;CAkDpB"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// FullNodePeer.ts
|
|
3
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
4
|
};
|
|
@@ -16,7 +15,6 @@ const config_1 = require("../utils/config");
|
|
|
16
15
|
const Environment_1 = require("../utils/Environment");
|
|
17
16
|
const node_cache_1 = __importDefault(require("node-cache"));
|
|
18
17
|
const bottleneck_1 = __importDefault(require("bottleneck"));
|
|
19
|
-
// Constants
|
|
20
18
|
const FULLNODE_PORT = 8444;
|
|
21
19
|
const LOCALHOST = "127.0.0.1";
|
|
22
20
|
const CHIA_NODES_HOST = "chia-nodes";
|
|
@@ -28,9 +26,8 @@ const DNS_HOSTS = [
|
|
|
28
26
|
];
|
|
29
27
|
const CONNECTION_TIMEOUT = 2000; // in milliseconds
|
|
30
28
|
const CACHE_DURATION = 30000; // in milliseconds
|
|
31
|
-
const COOLDOWN_DURATION =
|
|
29
|
+
const COOLDOWN_DURATION = 600000; // 10 minutes in milliseconds
|
|
32
30
|
const MAX_PEERS_TO_FETCH = 5; // Maximum number of peers to fetch from DNS
|
|
33
|
-
const MAX_RETRIES = 3; // Maximum number of retry attempts
|
|
34
31
|
const MAX_REQUESTS_PER_MINUTE = 100; // Per-peer rate limit
|
|
35
32
|
/**
|
|
36
33
|
* FullNodePeer manages connections to full nodes, prioritizing certain peers and handling reliability.
|
|
@@ -62,7 +59,7 @@ class FullNodePeer {
|
|
|
62
59
|
FullNodePeer.instance = this; // Assign the initialized instance
|
|
63
60
|
}
|
|
64
61
|
catch (error) {
|
|
65
|
-
console.error(`Initialization failed: ${error.message}`);
|
|
62
|
+
console.error(`Fullnode Initialization failed: ${error.message}`);
|
|
66
63
|
throw error;
|
|
67
64
|
}
|
|
68
65
|
}
|
|
@@ -73,6 +70,7 @@ class FullNodePeer {
|
|
|
73
70
|
*/
|
|
74
71
|
static async connect() {
|
|
75
72
|
const instance = FullNodePeer.getInstance();
|
|
73
|
+
// Remove cached peer to ensure a new connection each time
|
|
76
74
|
await instance.initialize();
|
|
77
75
|
return instance.peer;
|
|
78
76
|
}
|
|
@@ -162,6 +160,11 @@ class FullNodePeer {
|
|
|
162
160
|
// Fetch peers from DNS introducers
|
|
163
161
|
const fetchedPeers = [];
|
|
164
162
|
for (const DNS_HOST of DNS_HOSTS) {
|
|
163
|
+
// Check if DNS_HOST is in failedDNSCache
|
|
164
|
+
if (FullNodePeer.failedDNSCache.has(DNS_HOST)) {
|
|
165
|
+
console.warn(`Skipping DNS host ${DNS_HOST} due to recent failure.`);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
165
168
|
try {
|
|
166
169
|
const ips = await (0, promises_1.resolve4)(DNS_HOST);
|
|
167
170
|
if (ips && ips.length > 0) {
|
|
@@ -182,6 +185,8 @@ class FullNodePeer {
|
|
|
182
185
|
}
|
|
183
186
|
catch (error) {
|
|
184
187
|
console.error(`Failed to resolve IPs from ${DNS_HOST}: ${error.message}`);
|
|
188
|
+
// Add DNS_HOST to failedDNSCache for cooldown
|
|
189
|
+
FullNodePeer.failedDNSCache.set(DNS_HOST, true);
|
|
185
190
|
}
|
|
186
191
|
}
|
|
187
192
|
// Cache the fetched peer IPs
|
|
@@ -224,28 +229,18 @@ class FullNodePeer {
|
|
|
224
229
|
}
|
|
225
230
|
}
|
|
226
231
|
/**
|
|
227
|
-
* Selects
|
|
228
|
-
* Prioritized peers have higher weights.
|
|
232
|
+
* Selects the next peer based on round-robin selection.
|
|
229
233
|
* @returns {string} The selected peer IP.
|
|
230
234
|
*/
|
|
231
|
-
static
|
|
232
|
-
const peers = Array.from(FullNodePeer.peerWeights.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const totalWeight = peers.reduce((sum, peer) => sum + peer.weight, 0);
|
|
236
|
-
if (totalWeight === 0) {
|
|
237
|
-
throw new Error("All peers are in cooldown.");
|
|
238
|
-
}
|
|
239
|
-
const random = Math.random() * totalWeight;
|
|
240
|
-
let cumulative = 0;
|
|
241
|
-
for (const peer of peers) {
|
|
242
|
-
cumulative += peer.weight;
|
|
243
|
-
if (random < cumulative) {
|
|
244
|
-
return peer.ip;
|
|
245
|
-
}
|
|
235
|
+
static selectPeerRoundRobin() {
|
|
236
|
+
const peers = Array.from(FullNodePeer.peerWeights.keys()).filter((ip) => !FullNodePeer.cooldownCache.has(ip));
|
|
237
|
+
if (peers.length === 0) {
|
|
238
|
+
throw new Error("All fullnode peers are in cooldown.");
|
|
246
239
|
}
|
|
247
|
-
//
|
|
248
|
-
|
|
240
|
+
// Round-robin selection
|
|
241
|
+
const selectedPeer = peers[FullNodePeer.roundRobinIndex % peers.length];
|
|
242
|
+
FullNodePeer.roundRobinIndex += 1;
|
|
243
|
+
return selectedPeer;
|
|
249
244
|
}
|
|
250
245
|
/**
|
|
251
246
|
* Retrieves all reachable peer IPs, excluding those in cooldown.
|
|
@@ -263,27 +258,23 @@ class FullNodePeer {
|
|
|
263
258
|
FullNodePeer.initializePeerWeights(peerIPs);
|
|
264
259
|
}
|
|
265
260
|
/**
|
|
266
|
-
* Connects to the best available peer based on
|
|
261
|
+
* Connects to the best available peer based on round-robin selection and reliability.
|
|
267
262
|
* @returns {Promise<Peer>} The connected Peer instance.
|
|
268
263
|
*/
|
|
269
264
|
async getBestPeer() {
|
|
270
265
|
const now = Date.now();
|
|
271
|
-
//
|
|
272
|
-
if (FullNodePeer.cachedPeer &&
|
|
273
|
-
now - FullNodePeer.cachedPeer.timestamp < CACHE_DURATION) {
|
|
274
|
-
return FullNodePeer.cachedPeer.peer;
|
|
275
|
-
}
|
|
266
|
+
// Removed cachedPeer logic to ensure a new connection each time
|
|
276
267
|
// Fetch peer IPs
|
|
277
268
|
const peerIPs = await FullNodePeer.getPeerIPs();
|
|
278
269
|
// Setup peer weights with prioritization
|
|
279
270
|
FullNodePeer.setupPeers(peerIPs);
|
|
280
|
-
//
|
|
271
|
+
// Round-robin selection
|
|
281
272
|
let selectedPeerIP;
|
|
282
273
|
try {
|
|
283
|
-
selectedPeerIP = FullNodePeer.
|
|
274
|
+
selectedPeerIP = FullNodePeer.selectPeerRoundRobin();
|
|
284
275
|
}
|
|
285
276
|
catch (error) {
|
|
286
|
-
throw new Error(`Failed to select a peer: ${error.message}`);
|
|
277
|
+
throw new Error(`Failed to select a fullnode peer: ${error.message}`);
|
|
287
278
|
}
|
|
288
279
|
// Attempt to create a peer connection
|
|
289
280
|
const sslFolder = path_1.default.resolve(os_1.default.homedir(), ".dig", "ssl");
|
|
@@ -298,7 +289,7 @@ class FullNodePeer {
|
|
|
298
289
|
peer = await datalayer_driver_1.Peer.new(`${selectedPeerIP}:${FULLNODE_PORT}`, false, tls);
|
|
299
290
|
}
|
|
300
291
|
catch (error) {
|
|
301
|
-
console.error(`Failed to create peer for IP ${selectedPeerIP}: ${error.message}`);
|
|
292
|
+
console.error(`Failed to create fullnode peer for IP ${selectedPeerIP}: ${error.message}`);
|
|
302
293
|
// Add to cooldown
|
|
303
294
|
FullNodePeer.cooldownCache.set(selectedPeerIP, true);
|
|
304
295
|
// Decrease weight or remove peer
|
|
@@ -309,7 +300,7 @@ class FullNodePeer {
|
|
|
309
300
|
else {
|
|
310
301
|
FullNodePeer.peerWeights.delete(selectedPeerIP);
|
|
311
302
|
}
|
|
312
|
-
throw new Error(`Unable to connect to peer ${selectedPeerIP}`);
|
|
303
|
+
throw new Error(`Unable to connect to fullnode peer ${selectedPeerIP}`);
|
|
313
304
|
}
|
|
314
305
|
// Create a Bottleneck limiter for this peer
|
|
315
306
|
const limiter = new bottleneck_1.default({
|
|
@@ -325,8 +316,6 @@ class FullNodePeer {
|
|
|
325
316
|
// Initialize rate limiter for this peer
|
|
326
317
|
FullNodePeer.peerLimiters.set(selectedPeerIP, limiter);
|
|
327
318
|
const proxiedPeer = this.createPeerProxy(peer, selectedPeerIP);
|
|
328
|
-
// Cache the peer
|
|
329
|
-
FullNodePeer.cachedPeer = { peer: peer, timestamp: now };
|
|
330
319
|
console.log(`Using Fullnode Peer: ${selectedPeerIP}`);
|
|
331
320
|
return proxiedPeer;
|
|
332
321
|
}
|
|
@@ -340,8 +329,7 @@ class FullNodePeer {
|
|
|
340
329
|
// Start the timeout to forget the peer after 1 minute
|
|
341
330
|
const timeoutPromise = new Promise((_, reject) => {
|
|
342
331
|
timeoutId = setTimeout(() => {
|
|
343
|
-
|
|
344
|
-
reject(new Error("Operation timed out. Reconnecting to a new peer."));
|
|
332
|
+
reject(new Error("Operation timed out. Reconnecting to a new fullnode peer."));
|
|
345
333
|
}, 60000); // 1 minute
|
|
346
334
|
});
|
|
347
335
|
try {
|
|
@@ -360,8 +348,7 @@ class FullNodePeer {
|
|
|
360
348
|
// If the error is WebSocket-related or timeout, reset the peer
|
|
361
349
|
if (error.message.includes("WebSocket") ||
|
|
362
350
|
error.message.includes("Operation timed out")) {
|
|
363
|
-
FullNodePeer.
|
|
364
|
-
this.handlePeerDisconnection(peerIP);
|
|
351
|
+
FullNodePeer.handlePeerDisconnection(peerIP);
|
|
365
352
|
const newPeer = await this.getBestPeer();
|
|
366
353
|
return newPeer[prop](...args);
|
|
367
354
|
}
|
|
@@ -377,7 +364,7 @@ class FullNodePeer {
|
|
|
377
364
|
* Handles peer disconnection by marking it in cooldown and updating internal states.
|
|
378
365
|
* @param {string} peerIP - The IP address of the disconnected peer.
|
|
379
366
|
*/
|
|
380
|
-
handlePeerDisconnection(peerIP) {
|
|
367
|
+
static handlePeerDisconnection(peerIP) {
|
|
381
368
|
// Add the faulty peer to the cooldown cache
|
|
382
369
|
FullNodePeer.cooldownCache.set(peerIP, true);
|
|
383
370
|
// Decrease weight or remove peer
|
|
@@ -392,7 +379,7 @@ class FullNodePeer {
|
|
|
392
379
|
FullNodePeer.peerInfos.delete(peerIP);
|
|
393
380
|
// Remove the limiter
|
|
394
381
|
FullNodePeer.peerLimiters.delete(peerIP);
|
|
395
|
-
console.warn(`Peer ${peerIP} has been marked as disconnected and is in cooldown.`);
|
|
382
|
+
console.warn(`Fullnode Peer ${peerIP} has been marked as disconnected and is in cooldown.`);
|
|
396
383
|
}
|
|
397
384
|
/**
|
|
398
385
|
* Extracts the IP address from a Peer instance.
|
|
@@ -419,19 +406,19 @@ class FullNodePeer {
|
|
|
419
406
|
peer = await FullNodePeer.connect();
|
|
420
407
|
}
|
|
421
408
|
catch (error) {
|
|
422
|
-
spinner.error({ text: "Failed to connect to a peer." });
|
|
409
|
+
spinner.error({ text: "Failed to connect to a fullnode peer." });
|
|
423
410
|
console.error(`waitForConfirmation connection error: ${error.message}`);
|
|
424
411
|
throw error;
|
|
425
412
|
}
|
|
426
413
|
// Extract peer IP to access the corresponding limiter
|
|
427
414
|
const peerIP = FullNodePeer.extractPeerIP(peer);
|
|
428
415
|
if (!peerIP) {
|
|
429
|
-
spinner.error({ text: "Failed to extract peer IP." });
|
|
416
|
+
spinner.error({ text: "Failed to extract fullnode peer IP." });
|
|
430
417
|
throw new Error("Failed to extract peer IP.");
|
|
431
418
|
}
|
|
432
419
|
const limiter = FullNodePeer.peerLimiters.get(peerIP);
|
|
433
420
|
if (!limiter) {
|
|
434
|
-
spinner.error({ text: "No rate limiter found for the peer." });
|
|
421
|
+
spinner.error({ text: "No rate limiter found for the fullnode peer." });
|
|
435
422
|
throw new Error("No rate limiter found for the peer.");
|
|
436
423
|
}
|
|
437
424
|
try {
|
|
@@ -456,10 +443,10 @@ class FullNodePeer {
|
|
|
456
443
|
exports.FullNodePeer = FullNodePeer;
|
|
457
444
|
// Singleton instance
|
|
458
445
|
FullNodePeer.instance = null;
|
|
459
|
-
// Cached peer with timestamp
|
|
460
|
-
FullNodePeer.cachedPeer = null;
|
|
461
446
|
// Cooldown cache to exclude faulty peers temporarily
|
|
462
447
|
FullNodePeer.cooldownCache = new node_cache_1.default({ stdTTL: COOLDOWN_DURATION / 1000 });
|
|
448
|
+
// Failed DNS hosts cooldown cache
|
|
449
|
+
FullNodePeer.failedDNSCache = new node_cache_1.default({ stdTTL: COOLDOWN_DURATION / 1000 });
|
|
463
450
|
// Peer reliability weights
|
|
464
451
|
FullNodePeer.peerWeights = new Map();
|
|
465
452
|
// List of prioritized peers
|
|
@@ -470,3 +457,5 @@ FullNodePeer.peerInfos = new Map();
|
|
|
470
457
|
FullNodePeer.peerIPCache = new node_cache_1.default({ stdTTL: CACHE_DURATION / 1000 });
|
|
471
458
|
// Map to store rate limiters per peer IP
|
|
472
459
|
FullNodePeer.peerLimiters = new Map();
|
|
460
|
+
// Round-robin index
|
|
461
|
+
FullNodePeer.roundRobinIndex = 0;
|