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