forked from ethereum/nodemonitor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
117 lines (104 loc) · 2.97 KB
/
main.go
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
package main
import (
"errors"
"net/http"
"os"
"os/signal"
"time"
"github.com/ethereum/go-ethereum/log"
"github.com/holiman/nodemonitor/nodes"
"github.com/naoina/toml"
)
// ssh -L 8546:localhost:8545 ubuntu@nethermind.ethdevops.io
// ssh -L 8547:localhost:8545 ubuntu@besu.ethdevops.io
// ssh -L 8548:localhost:8545 ubuntu@mon02.ethdevops.io
func main() {
// Initialize the logger
log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
if len(os.Args) < 2 {
log.Error("Second arg must be path to config file")
os.Exit(1)
}
cFile := os.Args[1]
f, err := os.Open(cFile)
if err != nil {
log.Error("Error", "error", err)
os.Exit(1)
}
defer f.Close()
var config nodes.Config
if err := toml.NewDecoder(f).Decode(&config); err != nil {
log.Error("Error", "error", err)
os.Exit(1)
}
nodes.EnableMetrics(&config)
mon, err := spinupMonitor(config)
if err != nil {
log.Error("Error", "error", err)
os.Exit(1)
}
spinupServer(config)
mon.Start()
// Wait for ctrl-c
quitCh := make(chan os.Signal, 1)
signal.Notify(quitCh, os.Interrupt)
// TODO: Monitor changes to the config file
<-quitCh
mon.Stop()
os.Exit(0)
}
func spinupMonitor(config nodes.Config) (*nodes.NodeMonitor, error) {
db, err := nodes.NewBlockDB()
if err != nil {
return nil, err
}
reload, err := time.ParseDuration(config.ReloadInterval)
if err != nil {
return nil, err
}
var clients []nodes.Node
for _, c := range config.Clients {
var (
node nodes.Node
err error
)
switch c.Kind {
case "infura":
node, err = nodes.NewInfuraNode(c.Name, config.InfuraKey, config.InfuraEndpoint,
db, c.Ratelimit)
case "alchemy":
node, err = nodes.NewAlchemyNode(c.Name, config.AlchemyKey, config.AlchemyEndpoint,
db, c.Ratelimit)
case "rpc":
node, err = nodes.NewRPCNode(c.Name, c.Url, db, c.Ratelimit)
case "etherscan":
node, err = nodes.NewEtherscanNode(c.Name, config.EtherscanKey, config.EtherscanEndpoint,
db, c.Ratelimit)
case "testnode-canon":
node = nodes.NewLiveTestNode("canon", 13_000_000, []uint64{0}, []int{0})
case "testnode-fork-old":
node = nodes.NewLiveTestNode("old", 12_800_000, []uint64{0, 12_799_998}, []int{0, 2})
case "testnode-fork-recent":
node = nodes.NewLiveTestNode("legacy", 12_999_900, []uint64{0, 12_999_800}, []int{0, 1})
default:
log.Error("Wrong client type", "kind", c.Kind, "available", "[rpc, infura, alchemy]")
return nil, errors.New("invalid config")
}
if err != nil {
return nil, err
}
clients = append(clients, node)
log.Info("Client configured", "name", c.Name)
}
return nodes.NewMonitor(clients, db, reload, config.ChainName)
}
func spinupServer(config nodes.Config) error {
if len(config.ServerAddress) == 0 {
return nil
}
fs := http.FileServer(http.Dir("www/"))
http.Handle("/", http.StripPrefix("/", fs))
log.Info("Starting web server", "address", config.ServerAddress)
go http.ListenAndServe(config.ServerAddress, nil)
return nil
}