Uh oh!
There was an error while loading. Please reload this page.
forked from OriginStake/node_ping
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathping_node.py
More file actions
Latest commit
170 lines (139 loc) · 6.63 KB
/
Copy pathping_node.py
File metadata and controls
170 lines (139 loc) · 6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
importsocket
importtime
importconcurrent.futures
fromtqdmimporttqdm
# Configuration parameters
PEERS_FILE="peers_list.txt"
TOP_N_PEERS=10
SUCCESSFUL_PEERS_LOG_FILE="successful_peers_log.txt"
FULL_PEERS_LOG_FILE="full_peers_log.txt"
SORTED_PEERS_FILE="sorted_peers.txt"
FINAL_PEERS_FILE="final_peers_for_validators.txt"
NUM_PINGS=3
MAX_WORKERS=50
LOG_INTERVAL=10
defping_peer(peer, num_pings=NUM_PINGS):
id_ip_port=peer.strip()
try:
if"@"notinid_ip_port:
returnNone, f"Invalid format (missing '@'): {id_ip_port}"
ip_port=id_ip_port.split("@")[1]
if":"notinip_port:
returnNone, f"Invalid format (missing ':'): {id_ip_port}"
ip, port=ip_port.split(":")
port=int(port)
except (IndexError, ValueError):
returnNone, f"Invalid format: {id_ip_port}"
response_times= []
for_inrange(num_pings):
try:
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1) # Timeout 1 second
start_time_ping=time.time()
result=sock.connect_ex((ip, port))
end_time_ping=time.time()
sock.close()
response_time= (end_time_ping-start_time_ping) *1000
ifresult==0:
response_times.append(response_time)
else:
response_times.append(None)
exceptsocket.error:
response_times.append(None)
valid_response_times= [tfortinresponse_timesiftisnotNone]
avg_response_time=sum(valid_response_times) /len(valid_response_times) ifvalid_response_timeselseNone
ifavg_response_timeisnotNone:
returnid_ip_port, f"{avg_response_time:.0f}ms - {id_ip_port}"
else:
returnNone, f"Failed - {id_ip_port}"
defmain():
# Initialize the log files
open(SUCCESSFUL_PEERS_LOG_FILE, "w").close()
open(FULL_PEERS_LOG_FILE, "w").close()
valid_peers= []
invalid_peers= []
# Normalize and process the peer list from file
withopen(PEERS_FILE, "r") asfile:
raw_peers=file.read()
# Replace newlines with commas and split by commas to handle multiple formats
normalized_peers=raw_peers.replace("\n", ",").replace(", ", ",").split(",")
forpeerinnormalized_peers:
peer=peer.strip()
ifpeerand"@"inpeerand":"inpeer.split("@")[1]:
valid_peers.append(peer)
else:
invalid_peers.append(peer)
ifinvalid_peers:
print("The following peers have invalid formats and will be skipped:")
forinvalidininvalid_peers:
print(f" - {invalid}")
withconcurrent.futures.ThreadPoolExecutor(max_workers=MAX_WORKERS) asexecutor:
futures= [executor.submit(ping_peer, peer) forpeerinvalid_peers]
results= []
foridx, futureintqdm(enumerate(concurrent.futures.as_completed(futures)), total=len(futures)):
try:
result=future.result()
results.append(result)
ifidx%LOG_INTERVAL==0andresult[0] isnotNone:
print(f"{result[0]}: Connected successfully, average response time: {result[1].split()[0]}")
exceptExceptionase:
print(f"Error processing a peer: {e}")
withopen(SUCCESSFUL_PEERS_LOG_FILE, "w") aslog_file:
forresultinresults:
ifresult[0] isnotNone:
log_file.write(result[0] +",")
withopen(FULL_PEERS_LOG_FILE, "w") asfull_log_file:
forresultinresults:
full_log_file.write(result[1] +"\n")
print(f"Debug: Writing to log: {result[1]}") # Debug line
# Process and sort ping data
withopen(FULL_PEERS_LOG_FILE, 'r') asfile:
lines=file.readlines()
ping_data= []
forlineinlines:
parts=line.strip().split(' - ', 1) # Split on first occurrence of ' - '
iflen(parts) ==2:
ping, node=parts
ifping=="Failed":
ping_data.append((float('inf'), node)) # Use 'inf' to treat failed nodes as last
elif"ms"inping:
try:
ping_ms=int(ping.replace('ms', '').strip())
ping_data.append((ping_ms, node))
exceptValueError:
ping_data.append((float('inf'), node))
else:
print(f"Skipping malformed line: {line.strip()}")
# Sort the data
sorted_ping_data=sorted(ping_data, key=lambdax: x[0])
# Filter the top N nodes
top_n_nodes=sorted_ping_data[:TOP_N_PEERS]
nodes_below_100= [(ping, node) forping, nodeinsorted_ping_dataifping<100]
nodes_below_200= [(ping, node) forping, nodeinsorted_ping_dataifping<200]
count_below_100=len(nodes_below_100)
count_below_200=len(nodes_below_200)
count_above_200=sum(1forping, _insorted_ping_dataifping>=200)
count_failed=sum(1forping, _inping_dataifping==float('inf'))
total_nodes=len(ping_data)
# Write sorted data to the log file
withopen(SORTED_PEERS_FILE, 'w') asfile:
file.write(f"Top {TOP_N_PEERS} nodes with the lowest ping:\n")
forping, nodeintop_n_nodes:
file.write(f"{ping}ms - {node}\n")
file.write(f"\nNodes with ping below 100ms: {count_below_100}/{total_nodes} ({count_below_100/total_nodes*100:.2f}%)\n")
forping, nodeinnodes_below_100:
file.write(f"{ping}ms - {node}\n")
file.write(f"\nNodes with ping below 200ms: {count_below_200}/{total_nodes} ({count_below_200/total_nodes*100:.2f}%)\n")
forping, nodeinnodes_below_200:
file.write(f"{ping}ms - {node}\n")
file.write(f"\nNodes with ping above 200ms: {count_above_200}/{total_nodes} ({count_above_200/total_nodes*100:.2f}%)\n")
file.write(f"\nFailed nodes: {count_failed}/{total_nodes} ({count_failed/total_nodes*100:.2f}%)\n")
withopen(FINAL_PEERS_FILE, 'w') asfile:
file.write(','.join(nodefor_, nodeintop_n_nodes))
print(f"Top {TOP_N_PEERS} nodes with the lowest ping: {len(top_n_nodes)}/{total_nodes} ({len(top_n_nodes)/total_nodes*100:.2f}%)")
print(f"Nodes with ping below 100ms: {count_below_100}/{total_nodes} ({count_below_100/total_nodes*100:.2f}%)")
print(f"Nodes with ping below 200ms: {count_below_200}/{total_nodes} ({count_below_200/total_nodes*100:.2f}%)")
print(f"Nodes with ping above 200ms: {count_above_200}/{total_nodes} ({count_above_200/total_nodes*100:.2f}%)")
print(f"Failed nodes: {count_failed}/{total_nodes} ({count_failed/total_nodes*100:.2f}%)")
if__name__=="__main__":
main()