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