afe0b65405
This removes the dashboard project. The dashboard was an experimental browser UI for geth which displayed metrics and chain information in real time. We are removing it because it has marginal utility and nobody on the team can maintain it. Removing the dashboard removes a lot of dependency code and shaves 6 MB off the geth binary size.
209 lines
5.9 KiB
Go
209 lines
5.9 KiB
Go
// Copyright 2017 The go-ethereum Authors
|
|
// This file is part of go-ethereum.
|
|
//
|
|
// go-ethereum is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// go-ethereum is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"os"
|
|
"reflect"
|
|
"unicode"
|
|
|
|
cli "gopkg.in/urfave/cli.v1"
|
|
|
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
|
"github.com/ethereum/go-ethereum/eth"
|
|
"github.com/ethereum/go-ethereum/node"
|
|
"github.com/ethereum/go-ethereum/params"
|
|
whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
|
|
"github.com/naoina/toml"
|
|
)
|
|
|
|
var (
|
|
dumpConfigCommand = cli.Command{
|
|
Action: utils.MigrateFlags(dumpConfig),
|
|
Name: "dumpconfig",
|
|
Usage: "Show configuration values",
|
|
ArgsUsage: "",
|
|
Flags: append(append(nodeFlags, rpcFlags...), whisperFlags...),
|
|
Category: "MISCELLANEOUS COMMANDS",
|
|
Description: `The dumpconfig command shows configuration values.`,
|
|
}
|
|
|
|
configFileFlag = cli.StringFlag{
|
|
Name: "config",
|
|
Usage: "TOML configuration file",
|
|
}
|
|
)
|
|
|
|
// These settings ensure that TOML keys use the same names as Go struct fields.
|
|
var tomlSettings = toml.Config{
|
|
NormFieldName: func(rt reflect.Type, key string) string {
|
|
return key
|
|
},
|
|
FieldToKey: func(rt reflect.Type, field string) string {
|
|
return field
|
|
},
|
|
MissingField: func(rt reflect.Type, field string) error {
|
|
link := ""
|
|
if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" {
|
|
link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name())
|
|
}
|
|
return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link)
|
|
},
|
|
}
|
|
|
|
type ethstatsConfig struct {
|
|
URL string `toml:",omitempty"`
|
|
}
|
|
|
|
type gethConfig struct {
|
|
Eth eth.Config
|
|
Shh whisper.Config
|
|
Node node.Config
|
|
Ethstats ethstatsConfig
|
|
}
|
|
|
|
func loadConfig(file string, cfg *gethConfig) error {
|
|
f, err := os.Open(file)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg)
|
|
// Add file name to errors that have a line number.
|
|
if _, ok := err.(*toml.LineError); ok {
|
|
err = errors.New(file + ", " + err.Error())
|
|
}
|
|
return err
|
|
}
|
|
|
|
func defaultNodeConfig() node.Config {
|
|
cfg := node.DefaultConfig
|
|
cfg.Name = clientIdentifier
|
|
cfg.Version = params.VersionWithCommit(gitCommit, gitDate)
|
|
cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh")
|
|
cfg.WSModules = append(cfg.WSModules, "eth", "shh")
|
|
cfg.IPCPath = "geth.ipc"
|
|
return cfg
|
|
}
|
|
|
|
func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
|
|
// Load defaults.
|
|
cfg := gethConfig{
|
|
Eth: eth.DefaultConfig,
|
|
Shh: whisper.DefaultConfig,
|
|
Node: defaultNodeConfig(),
|
|
}
|
|
|
|
// Load config file.
|
|
if file := ctx.GlobalString(configFileFlag.Name); file != "" {
|
|
if err := loadConfig(file, &cfg); err != nil {
|
|
utils.Fatalf("%v", err)
|
|
}
|
|
}
|
|
|
|
// Apply flags.
|
|
utils.SetNodeConfig(ctx, &cfg.Node)
|
|
stack, err := node.New(&cfg.Node)
|
|
if err != nil {
|
|
utils.Fatalf("Failed to create the protocol stack: %v", err)
|
|
}
|
|
utils.SetEthConfig(ctx, stack, &cfg.Eth)
|
|
if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) {
|
|
cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name)
|
|
}
|
|
utils.SetShhConfig(ctx, stack, &cfg.Shh)
|
|
|
|
return stack, cfg
|
|
}
|
|
|
|
// enableWhisper returns true in case one of the whisper flags is set.
|
|
func enableWhisper(ctx *cli.Context) bool {
|
|
for _, flag := range whisperFlags {
|
|
if ctx.GlobalIsSet(flag.GetName()) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func makeFullNode(ctx *cli.Context) *node.Node {
|
|
stack, cfg := makeConfigNode(ctx)
|
|
if ctx.GlobalIsSet(utils.OverrideIstanbulFlag.Name) {
|
|
cfg.Eth.OverrideIstanbul = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideIstanbulFlag.Name))
|
|
}
|
|
utils.RegisterEthService(stack, &cfg.Eth)
|
|
|
|
// Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode
|
|
shhEnabled := enableWhisper(ctx)
|
|
shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name)
|
|
if shhEnabled || shhAutoEnabled {
|
|
if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) {
|
|
cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name))
|
|
}
|
|
if ctx.GlobalIsSet(utils.WhisperMinPOWFlag.Name) {
|
|
cfg.Shh.MinimumAcceptedPOW = ctx.Float64(utils.WhisperMinPOWFlag.Name)
|
|
}
|
|
if ctx.GlobalIsSet(utils.WhisperRestrictConnectionBetweenLightClientsFlag.Name) {
|
|
cfg.Shh.RestrictConnectionBetweenLightClients = true
|
|
}
|
|
utils.RegisterShhService(stack, &cfg.Shh)
|
|
}
|
|
// Configure GraphQL if requested
|
|
if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) {
|
|
utils.RegisterGraphQLService(stack, cfg.Node.GraphQLEndpoint(), cfg.Node.GraphQLCors, cfg.Node.GraphQLVirtualHosts, cfg.Node.HTTPTimeouts)
|
|
}
|
|
// Add the Ethereum Stats daemon if requested.
|
|
if cfg.Ethstats.URL != "" {
|
|
utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)
|
|
}
|
|
return stack
|
|
}
|
|
|
|
// dumpConfig is the dumpconfig command.
|
|
func dumpConfig(ctx *cli.Context) error {
|
|
_, cfg := makeConfigNode(ctx)
|
|
comment := ""
|
|
|
|
if cfg.Eth.Genesis != nil {
|
|
cfg.Eth.Genesis = nil
|
|
comment += "# Note: this config doesn't contain the genesis block.\n\n"
|
|
}
|
|
|
|
out, err := tomlSettings.Marshal(&cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dump := os.Stdout
|
|
if ctx.NArg() > 0 {
|
|
dump, err = os.OpenFile(ctx.Args().Get(0), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer dump.Close()
|
|
}
|
|
dump.WriteString(comment)
|
|
dump.Write(out)
|
|
|
|
return nil
|
|
}
|