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 obtain
Orderer
The block ledger store directory ld on the node, including the default directory/var/hyperledger/production/orderer
Or 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 (
fileLedgerFactory
Type) - Create subdirectories under the block ledger name chains (
/var/hyperledger/production/orderer/chains
), by each channel ledger block data store object is responsible inchains
A 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_num
Name,num
Is 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: start
profile
Service andOrderer
Sorting server, supportedgo tool pprof
Command 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