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