goBlockchainDataAnalysis/serverRoutes.go
serverRoutes.goRaw
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "net/http"
7 "sort"
8 "strconv"
9 "time"
10
11 "gopkg.in/mgo.v2/bson"
12
13 "github.com/gorilla/mux"
14)
15
16type Routes []Route
17
18var routes = Routes{
19 Route{
20 "Index",
21 "GET",
22 "/",
23 Index,
24 },
25 Route{
26 "Stats",
27 "Get",
28 "/stats",
29 Stats,
30 },
31 Route{
32 "AllAddresses",
33 "Get",
34 "/alladdresses",
35 AllAddresses,
36 },
37 Route{
38 "GetLastAddr",
39 "Get",
40 "/lastaddr",
41 GetLastAddr,
42 },
43 Route{
44 "GetLastTx",
45 "Get",
46 "/lasttx",
47 GetLastTx,
48 },
49 Route{
50 "Block",
51 "GET",
52 "/block/{height}",
53 Block,
54 },
55 Route{
56 "Address",
57 "GET",
58 "/address/{hash}",
59 Address,
60 },
61 Route{
62 "AddressNetwork",
63 "GET",
64 "/address/network/{address}",
65 AddressNetwork,
66 },
67 Route{
68 "AddressSankey",
69 "GET",
70 "/address/sankey/{address}",
71 AddressSankey,
72 },
73 Route{
74 "NetworkMap",
75 "Get",
76 "/map",
77 NetworkMap,
78 },
79 Route{
80 "GetTotalHourAnalysis",
81 "Get",
82 "/totalhouranalysis",
83 GetTotalHourAnalysis,
84 },
85 Route{
86 "GetLast24HourAnalysis",
87 "Get",
88 "/last24hour",
89 GetLast24HourAnalysis,
90 },
91 Route{
92 "GetLast7DayAnalysis",
93 "Get",
94 "/last7day",
95 GetLast7DayAnalysis,
96 },
97 Route{
98 "GetLast7DayHourAnalysis",
99 "Get",
100 "/last7dayhour",
101 GetLast7DayHourAnalysis,
102 },
103}
104
105//ROUTES
106
107func Index(w http.ResponseWriter, r *http.Request) {
108 fmt.Fprintln(w, "ask for recommendations in /r")
109 //http.FileServer(http.Dir("./web"))
110}
111
112/*
113func NewUser(w http.ResponseWriter, r *http.Request) {
114 ipFilter(w, r)
115 decoder := json.NewDecoder(r.Body)
116 var newUser UserModel
117 err := decoder.Decode(&newUser)
118 check(err)
119 defer r.Body.Close()
120
121 saveUser(userCollection, newUser)
122
123 fmt.Println(newUser)
124 fmt.Fprintln(w, "new user added: ", newUser.ID)
125}
126*/
127func Stats(w http.ResponseWriter, r *http.Request) {
128 ipFilter(w, r)
129
130 stats := getStats()
131
132 jsonResp, err := json.Marshal(stats)
133 check(err)
134
135 fmt.Fprintln(w, string(jsonResp))
136}
137func AllAddresses(w http.ResponseWriter, r *http.Request) {
138 ipFilter(w, r)
139
140 nodes := []NodeModel{}
141 iter := nodeCollection.Find(bson.M{"type": "address"}).Limit(10000).Iter()
142 err := iter.All(&nodes)
143
144 //convert []resp struct to json
145 jsonNodes, err := json.Marshal(nodes)
146 check(err)
147
148 fmt.Fprintln(w, string(jsonNodes))
149}
150func GetLastAddr(w http.ResponseWriter, r *http.Request) {
151 ipFilter(w, r)
152
153 addresses := []AddressModel{}
154 err := addressCollection.Find(bson.M{}).Limit(10).Sort("-$natural").All(&addresses)
155 check(err)
156
157 //convert []resp struct to json
158 jsonResp, err := json.Marshal(addresses)
159 check(err)
160
161 fmt.Fprintln(w, string(jsonResp))
162}
163func GetLastTx(w http.ResponseWriter, r *http.Request) {
164 ipFilter(w, r)
165
166 txs := []TxModel{}
167 err := txCollection.Find(bson.M{}).Limit(10).Sort("-$natural").All(&txs)
168 check(err)
169
170 //convert []resp struct to json
171 jsonData, err := json.Marshal(txs)
172 check(err)
173
174 fmt.Fprintln(w, string(jsonData))
175}
176func Block(w http.ResponseWriter, r *http.Request) {
177 ipFilter(w, r)
178
179 vars := mux.Vars(r)
180 var heightString string
181 heightString = vars["height"]
182 height, err := strconv.ParseInt(heightString, 10, 64)
183 if err != nil {
184 fmt.Fprintln(w, "not valid height")
185 } else {
186 block := BlockModel{}
187 err := blockCollection.Find(bson.M{"height": height}).One(&block)
188
189 txs := []TxModel{}
190 err = txCollection.Find(bson.M{"blockheight": heightString}).All(&txs)
191 block.Txs = txs
192
193 /*for _, tx := range address.Txs {
194 blocks := []BlockModel{}
195 err = blockCollection.Find(bson.M{"blockheight": tx.BlockHash}).All(&blocks)
196 for _, block := range blocks {
197 address.Blocks = append(address.Blocks, block)
198 }
199 }*/
200
201 //convert []resp struct to json
202 jsonResp, err := json.Marshal(block)
203 check(err)
204
205 fmt.Fprintln(w, string(jsonResp))
206 }
207}
208func Address(w http.ResponseWriter, r *http.Request) {
209 ipFilter(w, r)
210
211 vars := mux.Vars(r)
212 hash := vars["hash"]
213 if hash == "undefined" {
214 fmt.Fprintln(w, "not valid hash")
215 } else {
216 address := AddressModel{}
217 err := addressCollection.Find(bson.M{"hash": hash}).One(&address)
218
219 txs := []TxModel{}
220 err = txCollection.Find(bson.M{"$or": []bson.M{bson.M{"from": hash}, bson.M{"to": hash}}}).All(&txs)
221 address.Txs = txs
222
223 for _, tx := range address.Txs {
224 blocks := []BlockModel{}
225 err = blockCollection.Find(bson.M{"hash": tx.BlockHash}).All(&blocks)
226 for _, block := range blocks {
227 address.Blocks = append(address.Blocks, block)
228 }
229 }
230
231 //convert []resp struct to json
232 jsonResp, err := json.Marshal(address)
233 check(err)
234
235 fmt.Fprintln(w, string(jsonResp))
236 }
237}
238func AddressNetwork(w http.ResponseWriter, r *http.Request) {
239 ipFilter(w, r)
240
241 vars := mux.Vars(r)
242 address := vars["address"]
243 if address == "undefined" {
244 fmt.Fprintln(w, "not valid address")
245 } else {
246 network := addressTree(address)
247 network.Nodes[0].Shape = "triangle"
248
249 //convert []resp struct to json
250 jNetwork, err := json.Marshal(network)
251 check(err)
252
253 fmt.Fprintln(w, string(jNetwork))
254 }
255}
256func AddressSankey(w http.ResponseWriter, r *http.Request) {
257 ipFilter(w, r)
258 vars := mux.Vars(r)
259 address := vars["address"]
260 if address == "undefined" {
261 fmt.Fprintln(w, "not valid address")
262 } else {
263 network := addressTree(address)
264 var sankey SankeyModel
265
266 fmt.Println("network generated")
267 mapNodeK := make(map[string]int)
268 for k, n := range network.Nodes {
269 var sankeyNode SankeyNodeModel
270 //sankeyNode.StringNode = n.Id
271 sankeyNode.Node = k
272 sankeyNode.Name = n.Id
273 sankey.Nodes = append(sankey.Nodes, sankeyNode)
274 mapNodeK[n.Id] = k
275 }
276 for _, e := range network.Edges {
277 var sankeyLink SankeyLinkModel
278 //sankeyLink.StringSource = e.From
279 sankeyLink.Source = mapNodeK[e.From]
280 //sankeyLink.StringTarget = e.To
281 sankeyLink.Target = mapNodeK[e.To]
282 sankeyLink.Value = e.Label
283 sankey.Links = append(sankey.Links, sankeyLink)
284 }
285 fmt.Println("Sankey generated")
286
287 //convert []resp struct to json
288 jsonSankey, err := json.Marshal(sankey)
289 check(err)
290
291 fmt.Fprintln(w, string(jsonSankey))
292 }
293}
294func NetworkMap(w http.ResponseWriter, r *http.Request) {
295 ipFilter(w, r)
296
297 nodes, err := getAllNodes()
298 check(err)
299 edges, err := getAllEdges()
300 check(err)
301
302 var network NetworkModel
303 network.Nodes = nodes
304 network.Edges = edges
305
306 //convert []resp struct to json
307 jNetwork, err := json.Marshal(network)
308 check(err)
309
310 fmt.Fprintln(w, string(jNetwork))
311}
312
313func GetTotalHourAnalysis(w http.ResponseWriter, r *http.Request) {
314 ipFilter(w, r)
315
316 hourAnalysis := []ChartCountModel{}
317 iter := hourCountCollection.Find(bson.M{}).Limit(10000).Iter()
318 err := iter.All(&hourAnalysis)
319
320 //sort by hour
321 sort.Slice(hourAnalysis, func(i, j int) bool {
322 return hourAnalysis[i].Elem < hourAnalysis[j].Elem
323 })
324
325 var resp ChartAnalysisResp
326 for _, d := range hourAnalysis {
327 resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
328 resp.Data = append(resp.Data, d.Count)
329 }
330
331 //convert []resp struct to json
332 jsonResp, err := json.Marshal(resp)
333 check(err)
334 fmt.Fprintln(w, string(jsonResp))
335}
336
337func GetLast24HourAnalysis(w http.ResponseWriter, r *http.Request) {
338 ipFilter(w, r)
339
340 fromDate := time.Now().AddDate(0, 0, -1)
341 toDate := time.Now()
342
343 txs := []TxModel{}
344 err := txCollection.Find(bson.M{
345 "datet": bson.M{
346 "$gt": fromDate,
347 "$lt": toDate,
348 },
349 }).Sort("-$natural").All(&txs)
350 check(err)
351
352 //generate map with 24 hours
353 hourFrequencies := map24hours()
354 for _, tx := range txs {
355 hourFrequencies[tx.Date.Hour]++
356 }
357 var hourCount []ChartCountModel
358 for hour, frequency := range hourFrequencies {
359 hourCount = append(hourCount, ChartCountModel{hour, frequency})
360 }
361 //sort by hour
362 sort.Slice(hourCount, func(i, j int) bool {
363 return hourCount[i].Elem < hourCount[j].Elem
364 })
365
366 var resp ChartAnalysisResp
367 for _, d := range hourCount {
368 resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
369 resp.Data = append(resp.Data, d.Count)
370 }
371
372 //convert []resp struct to json
373 jsonResp, err := json.Marshal(resp)
374 check(err)
375 fmt.Fprintln(w, string(jsonResp))
376}
377func GetLast7DayAnalysis(w http.ResponseWriter, r *http.Request) {
378 ipFilter(w, r)
379
380 fromDate := time.Now().AddDate(0, 0, -7)
381 toDate := time.Now()
382
383 txs := []TxModel{}
384 err := txCollection.Find(bson.M{
385 "datet": bson.M{
386 "$gt": fromDate,
387 "$lt": toDate,
388 },
389 }).Sort("-$natural").All(&txs)
390 check(err)
391
392 //generate map with 24 hours
393 //hourFrequencies := map24hours()
394 dayFrequencies := make(map[int]int)
395 for _, tx := range txs {
396 dayFrequencies[tx.Date.Day]++
397 }
398 var dayCount []ChartCountModel
399 for day, frequency := range dayFrequencies {
400 dayCount = append(dayCount, ChartCountModel{day, frequency})
401 }
402 //sort by hour
403 sort.Slice(dayCount, func(i, j int) bool {
404 return dayCount[i].Elem < dayCount[j].Elem
405 })
406
407 var resp ChartAnalysisResp
408 for _, d := range dayCount {
409 resp.Labels = append(resp.Labels, strconv.Itoa(d.Elem))
410 resp.Data = append(resp.Data, d.Count)
411 }
412
413 //convert []resp struct to json
414 jsonResp, err := json.Marshal(resp)
415 check(err)
416 fmt.Fprintln(w, string(jsonResp))
417}
418
419func GetLast7DayHourAnalysis(w http.ResponseWriter, r *http.Request) {
420 ipFilter(w, r)
421
422 var resp ChartSeriesAnalysisResp
423
424 for i := 0; i < 7; i++ {
425 fromDate := time.Now().AddDate(0, 0, -i-1)
426 toDate := time.Now().AddDate(0, 0, -i)
427 txs := []TxModel{}
428 err := txCollection.Find(bson.M{
429 "datet": bson.M{
430 "$gt": fromDate,
431 "$lt": toDate,
432 },
433 }).Sort("-$natural").All(&txs)
434 check(err)
435
436 //generate map with 24 hours
437 hourFrequencies := map24hours()
438 for _, tx := range txs {
439 hourFrequencies[tx.Date.Hour]++
440 }
441 var hourCount []ChartCountModel
442 for hour, frequency := range hourFrequencies {
443 hourCount = append(hourCount, ChartCountModel{hour, frequency})
444 }
445 //sort by hour
446 sort.Slice(hourCount, func(i, j int) bool {
447 return hourCount[i].Elem < hourCount[j].Elem
448 })
449 var dayData []int
450 for _, d := range hourCount {
451 dayData = append(dayData, d.Count)
452 }
453 if len(txs) > 0 {
454 resp.Series = append(resp.Series, txs[0].Date.Day)
455 resp.Data = append(resp.Data, dayData)
456 }
457 }
458 hourLabels := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"}
459 resp.Labels = hourLabels
460
461 //convert []resp struct to json
462 jsonResp, err := json.Marshal(resp)
463 check(err)
464 fmt.Fprintln(w, string(jsonResp))
465}