github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/cmd/gvnt/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 // gvnt is the official command-line client for VNT. 18 package main 19 20 import ( 21 "fmt" 22 "math" 23 "os" 24 "runtime" 25 godebug "runtime/debug" 26 "sort" 27 "strconv" 28 "strings" 29 "time" 30 31 "github.com/elastic/gosigar" 32 "github.com/vntchain/go-vnt/accounts" 33 "github.com/vntchain/go-vnt/accounts/keystore" 34 "github.com/vntchain/go-vnt/cmd/utils" 35 "github.com/vntchain/go-vnt/console" 36 "github.com/vntchain/go-vnt/internal/debug" 37 "github.com/vntchain/go-vnt/log" 38 "github.com/vntchain/go-vnt/metrics" 39 "github.com/vntchain/go-vnt/node" 40 "github.com/vntchain/go-vnt/vnt" 41 "github.com/vntchain/go-vnt/vntclient" 42 cli "gopkg.in/urfave/cli.v1" 43 ) 44 45 const ( 46 clientIdentifier = "gvnt" // 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-vnt command line interface") 54 // flags that configure the node 55 nodeFlags = []cli.Flag{ 56 utils.IdentityFlag, 57 utils.UnlockedAccountFlag, 58 utils.PasswordFileFlag, 59 utils.FindNodeFlag, 60 utils.VNTBootnodeFlag, 61 utils.BootnodesFlag, 62 utils.BootnodesV4Flag, 63 utils.BootnodesV5Flag, 64 utils.DataDirFlag, 65 utils.KeyStoreDirFlag, 66 utils.TxPoolNoLocalsFlag, 67 utils.TxPoolJournalFlag, 68 utils.TxPoolRejournalFlag, 69 utils.TxPoolPriceLimitFlag, 70 utils.TxPoolPriceBumpFlag, 71 utils.TxPoolAccountSlotsFlag, 72 utils.TxPoolGlobalSlotsFlag, 73 utils.TxPoolAccountQueueFlag, 74 utils.TxPoolGlobalQueueFlag, 75 utils.TxPoolLifetimeFlag, 76 utils.SyncModeFlag, 77 utils.GCModeFlag, 78 utils.LightServFlag, 79 utils.LightPeersFlag, 80 utils.LightKDFFlag, 81 utils.CacheFlag, 82 utils.CacheDatabaseFlag, 83 utils.CacheGCFlag, 84 utils.TrieCacheGenFlag, 85 utils.ListenPortFlag, 86 utils.MaxPeersFlag, 87 utils.MaxPendingPeersFlag, 88 utils.CoinbaseFlag, 89 utils.GasPriceFlag, 90 utils.ProducingEnabledFlag, 91 utils.TargetGasLimitFlag, 92 utils.NATFlag, 93 utils.NoDiscoverFlag, 94 utils.DiscoveryV5Flag, 95 utils.NetrestrictFlag, 96 utils.NodeKeyFileFlag, 97 utils.NodeKeyHexFlag, 98 utils.VMEnableDebugFlag, 99 utils.NetworkIdFlag, 100 utils.RPCCORSDomainFlag, 101 utils.RPCVirtualHostsFlag, 102 utils.VntStatsURLFlag, 103 utils.MetricsEnabledFlag, 104 utils.NoCompactionFlag, 105 utils.GpoBlocksFlag, 106 utils.GpoPercentileFlag, 107 utils.ExtraDataFlag, 108 configFileFlag, 109 } 110 111 rpcFlags = []cli.Flag{ 112 utils.RPCEnabledFlag, 113 utils.RPCListenAddrFlag, 114 utils.RPCPortFlag, 115 utils.RPCApiFlag, 116 utils.WSEnabledFlag, 117 utils.WSListenAddrFlag, 118 utils.WSPortFlag, 119 utils.WSApiFlag, 120 utils.WSAllowedOriginsFlag, 121 utils.IPCDisabledFlag, 122 utils.IPCPathFlag, 123 } 124 125 whisperFlags = []cli.Flag{ 126 utils.WhisperEnabledFlag, 127 utils.WhisperMaxMessageSizeFlag, 128 utils.WhisperMinPOWFlag, 129 } 130 ) 131 132 func init() { 133 // Initialize the CLI app and start Gvnt 134 app.Action = gvnt 135 app.HideVersion = true // we have a command to print the version 136 app.Copyright = "Copyright 2018-2019 The go-vnt Authors" 137 app.Commands = []cli.Command{ 138 // See chaincmd.go: 139 initCommand, 140 importCommand, 141 exportCommand, 142 importPreimagesCommand, 143 exportPreimagesCommand, 144 copydbCommand, 145 removedbCommand, 146 dumpCommand, 147 // See monitorcmd.go: 148 monitorCommand, 149 // See accountcmd.go: 150 accountCommand, 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 // Cap the cache allowance and tune the garbage colelctor 176 var mem gosigar.Mem 177 if err := mem.Get(); err == nil { 178 allowance := int(mem.Total / 1024 / 1024 / 3) 179 if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance { 180 log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance) 181 ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance)) 182 } 183 } 184 // Ensure Go's GC ignores the database cache for trigger percentage 185 cache := ctx.GlobalInt(utils.CacheFlag.Name) 186 gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) 187 188 log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) 189 godebug.SetGCPercent(int(gogc)) 190 191 // Start system runtime metrics collection 192 go metrics.CollectProcessMetrics(3 * time.Second) 193 194 utils.SetupNetwork(ctx) 195 return nil 196 } 197 198 app.After = func(ctx *cli.Context) error { 199 debug.Exit() 200 console.Stdin.Close() // Resets terminal mode. 201 return nil 202 } 203 } 204 205 func main() { 206 if err := app.Run(os.Args); err != nil { 207 fmt.Fprintln(os.Stderr, err) 208 os.Exit(1) 209 } 210 } 211 212 // gvnt is the main entry point into the system if no special subcommand is ran. 213 // It creates a default node based on the command line arguments and runs it in 214 // blocking mode, waiting for it to be shut down. 215 func gvnt(ctx *cli.Context) error { 216 node := makeFullNode(ctx) 217 // go startVNTNode(node) 218 startNode(ctx, node) 219 node.Wait() 220 return nil 221 } 222 223 /* func startVNTNode(stack *node.Node) { 224 findnode := stack.Config().P2P.FindNode 225 bootnode := stack.Config().P2P.VNTBootnode 226 listenPort := stack.Config().P2P.ListenAddr[1:] 227 log.Info("startVNTNode()", "listenPort", listenPort) 228 ctx, cancel := context.WithCancel(context.Background()) 229 defer cancel() 230 231 vdht, host, err := vntp2p.ConstructDHT(ctx, vntp2p.MakePort(listenPort), nil) 232 if err != nil { 233 log.Error("startVNTNode()", "constructDHT error", err) 234 return 235 } 236 log.Info("startVNTNode()", "own nodeID", host.ID()) 237 238 h := &vntprotocol.HostWrapper{ 239 Host: host, 240 } 241 242 host.SetStreamHandler(vntp2p.PID, h.HandleStream) 243 bootnodeAddr, bootnodeID, err := vntp2p.GetAddr(bootnode) 244 if err != nil { 245 log.Error("startVNTNode()", "getAddr error", err) 246 return 247 } 248 host.Peerstore().AddAddrs(bootnodeID, []ma.Multiaddr{bootnodeAddr}, peerstore.PermanentAddrTTL) 249 vdht.Update(ctx, bootnodeID) 250 251 // test vntdb 252 //err = vdht.PutValue(ctx, "/v/hello2", []byte("helloworld2")) 253 //if err != nil { 254 // log.Error("startVNTNode()", "putValue error", err) 255 //} 256 257 contentKey := "/v/hello2" 258 log.Info("begin getValue now!") 259 best, err := vdht.GetValue(ctx, contentKey) 260 if err != nil { 261 log.Error("startVNTNode()", "getValue error", err) 262 } else { 263 log.Info("startVNTNode(), value gotten", "key", contentKey, "value", string(best)) 264 } 265 266 content := host.Peerstore().Peers() 267 for i := range content { 268 log.Info("startVNTNode()", "---> index", i, "PeerInfo", host.Peerstore().PeerInfo(content[i])) 269 } 270 271 //sayHelloToBootnode(ctx, host, bootnodeID) 272 273 if findnode != "" { 274 findNode(ctx, findnode, vdht) 275 } 276 277 select {} 278 } */ 279 280 /* func findNode(ctx context.Context, findnode string, vdht *dht.IpfsDHT) { 281 _, findnodeID, err := vntp2p.GetAddr(findnode) 282 if err != nil { 283 log.Error("findNode()", "getAddr error", err) 284 return 285 } 286 log.Info("findNode()", "findnodeID", findnodeID) 287 targetPeerInfo, err := vdht.FindPeer(ctx, findnodeID) 288 if err != nil { 289 log.Error("findNode()", "findPeer error", err) 290 return 291 } 292 log.Info("findNode()", "find peerid SUCCESS with info", targetPeerInfo) 293 } */ 294 295 /* func sayHelloToBootnode(ctx context.Context, host p2phost.Host, nodeID peer.ID) { 296 s, err := host.NewStream(ctx, nodeID, vntp2p.PID) 297 if err != nil { 298 log.Error("sayHelloToBootnode()", "NewStream Error", err) 299 return 300 } 301 302 rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s)) 303 304 // 封包,并且发送 305 msg, err := vntp2p.WritePackage(rw, 1, []byte("yoyoyo\n")) 306 if err != nil { 307 log.Error("sayHelloToBootnode()", "WritePackage Error", err) 308 return 309 } 310 311 log.Info("sayHelloToBootnode()", "msg", string(msg)) 312 _, err = rw.Write(msg) 313 if err != nil { 314 log.Error("sayHelloToBootnode()", "Write Error", err) 315 return 316 } 317 rw.WriteByte('\n') 318 rw.Flush() 319 } */ 320 321 // startNode boots up the system node and all registered protocols, after which 322 // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the 323 // producer. 324 func startNode(ctx *cli.Context, stack *node.Node) { 325 debug.Memsize.Add("node", stack) 326 327 // Start up the node itself 328 utils.StartNode(stack) 329 330 // Unlock any account specifically requested 331 ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) 332 passwords := utils.MakePasswordList(ctx) 333 unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",") 334 for i, account := range unlocks { 335 if trimmed := strings.TrimSpace(account); trimmed != "" { 336 unlockAccount(ctx, ks, trimmed, i, passwords) 337 } 338 } 339 // Register wallet event handlers to open and auto-derive wallets 340 events := make(chan accounts.WalletEvent, 16) 341 stack.AccountManager().Subscribe(events) 342 343 go func() { 344 // Create a chain state reader for self-derivation 345 rpcClient, err := stack.Attach() 346 if err != nil { 347 utils.Fatalf("Failed to attach to self: %v", err) 348 } 349 stateReader := vntclient.NewClient(rpcClient) 350 351 // Open any wallets already attached 352 for _, wallet := range stack.AccountManager().Wallets() { 353 if err := wallet.Open(""); err != nil { 354 log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err) 355 } 356 } 357 // Listen for wallet event till termination 358 for event := range events { 359 switch event.Kind { 360 case accounts.WalletArrived: 361 if err := event.Wallet.Open(""); err != nil { 362 log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err) 363 } 364 case accounts.WalletOpened: 365 status, _ := event.Wallet.Status() 366 log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status) 367 368 if event.Wallet.URL().Scheme == "ledger" { 369 event.Wallet.SelfDerive(accounts.DefaultLedgerBaseDerivationPath, stateReader) 370 } else { 371 event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader) 372 } 373 374 case accounts.WalletDropped: 375 log.Info("Old wallet dropped", "url", event.Wallet.URL()) 376 event.Wallet.Close() 377 } 378 } 379 }() 380 // Start auxiliary services if enabled 381 if ctx.GlobalBool(utils.ProducingEnabledFlag.Name) { 382 // Producing only makes sense if a full VNT node is running 383 if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" { 384 utils.Fatalf("Light clients do not support block producing") 385 } 386 var vnt *vnt.VNT 387 if err := stack.Service(&vnt); err != nil { 388 utils.Fatalf("VNT service not running: %v", err) 389 } 390 391 // Set the gas price to the limits from the CLI and start producing 392 vnt.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name)) 393 if err := vnt.StartProducing(true); err != nil { 394 utils.Fatalf("Failed to start block producing: %v", err) 395 } 396 } 397 }