-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathmain.go
135 lines (117 loc) · 3.89 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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright (c) Gabriel de Quadros Ligneul
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)
// This package contains the main function that executes the nonodo command.
package main
import (
"fmt"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"github.com/carlmjohnson/versioninfo"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/gligneul/nonodo/internal/nonodo"
"github.com/lmittmann/tint"
"github.com/mattn/go-isatty"
"github.com/spf13/cobra"
)
var cmd = &cobra.Command{
Use: "nonodo [flags] [-- application [args]...]",
Short: "nonodo is a development node for Cartesi Rollups",
Run: run,
Version: versioninfo.Short(),
}
var debug bool
var color bool
var opts = nonodo.NewNonodoOpts()
func init() {
// anvil-*
cmd.Flags().IntVar(&opts.AnvilPort, "anvil-port", opts.AnvilPort,
"HTTP port used by Anvil")
cmd.Flags().BoolVar(&opts.AnvilVerbose, "anvil-verbose", opts.AnvilVerbose,
"If set, prints Anvil's output")
// contracts-*
cmd.Flags().StringVar(&opts.ApplicationAddress, "contracts-application-address",
opts.ApplicationAddress, "Application contract address")
cmd.Flags().StringVar(&opts.InputBoxAddress, "contracts-input-box-address",
opts.InputBoxAddress, "InputBox contract address")
cmd.Flags().Uint64Var(&opts.InputBoxBlock, "contracts-input-box-block",
opts.InputBoxBlock, "InputBox deployment block number")
// enable-*
cmd.Flags().BoolVarP(&debug, "enable-debug", "d", false, "If set, enable debug output")
cmd.Flags().BoolVar(&color, "enable-color", true, "If set, enables logs color")
cmd.Flags().BoolVar(&opts.EnableEcho, "enable-echo", opts.EnableEcho,
"If set, nonodo starts a built-in echo application")
// http-*
cmd.Flags().StringVar(&opts.HttpAddress, "http-address", opts.HttpAddress,
"HTTP address used by nonodo to serve its APIs")
cmd.Flags().IntVar(&opts.HttpPort, "http-port", opts.HttpPort,
"HTTP port used by nonodo to serve its APIs")
// rpc-url
cmd.Flags().StringVar(&opts.RpcUrl, "rpc-url", opts.RpcUrl,
"If set, nonodo connects to this url instead of setting up Anvil")
}
func run(cmd *cobra.Command, args []string) {
var startTime = time.Now()
// setup log
logOpts := new(tint.Options)
if debug {
logOpts.Level = slog.LevelDebug
}
logOpts.AddSource = debug
logOpts.NoColor = !color || !isatty.IsTerminal(os.Stdout.Fd())
logOpts.TimeFormat = "[15:04:05.000]"
handler := tint.NewHandler(os.Stdout, logOpts)
logger := slog.New(handler)
slog.SetDefault(logger)
// check args
checkEthAddress(cmd, "address-input-box")
checkEthAddress(cmd, "address-application")
if opts.AnvilPort == 0 {
exitf("--anvil-port cannot be 0")
}
if cmd.Flags().Changed("rpc-url") && !cmd.Flags().Changed("contracts-input-box-block") {
exitf("must set --contracts-input-box-block when setting --rpc-url")
}
if opts.EnableEcho && len(args) > 0 {
exitf("can't use built-in echo with custom application")
}
opts.ApplicationArgs = args
// handle signals with notify context
ctx, cancel := signal.NotifyContext(cmd.Context(), syscall.SIGINT, syscall.SIGTERM)
defer cancel()
// start nonodo
ready := make(chan struct{}, 1)
go func() {
select {
case <-ready:
slog.Info("nonodo: ready", "after", time.Since(startTime))
case <-ctx.Done():
}
}()
err := nonodo.NewSupervisor(opts).Start(ctx, ready)
cobra.CheckErr(err)
}
func main() {
cobra.CheckErr(cmd.Execute())
}
func exitf(format string, args ...any) {
err := fmt.Sprintf(format, args...)
slog.Error("configuration error", "error", err)
os.Exit(1)
}
func checkEthAddress(cmd *cobra.Command, varName string) {
if cmd.Flags().Changed(varName) {
value, err := cmd.Flags().GetString(varName)
cobra.CheckErr(err)
bytes, err := hexutil.Decode(value)
if err != nil {
exitf("invalid address for --%v: %v", varName, err)
}
if len(bytes) != common.AddressLength {
exitf("invalid address for --%v: wrong length", varName)
}
}
}