cool hit counter Derek Explains Bytom Source Code - Start and Stop_Intefrankly

Derek Explains Bytom Source Code - Start and Stop


By Derek

brief introduction

Github address.https://github.com/Bytom/bytom

Gitee address.https://gitee.com/BytomBlockchain/bytom

This chapter describes the bytom code start, node initialization, and stop process

The author uses the MacOS operating system, and other platforms are much the same Golang Version: 1.8

preparatory work

compile and install

See the official steps for details bytom install

Setting debug log output

Turn on debug to output details of files, functions, line numbers, etc.

export BYTOM_DEBUG=debug

Initialize and start bytomd

initialize

./bytomd init --chain_id testnet

bytomd currently supports two networks, here we use the test network

mainnet: mainnet

testnet: test.com

Start bytomd

./bytomd node --mining --prof_laddr=":8011"

--prof_laddr=":8080" // turn onpprof Output Performance Indicators

Visit: http://127.0.0.1:8080/debug/pprof/

bytomd init initialization

entry function

cmd/bytomd/main.go

func init() {
	log.SetFormatter(&log.TextFormatter{FullTimestamp: true, DisableColors: true})

	// If environment variable BYTOM_DEBUG is not empty,
	// then add the hook to logrus and set the log level to DEBUG
	if os.Getenv("BYTOM_DEBUG") != "" {
		log.AddHook(ContextHook{})
		log.SetLevel(log.DebugLevel)
	}
}

func main() {
	cmd := cli.PrepareBaseCmd(commands.RootCmd, "TM", os.ExpandEnv(config.DefaultDataDir()))
	cmd.Execute()
}

init The function will be used in themain Do it before you execute initialize operations, As you can seeinit inbytomd loadedBYTOM_DEBUG variables toSetting debug log output

command cli pass initialization

Use of bytomd's cli parsingcobra warehouse

cmd/bytomd/commands

  • cmd/bytomd/commands/root.go Initialization - root passes the reference. The root directory where bytomd stores configuration, keystore, and data. Under MacOS, the default path is ~/Library/Bytom/
  • cmd/bytomd/commands/init.go Initialization - chain_id passed as a reference. Select the network type, when starting bytomd we selected testnet which is the test network
  • cmd/bytomd/commands/version.go Initialization version pass reference
  • cmd/bytomd/commands/run_node.go Initialize the node to run with the required pass-through parameters

Initializing the default configuration

The user passes only a portion of the parameters, and the rest of the parameters needed for that node need to be loaded from the default configuration.

cmd/bytomd/commands/root.go

var (
	config = cfg.DefaultConfig()
)

There is a config global variable in root.go that loads all the default parameters required by node

// Default configurable parameters.
func DefaultConfig() *Config {
	return &Config{
 		BaseConfig: DefaultBaseConfig(), // node base related configuration
 		P2P: DefaultP2PConfig(), // p2p network related configuration
 		Wallet: DefaultWalletConfig(), // Wallet-related configuration
 		Auth: DefaultRPCAuthConfig(), // authentication related configuration
 		Web: DefaultWebConfig(), // web-related configuration
	}
}

A later article will go over what each configuration does

bytomd daemon start and exit

cmd/bytomd/commands/run_node.go

func runNode(cmd *cobra.Command, args []string) error {
	// Create & start node
	n := node.NewNode(config)
	if _, err := n.Start(); err != nil {
		return fmt.Errorf("Failed to start node: %v", err)
	} else {
		log.WithField("nodeInfo", n.SyncManager().Switch().NodeInfo()).Info("Started node")
	}

	// Trap signal, run forever.
	n.RunForever()

	return nil
}

The runNode function has a three-step operation.

node.NewNode: Initializing the node runtime environment

n.Start: Start node

n.RunForever: listen for the exit signal, and exit the node when the ctrl+c action is received. In linux the daemon generally listens for the SIGTERM signal (ctrl+c) as a signal to exit the daemon

Initializing the node runtime environment

There are five db databases in bytomd stored in the data directory under the --root parameter

  • accesstoken.db // Store token-related information (wallet access control permissions)
  • trusthistory.db // store p2p network sync related information
  • txdb.db // Store transaction-related information
  • txfeeds.db //
  • wallet.db // Store wallet-related information

node/node.go

