arnaucube
arnaucube/hermez-nodePublic Self-hosted repository
hermez-node/cli/node/main.go
cli/node/main.goRaw
  1package main
  2
  3import (
  4	"fmt"
  5	"os"
  6	"os/signal"
  7	"strings"
  8
  9	ethKeystore "github.com/ethereum/go-ethereum/accounts/keystore"
 10	"github.com/ethereum/go-ethereum/crypto"
 11	"github.com/hermeznetwork/hermez-node/config"
 12	"github.com/hermeznetwork/hermez-node/log"
 13	"github.com/hermeznetwork/hermez-node/node"
 14	"github.com/hermeznetwork/tracerr"
 15	"github.com/urfave/cli/v2"
 16)
 17
 18const (
 19	flagCfg   = "cfg"
 20	flagMode  = "mode"
 21	flagSK    = "privatekey"
 22	modeSync  = "sync"
 23	modeCoord = "coord"
 24)
 25
 26func cmdImportKey(c *cli.Context) error {
 27	_cfg, err := parseCli(c)
 28	if err != nil {
 29		return tracerr.Wrap(fmt.Errorf("error parsing flags and config: %w", err))
 30	}
 31	if _cfg.mode != node.ModeCoordinator {
 32		return tracerr.Wrap(fmt.Errorf("importkey must use mode coordinator"))
 33	}
 34	cfg := _cfg.node
 35
 36	scryptN := ethKeystore.StandardScryptN
 37	scryptP := ethKeystore.StandardScryptP
 38	if cfg.Coordinator.Debug.LightScrypt {
 39		scryptN = ethKeystore.LightScryptN
 40		scryptP = ethKeystore.LightScryptP
 41	}
 42	keyStore := ethKeystore.NewKeyStore(cfg.Coordinator.EthClient.Keystore.Path,
 43		scryptN, scryptP)
 44	hexKey := c.String(flagSK)
 45	hexKey = strings.TrimPrefix(hexKey, "0x")
 46	sk, err := crypto.HexToECDSA(hexKey)
 47	if err != nil {
 48		return tracerr.Wrap(err)
 49	}
 50	acc, err := keyStore.ImportECDSA(sk, cfg.Coordinator.EthClient.Keystore.Password)
 51	if err != nil {
 52		return tracerr.Wrap(err)
 53	}
 54	log.Infow("Imported private key", "addr", acc.Address.Hex())
 55	return nil
 56}
 57
 58func cmdRun(c *cli.Context) error {
 59	cfg, err := parseCli(c)
 60	if err != nil {
 61		return tracerr.Wrap(fmt.Errorf("error parsing flags and config: %w", err))
 62	}
 63	node, err := node.NewNode(cfg.mode, cfg.node)
 64	if err != nil {
 65		return tracerr.Wrap(fmt.Errorf("error starting node: %w", err))
 66	}
 67	node.Start()
 68
 69	stopCh := make(chan interface{})
 70
 71	// catch ^C to send the stop signal
 72	ossig := make(chan os.Signal, 1)
 73	signal.Notify(ossig, os.Interrupt)
 74	go func() {
 75		for sig := range ossig {
 76			if sig == os.Interrupt {
 77				stopCh <- nil
 78			}
 79		}
 80	}()
 81	<-stopCh
 82	node.Stop()
 83
 84	return nil
 85}
 86
 87// Config is the configuration of the hermez node execution
 88type Config struct {
 89	mode node.Mode
 90	node *config.Node
 91}
 92
 93func parseCli(c *cli.Context) (*Config, error) {
 94	cfg, err := getConfig(c)
 95	if err != nil {
 96		if err := cli.ShowAppHelp(c); err != nil {
 97			panic(err)
 98		}
 99		return nil, tracerr.Wrap(err)
100	}
101	return cfg, nil
102}
103
104func getConfig(c *cli.Context) (*Config, error) {
105	var cfg Config
106	mode := c.String(flagMode)
107	nodeCfgPath := c.String(flagCfg)
108	if nodeCfgPath == "" {
109		return nil, tracerr.Wrap(fmt.Errorf("required flag \"%v\" not set", flagCfg))
110	}
111	var err error
112	switch mode {
113	case modeSync:
114		cfg.mode = node.ModeSynchronizer
115		cfg.node, err = config.LoadNode(nodeCfgPath)
116		if err != nil {
117			return nil, tracerr.Wrap(err)
118		}
119	case modeCoord:
120		cfg.mode = node.ModeCoordinator
121		cfg.node, err = config.LoadCoordinator(nodeCfgPath)
122		if err != nil {
123			return nil, tracerr.Wrap(err)
124		}
125	default:
126		return nil, tracerr.Wrap(fmt.Errorf("invalid mode \"%v\"", mode))
127	}
128
129	return &cfg, nil
130}
131
132func main() {
133	app := cli.NewApp()
134	app.Name = "hermez-node"
135	app.Version = "0.1.0-alpha"
136	app.Flags = []cli.Flag{
137		&cli.StringFlag{
138			Name:     flagMode,
139			Usage:    fmt.Sprintf("Set node `MODE` (can be \"%v\" or \"%v\")", modeSync, modeCoord),
140			Required: true,
141		},
142		&cli.StringFlag{
143			Name:     flagCfg,
144			Usage:    "Node configuration `FILE`",
145			Required: true,
146		},
147	}
148
149	app.Commands = []*cli.Command{
150		{
151			Name:    "importkey",
152			Aliases: []string{},
153			Usage:   "Import ethereum private key",
154			Action:  cmdImportKey,
155			Flags: []cli.Flag{
156				&cli.StringFlag{
157					Name:     flagSK,
158					Usage:    "ethereum `PRIVATE_KEY` in hex",
159					Required: true,
160				}},
161		},
162		{
163			Name:    "run",
164			Aliases: []string{},
165			Usage:   "Run the hermez-node in the indicated mode",
166			Action:  cmdRun,
167		},
168	}
169
170	err := app.Run(os.Args)
171	if err != nil {
172		fmt.Printf("\nError: %v\n", tracerr.Sprint(err))
173		os.Exit(1)
174	}
175}