Start screwing hyperledger fabric source | Order node

Article and code: github.com/blockchainG…

Branches: v1.1.0

The Orderer node starts the process

Node launch in/orderer/common/server/main go:

func Main(a) {
	fullCmd := kingpin.MustParse(app.Parse(os.Args[1:))// Parse the user command line. conf, err := config.Load()// Load orderer.yaml configuration file. initializeLoggingLevel(conf)// Initialize the log level
	initializeLocalMsp(conf) // Initialize the local MSP component

	prettyPrintStruct(conf) // Prints configuration information
	Start(fullCmd, conf) // Start the Orderer sorting server
}
Copy the code

We mainly did the following things:

  • Parse the user command line
  • Load the orderer.yaml configuration file
  • Initialize the log level
  • Initialize the local MSP component
  • Printing Configuration Information
  • Start the Orderer sorting server

Next, I will expand to talk about some of the more important content above.

Load the orderer.yaml configuration file

Is the config. The Load () open, into the orderer/common/localconfig/config. Go/Load ()

① initialize viper

Call InitViper() to set the configuration file path and default to $FABRIC_CFG_PATH (such as /etc/hyperledger/fabric) to find the configuration file. Can’t find the file again, in turn, find the current directory, the default configuration directory ($GOPATH/src/github.com/hyperledger/fabric/sampleconfig) and system default configuration path (/ etc/hyperledger/fabric). Then turn on the pattern that matches the system environment variables, that is, the Viper component configuration item (to. Add the specified prefix “ORDERER_”, convert it to uppercase, and then add “. Replace it with _. In this way, the Viper component can match an environment variable starting with the prefix “ORDERER_” to get its configuration value in the environment variable when looking for a configuration item.

config := viper.New()
	cf.InitViper(config, configName)
	config.SetEnvPrefix(Prefix)
	config.AutomaticEnv()
	replacer := strings.NewReplacer("."."_")
	config.SetEnvKeyReplacer(replacer)
Copy the code

② load orderer. yaml configuration file

err := config.ReadInConfig()
Copy the code

Parse the configuration file into an Orderer configuration object

var uconf TopLevel
err = viperutil.EnhancedExactUnmarshal(config, &uconf)
Copy the code

This configuration object is of type TopLevel and has the following structure:

type TopLevel struct {
	General    General    // Generic configuration object
	FileLedger FileLedger // Text ledger configuration object
	RAMLedger  RAMLedger  //RAM ledger configuration object
	Kafka      Kafka      // Kafka consensus component configuration object
	Debug      Debug      // Debug information Configuration object
}
Copy the code

Check the Orderer configuration object conf configuration item and set the default value

uconf.completeInitialization(filepath.Dir(config.ConfigFileUsed()))
Copy the code

Initialize logs with local MSP components

(1) initialize logs

InitializeLoggingLevel Sets the log backend output stream, output grid, and default log level (INFO level) on the Orderer node.

func initializeLoggingLevel(conf *config.TopLevel) {
	flogging.InitBackend(flogging.SetFormat(conf.General.LogFormat), os.Stderr)
	flogging.InitFromSpec(conf.General.LogLevel)
}
Copy the code

② : Initializes the local MSP component

Load the local MSP component and initialize the local MSP component based on the MSP configuration file path, BCCSP password service component configuration, and MSP name.

func initializeLocalMsp(conf *config.TopLevel) {
	err := mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
	...
}
Copy the code

By default, local MSP components use objects of type BCCSPMSP. This type of MSP component provides password suite service based on BCCSP component. It encapsulates the list of related certificates (including root CA certificate, intermediate CA certificate, etc.), MSP name, signer identity entity list and administrator identity entity list that MSP component (usually corresponding to an organization) trusts. The key content of the MSP component will be explained later.

Start the Orderer sort node

Start the function in the orderer/common/server/main. Go/Start () function, the next step by step analysis:

Create a local MSP signer entity

signer := localmsp.NewSigner()       
Copy the code

② : Initializes the security server configuration item and gRPC server for TLS authentication

The default port number of the local gRPC server grpcServer is 7050

serverConfig := initializeServerConfig(conf)       
grpcServer := initializeGrpcServer(conf, serverConfig) 
Copy the code

③ : Set the TLS connection authentication callback function

tlsCallback := func(bundle *channelconfig.Bundle) {
		if grpcServer.MutualTLSRequired() { // Check whether the TLS client certificate needs to be authenticated
			logger.Debug("Executing callback to update root CAs")
			updateTrustedRoots(grpcServer, caSupport, bundle) // Execute the callback function to update the root CA certificate}}Copy the code

④ Create a multi-channel registration manager

The Registrar object registers all the channels on the Orderer node (including system and application channels) and maintains the channel configuration, ledger and other important resources.

The Registrar object is the “resource manager” on the Orderer node. The Registrar object creates the associated consensus component chain object for each channel to sort transactions, package out blocks, submit ledgers, and manage the channel

manager := initializeMultichannelRegistrar(conf, signer, tlsCallback)
Copy the code
func initializeMultichannelRegistrar(conf *config.TopLevel, signer crypto.LocalSigner,
	callbacks ...func(bundle *channelconfig.Bundle)) *multichannel.Registrar {
	lf, _ := createLedgerFactory(conf) // Create the ledger factory object for the channel
	if len(lf.ChainIDs()) == 0 {
		initializeBootstrapChannel(conf, lf) // Initialize the system channel
	} else {
		logger.Info("Not bootstrapping because of existing chains")}// Create and set the consensus component dictionary
	consenters := make(map[string]consensus.Consenter)
	consenters["solo"] = solo.New()
	consenters["kafka"] = kafka.New(conf.Kafka) //// Kafka common component
	return multichannel.NewRegistrar(lf, consenters, signer, callbacks...)
}
Copy the code

4.1 Create the ledger factory object for the channel

Code path/orderer/common/server/util. Go, probably do the following things:

  • To obtainOrdererThe block ledger store directory ld on the node, including the default directory/var/hyperledger/production/ordererOr subdirectories in a temporary directoryhyperledger-fabric-ordererledger+ suffix for random number (used if default directory does not exist)
  • Create a file-based block ledger factory object LF (fileLedgerFactoryType)
  • Create subdirectories under the block ledger name chains (/var/hyperledger/production/orderer/chains), by each channel ledger block data store object is responsible inchainsA channel ledger subdirectory named channel ID (chain ID) is created and maintained under the subdirectory, which is used to store all block data files of the channel ledger. Among them, block data file names areblockfile_numName,numIs a 6-digit block file number, which is complemented by zeros.

4.2 Initializing system Channels

func initializeBootstrapChannel(conf *config.TopLevel, lf blockledger.Factory){...switch conf.General.GenesisMethod { // Analyze the generation mode of genesis block
	case "provisional": // Generate genesis block according to configuration file
		genesisBlock = encoder.New(genesisconfig.Load(conf.General.GenesisProfile)).GenesisBlockForChannel(conf.General.SystemChannel)
	case "file": // Generate genesis block according to genesis block file
		genesisBlock = file.New(conf.General.GenesisFile).GenesisBlock()
	default:
	}

	chainID, err := utils.GetChainIDFromBlock(genesisBlock) // Get channel ID from genesis block. gl, err := lf.GetOrCreate(chainID)// Create a block ledger object for the system channel. err = gl.Append(genesisBlock)// Add blocks to the system channel ledger. }Copy the code

⑤ : Create the Orderer sorting server

Orderer ordering server, which provides Orderer services and manages all channel resources, their ledgers, consensus components, and so on.

server := NewServer(manager, signer, &conf.Debug, conf.General.Authentication.TimeWindow, mutualTLS)
Copy the code
func NewServer(r *multichannel.Registrar, _ crypto.LocalSigner, debug *localconfig.Debug, timeWindow time.Duration, mutualTLS bool) ab.AtomicBroadcastServer {
	s := &server{
		dh:        deliver.NewHandlerImpl(deliverSupport{Registrar: r}, timeWindow, mutualTLS),
		bh:        broadcast.NewHandlerImpl(broadcastSupport{Registrar: r}),
		debug:     debug,
		Registrar: r,
	}
	return s
}
Copy the code
  • Bh: Broadcast service processing handle (type of deliverHandler). AtomicBroadcast_BroadcastServer implements the Handle(SRV AB. AtomicBroadcast_BroadcastServer) message processing interface of Broadcast transaction Broadcast service, which is responsible for receiving and processing ordinary transaction messages and configuration transaction messages submitted by clients. After filtering, it is forwarded to the consensus component chain object of channel binding for processing.

  • Dh: Deliver Service processing handle (type handlerImpl). This object implements the Handle(SRV *DeliverServer) message processing interface of the Deliver Block distribution service, which is responsible for receiving the block request message submitted by the client, reading the specified block data from the Orderer node block ledger, and returning it to the requesting node. If the requested block has not yet been generated, it is blocked by default until the block is created and committed.

  • Registrar: The Registrar type of the Orderer node. This object encapsulates all channels on the Orderer node chain support object dictionary Chains, consenters, ledgerFactory, system channel chain support object and ID, local signer entity, etc. Manages core resources such as channel configurations, block ledger objects, consensus components, and acts as a “resource manager” on the Orderer node.

⑥ : Parses and executes subcommands

  • Start subcommand: startprofileService andOrdererSorting server, supportedgo tool pprofCommand to view and analyze application performance bottlenecks
  • Benchmark subcommand: used to start a test server
switch cmd { // Parse the command type
	case start.FullCommand(): // "start" command // start starts a subcommand
		logger.Infof("Starting %s", metadata.GetVersionInfo())
		initializeProfilingService(conf) // Goroutine starts the Go Profile service
		ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server)
		logger.Info("Beginning to serve requests")
		grpcServer.Start() // Start gRPC server to provide Orderer service
	case benchmark.FullCommand(): // "benchmark" command // "benchmark" test example command
		logger.Info("Starting orderer in benchmark mode")
		benchmarkServer := performance.GetBenchmarkServer()
		benchmarkServer.RegisterService(server)
		benchmarkServer.Start()
	}
Copy the code

reference

Github.com/blockchainG…

Public number: Blockchain technology stack