github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/cmd/geth/main.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 // geth is the official command-line client for Sberex. 13 package main 14 15 import ( 16 "fmt" 17 "os" 18 "runtime" 19 "sort" 20 "strings" 21 "time" 22 23 "github.com/Sberex/go-sberex/accounts" 24 "github.com/Sberex/go-sberex/accounts/keystore" 25 "github.com/Sberex/go-sberex/cmd/utils" 26 "github.com/Sberex/go-sberex/common" 27 "github.com/Sberex/go-sberex/console" 28 "github.com/Sberex/go-sberex/eth" 29 "github.com/Sberex/go-sberex/ethclient" 30 "github.com/Sberex/go-sberex/internal/debug" 31 "github.com/Sberex/go-sberex/log" 32 "github.com/Sberex/go-sberex/metrics" 33 "github.com/Sberex/go-sberex/node" 34 "gopkg.in/urfave/cli.v1" 35 ) 36 37 const ( 38 clientIdentifier = "geth" // Client identifier to advertise over the network 39 ) 40 41 var ( 42 // Git SHA1 commit hash of the release (set via linker flags) 43 gitCommit = "" 44 // Sberex address of the Geth release oracle. 45 relOracle = common.HexToAddress("0xfa7b9770ca4cb04296cac84f37736d4041251cdf") 46 // The app that holds all commands and flags. 47 app = utils.NewApp(gitCommit, "the go-sberex command line interface") 48 // flags that configure the node 49 nodeFlags = []cli.Flag{ 50 utils.IdentityFlag, 51 utils.UnlockedAccountFlag, 52 utils.PasswordFileFlag, 53 utils.BootnodesFlag, 54 utils.BootnodesV4Flag, 55 utils.BootnodesV5Flag, 56 utils.DataDirFlag, 57 utils.KeyStoreDirFlag, 58 utils.NoUSBFlag, 59 utils.DashboardEnabledFlag, 60 utils.DashboardAddrFlag, 61 utils.DashboardPortFlag, 62 utils.DashboardRefreshFlag, 63 utils.DashboardAssetsFlag, 64 utils.EthashCacheDirFlag, 65 utils.EthashCachesInMemoryFlag, 66 utils.EthashCachesOnDiskFlag, 67 utils.EthashDatasetDirFlag, 68 utils.EthashDatasetsInMemoryFlag, 69 utils.EthashDatasetsOnDiskFlag, 70 utils.TxPoolNoLocalsFlag, 71 utils.TxPoolJournalFlag, 72 utils.TxPoolRejournalFlag, 73 utils.TxPoolPriceLimitFlag, 74 utils.TxPoolPriceBumpFlag, 75 utils.TxPoolAccountSlotsFlag, 76 utils.TxPoolGlobalSlotsFlag, 77 utils.TxPoolAccountQueueFlag, 78 utils.TxPoolGlobalQueueFlag, 79 utils.TxPoolLifetimeFlag, 80 utils.FastSyncFlag, 81 utils.LightModeFlag, 82 utils.SyncModeFlag, 83 utils.GCModeFlag, 84 utils.LightServFlag, 85 utils.LightPeersFlag, 86 utils.LightKDFFlag, 87 utils.CacheFlag, 88 utils.CacheDatabaseFlag, 89 utils.CacheGCFlag, 90 utils.TrieCacheGenFlag, 91 utils.ListenPortFlag, 92 utils.MaxPeersFlag, 93 utils.MaxPendingPeersFlag, 94 utils.EtherbaseFlag, 95 utils.GasPriceFlag, 96 utils.MinerThreadsFlag, 97 utils.MiningEnabledFlag, 98 utils.TargetGasLimitFlag, 99 utils.NATFlag, 100 utils.NoDiscoverFlag, 101 utils.DiscoveryV5Flag, 102 utils.NetrestrictFlag, 103 utils.NodeKeyFileFlag, 104 utils.NodeKeyHexFlag, 105 utils.DeveloperFlag, 106 utils.DeveloperPeriodFlag, 107 utils.TestnetFlag, 108 utils.RinkebyFlag, 109 utils.VMEnableDebugFlag, 110 utils.NetworkIdFlag, 111 utils.RPCCORSDomainFlag, 112 utils.RPCVirtualHostsFlag, 113 utils.EthStatsURLFlag, 114 utils.MetricsEnabledFlag, 115 utils.FakePoWFlag, 116 utils.NoCompactionFlag, 117 utils.GpoBlocksFlag, 118 utils.GpoPercentileFlag, 119 utils.ExtraDataFlag, 120 configFileFlag, 121 } 122 123 rpcFlags = []cli.Flag{ 124 utils.RPCEnabledFlag, 125 utils.RPCListenAddrFlag, 126 utils.RPCPortFlag, 127 utils.RPCApiFlag, 128 utils.WSEnabledFlag, 129 utils.WSListenAddrFlag, 130 utils.WSPortFlag, 131 utils.WSApiFlag, 132 utils.WSAllowedOriginsFlag, 133 utils.IPCDisabledFlag, 134 utils.IPCPathFlag, 135 } 136 137 whisperFlags = []cli.Flag{ 138 utils.WhisperEnabledFlag, 139 utils.WhisperMaxMessageSizeFlag, 140 utils.WhisperMinPOWFlag, 141 } 142 ) 143 144 func init() { 145 // Initialize the CLI app and start Geth 146 app.Action = geth 147 app.HideVersion = true // we have a command to print the version 148 app.Copyright = "Copyright 2018 The go-sberex Authors" 149 app.Commands = []cli.Command{ 150 // See chaincmd.go: 151 initCommand, 152 importCommand, 153 exportCommand, 154 copydbCommand, 155 removedbCommand, 156 dumpCommand, 157 // See monitorcmd.go: 158 monitorCommand, 159 // See accountcmd.go: 160 accountCommand, 161 walletCommand, 162 // See consolecmd.go: 163 consoleCommand, 164 attachCommand, 165 javascriptCommand, 166 // See misccmd.go: 167 makecacheCommand, 168 makedagCommand, 169 versionCommand, 170 bugCommand, 171 licenseCommand, 172 // See config.go 173 dumpConfigCommand, 174 } 175 sort.Sort(cli.CommandsByName(app.Commands)) 176 177 app.Flags = append(app.Flags, nodeFlags...) 178 app.Flags = append(app.Flags, rpcFlags...) 179 app.Flags = append(app.Flags, consoleFlags...) 180 app.Flags = append(app.Flags, debug.Flags...) 181 app.Flags = append(app.Flags, whisperFlags...) 182 183 app.Before = func(ctx *cli.Context) error { 184 runtime.GOMAXPROCS(runtime.NumCPU()) 185 if err := debug.Setup(ctx); err != nil { 186 return err 187 } 188 // Start system runtime metrics collection 189 go metrics.CollectProcessMetrics(3 * time.Second) 190 191 utils.SetupNetwork(ctx) 192 return nil 193 } 194 195 app.After = func(ctx *cli.Context) error { 196 debug.Exit() 197 console.Stdin.Close() // Resets terminal mode. 198 return nil 199 } 200 } 201 202 func main() { 203 if err := app.Run(os.Args); err != nil { 204 fmt.Fprintln(os.Stderr, err) 205 os.Exit(1) 206 } 207 } 208 209 // geth is the main entry point into the system if no special subcommand is ran. 210 // It creates a default node based on the command line arguments and runs it in 211 // blocking mode, waiting for it to be shut down. 212 func geth(ctx *cli.Context) error { 213 node := makeFullNode(ctx) 214 startNode(ctx, node) 215 node.Wait() 216 return nil 217 } 218 219 // startNode boots up the system node and all registered protocols, after which 220 // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the 221 // miner. 222 func startNode(ctx *cli.Context, stack *node.Node) { 223 // Start up the node itself 224 utils.StartNode(stack) 225 226 // Unlock any account specifically requested 227 ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) 228 229 passwords := utils.MakePasswordList(ctx) 230 unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") 231 for i, account := range unlocks { 232 if trimmed := strings.TrimSpace(account); trimmed != "" { 233 unlockAccount(ctx, ks, trimmed, i, passwords) 234 } 235 } 236 // Register wallet event handlers to open and auto-derive wallets 237 events := make(chan accounts.WalletEvent, 16) 238 stack.AccountManager().Subscribe(events) 239 240 go func() { 241 // Create an chain state reader for self-derivation 242 rpcClient, err := stack.Attach() 243 if err != nil { 244 utils.Fatalf("Failed to attach to self: %v", err) 245 } 246 stateReader := ethclient.NewClient(rpcClient) 247 248 // Open any wallets already attached 249 for _, wallet := range stack.AccountManager().Wallets() { 250 if err := wallet.Open(""); err != nil { 251 log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) 252 } 253 } 254 // Listen for wallet event till termination 255 for event := range events { 256 switch event.Kind { 257 case accounts.WalletArrived: 258 if err := event.Wallet.Open(""); err != nil { 259 log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) 260 } 261 case accounts.WalletOpened: 262 status, _ := event.Wallet.Status() 263 log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) 264 265 if event.Wallet.URL().Scheme == "ledger" { 266 event.Wallet.SelfDerive(accounts.DefaultLedgerBaseDerivationPath, stateReader) 267 } else { 268 event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) 269 } 270 271 case accounts.WalletDropped: 272 log.Info("Old wallet dropped", "url", event.Wallet.URL()) 273 event.Wallet.Close() 274 } 275 } 276 }() 277 // Start auxiliary services if enabled 278 if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { 279 // Mining only makes sense if a full Sberex node is running 280 if ctx.GlobalBool(utils.LightModeFlag.Name) || ctx.GlobalString(utils.SyncModeFlag.Name) == "light" { 281 utils.Fatalf("Light clients do not support mining") 282 } 283 var sberex *eth.Sberex 284 if err := stack.Service(&sberex); err != nil { 285 utils.Fatalf("Sberex service not running: %v", err) 286 } 287 // Use a reduced number of threads if requested 288 if threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name); threads > 0 { 289 type threaded interface { 290 SetThreads(threads int) 291 } 292 if th, ok := sberex.Engine().(threaded); ok { 293 th.SetThreads(threads) 294 } 295 } 296 // Set the gas price to the limits from the CLI and start mining 297 sberex.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) 298 if err := sberex.StartMining(true); err != nil { 299 utils.Fatalf("Failed to start mining: %v", err) 300 } 301 } 302 }