-
Notifications
You must be signed in to change notification settings - Fork 0
/
delegatemonitor.ahk
353 lines (251 loc) · 9.78 KB
/
delegatemonitor.ahk
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
/*
Remote Lisk Delegate Monitoring
by Vega
For more information see:
https://forum.lisk.io/viewtopic.php?f=25&t=319
Version: v0.1 (2016.04.10)
Version: v0.2 (2016.04.12)
Version: v0.2.5 (2016.05.21)
Version: v1 (2016.11.30)
Version: v1.1 (2016.12.09) - fix for lisk 0.5.1
v1 is the final version not counting bug fixes.
Development will continue in Lisk Node Monitor, coming soon.
-----------------------
You have to install AutoHotKey to run this script.
You can find the latest version here: https://autohotkey.com
requirements:
- autohotkey installed
- api access to the delegate node that you want to monitor (config.json, forging:whitelist have to contain your ip, or have to be empty to accept post api calls from anyone)
This version will display:
- Your basic delegate information
- Your nodes current height and if they are forging or not
- A list of height distribution from peers, that is a good indicatior if a node of yours is experiencing a problem
- A message if one of your nodes is behind on block (optinal)
- A sound file can also be played on this event (optional)
- It can be set that this only happens if the forging node is behind
*/
;### some initialisation ###
#SingleInstance force
#Persistent
#NoEnv
SetBatchLines -1
SetTitleMatchMode 2
DetectHiddenWindows, On
ComObjError(false)
Menu, tray, icon, shell32.dll, 210
onexit, OnExit
GroupAdd justthiswin, %A_ScriptName% - Notepad ; for editing purposes
#include notify.ahk
; notification function by gwarble. source: https://autohotkey.com/board/topic/44870-notify-multiple-easy-tray-area-notifications-v04991/
;https://autohotkey.com/board/topic/81807-notify-builder/
;###################################################
;startup - read data from settings.ini, check stuff
;###################################################
IfnotExist settings.ini ; if no setting.ini,
gosub createsettingsini ;go to subroutine to create it
loop, read, settings.ini, `n ; read settings into variables
{
if regexmatch(A_LoopReadLine,"(.*?) ?:=.*?""(.*?)""",d)
%d1% := Trim(d2)
if %d2%
Ifinstring A_LoopReadLine, nodeurl
nodeurl_count++
}
; create an object. this will be used later for API calls. for more about this method: https://msdn.microsoft.com/en-us/library/windows/desktop/aa384106%28v=vs.85%29.aspx
WinHttpReq:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
;######## do some stuff based on settings.ini #########
check_nodes_height *= 1000 ; convert check time to milliseconds
check_delegateinfo *= 1000 ; convert check time to milliseconds
delegate_message := "`n`n`n`n`n"
; remove / char from end of URL if present
loop % nodeurl_count
nodeurl%a_index% := RegExReplace(nodeurl%a_index%,"(.*)\/$","$1")
if check_nodes_height != 0
{
gosub GETHEIGHTS
settimer GETHEIGHTS,%check_nodes_height%
}
if delegate_name
if check_delegateinfo != 0
{
gosub GETDELEGATEINFO
settimer GETDELEGATEINFO,%check_delegateinfo%
}
;#######################################################
;############ END OF STARTUP SECTION ##################
;#######################################################
return
GETHEIGHTS:
gui_message := ""
gosub GETPEERHEIGHTS
gosub GETNODEHEIGHTS
gosub CHECKHEIGHTPROBLEM
gui_message .= "`n" peer_message
FormatTime gotheights,%a_now%,HH:mm:ss
gui_message .= "`nUpdated on " gotheights "`n"
if delegate_name
gui_message .= "`nDelegate " delegate_name " (from lisk.io)`n---------------------`n" delegate_message
if gui
Notify("",gui_message,100000000,"UPDATE=" gui)
else
gui := Notify("",gui_message,100000000,notification_style)
return
GETPEERHEIGHTS:
;##############################################
; determine how many peers at different heights
;##############################################
Thread, NoTimers
peers := "", offset := "0"
;loop 2
loop 1
{
peers .= WinHttpReq.ResponseText(WinHttpReq.Send(WinHttpReq.Open("GET","https://login.lisk.io/api/peers?state=2&limit=100&offset=" offset)))
offset+=100
}
peerdata := "", uniquehights := ""
Pos := 1
regex = {"ip":"(.*?)",.*?"height":(.*?)}
While Pos {
Pos:=RegExMatch(peers,regex, d, Pos+StrLen(d1) )
if !d
Break
IfNotInString peerdata, %d1%|%d2%
peerdata .= d1 "|" d2 "`n"
if d2 = null
continue
IfNotInString uniquehights, %d2%
uniquehights .= d2 "|"
}
Sort, uniquehights, N R D|
heightdistribution := "", heightnumbers :=""
loop, parse, uniquehights, |
{
if !a_loopfield
break
StringReplace, peerdata, peerdata, |%a_loopfield%, |%a_loopfield%, UseErrorLevel
if ErrorLevel < 5 ; don't list errant heights
continue
heightdistribution .= a_loopfield " on " ErrorLevel " peers`n"
heightnumbers .= a_loopfield " - " ErrorLevel "`n"
}
; get highest block on network
loop, parse, heightnumbers, -, %a_index%
{
topheight := a_loopfield ; highest block on any peer
break
}
peer_message := "Heights Consensus`n---------------------`n" heightdistribution
;##############################################
return
GETNODEHEIGHTS:
Thread, NoTimers
gui_message := "Your Own Nodes`n---------------------`n"
loop % nodeurl_count
{
apiresponse := WinHttpReq.ResponseText(WinHttpReq.Send(WinHttpReq.Open("GET",nodeurl%a_index% "/api/loader/status/sync")))
RegExMatch(apiresponse,"{""success"":(.*?),""syncing"":(.*?),""blocks"":(.*?),""height"":(.*?),""broadhash"":""(.*?)"",""consensus"":(.*?)}",d)
; later othen info than height can be added
if d3 != 0
gui_message .= d3 " | "
nodeurl%a_index%_height := d4
if !d4
nodeurl%a_index%_height := "no response from node"
;check if forging is enabled on this delegate
if delegate_publickey
forgingstatus := regexreplace(WinHttpReq.ResponseText(WinHttpReq.Send(WinHttpReq.Open("GET",nodeurl%a_index% "/api/delegates/forging/status?publicKey=" delegate_publickey))),".*""enabled"":(.*?)}","$1")
if forgingstatus = true
forgingstatus := "F"
if forgingstatus = false
forgingstatus := "N"
if !forgingstatus
forgingstatus := "U"
if !delegate_name
forgingstatus := ""
nodeurl%a_index%_forgingstatus := forgingstatus
gui_message .= d4 " - " RegExReplace(nodeurl%a_index%,"https?://","") " " forgingstatus "`n"
}
Return
CHECKHEIGHTPROBLEM:
;compair your nodes height with peers height
loop % nodeurl_count
{
heightdiff := topheight - nodeurl%a_index%_height
if heightdiff between -%blockdifferenceallowed% and %blockdifferenceallowed%
continue
else
{
If onlyforgingnode = yes
if nodeurl%a_index%_forgingstatus != F
continue
gui_message .= "`n(ONE OF) YOUR NODE BLOCKS BEHIND OR NOT RESPONDING`n"
if playsoundifproblem
{
if soundcount != 1
continue
SoundPlay, %playsoundifproblem%
soundcount++
}
}
}
return
GETDELEGATEINFO: ; get minimal info about delegate
Thread, NoTimers
if !delegate_name
return ; no delegate set in settings.ini
; it should really get it only after it's sure that this not is not forked or get it from multiple nodes and compair
apiresponse := WinHttpReq.ResponseText(WinHttpReq.Send(WinHttpReq.Open("GET","https://login.lisk.io/api/delegates/search?q=" delegate_name)))
regex = {"username":"%delegate_name%","address":"(.*?)","publicKey":"(.*?)","vote":"(.*?)","producedblocks":(.*?),"missedblocks":(.*?)}
RegExMatch(apiresponse,regex,d)
delegate_address := d1, delegate_pubkey := d2, delegate_vote := d3, delegate_forgedblocks := d4, delegate_missedblocks := d5, delegate_data := d4 d5
delegate_message := "Blocks " d4 " Forged / "d5 " Missed`n"
if !delegate_publickey
delegate_publickey := d2
FormatTime getdel,%a_now%,HH:mm:ss
delegate_message .= "`nUpdated on " getdel
return
; #### just stuff to make editing the script easier (restarts at every save in notepad)
#IfWinActive ahk_group justthiswin
~^s::
Sleep 500
reload
return
#IfWinActive
;################################################
ONEXIT:
exitapp
;### this is the default content of the ini file. if not exist this will create it ###
createsettingsini: ; creates a settings ini file
defaultf =
(
/*
Notes:
- start or reload Delegate Monitor after changing this file
*/
;############################
;##### Private Nodes ######
;############################
/*
Notes:
Your own node addresses. Domain or ip address with http(s) prefix and port if needed
First node should be called "nodeurl1" the second "nodeurl2" and so on. You can add or replace us many nodes as you want. But take care, there shouldn't be any gap in the numbering.
*/
nodeurl1 := ""
nodeurl2 := ""
nodeurl3 := ""
nodeurl4 := ""
nodeurl5 := ""
;#############################
;##### Other Settings ######
;#############################
check_nodes_height := "15" ;in seconds. how often the script should check your nodes height?
check_delegateinfo := "120" ;in seconds. how often the script should check delegate information?
delegate_name := "" ; your delegate username
blockdifferenceallowed := "10" ; the least amount of block from the highest block on the network have to be your node to have it rebuild
playsoundifproblem := "" ; path to a sound file to be played when one of your nodes are out of sync; keep it empty if no sound
onlyforgingnode := "no" ; if yes, only displays message and plays sound if the problem message is the currently forging node
notification_style := "GC=asdasd TC=White MC=White" ; you can change the notification popups design. for more see: http://www.gwarble.com/ahk/Notify/
)
FileAppend %defaultf%, settings.ini
;msgbox A default settings.ini was created. Please edit your preferences to the ini file and start the script again.`n`nPress OK to exit
msgbox A default settings.ini was created. Edit the file and reload the script after.
reload