func NewNode(config *cfg.Config) *Node {
	ctx := context.Background()
	initActiveNetParams(config)
 	// Get store Initialize the txdb database
	txDB := dbm.NewDB("txdb", config.DBBackend, config.DBDir())
	store := leveldb.NewStore(txDB)

   // Initialize the accesstoken database
	tokenDB := dbm.NewDB("accesstoken", config.DBBackend, config.DBDir())
	accessTokens := accesstoken.NewStore(tokenDB)

   // Initialize the event event scheduler, also called the task scheduler. A task can be called multiple times
	// Make event switch
	eventSwitch := types.NewEventSwitch()
	_, err := eventSwitch.Start()
	if err != nil {
		cmn.Exit(cmn.Fmt("Failed to start switch: %v", err))
	}

   // Initialization of the trading pool
	txPool := protocol.NewTxPool()
	chain, err := protocol.NewChain(store, txPool)
	if err != nil {
		cmn.Exit(cmn.Fmt("Failed to create chain structure: %v", err))
	}

	var accounts *account.Manager = nil
	var assets *asset.Registry = nil
	var wallet *w.Wallet = nil
	var txFeed *txfeed.Tracker = nil

   // Initialize the txfeeds database
	txFeedDB := dbm.NewDB("txfeeds", config.DBBackend, config.DBDir())
	txFeed = txfeed.NewTracker(txFeedDB, chain)

	if err = txFeed.Prepare(ctx); err != nil {
		log.WithField("error", err).Error("start txfeed")
		return nil
	}

   // Initialize the keystore
	hsm, err := pseudohsm.New(config.KeysDir())
	if err != nil {
		cmn.Exit(cmn.Fmt("initialize HSM failed: %v", err))
	}

   // Initialize wallet, default wallet is on
	if !config.Wallet.Disable {
		walletDB := dbm.NewDB("wallet", config.DBBackend, config.DBDir())
		accounts = account.NewManager(walletDB, chain)
		assets = asset.NewRegistry(walletDB, chain)
		wallet, err = w.NewWallet(walletDB, accounts, assets, hsm, chain)
		if err != nil {
			log.WithField("error", err).Error("init NewWallet")
		}

		// Clean up expired UTXO reservations periodically.
		go accounts.ExpireReservations(ctx, expireReservationsPeriod)
	}
	newBlockCh := make(chan *bc.Hash, maxNewBlockChSize)

   // Initialize network node synchronization management
	syncManager, _ := netsync.NewSyncManager(config, chain, txPool, newBlockCh)

// Initialize pprof, which is used to output performance metrics and needs to be turned on by making the --prof_laddr parameter, which we turned on at the beginning of the article
	// run the profile server
	profileHost := config.ProfListenAddress
	if profileHost != "" {
		// Profiling bytomd programs.see (https://blog.golang.org/profiling-go-programs)
		// go tool pprof http://profileHose/debug/pprof/heap
		go func() {
			http.ListenAndServe(profileHost, nil)
		}()
	}

   // Initialize the node and populate the environment with all the parameters needed for the node
	node := &Node{
		config:       config,
		syncManager:  syncManager,
		evsw:         eventSwitch,
		accessTokens: accessTokens,
		wallet:       wallet,
		chain:        chain,
		txfeed:       txFeed,
		miningEnable: config.Mining,
	}

   // Initial mining
	node.cpuMiner = cpuminer.NewCPUMiner(chain, accounts, txPool, newBlockCh)
	node.miningPool = miningpool.NewMiningPool(chain, accounts, txPool, newBlockCh)

	node.BaseService = *cmn.NewBaseService(nil, "Node", node)

	return node
}

Currently bytomd only supports cpu mining, so there is only initialization information for cpuminer in the code

Start node

node/node.go

// Lanch web broser or not
func lanchWebBroser() {
	log.Info("Launching System Browser with :", webAddress)
	if err := browser.Open(webAddress); err != nil {
		log.Error(err.Error())
		return
	}
}

func (n *Node) initAndstartApiServer() {
	n.api = api.NewAPI(n.syncManager, n.wallet, n.txfeed, n.cpuMiner, n.miningPool, n.chain, n.config, n.accessTokens)

	listenAddr := env.String("LISTEN", n.config.ApiAddress)
	env.Parse()
	n.api.StartServer(*listenAddr)
}

func (n *Node) OnStart() error {
	if n.miningEnable {
		n.cpuMiner.Start()
	}
	n.syncManager.Start()
	n.initAndstartApiServer()
	if !n.config.Web.Closed {
		lanchWebBroser()
	}

	return nil
}

OnStart() starts the node process as follows.

  • Start mining function
  • Start p2p network synchronization
  • Start the apiserver service for the http protocol
  • Open your browser to visit bytond's trading page

Stop node

bytomd is executed at startup n. The RunForever() function, which is initiated by the tendermint framework to listen for signals.

vendor/github.com/tendermint/tmlibs/common/os.go

func TrapSignal(cb func()) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		for sig := range c {
			fmt.Printf("captured %v, exiting...
", sig)
			if cb != nil {
				cb()
			}
			os.Exit(1)
		}
	}()
	select {}
}

The TrapSignal function listens for the SIGTERM signal for bytomd to become a non-exiting daemon. The bytomd process can only be terminated when ctrl+c or kill bytomd_pid is triggered to exit. On exit bytomd performs the following actions

node/node.go

func (n *Node) OnStop() {
	n.BaseService.OnStop()
	if n.miningEnable {
		n.cpuMiner.Stop()
	}
	n.syncManager.Stop()
	log.Info("Stopping Node")
	// TODO: gracefully disconnect from peers.
}

bytomd will stop the mining function, the p2p network, and other actions.


Recommended>>
1、ACEUbuntu environment setup
2、The 5 Programming Languages That Walked Away
3、Interpreted versus compiled languages
4、World War Under Control An Inventory of RealTime Tracking Systems for Global Cyberattacks
5、PSVR version of Arizona Sunshine coming to European retailers next month will include the latest content

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号