github.com/nnlgsakib/mind-dpos@v0.0.0-20230606105614-f3c8ca06f808/cmd/gttc/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  // gttc is the official command-line client for GTTC.
    18  package main
    19  
    20  import (
    21  	"fmt"
    22  	"math/rand"
    23  	"os"
    24  	"runtime"
    25  	"sort"
    26  	"strings"
    27  	"time"
    28  
    29  	"github.com/TTCECO/gttc/accounts"
    30  	"github.com/TTCECO/gttc/accounts/keystore"
    31  	"github.com/TTCECO/gttc/cmd/utils"
    32  	"github.com/TTCECO/gttc/console"
    33  	"github.com/TTCECO/gttc/eth"
    34  	"github.com/TTCECO/gttc/ethclient"
    35  	"github.com/TTCECO/gttc/internal/debug"
    36  	"github.com/TTCECO/gttc/log"
    37  	"github.com/TTCECO/gttc/metrics"
    38  	"github.com/TTCECO/gttc/node"
    39  	"github.com/TTCECO/gttc/params"
    40  	"github.com/TTCECO/gttc/rpc"
    41  	"gopkg.in/urfave/cli.v1"
    42  	"strconv"
    43  )
    44  
    45  const (
    46  	clientIdentifier = "gttc" // 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 gttc 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.TxPoolNoLocalsFlag,
    76  		utils.TxPoolJournalFlag,
    77  		utils.TxPoolRejournalFlag,
    78  		utils.TxPoolPriceLimitFlag,
    79  		utils.TxPoolPriceBumpFlag,
    80  		utils.TxPoolAccountSlotsFlag,
    81  		utils.TxPoolGlobalSlotsFlag,
    82  		utils.TxPoolAccountQueueFlag,
    83  		utils.TxPoolGlobalQueueFlag,
    84  		utils.TxPoolLifetimeFlag,
    85  		utils.FastSyncFlag,
    86  		utils.LightModeFlag,
    87  		utils.SyncModeFlag,
    88  		utils.GCModeFlag,
    89  		utils.LightServFlag,
    90  		utils.LightPeersFlag,
    91  		utils.LightKDFFlag,
    92  		utils.CacheFlag,
    93  		utils.CacheDatabaseFlag,
    94  		utils.CacheGCFlag,
    95  		utils.TrieCacheGenFlag,
    96  		utils.ListenPortFlag,
    97  		utils.MaxPeersFlag,
    98  		utils.MaxPendingPeersFlag,
    99  		utils.EtherbaseFlag,
   100  		utils.GasPriceFlag,
   101  		utils.MinerThreadsFlag,
   102  		utils.MiningEnabledFlag,
   103  		utils.TargetGasLimitFlag,
   104  		utils.NATFlag,
   105  		utils.NoDiscoverFlag,
   106  		utils.DiscoveryV5Flag,
   107  		utils.NetrestrictFlag,
   108  		utils.NodeKeyFileFlag,
   109  		utils.NodeKeyHexFlag,
   110  		utils.DeveloperFlag,
   111  		utils.DeveloperPeriodFlag,
   112  		utils.TestnetFlag,
   113  		utils.RinkebyFlag,
   114  		utils.VMEnableDebugFlag,
   115  		utils.NetworkIdFlag,
   116  		utils.RPCCORSDomainFlag,
   117  		utils.RPCVirtualHostsFlag,
   118  		utils.EthStatsURLFlag,
   119  		utils.MetricsEnabledFlag,
   120  		utils.FakePoWFlag,
   121  		utils.NoCompactionFlag,
   122  		utils.GpoBlocksFlag,
   123  		utils.GpoPercentileFlag,
   124  		utils.ExtraDataFlag,
   125  		configFileFlag,
   126  	}
   127  
   128  	rpcFlags = []cli.Flag{
   129  		utils.RPCEnabledFlag,
   130  		utils.RPCListenAddrFlag,
   131  		utils.RPCPortFlag,
   132  		utils.RPCApiFlag,
   133  		utils.WSEnabledFlag,
   134  		utils.WSListenAddrFlag,
   135  		utils.WSPortFlag,
   136  		utils.WSApiFlag,
   137  		utils.WSAllowedOriginsFlag,
   138  		utils.IPCDisabledFlag,
   139  		utils.IPCPathFlag,
   140  	}
   141  
   142  	whisperFlags = []cli.Flag{
   143  		utils.WhisperEnabledFlag,
   144  		utils.WhisperMaxMessageSizeFlag,
   145  		utils.WhisperMinPOWFlag,
   146  	}
   147  
   148  	pbftFlags = []cli.Flag{
   149  		utils.PBFTEnableFlag,
   150  	}
   151  
   152  	scaFlags = []cli.Flag{
   153  		utils.SCAEnableFlag,
   154  		utils.SCAMainRPCAddrFlag,
   155  		utils.SCAMainRPCPortFlag,
   156  		utils.SCAPeriod,
   157  	}
   158  )
   159  
   160  func init() {
   161  	// Initialize the CLI app and start Gttc
   162  	app.Action = gttc
   163  	app.HideVersion = true // we have a command to print the version
   164  	app.Copyright = "Copyright 2018 The TTCECO Authors"
   165  	app.Commands = []cli.Command{
   166  		// See chaincmd.go:
   167  		initCommand,
   168  		importCommand,
   169  		exportCommand,
   170  		importPreimagesCommand,
   171  		exportPreimagesCommand,
   172  		copydbCommand,
   173  		removedbCommand,
   174  		dumpCommand,
   175  		// See monitorcmd.go:
   176  		monitorCommand,
   177  		// See accountcmd.go:
   178  		accountCommand,
   179  		walletCommand,
   180  		// See consolecmd.go:
   181  		consoleCommand,
   182  		attachCommand,
   183  		javascriptCommand,
   184  		// See misccmd.go:
   185  		makecacheCommand,
   186  		makedagCommand,
   187  		versionCommand,
   188  		bugCommand,
   189  		licenseCommand,
   190  		// See config.go
   191  		dumpConfigCommand,
   192  	}
   193  	sort.Sort(cli.CommandsByName(app.Commands))
   194  
   195  	app.Flags = append(app.Flags, nodeFlags...)
   196  	app.Flags = append(app.Flags, rpcFlags...)
   197  	app.Flags = append(app.Flags, consoleFlags...)
   198  	app.Flags = append(app.Flags, debug.Flags...)
   199  	app.Flags = append(app.Flags, whisperFlags...)
   200  	app.Flags = append(app.Flags, pbftFlags...)
   201  	app.Flags = append(app.Flags, scaFlags...)
   202  
   203  	app.Before = func(ctx *cli.Context) error {
   204  		runtime.GOMAXPROCS(runtime.NumCPU())
   205  		if err := debug.Setup(ctx); err != nil {
   206  			return err
   207  		}
   208  		// Start system runtime metrics collection
   209  		go metrics.CollectProcessMetrics(3 * time.Second)
   210  
   211  		utils.SetupNetwork(ctx)
   212  		return nil
   213  	}
   214  
   215  	app.After = func(ctx *cli.Context) error {
   216  		debug.Exit()
   217  		console.Stdin.Close() // Resets terminal mode.
   218  		return nil
   219  	}
   220  }
   221  
   222  func main() {
   223  	if err := app.Run(os.Args); err != nil {
   224  		fmt.Fprintln(os.Stderr, err)
   225  		os.Exit(1)
   226  	}
   227  }
   228  
   229  // gttc is the main entry point into the system if no special subcommand is ran.
   230  // It creates a default node based on the command line arguments and runs it in
   231  // blocking mode, waiting for it to be shut down.
   232  func gttc(ctx *cli.Context) error {
   233  	node := makeFullNode(ctx)
   234  	startNode(ctx, node)
   235  	node.Wait()
   236  	return nil
   237  }
   238  
   239  // startNode boots up the system node and all registered protocols, after which
   240  // it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
   241  // miner.
   242  func startNode(ctx *cli.Context, stack *node.Node) {
   243  	debug.Memsize.Add("node", stack)
   244  
   245  	// Start up the node itself
   246  	utils.StartNode(stack)
   247  
   248  	// Unlock any account specifically requested
   249  	ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
   250  
   251  	passwords := utils.MakePasswordList(ctx)
   252  	unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",")
   253  	for i, account := range unlocks {
   254  		if trimmed := strings.TrimSpace(account); trimmed != "" {
   255  			unlockAccount(ctx, ks, trimmed, i, passwords)
   256  		}
   257  	}
   258  	// Register wallet event handlers to open and auto-derive wallets
   259  	events := make(chan accounts.WalletEvent, 16)
   260  	stack.AccountManager().Subscribe(events)
   261  
   262  	go func() {
   263  		// Create a chain state reader for self-derivation
   264  		rpcClient, err := stack.Attach()
   265  		if err != nil {
   266  			utils.Fatalf("Failed to attach to self: %v", err)
   267  		}
   268  		stateReader := ethclient.NewClient(rpcClient)
   269  
   270  		// Open any wallets already attached
   271  		for _, wallet := range stack.AccountManager().Wallets() {
   272  			if err := wallet.Open(""); err != nil {
   273  				log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err)
   274  			}
   275  		}
   276  		// Listen for wallet event till termination
   277  		for event := range events {
   278  			switch event.Kind {
   279  			case accounts.WalletArrived:
   280  				if err := event.Wallet.Open(""); err != nil {
   281  					log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err)
   282  				}
   283  			case accounts.WalletOpened:
   284  				status, _ := event.Wallet.Status()
   285  				log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status)
   286  
   287  				if event.Wallet.URL().Scheme == "ledger" {
   288  					event.Wallet.SelfDerive(accounts.DefaultLedgerBaseDerivationPath, stateReader)
   289  				} else {
   290  					event.Wallet.SelfDerive(accounts.DefaultBaseDerivationPath, stateReader)
   291  				}
   292  
   293  			case accounts.WalletDropped:
   294  				log.Info("Old wallet dropped", "url", event.Wallet.URL())
   295  				event.Wallet.Close()
   296  			}
   297  		}
   298  	}()
   299  	// Set Side chain config
   300  	if ctx.GlobalBool(utils.SCAEnableFlag.Name) {
   301  		var ethereum *eth.Ethereum
   302  		if err := stack.Service(&ethereum); err != nil {
   303  			utils.Fatalf("Ethereum service not running: %v", err)
   304  		}
   305  		mcRPCAddress := ctx.GlobalString(utils.SCAMainRPCAddrFlag.Name)
   306  
   307  		// got random rpc
   308  		mainRPCnode := params.MainnetRPCnodes[rand.Intn(len(params.MainnetRPCnodes))]
   309  
   310  		if mcRPCAddress == "" {
   311  			mcRPCAddress = strings.Split(mainRPCnode, ":")[0]
   312  		}
   313  
   314  		mcRPCPort := ctx.GlobalInt(utils.SCAMainRPCPortFlag.Name)
   315  		if mcRPCPort == 0 {
   316  			mcRPCPort, _ = strconv.Atoi(strings.Split(mainRPCnode, ":")[1])
   317  		}
   318  
   319  		mcPeriod := ctx.GlobalInt(utils.SCAPeriod.Name)
   320  		client, err := rpc.Dial("http://" + mcRPCAddress + ":" + strconv.Itoa(mcRPCPort))
   321  		if err != nil {
   322  			utils.Fatalf("Main net rpc connect fail: %v", err)
   323  		}
   324  		ethereum.BlockChain().Config().Alien.SideChain = true
   325  		ethereum.BlockChain().Config().Alien.Period = uint64(mcPeriod)
   326  		ethereum.BlockChain().Config().Alien.MCRPCClient = client
   327  	}
   328  
   329  	// Start auxiliary services if enabled
   330  	if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
   331  		// Mining only makes sense if a full Ethereum node is running
   332  		if ctx.GlobalBool(utils.LightModeFlag.Name) || ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {
   333  			utils.Fatalf("Light clients do not support mining")
   334  		}
   335  		var ethereum *eth.Ethereum
   336  		if err := stack.Service(&ethereum); err != nil {
   337  			utils.Fatalf("Ethereum service not running: %v", err)
   338  		}
   339  		if ethereum.BlockChain().Config().Alien != nil {
   340  			ethereum.BlockChain().Config().Alien.PBFTEnable = ctx.GlobalBool(utils.PBFTEnableFlag.Name)
   341  		}
   342  
   343  		// Use a reduced number of threads if requested
   344  		if threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name); threads > 0 {
   345  			type threaded interface {
   346  				SetThreads(threads int)
   347  			}
   348  			if th, ok := ethereum.Engine().(threaded); ok {
   349  				th.SetThreads(threads)
   350  			}
   351  		}
   352  
   353  		// Set the gas price to the limits from the CLI and start mining
   354  		ethereum.TxPool().SetGasPrice(utils.GlobalBig(ctx, utils.GasPriceFlag.Name))
   355  		if err := ethereum.StartMining(true); err != nil {
   356  			utils.Fatalf("Failed to start mining: %v", err)
   357  		}
   358  	}
   359  }