11use crate :: config:: Config ;
2+ use crate :: grpc_client;
23use crate :: masternode:: EvoMasternodeList ;
34use crate :: masternode_loader;
4- use crate :: grpc_client ;
5+ use chrono :: Local ;
56use std:: sync:: { Arc , RwLock } ;
67use std:: time:: { Duration , Instant } ;
78use tokio:: sync:: Mutex ;
8- use chrono:: Local ;
99
1010pub struct MasternodeCache {
1111 data : Arc < RwLock < Option < EvoMasternodeList > > > ,
@@ -24,7 +24,9 @@ impl MasternodeCache {
2424 }
2525 }
2626
27- pub async fn get_masternodes ( & self ) -> Result < EvoMasternodeList , Box < dyn std:: error:: Error + Send + Sync > > {
27+ pub async fn get_masternodes (
28+ & self ,
29+ ) -> Result < EvoMasternodeList , Box < dyn std:: error:: Error + Send + Sync > > {
2830 // Check if we need to update the cache
2931 let should_update = {
3032 let last_update_guard = self . last_update . lock ( ) . await ;
@@ -40,18 +42,16 @@ impl MasternodeCache {
4042
4143 // Return the cached data
4244 let cached_data = {
43- let data = self . data . read ( )
44- . map_err ( |_| "Failed to read cache" ) ?;
45+ let data = self . data . read ( ) . map_err ( |_| "Failed to read cache" ) ?;
4546 data. clone ( )
4647 } ;
47-
48+
4849 match cached_data {
4950 Some ( masternodes) => Ok ( masternodes) ,
5051 None => {
5152 // This shouldn't happen as we just updated, but handle it gracefully
5253 self . update_cache ( ) . await ?;
53- let data = self . data . read ( )
54- . map_err ( |_| "Failed to read cache" ) ?;
54+ let data = self . data . read ( ) . map_err ( |_| "Failed to read cache" ) ?;
5555 Ok ( data. as_ref ( ) . ok_or ( "No masternode data available" ) ?. clone ( ) )
5656 }
5757 }
@@ -63,8 +63,9 @@ impl MasternodeCache {
6363 // Wrap the entire operation in a timeout (30 seconds)
6464 let result = tokio:: time:: timeout (
6565 tokio:: time:: Duration :: from_secs ( 30 ) ,
66- self . update_cache_internal ( )
67- ) . await ;
66+ self . update_cache_internal ( ) ,
67+ )
68+ . await ;
6869
6970 match result {
7071 Ok ( Ok ( ( ) ) ) => Ok ( ( ) ) ,
@@ -80,12 +81,16 @@ impl MasternodeCache {
8081 // Fetch new data
8182 let mut masternodes = masternode_loader:: load_masternode_list ( & self . config ) . await ?;
8283
83- println ! ( "Checking version for {} Evo masternodes..." , masternodes. len( ) ) ;
84-
84+ println ! (
85+ "Checking version for {} Evo masternodes..." ,
86+ masternodes. len( )
87+ ) ;
88+
8589 // Check version for each masternode
8690 let check_tasks: Vec < _ > = masternodes. iter ( ) . enumerate ( ) . map ( |( idx, node) | {
8791 let address = node. address . clone ( ) ;
8892 let status = node. status . clone ( ) ;
93+ let platform_http_port = node. platform_http_port ;
8994 let config = self . config . clone ( ) ;
9095
9196 async move {
@@ -97,23 +102,17 @@ impl MasternodeCache {
97102 return ( idx, "fail" . to_string ( ) , None , None , start. elapsed ( ) ) ;
98103 }
99104
100- // Parse address to get IP and port, applying localhost replacement if configured
101- let resolved_address = config. replace_localhost ( & address) ;
102- let parts: Vec < & str > = resolved_address. split ( ':' ) . collect ( ) ;
103- if parts. len ( ) != 2 {
104- println ! ( "❌ Node {} at {} - invalid address format" , idx, address) ;
105- return ( idx, "fail" . to_string ( ) , None , None , start. elapsed ( ) ) ;
106- }
107-
108- let ip = parts[ 0 ] . to_string ( ) ;
109- let port = config. get_dapi_port ( ) ;
105+ // Get the host to use for version check (may be replaced by version_check_host)
106+ let ip = config. get_version_check_host ( & address) ;
107+ // Use platformHTTPPort from masternode info, fallback to config default
108+ let port = platform_http_port. unwrap_or_else ( || config. get_dapi_port ( ) ) ;
110109
111110 println ! ( "🔍 Node {} at {} (resolved: {}:{}) - checking version..." , idx, address, ip, port) ;
112111
113112 // Check version with additional timeout wrapper (2 seconds total)
114113 let result = match tokio:: time:: timeout (
115114 tokio:: time:: Duration :: from_secs ( 2 ) ,
116- grpc_client:: check_node_version ( & ip, port)
115+ grpc_client:: check_node_version ( & ip, port, config . network )
117116 ) . await {
118117 Ok ( Ok ( result) ) => {
119118 let elapsed = start. elapsed ( ) ;
@@ -141,7 +140,7 @@ impl MasternodeCache {
141140 result
142141 }
143142 } ) . collect ( ) ;
144-
143+
145144 // Execute all version checks concurrently
146145 let overall_start = std:: time:: Instant :: now ( ) ;
147146 let results = futures:: future:: join_all ( check_tasks) . await ;
@@ -162,33 +161,44 @@ impl MasternodeCache {
162161 }
163162 }
164163
165- let success_count = masternodes. iter ( ) . filter ( |n| n. version_check == "success" ) . count ( ) ;
166- let fail_count = masternodes. iter ( ) . filter ( |n| n. version_check == "fail" ) . count ( ) ;
167- println ! ( "Version check complete: {} success, {} fail (total time: {:?})" , success_count, fail_count, total_elapsed) ;
164+ let success_count = masternodes
165+ . iter ( )
166+ . filter ( |n| n. version_check == "success" )
167+ . count ( ) ;
168+ let fail_count = masternodes
169+ . iter ( )
170+ . filter ( |n| n. version_check == "fail" )
171+ . count ( ) ;
172+ println ! (
173+ "Version check complete: {} success, {} fail (total time: {:?})" ,
174+ success_count, fail_count, total_elapsed
175+ ) ;
168176
169177 // Report slow nodes
170178 if !slow_nodes. is_empty ( ) {
171- println ! ( "\n 🐌 SLOW NODES DETECTED ({} nodes took >2s):" , slow_nodes. len( ) ) ;
179+ println ! (
180+ "\n 🐌 SLOW NODES DETECTED ({} nodes took >2s):" ,
181+ slow_nodes. len( )
182+ ) ;
172183 slow_nodes. sort_by ( |a, b| b. 2 . cmp ( & a. 2 ) ) ; // Sort by duration, slowest first
173184 for ( idx, address, duration) in slow_nodes. iter ( ) . take ( 10 ) {
174185 println ! ( " Node {} at {} took {:?}" , idx, address, duration) ;
175186 }
176187 println ! ( ) ;
177188 }
178-
189+
179190 // Update the cache
180191 {
181- let mut data = self . data . write ( )
182- . map_err ( |_| "Failed to write to cache" ) ?;
192+ let mut data = self . data . write ( ) . map_err ( |_| "Failed to write to cache" ) ?;
183193 * data = Some ( masternodes) ;
184194 }
185-
195+
186196 // Update the timestamp
187197 {
188198 let mut last_update = self . last_update . lock ( ) . await ;
189199 * last_update = Some ( Instant :: now ( ) ) ;
190200 }
191-
201+
192202 println ! ( "Masternode cache updated successfully" ) ;
193203 Ok ( ( ) )
194204 }
@@ -198,12 +208,22 @@ impl MasternodeCache {
198208 loop {
199209 tokio:: time:: sleep ( self . update_interval ) . await ;
200210 let now = Local :: now ( ) ;
201- println ! ( "🔄 [{}] Background refresh: Starting masternode cache update..." , now. format( "%Y-%m-%d %H:%M:%S" ) ) ;
211+ println ! (
212+ "🔄 [{}] Background refresh: Starting masternode cache update..." ,
213+ now. format( "%Y-%m-%d %H:%M:%S" )
214+ ) ;
202215 match self . update_cache ( ) . await {
203- Ok ( _) => println ! ( "✅ [{}] Background refresh: Masternode cache updated successfully" , Local :: now( ) . format( "%Y-%m-%d %H:%M:%S" ) ) ,
204- Err ( e) => eprintln ! ( "❌ [{}] Background refresh: Failed to update masternode cache: {}" , Local :: now( ) . format( "%Y-%m-%d %H:%M:%S" ) , e) ,
216+ Ok ( _) => println ! (
217+ "✅ [{}] Background refresh: Masternode cache updated successfully" ,
218+ Local :: now( ) . format( "%Y-%m-%d %H:%M:%S" )
219+ ) ,
220+ Err ( e) => eprintln ! (
221+ "❌ [{}] Background refresh: Failed to update masternode cache: {}" ,
222+ Local :: now( ) . format( "%Y-%m-%d %H:%M:%S" ) ,
223+ e
224+ ) ,
205225 }
206226 }
207227 } ) ;
208228 }
209- }
229+ }
0 commit comments