@@ -12,7 +12,6 @@ import Bottleneck from "bottleneck";
12
12
13
13
const FULLNODE_PORT = 8444 ;
14
14
const LOCALHOST = "127.0.0.1" ;
15
- const CHIA_NODES_HOST = "chia-nodes" ;
16
15
const DNS_HOSTS = [
17
16
"dns-introducer.chia.net" ,
18
17
"chia.ctrlaltdel.ch" ,
@@ -42,7 +41,9 @@ export class FullNodePeer {
42
41
private static instance : FullNodePeer | null = null ;
43
42
44
43
// Cooldown cache to exclude faulty peers temporarily
45
- private static cooldownCache = new NodeCache ( { stdTTL : COOLDOWN_DURATION / 1000 } ) ;
44
+ private static cooldownCache = new NodeCache ( {
45
+ stdTTL : COOLDOWN_DURATION / 1000 ,
46
+ } ) ;
46
47
47
48
// Failed DNS hosts cooldown cache
48
49
private static failedDNSCache = new NodeCache ( { stdTTL : 86400 } ) ;
@@ -59,6 +60,12 @@ export class FullNodePeer {
59
60
// Cache for fetched peer IPs
60
61
private static peerIPCache = new NodeCache ( { stdTTL : CACHE_DURATION / 1000 } ) ;
61
62
63
+ // Cache for DNS_HOST resolved IPs with a TTL of 3 days (259200 seconds)
64
+ private static dnsCache = new NodeCache ( {
65
+ stdTTL : 259200 ,
66
+ checkperiod : 3600 ,
67
+ } ) ;
68
+
62
69
// Map to store rate limiters per peer IP
63
70
private static peerLimiters : Map < string , Bottleneck > = new Map ( ) ;
64
71
@@ -171,7 +178,7 @@ export class FullNodePeer {
171
178
const priorityIps : string [ ] = [ ] ;
172
179
173
180
// Define prioritized peers
174
- FullNodePeer . prioritizedPeers = [ CHIA_NODES_HOST , LOCALHOST ] ;
181
+ FullNodePeer . prioritizedPeers = [ LOCALHOST ] ;
175
182
176
183
// Add trustedNodeIp if available
177
184
if ( trustedNodeIp ) {
@@ -195,14 +202,6 @@ export class FullNodePeer {
195
202
priorityIps . push ( LOCALHOST ) ;
196
203
}
197
204
198
- // Prioritize CHIA_NODES_HOST
199
- if (
200
- ! FullNodePeer . cooldownCache . has ( CHIA_NODES_HOST ) &&
201
- ( await FullNodePeer . isPortReachable ( CHIA_NODES_HOST , FULLNODE_PORT ) )
202
- ) {
203
- priorityIps . push ( CHIA_NODES_HOST ) ;
204
- }
205
-
206
205
if ( priorityIps . length > 0 ) {
207
206
return priorityIps ;
208
207
}
@@ -218,19 +217,31 @@ export class FullNodePeer {
218
217
for ( const DNS_HOST of DNS_HOSTS ) {
219
218
// Check if DNS_HOST is in failedDNSCache
220
219
if ( FullNodePeer . failedDNSCache . has ( DNS_HOST ) ) {
221
- console . warn ( `Skipping DNS host ${ DNS_HOST } due to recent failure.` ) ;
222
220
continue ;
223
221
}
224
222
225
223
try {
226
- const ips = await resolve4 ( DNS_HOST ) ;
227
- if ( ips && ips . length > 0 ) {
224
+ let ips : string [ ] = [ ] ;
225
+
226
+ // Check if DNS_HOST's IPs are cached
227
+ if ( FullNodePeer . dnsCache . has ( DNS_HOST ) ) {
228
+ ips = FullNodePeer . dnsCache . get < string [ ] > ( DNS_HOST ) || [ ] ;
229
+ } else {
230
+ // Resolve DNS_HOST and cache the results
231
+ ips = await resolve4 ( DNS_HOST ) ;
232
+ if ( ips && ips . length > 0 ) {
233
+ FullNodePeer . dnsCache . set ( DNS_HOST , ips ) ;
234
+ }
235
+ }
236
+
237
+ if ( ips . length > 0 ) {
228
238
const shuffledIps = FullNodePeer . shuffleArray ( ips ) ;
229
239
const reachableIps : string [ ] = [ ] ;
230
240
231
241
for ( const ip of shuffledIps ) {
232
242
if (
233
243
! FullNodePeer . cooldownCache . has ( ip ) &&
244
+ FullNodePeer . isValidIpAddress ( ip ) &&
234
245
( await FullNodePeer . isPortReachable ( ip , FULLNODE_PORT ) )
235
246
) {
236
247
reachableIps . push ( ip ) ;
@@ -243,13 +254,15 @@ export class FullNodePeer {
243
254
}
244
255
}
245
256
} catch ( error : any ) {
246
- console . error ( `Failed to resolve IPs from ${ DNS_HOST } : ${ error . message } ` ) ;
257
+ console . error (
258
+ `Failed to resolve IPs from ${ DNS_HOST } : ${ error . message } `
259
+ ) ;
247
260
// Add DNS_HOST to failedDNSCache for cooldown
248
261
FullNodePeer . failedDNSCache . set ( DNS_HOST , true ) ;
249
262
}
250
263
}
251
264
252
- // Cache the fetched peer IPs
265
+ // Cache the fetched peer IPs if any
253
266
if ( fetchedPeers . length > 0 ) {
254
267
FullNodePeer . peerIPCache . set ( "peerIPs" , fetchedPeers ) ;
255
268
return fetchedPeers ;
@@ -281,7 +294,6 @@ export class FullNodePeer {
281
294
for ( const ip of peerIPs ) {
282
295
if ( ! FullNodePeer . peerWeights . has ( ip ) ) {
283
296
if (
284
- ip === CHIA_NODES_HOST ||
285
297
ip === LOCALHOST ||
286
298
ip === FullNodePeer . getTrustedFullNode ( )
287
299
) {
@@ -417,7 +429,9 @@ export class FullNodePeer {
417
429
const timeoutPromise = new Promise < null > ( ( _ , reject ) => {
418
430
timeoutId = setTimeout ( ( ) => {
419
431
reject (
420
- new Error ( "Operation timed out. Reconnecting to a new fullnode peer." )
432
+ new Error (
433
+ "Operation timed out. Reconnecting to a new fullnode peer."
434
+ )
421
435
) ;
422
436
} , 60000 ) ; // 1 minute
423
437
} ) ;
@@ -476,7 +490,9 @@ export class FullNodePeer {
476
490
// Remove the limiter
477
491
FullNodePeer . peerLimiters . delete ( peerIP ) ;
478
492
479
- console . warn ( `Fullnode Peer ${ peerIP } has been marked as disconnected and is in cooldown.` ) ;
493
+ console . warn (
494
+ `Fullnode Peer ${ peerIP } has been marked as disconnected and is in cooldown.`
495
+ ) ;
480
496
}
481
497
482
498
/**
@@ -519,21 +535,14 @@ export class FullNodePeer {
519
535
throw new Error ( "Failed to extract peer IP." ) ;
520
536
}
521
537
522
- const limiter = FullNodePeer . peerLimiters . get ( peerIP ) ;
523
- if ( ! limiter ) {
524
- spinner . error ( { text : "No rate limiter found for the fullnode peer." } ) ;
525
- throw new Error ( "No rate limiter found for the peer." ) ;
526
- }
527
-
528
538
try {
529
539
while ( true ) {
530
540
// Schedule the isCoinSpent method call through the limiter
531
- const confirmed = await limiter . schedule ( ( ) =>
532
- peer . isCoinSpent (
533
- parentCoinInfo ,
534
- MIN_HEIGHT ,
535
- Buffer . from ( MIN_HEIGHT_HEADER_HASH , "hex" )
536
- )
541
+
542
+ const confirmed = await peer . isCoinSpent (
543
+ parentCoinInfo ,
544
+ MIN_HEIGHT ,
545
+ Buffer . from ( MIN_HEIGHT_HEADER_HASH , "hex" )
537
546
) ;
538
547
539
548
if ( confirmed ) {
0 commit comments