github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/cmd/quickchain/config.go (about) 1 2 package main 3 4 import ( 5 "bufio" 6 "errors" 7 "fmt" 8 "io" 9 "os" 10 "reflect" 11 "unicode" 12 13 cli "gopkg.in/urfave/cli.v1" 14 15 "github.com/quickchainproject/quickchain/cmd/utils" 16 "github.com/quickchainproject/quickchain/dashboard" 17 "github.com/quickchainproject/quickchain/qct" 18 "github.com/quickchainproject/quickchain/node" 19 "github.com/quickchainproject/quickchain/params" 20 "github.com/naoina/toml" 21 ) 22 23 var ( 24 dumpConfigCommand = cli.Command{ 25 Action: utils.MigrateFlags(dumpConfig), 26 Name: "dumpconfig", 27 Usage: "Show configuration values", 28 ArgsUsage: "", 29 Flags: append(nodeFlags, rpcFlags...), 30 Category: "MISCELLANEOUS COMMANDS", 31 Description: `The dumpconfig command shows configuration values.`, 32 } 33 34 configFileFlag = cli.StringFlag{ 35 Name: "config", 36 Usage: "TOML configuration file", 37 } 38 ) 39 40 // These settings ensure that TOML keys use the same names as Go struct fields. 41 var tomlSettings = toml.Config{ 42 NormFieldName: func(rt reflect.Type, key string) string { 43 return key 44 }, 45 FieldToKey: func(rt reflect.Type, field string) string { 46 return field 47 }, 48 MissingField: func(rt reflect.Type, field string) error { 49 link := "" 50 if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" { 51 link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name()) 52 } 53 return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link) 54 }, 55 } 56 57 type ethstatsConfig struct { 58 URL string `toml:",omitempty"` 59 } 60 61 type gethConfig struct { 62 Eth qct.Config 63 Node node.Config 64 Ethstats ethstatsConfig 65 Dashboard dashboard.Config 66 } 67 68 func loadConfig(file string, cfg *gethConfig) error { 69 f, err := os.Open(file) 70 if err != nil { 71 return err 72 } 73 defer f.Close() 74 75 err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg) 76 // Add file name to errors that have a line number. 77 if _, ok := err.(*toml.LineError); ok { 78 err = errors.New(file + ", " + err.Error()) 79 } 80 return err 81 } 82 83 func defaultNodeConfig() node.Config { 84 cfg := node.DefaultConfig 85 cfg.Name = clientIdentifier 86 cfg.Version = params.VersionWithCommit(gitCommit) 87 cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh") 88 cfg.WSModules = append(cfg.WSModules, "eth", "shh") 89 cfg.IPCPath = "qct.ipc" 90 return cfg 91 } 92 93 func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { 94 // Load defaults. 95 cfg := gethConfig{ 96 Eth: qct.DefaultConfig, 97 Node: defaultNodeConfig(), 98 Dashboard: dashboard.DefaultConfig, 99 } 100 101 // Load config file. 102 if file := ctx.GlobalString(configFileFlag.Name); file != "" { 103 if err := loadConfig(file, &cfg); err != nil { 104 utils.Fatalf("%v", err) 105 } 106 } 107 108 // Apply flags. 109 utils.SetNodeConfig(ctx, &cfg.Node) 110 stack, err := node.New(&cfg.Node) 111 if err != nil { 112 utils.Fatalf("Failed to create the protocol stack: %v", err) 113 } 114 utils.SetEthConfig(ctx, stack, &cfg.Eth) 115 if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) { 116 cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name) 117 } 118 119 utils.SetDashboardConfig(ctx, &cfg.Dashboard) 120 121 return stack, cfg 122 } 123 124 func makeFullNode(ctx *cli.Context) *node.Node { 125 stack, cfg := makeConfigNode(ctx) 126 127 utils.RegisterEthService(stack, &cfg.Eth) 128 129 if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { 130 utils.RegisterDashboardService(stack, &cfg.Dashboard, gitCommit) 131 } 132 133 // Add the Ethereum Stats daemon if requested. 134 if cfg.Ethstats.URL != "" { 135 utils.RegisterEthStatsService(stack, cfg.Ethstats.URL) 136 } 137 return stack 138 } 139 140 // dumpConfig is the dumpconfig command. 141 func dumpConfig(ctx *cli.Context) error { 142 _, cfg := makeConfigNode(ctx) 143 comment := "" 144 145 if cfg.Eth.Genesis != nil { 146 cfg.Eth.Genesis = nil 147 comment += "# Note: this config doesn't contain the genesis block.\n\n" 148 } 149 150 out, err := tomlSettings.Marshal(&cfg) 151 if err != nil { 152 return err 153 } 154 io.WriteString(os.Stdout, comment) 155 os.Stdout.Write(out) 156 return nil 157 }