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