github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/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 "math" 23 "os" 24 godebug "runtime/debug" 25 "sort" 26 "strconv" 27 "strings" 28 "time" 29 30 "github.com/elastic/gosigar" 31 "github.com/ethereum/go-ethereum/accounts" 32 "github.com/ethereum/go-ethereum/accounts/keystore" 33 "github.com/ethereum/go-ethereum/cmd/utils" 34 "github.com/ethereum/go-ethereum/console" 35 "github.com/ethereum/go-ethereum/contract_comm/blockchain_parameters" 36 "github.com/ethereum/go-ethereum/eth" 37 "github.com/ethereum/go-ethereum/ethclient" 38 "github.com/ethereum/go-ethereum/internal/debug" 39 "github.com/ethereum/go-ethereum/log" 40 "github.com/ethereum/go-ethereum/metrics" 41 "github.com/ethereum/go-ethereum/node" 42 cli "gopkg.in/urfave/cli.v1" 43 ) 44 45 const ( 46 clientIdentifier = "geth" // Client identifier to advertise over the network 47 ) 48 49 var ( 50 // Git SHA1 commit hash of the release (set via linker flags) 51 gitCommit = "" 52 // The app that holds all commands and flags. 53 app = utils.NewApp(gitCommit, "the go-ethereum command line interface") 54 // flags that configure the node 55 nodeFlags = []cli.Flag{ 56 utils.IdentityFlag, 57 utils.UnlockedAccountFlag, 58 utils.PasswordFileFlag, 59 utils.BootnodesFlag, 60 utils.BootnodesV4Flag, 61 utils.BootnodesV5Flag, 62 utils.DataDirFlag, 63 utils.KeyStoreDirFlag, 64 utils.NoUSBFlag, 65 utils.DashboardEnabledFlag, 66 utils.DashboardAddrFlag, 67 utils.DashboardPortFlag, 68 utils.DashboardRefreshFlag, 69 utils.EthashCacheDirFlag, 70 utils.EthashCachesInMemoryFlag, 71 utils.EthashCachesOnDiskFlag, 72 utils.EthashDatasetDirFlag, 73 utils.EthashDatasetsInMemoryFlag, 74 utils.EthashDatasetsOnDiskFlag, 75 utils.TxPoolLocalsFlag, 76 utils.TxPoolNoLocalsFlag, 77 utils.TxPoolJournalFlag, 78 utils.TxPoolRejournalFlag, 79 utils.TxPoolPriceLimitFlag, 80 utils.TxPoolPriceBumpFlag, 81 utils.TxPoolAccountSlotsFlag, 82 utils.TxPoolGlobalSlotsFlag, 83 utils.TxPoolAccountQueueFlag, 84 utils.TxPoolGlobalQueueFlag, 85 utils.TxPoolLifetimeFlag, 86 utils.SyncModeFlag, 87 utils.GCModeFlag, 88 utils.LightServFlag, 89 utils.LightPeersFlag, 90 utils.LightKDFFlag, 91 utils.WhitelistFlag, 92 utils.EtherbaseFlag, 93 utils.BLSbaseFlag, 94 utils.CacheFlag, 95 utils.CacheDatabaseFlag, 96 utils.CacheTrieFlag, 97 utils.CacheGCFlag, 98 utils.TrieCacheGenFlag, 99 utils.ListenPortFlag, 100 utils.MaxPeersFlag, 101 utils.MaxPendingPeersFlag, 102 utils.MiningEnabledFlag, 103 utils.MinerThreadsFlag, 104 utils.MinerLegacyThreadsFlag, 105 utils.MinerNotifyFlag, 106 utils.MinerGasTargetFlag, 107 utils.MinerLegacyGasTargetFlag, 108 utils.MinerGasLimitFlag, 109 utils.MinerGasPriceFlag, 110 utils.MinerLegacyGasPriceFlag, 111 utils.MinerExtraDataFlag, 112 utils.MinerLegacyExtraDataFlag, 113 utils.MinerRecommitIntervalFlag, 114 utils.MinerNoVerfiyFlag, 115 utils.NATFlag, 116 utils.NoDiscoverFlag, 117 utils.DiscoveryV5Flag, 118 utils.NetrestrictFlag, 119 utils.NodeKeyFileFlag, 120 utils.NodeKeyHexFlag, 121 utils.DeveloperFlag, 122 utils.DeveloperPeriodFlag, 123 utils.TestnetFlag, 124 utils.RinkebyFlag, 125 utils.GoerliFlag, 126 utils.OttomanFlag, 127 utils.VMEnableDebugFlag, 128 utils.NetworkIdFlag, 129 utils.ConstantinopleOverrideFlag, 130 utils.RPCCORSDomainFlag, 131 utils.RPCVirtualHostsFlag, 132 utils.EthStatsURLFlag, 133 utils.MetricsEnabledFlag, 134 utils.FakePoWFlag, 135 utils.NoCompactionFlag, 136 utils.EWASMInterpreterFlag, 137 utils.EVMInterpreterFlag, 138 configFileFlag, 139 utils.IstanbulRequestTimeoutFlag, 140 utils.IstanbulBlockPeriodFlag, 141 utils.IstanbulProposerPolicyFlag, 142 utils.IstanbulLookbackWindowFlag, 143 utils.PingIPFromPacketFlag, 144 utils.UseInMemoryDiscoverTableFlag, 145 utils.VersionCheckFlag, 146 utils.ProxyFlag, 147 utils.ProxyInternalFacingEndpointFlag, 148 utils.ProxiedValidatorAddressFlag, 149 utils.ProxiedFlag, 150 utils.ProxyEnodeURLPairFlag, 151 utils.ProxyAllowPrivateIPFlag, 152 } 153 154 rpcFlags = []cli.Flag{ 155 utils.RPCEnabledFlag, 156 utils.RPCListenAddrFlag, 157 utils.RPCPortFlag, 158 utils.RPCApiFlag, 159 utils.WSEnabledFlag, 160 utils.WSListenAddrFlag, 161 utils.WSPortFlag, 162 utils.WSApiFlag, 163 utils.WSAllowedOriginsFlag, 164 utils.IPCDisabledFlag, 165 utils.IPCPathFlag, 166 } 167 168 whisperFlags = []cli.Flag{ 169 utils.WhisperEnabledFlag, 170 utils.WhisperMaxMessageSizeFlag, 171 utils.WhisperMinPOWFlag, 172 utils.WhisperRestrictConnectionBetweenLightClientsFlag, 173 } 174 175 metricsFlags = []cli.Flag{ 176 utils.MetricsEnableInfluxDBFlag, 177 utils.MetricsInfluxDBEndpointFlag, 178 utils.MetricsInfluxDBDatabaseFlag, 179 utils.MetricsInfluxDBUsernameFlag, 180 utils.MetricsInfluxDBPasswordFlag, 181 utils.MetricsInfluxDBTagsFlag, 182 } 183 ) 184 185 func init() { 186 // Initialize the CLI app and start Geth 187 app.Action = geth 188 app.HideVersion = true // we have a command to print the version 189 app.Copyright = "Copyright 2013-2018 The go-ethereum Authors" 190 app.Commands = []cli.Command{ 191 // See chaincmd.go: 192 initCommand, 193 importCommand, 194 exportCommand, 195 importPreimagesCommand, 196 exportPreimagesCommand, 197 copydbCommand, 198 removedbCommand, 199 dumpCommand, 200 // See monitorcmd.go: 201 monitorCommand, 202 // See accountcmd.go: 203 accountCommand, 204 walletCommand, 205 // See consolecmd.go: 206 consoleCommand, 207 attachCommand, 208 javascriptCommand, 209 // See misccmd.go: 210 makecacheCommand, 211 makedagCommand, 212 versionCommand, 213 bugCommand, 214 licenseCommand, 215 // See config.go 216 dumpConfigCommand, 217 } 218 sort.Sort(cli.CommandsByName(app.Commands)) 219 220 app.Flags = append(app.Flags, nodeFlags...) 221 app.Flags = append(app.Flags, rpcFlags...) 222 app.Flags = append(app.Flags, consoleFlags...) 223 app.Flags = append(app.Flags, debug.Flags...) 224 app.Flags = append(app.Flags, whisperFlags...) 225 app.Flags = append(app.Flags, metricsFlags...) 226 227 app.Before = func(ctx *cli.Context) error { 228 logdir := "" 229 if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) { 230 logdir = (&node.Config{DataDir: utils.MakeDataDir(ctx)}).ResolvePath("logs") 231 } 232 if err := debug.Setup(ctx, logdir); err != nil { 233 return err 234 } 235 // Cap the cache allowance and tune the garbage collector 236 var mem gosigar.Mem 237 if err := mem.Get(); err == nil { 238 allowance := int(mem.Total / 1024 / 1024 / 3) 239 if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance { 240 log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) 241 ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance)) 242 } 243 } 244 // Ensure Go's GC ignores the database cache for trigger percentage 245 cache := ctx.GlobalInt(utils.CacheFlag.Name) 246 gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) 247 248 log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) 249 godebug.SetGCPercent(int(gogc)) 250 251 // Start metrics export if enabled 252 utils.SetupMetrics(ctx) 253 254 // Start system runtime metrics collection 255 go metrics.CollectProcessMetrics(3 * time.Second) 256 257 return nil 258 } 259 260 app.After = func(ctx *cli.Context) error { 261 debug.Exit() 262 console.Stdin.Close() // Resets terminal mode. 263 return nil 264 } 265 } 266 267 func main() { 268 if err := app.Run(os.Args); err != nil { 269 fmt.Fprintln(os.Stderr, err) 270 os.Exit(1) 271 } 272 } 273 274 // geth is the main entry point into the system if no special subcommand is ran. 275 // It creates a default node based on the command line arguments and runs it in 276 // blocking mode, waiting for it to be shut down. 277 func geth(ctx *cli.Context) error { 278 if args := ctx.Args(); len(args) > 0 { 279 return fmt.Errorf("invalid command: %q", args[0]) 280 } 281 node := makeFullNode(ctx) 282 startNode(ctx, node) 283 node.Wait() 284 return nil 285 } 286 287 // startNode boots up the system node and all registered protocols, after which 288 // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the 289 // miner. 290 func startNode(ctx *cli.Context, stack *node.Node) { 291 debug.Memsize.Add("node", stack) 292 293 // Start up the node itself 294 utils.StartNode(stack) 295 296 // Unlock any account specifically requested 297 ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) 298 299 passwords := utils.MakePasswordList(ctx) 300 unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") 301 for i, account := range unlocks { 302 if trimmed := strings.TrimSpace(account); trimmed != "" { 303 unlockAccount(ctx, ks, trimmed, i, passwords) 304 } 305 } 306 // Register wallet event handlers to open and auto-derive wallets 307 events := make(chan accounts.WalletEvent, 16) 308 stack.AccountManager().Subscribe(events) 309 310 go func() { 311 // Create a chain state reader for self-derivation 312 rpcClient, err := stack.Attach() 313 if err != nil { 314 utils.Fatalf("Failed to attach to self: %v", err) 315 } 316 stateReader := ethclient.NewClient(rpcClient) 317 318 // Open any wallets already attached 319 for _, wallet := range stack.AccountManager().Wallets() { 320 if err := wallet.Open(""); err != nil { 321 log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) 322 } 323 } 324 // Listen for wallet event till termination 325 for event := range events { 326 switch event.Kind { 327 case accounts.WalletArrived: 328 if err := event.Wallet.Open(""); err != nil { 329 log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) 330 } 331 case accounts.WalletOpened: 332 status, _ := event.Wallet.Status() 333 log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) 334 335 derivationPath := accounts.DefaultBaseDerivationPath 336 if event.Wallet.URL().Scheme == "ledger" { 337 derivationPath = accounts.DefaultLedgerBaseDerivationPath 338 } 339 event.Wallet.SelfDerive(derivationPath, stateReader) 340 341 case accounts.WalletDropped: 342 log.Info("Old wallet dropped", "url", event.Wallet.URL()) 343 event.Wallet.Close() 344 } 345 } 346 }() 347 348 // Miners and proxies only makes sense if a full node is running 349 if ctx.GlobalBool(utils.ProxyFlag.Name) || ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { 350 if ctx.GlobalString(utils.SyncModeFlag.Name) != "fast" && ctx.GlobalString(utils.SyncModeFlag.Name) != "full" { 351 utils.Fatalf("Miners and Proxies must be run as a full node") 352 } 353 } 354 355 // Start auxiliary services if enabled 356 if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) { 357 if ctx.GlobalBool(utils.ProxyFlag.Name) { 358 utils.Fatalf("Proxies can't mine") 359 } 360 361 var ethereum *eth.Ethereum 362 if err := stack.Service(ðereum); err != nil { 363 utils.Fatalf("Ethereum service not running: %v", err) 364 } 365 // Set the gas price to the limits from the CLI and start mining 366 gasprice := utils.GlobalBig(ctx, utils.MinerLegacyGasPriceFlag.Name) 367 if ctx.IsSet(utils.MinerGasPriceFlag.Name) { 368 gasprice = utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name) 369 } 370 ethereum.TxPool().SetGasPrice(gasprice) 371 372 threads := ctx.GlobalInt(utils.MinerLegacyThreadsFlag.Name) 373 if ctx.GlobalIsSet(utils.MinerThreadsFlag.Name) { 374 threads = ctx.GlobalInt(utils.MinerThreadsFlag.Name) 375 } 376 if err := ethereum.StartMining(threads); err != nil { 377 utils.Fatalf("Failed to start mining: %v", err) 378 } 379 } 380 if !ctx.GlobalBool(utils.VersionCheckFlag.Name) { 381 blockchain_parameters.SpawnCheck() 382 } 383 }