github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/orderer/common/server/main.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package server
     8  
     9  import (
    10  	"bytes"
    11  	"context"
    12  	"fmt"
    13  	"io/ioutil"
    14  	"net"
    15  	"net/http"
    16  	_ "net/http/pprof" // This is essentially the main package for the orderer
    17  	"os"
    18  	"os/signal"
    19  	"sync"
    20  	"syscall"
    21  	"time"
    22  
    23  	"github.com/golang/protobuf/proto"
    24  	"github.com/hechain20/hechain/bccsp"
    25  	"github.com/hechain20/hechain/bccsp/factory"
    26  	"github.com/hechain20/hechain/common/channelconfig"
    27  	"github.com/hechain20/hechain/common/crypto"
    28  	"github.com/hechain20/hechain/common/fabhttp"
    29  	"github.com/hechain20/hechain/common/flogging"
    30  	floggingmetrics "github.com/hechain20/hechain/common/flogging/metrics"
    31  	"github.com/hechain20/hechain/common/grpclogging"
    32  	"github.com/hechain20/hechain/common/grpcmetrics"
    33  	"github.com/hechain20/hechain/common/ledger/blockledger"
    34  	"github.com/hechain20/hechain/common/metrics"
    35  	"github.com/hechain20/hechain/common/metrics/disabled"
    36  	"github.com/hechain20/hechain/core/operations"
    37  	"github.com/hechain20/hechain/internal/pkg/comm"
    38  	"github.com/hechain20/hechain/internal/pkg/identity"
    39  	"github.com/hechain20/hechain/msp"
    40  	"github.com/hechain20/hechain/orderer/common/bootstrap/file"
    41  	"github.com/hechain20/hechain/orderer/common/channelparticipation"
    42  	"github.com/hechain20/hechain/orderer/common/cluster"
    43  	"github.com/hechain20/hechain/orderer/common/localconfig"
    44  	"github.com/hechain20/hechain/orderer/common/metadata"
    45  	"github.com/hechain20/hechain/orderer/common/multichannel"
    46  	"github.com/hechain20/hechain/orderer/common/onboarding"
    47  	"github.com/hechain20/hechain/orderer/consensus"
    48  	"github.com/hechain20/hechain/orderer/consensus/etcdraft"
    49  	"github.com/hechain20/hechain/orderer/consensus/kafka"
    50  	"github.com/hechain20/hechain/orderer/consensus/solo"
    51  	"github.com/hechain20/hechain/protoutil"
    52  	"github.com/hyperledger/fabric-lib-go/healthz"
    53  	cb "github.com/hyperledger/fabric-protos-go/common"
    54  	ab "github.com/hyperledger/fabric-protos-go/orderer"
    55  	"go.uber.org/zap/zapcore"
    56  	"google.golang.org/grpc"
    57  	"gopkg.in/alecthomas/kingpin.v2"
    58  )
    59  
    60  var logger = flogging.MustGetLogger("orderer.common.server")
    61  
    62  // command line flags
    63  var (
    64  	app = kingpin.New("orderer", "Hechain orderer node")
    65  
    66  	_       = app.Command("start", "Start the orderer node").Default() // preserved for cli compatibility
    67  	version = app.Command("version", "Show version information")
    68  
    69  	clusterTypes = map[string]struct{}{"etcdraft": {}}
    70  )
    71  
    72  // Main is the entry point of orderer process
    73  func Main() {
    74  	fullCmd := kingpin.MustParse(app.Parse(os.Args[1:]))
    75  
    76  	// "version" command
    77  	if fullCmd == version.FullCommand() {
    78  		fmt.Println(metadata.GetVersionInfo())
    79  		return
    80  	}
    81  
    82  	conf, err := localconfig.Load()
    83  	if err != nil {
    84  		logger.Error("failed to parse config: ", err)
    85  		os.Exit(1)
    86  	}
    87  	initializeLogging()
    88  
    89  	prettyPrintStruct(conf)
    90  
    91  	cryptoProvider := factory.GetDefault()
    92  
    93  	signer, signErr := loadLocalMSP(conf).GetDefaultSigningIdentity()
    94  	if signErr != nil {
    95  		logger.Panicf("Failed to get local MSP identity: %s", signErr)
    96  	}
    97  
    98  	opsSystem := newOperationsSystem(conf.Operations, conf.Metrics)
    99  	if err = opsSystem.Start(); err != nil {
   100  		logger.Panicf("failed to start operations subsystem: %s", err)
   101  	}
   102  	defer opsSystem.Stop()
   103  	metricsProvider := opsSystem.Provider
   104  	logObserver := floggingmetrics.NewObserver(metricsProvider)
   105  	flogging.SetObserver(logObserver)
   106  
   107  	serverConfig := initializeServerConfig(conf, metricsProvider)
   108  	grpcServer := initializeGrpcServer(conf, serverConfig)
   109  	caMgr := &caManager{
   110  		appRootCAsByChain:     make(map[string][][]byte),
   111  		ordererRootCAsByChain: make(map[string][][]byte),
   112  		clientRootCAs:         serverConfig.SecOpts.ClientRootCAs,
   113  	}
   114  
   115  	lf, err := createLedgerFactory(conf, metricsProvider)
   116  	if err != nil {
   117  		logger.Panicf("Failed to create ledger factory: %v", err)
   118  	}
   119  
   120  	var bootstrapBlock *cb.Block
   121  	switch conf.General.BootstrapMethod {
   122  	case "file":
   123  		if len(lf.ChannelIDs()) > 0 {
   124  			logger.Info("Not bootstrapping the system channel because of existing channels")
   125  			break
   126  		}
   127  
   128  		bootstrapBlock = file.New(conf.General.BootstrapFile).GenesisBlock()
   129  		if err := onboarding.ValidateBootstrapBlock(bootstrapBlock, cryptoProvider); err != nil {
   130  			logger.Panicf("Failed validating bootstrap block: %v", err)
   131  		}
   132  
   133  		if bootstrapBlock.Header.Number > 0 {
   134  			logger.Infof("Not bootstrapping the system channel because the bootstrap block number is %d (>0), replication is needed", bootstrapBlock.Header.Number)
   135  			break
   136  		}
   137  
   138  		// bootstrapping with a genesis block (i.e. bootstrap block number = 0)
   139  		// generate the system channel with a genesis block.
   140  		logger.Info("Bootstrapping the system channel")
   141  		initializeBootstrapChannel(bootstrapBlock, lf)
   142  	case "none":
   143  		bootstrapBlock = initSystemChannelWithJoinBlock(conf, cryptoProvider, lf)
   144  	default:
   145  		logger.Panicf("Unknown bootstrap method: %s", conf.General.BootstrapMethod)
   146  	}
   147  
   148  	// select the highest numbered block among the bootstrap block and the last config block if the system channel.
   149  	sysChanConfigBlock := extractSystemChannel(lf, cryptoProvider)
   150  	clusterBootBlock := selectClusterBootBlock(bootstrapBlock, sysChanConfigBlock)
   151  
   152  	// determine whether the orderer is of cluster type
   153  	var isClusterType bool
   154  	if clusterBootBlock == nil {
   155  		logger.Infof("Starting without a system channel")
   156  		isClusterType = true
   157  	} else {
   158  		sysChanID, err := protoutil.GetChannelIDFromBlock(clusterBootBlock)
   159  		if err != nil {
   160  			logger.Panicf("Failed getting channel ID from clusterBootBlock: %s", err)
   161  		}
   162  
   163  		consensusTypeName := consensusType(clusterBootBlock, cryptoProvider)
   164  		logger.Infof("Starting with system channel: %s, consensus type: %s", sysChanID, consensusTypeName)
   165  		_, isClusterType = clusterTypes[consensusTypeName]
   166  	}
   167  
   168  	// configure following artifacts properly if orderer is of cluster type
   169  	var repInitiator *onboarding.ReplicationInitiator
   170  	clusterServerConfig := serverConfig
   171  	clusterGRPCServer := grpcServer // by default, cluster shares the same grpc server
   172  	var clusterClientConfig comm.ClientConfig
   173  	var clusterDialer *cluster.PredicateDialer
   174  
   175  	var reuseGrpcListener bool
   176  	var serversToUpdate []*comm.GRPCServer
   177  
   178  	if isClusterType {
   179  		logger.Infof("Setting up cluster")
   180  		clusterClientConfig, reuseGrpcListener = initializeClusterClientConfig(conf)
   181  		clusterDialer = &cluster.PredicateDialer{
   182  			Config: clusterClientConfig,
   183  		}
   184  
   185  		if !reuseGrpcListener {
   186  			clusterServerConfig, clusterGRPCServer = configureClusterListener(conf, serverConfig, ioutil.ReadFile)
   187  		}
   188  
   189  		// If we have a separate gRPC server for the cluster,
   190  		// we need to update its TLS CA certificate pool.
   191  		serversToUpdate = append(serversToUpdate, clusterGRPCServer)
   192  
   193  		// If the orderer has a system channel and is of cluster type, it may have
   194  		// to replicate first.
   195  		if clusterBootBlock != nil {
   196  			// When we are bootstrapping with a clusterBootBlock with number >0,
   197  			// replication will be performed. Only clusters that are equipped with
   198  			// a recent config block (number i.e. >0) can replicate. This will
   199  			// replicate all channels if the clusterBootBlock number > system-channel
   200  			// height (i.e. there is a gap in the ledger).
   201  			repInitiator = onboarding.NewReplicationInitiator(lf, clusterBootBlock, conf, clusterClientConfig.SecOpts, signer, cryptoProvider)
   202  			repInitiator.ReplicateIfNeeded(clusterBootBlock)
   203  			// With BootstrapMethod == "none", the bootstrapBlock comes from a
   204  			// join-block. If it exists, we need to remove the system channel
   205  			// join-block from the filerepo.
   206  			if conf.General.BootstrapMethod == "none" && bootstrapBlock != nil {
   207  				discardSystemChannelJoinBlock(conf, bootstrapBlock)
   208  			}
   209  		}
   210  	}
   211  
   212  	identityBytes, err := signer.Serialize()
   213  	if err != nil {
   214  		logger.Panicf("Failed serializing signing identity: %v", err)
   215  	}
   216  
   217  	expirationLogger := flogging.MustGetLogger("certmonitor")
   218  	crypto.TrackExpiration(
   219  		serverConfig.SecOpts.UseTLS,
   220  		serverConfig.SecOpts.Certificate,
   221  		[][]byte{clusterClientConfig.SecOpts.Certificate},
   222  		identityBytes,
   223  		expirationLogger.Infof,
   224  		expirationLogger.Warnf, // This can be used to piggyback a metric event in the future
   225  		time.Now(),
   226  		time.AfterFunc)
   227  
   228  	// if cluster is reusing client-facing server, then it is already
   229  	// appended to serversToUpdate at this point.
   230  	if grpcServer.MutualTLSRequired() && !reuseGrpcListener {
   231  		serversToUpdate = append(serversToUpdate, grpcServer)
   232  	}
   233  
   234  	tlsCallback := func(bundle *channelconfig.Bundle) {
   235  		logger.Debug("Executing callback to update root CAs")
   236  		caMgr.updateTrustedRoots(bundle, serversToUpdate...)
   237  		if isClusterType {
   238  			caMgr.updateClusterDialer(
   239  				clusterDialer,
   240  				clusterClientConfig.SecOpts.ServerRootCAs,
   241  			)
   242  		}
   243  	}
   244  
   245  	manager := initializeMultichannelRegistrar(
   246  		clusterBootBlock,
   247  		repInitiator,
   248  		clusterDialer,
   249  		clusterServerConfig,
   250  		clusterGRPCServer,
   251  		conf,
   252  		signer,
   253  		metricsProvider,
   254  		opsSystem,
   255  		lf,
   256  		cryptoProvider,
   257  		tlsCallback,
   258  	)
   259  
   260  	adminServer := newAdminServer(conf.Admin)
   261  	adminServer.RegisterHandler(
   262  		channelparticipation.URLBaseV1,
   263  		channelparticipation.NewHTTPHandler(conf.ChannelParticipation, manager),
   264  		conf.Admin.TLS.Enabled,
   265  	)
   266  	if err = adminServer.Start(); err != nil {
   267  		logger.Panicf("failed to start admin server: %s", err)
   268  	}
   269  	defer adminServer.Stop()
   270  
   271  	mutualTLS := serverConfig.SecOpts.UseTLS && serverConfig.SecOpts.RequireClientCert
   272  	server := NewServer(
   273  		manager,
   274  		metricsProvider,
   275  		&conf.Debug,
   276  		conf.General.Authentication.TimeWindow,
   277  		mutualTLS,
   278  		conf.General.Authentication.NoExpirationChecks,
   279  	)
   280  
   281  	logger.Infof("Starting %s", metadata.GetVersionInfo())
   282  	handleSignals(addPlatformSignals(map[os.Signal]func(){
   283  		syscall.SIGTERM: func() {
   284  			grpcServer.Stop()
   285  			if clusterGRPCServer != grpcServer {
   286  				clusterGRPCServer.Stop()
   287  			}
   288  		},
   289  	}))
   290  
   291  	if !reuseGrpcListener && isClusterType {
   292  		logger.Info("Starting cluster listener on", clusterGRPCServer.Address())
   293  		go clusterGRPCServer.Start()
   294  	}
   295  
   296  	if conf.General.Profile.Enabled {
   297  		go initializeProfilingService(conf)
   298  	}
   299  	ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server)
   300  	logger.Info("Beginning to serve requests")
   301  	if err := grpcServer.Start(); err != nil {
   302  		logger.Fatalf("Atomic Broadcast gRPC server has terminated while serving requests due to: %v", err)
   303  	}
   304  }
   305  
   306  // Searches whether there is a join block for a system channel, and if there is, and it is a genesis block,
   307  // initializes the ledger with it. Returns the join-block if it finds one.
   308  func initSystemChannelWithJoinBlock(
   309  	config *localconfig.TopLevel,
   310  	cryptoProvider bccsp.BCCSP,
   311  	lf blockledger.Factory,
   312  ) (bootstrapBlock *cb.Block) {
   313  	if !config.ChannelParticipation.Enabled {
   314  		return nil
   315  	}
   316  
   317  	joinBlockFileRepo, err := multichannel.InitJoinBlockFileRepo(config)
   318  	if err != nil {
   319  		logger.Panicf("Failed initializing join-block file repo: %v", err)
   320  	}
   321  
   322  	joinBlockFiles, err := joinBlockFileRepo.List()
   323  	if err != nil {
   324  		logger.Panicf("Failed listing join-block file repo: %v", err)
   325  	}
   326  
   327  	var systemChannelID string
   328  	for _, fileName := range joinBlockFiles {
   329  		channelName := joinBlockFileRepo.FileToBaseName(fileName)
   330  		blockBytes, err := joinBlockFileRepo.Read(channelName)
   331  		if err != nil {
   332  			logger.Panicf("Failed reading join-block for channel '%s', error: %v", channelName, err)
   333  		}
   334  		block, err := protoutil.UnmarshalBlock(blockBytes)
   335  		if err != nil {
   336  			logger.Panicf("Failed unmarshalling join-block for channel '%s', error: %v", channelName, err)
   337  		}
   338  		if err = onboarding.ValidateBootstrapBlock(block, cryptoProvider); err == nil {
   339  			bootstrapBlock = block
   340  			systemChannelID = channelName
   341  			break
   342  		}
   343  	}
   344  
   345  	if bootstrapBlock == nil {
   346  		logger.Debug("No join-block was found for the system channel")
   347  		return nil
   348  	}
   349  
   350  	if bootstrapBlock.Header.Number == 0 {
   351  		initializeBootstrapChannel(bootstrapBlock, lf)
   352  	}
   353  
   354  	logger.Infof("Join-block was found for the system channel: %s, number: %d", systemChannelID, bootstrapBlock.Header.Number)
   355  	return bootstrapBlock
   356  }
   357  
   358  func discardSystemChannelJoinBlock(config *localconfig.TopLevel, bootstrapBlock *cb.Block) {
   359  	if !config.ChannelParticipation.Enabled {
   360  		return
   361  	}
   362  
   363  	systemChannelName, err := protoutil.GetChannelIDFromBlock(bootstrapBlock)
   364  	if err != nil {
   365  		logger.Panicf("Failed to extract system channel name from join-block: %s", err)
   366  	}
   367  	joinBlockFileRepo, err := multichannel.InitJoinBlockFileRepo(config)
   368  	if err != nil {
   369  		logger.Panicf("Failed initializing join-block file repo: %v", err)
   370  	}
   371  	err = joinBlockFileRepo.Remove(systemChannelName)
   372  	if err != nil {
   373  		logger.Panicf("Failed to remove join-block for system channel: %s", err)
   374  	}
   375  }
   376  
   377  func reuseListener(conf *localconfig.TopLevel) bool {
   378  	clusterConf := conf.General.Cluster
   379  	// If listen address is not configured, and the TLS certificate isn't configured,
   380  	// it means we use the general listener of the node.
   381  	if clusterConf.ListenPort == 0 && clusterConf.ServerCertificate == "" && clusterConf.ListenAddress == "" && clusterConf.ServerPrivateKey == "" {
   382  		logger.Info("Cluster listener is not configured, defaulting to use the general listener on port", conf.General.ListenPort)
   383  
   384  		if !conf.General.TLS.Enabled {
   385  			logger.Panicf("TLS is required for running ordering nodes of cluster type.")
   386  		}
   387  
   388  		return true
   389  	}
   390  
   391  	// Else, one of the above is defined, so all 4 properties should be defined.
   392  	if clusterConf.ListenPort == 0 || clusterConf.ServerCertificate == "" || clusterConf.ListenAddress == "" || clusterConf.ServerPrivateKey == "" {
   393  		logger.Panic("Options: General.Cluster.ListenPort, General.Cluster.ListenAddress, General.Cluster.ServerCertificate, General.Cluster.ServerPrivateKey, should be defined altogether.")
   394  	}
   395  
   396  	return false
   397  }
   398  
   399  // extractSystemChannel loops through all channels, and return the last
   400  // config block for the system channel. Returns nil if no system channel
   401  // was found.
   402  func extractSystemChannel(lf blockledger.Factory, bccsp bccsp.BCCSP) *cb.Block {
   403  	for _, cID := range lf.ChannelIDs() {
   404  		channelLedger, err := lf.GetOrCreate(cID)
   405  		if err != nil {
   406  			logger.Panicf("Failed getting channel %v's ledger: %v", cID, err)
   407  		}
   408  		if channelLedger.Height() == 0 {
   409  			continue // Some channels may have an empty ledger and (possibly) a join-block, skip those
   410  		}
   411  
   412  		channelConfigBlock := multichannel.ConfigBlockOrPanic(channelLedger)
   413  
   414  		err = onboarding.ValidateBootstrapBlock(channelConfigBlock, bccsp)
   415  		if err == nil {
   416  			logger.Infof("Found system channel config block, number: %d", channelConfigBlock.Header.Number)
   417  			return channelConfigBlock
   418  		}
   419  	}
   420  	return nil
   421  }
   422  
   423  // Select cluster boot block
   424  func selectClusterBootBlock(bootstrapBlock, sysChanLastConfig *cb.Block) *cb.Block {
   425  	if sysChanLastConfig == nil {
   426  		logger.Debug("Selected bootstrap block, because system channel last config block is nil")
   427  		return bootstrapBlock
   428  	}
   429  
   430  	if bootstrapBlock == nil {
   431  		logger.Debug("Selected system channel last config block, because bootstrap block is nil")
   432  		return sysChanLastConfig
   433  	}
   434  
   435  	if sysChanLastConfig.Header.Number > bootstrapBlock.Header.Number {
   436  		logger.Infof("Cluster boot block is system channel last config block; Blocks Header.Number system-channel=%d, bootstrap=%d",
   437  			sysChanLastConfig.Header.Number, bootstrapBlock.Header.Number)
   438  		return sysChanLastConfig
   439  	}
   440  
   441  	logger.Infof("Cluster boot block is bootstrap (genesis) block; Blocks Header.Number system-channel=%d, bootstrap=%d",
   442  		sysChanLastConfig.Header.Number, bootstrapBlock.Header.Number)
   443  	return bootstrapBlock
   444  }
   445  
   446  func initializeLogging() {
   447  	loggingSpec := os.Getenv("FABRIC_LOGGING_SPEC")
   448  	loggingFormat := os.Getenv("FABRIC_LOGGING_FORMAT")
   449  	flogging.Init(flogging.Config{
   450  		Format:  loggingFormat,
   451  		Writer:  os.Stderr,
   452  		LogSpec: loggingSpec,
   453  	})
   454  }
   455  
   456  // Start the profiling service if enabled.
   457  func initializeProfilingService(conf *localconfig.TopLevel) {
   458  	logger.Info("Starting Go pprof profiling service on:", conf.General.Profile.Address)
   459  	// The ListenAndServe() call does not return unless an error occurs.
   460  	logger.Panic("Go pprof service failed:", http.ListenAndServe(conf.General.Profile.Address, nil))
   461  }
   462  
   463  func handleSignals(handlers map[os.Signal]func()) {
   464  	var signals []os.Signal
   465  	for sig := range handlers {
   466  		signals = append(signals, sig)
   467  	}
   468  
   469  	signalChan := make(chan os.Signal, 1)
   470  	signal.Notify(signalChan, signals...)
   471  
   472  	go func() {
   473  		for sig := range signalChan {
   474  			logger.Infof("Received signal: %d (%s)", sig, sig)
   475  			handlers[sig]()
   476  		}
   477  	}()
   478  }
   479  
   480  type loadPEMFunc func(string) ([]byte, error)
   481  
   482  // configureClusterListener returns a new ServerConfig and a new gRPC server (with its own TLS listener).
   483  func configureClusterListener(conf *localconfig.TopLevel, generalConf comm.ServerConfig, loadPEM loadPEMFunc) (comm.ServerConfig, *comm.GRPCServer) {
   484  	clusterConf := conf.General.Cluster
   485  
   486  	cert, err := loadPEM(clusterConf.ServerCertificate)
   487  	if err != nil {
   488  		logger.Panicf("Failed to load cluster server certificate from '%s' (%s)", clusterConf.ServerCertificate, err)
   489  	}
   490  
   491  	key, err := loadPEM(clusterConf.ServerPrivateKey)
   492  	if err != nil {
   493  		logger.Panicf("Failed to load cluster server key from '%s' (%s)", clusterConf.ServerPrivateKey, err)
   494  	}
   495  
   496  	port := fmt.Sprintf("%d", clusterConf.ListenPort)
   497  	bindAddr := net.JoinHostPort(clusterConf.ListenAddress, port)
   498  
   499  	var clientRootCAs [][]byte
   500  	for _, serverRoot := range conf.General.Cluster.RootCAs {
   501  		rootCACert, err := loadPEM(serverRoot)
   502  		if err != nil {
   503  			logger.Panicf("Failed to load CA cert file '%s' (%s)", serverRoot, err)
   504  		}
   505  		clientRootCAs = append(clientRootCAs, rootCACert)
   506  	}
   507  
   508  	serverConf := comm.ServerConfig{
   509  		StreamInterceptors: generalConf.StreamInterceptors,
   510  		UnaryInterceptors:  generalConf.UnaryInterceptors,
   511  		ConnectionTimeout:  generalConf.ConnectionTimeout,
   512  		ServerStatsHandler: generalConf.ServerStatsHandler,
   513  		Logger:             generalConf.Logger,
   514  		KaOpts:             generalConf.KaOpts,
   515  		SecOpts: comm.SecureOptions{
   516  			TimeShift:         conf.General.Cluster.TLSHandshakeTimeShift,
   517  			CipherSuites:      comm.DefaultTLSCipherSuites,
   518  			ClientRootCAs:     clientRootCAs,
   519  			RequireClientCert: true,
   520  			Certificate:       cert,
   521  			UseTLS:            true,
   522  			Key:               key,
   523  		},
   524  	}
   525  
   526  	srv, err := comm.NewGRPCServer(bindAddr, serverConf)
   527  	if err != nil {
   528  		logger.Panicf("Failed creating gRPC server on %s:%d due to %v", clusterConf.ListenAddress, clusterConf.ListenPort, err)
   529  	}
   530  
   531  	return serverConf, srv
   532  }
   533  
   534  func initializeClusterClientConfig(conf *localconfig.TopLevel) (comm.ClientConfig, bool) {
   535  	cc := comm.ClientConfig{
   536  		AsyncConnect:   true,
   537  		KaOpts:         comm.DefaultKeepaliveOptions,
   538  		DialTimeout:    conf.General.Cluster.DialTimeout,
   539  		SecOpts:        comm.SecureOptions{},
   540  		MaxRecvMsgSize: int(conf.General.MaxRecvMsgSize),
   541  		MaxSendMsgSize: int(conf.General.MaxSendMsgSize),
   542  	}
   543  
   544  	reuseGrpcListener := reuseListener(conf)
   545  
   546  	certFile := conf.General.Cluster.ClientCertificate
   547  	keyFile := conf.General.Cluster.ClientPrivateKey
   548  	if certFile == "" && keyFile == "" {
   549  		if !reuseGrpcListener {
   550  			return cc, reuseGrpcListener
   551  		}
   552  		certFile = conf.General.TLS.Certificate
   553  		keyFile = conf.General.TLS.PrivateKey
   554  	}
   555  
   556  	certBytes, err := ioutil.ReadFile(certFile)
   557  	if err != nil {
   558  		logger.Fatalf("Failed to load client TLS certificate file '%s' (%s)", certFile, err)
   559  	}
   560  
   561  	keyBytes, err := ioutil.ReadFile(keyFile)
   562  	if err != nil {
   563  		logger.Fatalf("Failed to load client TLS key file '%s' (%s)", keyFile, err)
   564  	}
   565  
   566  	var serverRootCAs [][]byte
   567  	for _, serverRoot := range conf.General.Cluster.RootCAs {
   568  		rootCACert, err := ioutil.ReadFile(serverRoot)
   569  		if err != nil {
   570  			logger.Fatalf("Failed to load ServerRootCAs file '%s' (%s)", serverRoot, err)
   571  		}
   572  		serverRootCAs = append(serverRootCAs, rootCACert)
   573  	}
   574  
   575  	timeShift := conf.General.TLS.TLSHandshakeTimeShift
   576  	if !reuseGrpcListener {
   577  		timeShift = conf.General.Cluster.TLSHandshakeTimeShift
   578  	}
   579  
   580  	cc.SecOpts = comm.SecureOptions{
   581  		TimeShift:         timeShift,
   582  		RequireClientCert: true,
   583  		CipherSuites:      comm.DefaultTLSCipherSuites,
   584  		ServerRootCAs:     serverRootCAs,
   585  		Certificate:       certBytes,
   586  		Key:               keyBytes,
   587  		UseTLS:            true,
   588  	}
   589  
   590  	return cc, reuseGrpcListener
   591  }
   592  
   593  func initializeServerConfig(conf *localconfig.TopLevel, metricsProvider metrics.Provider) comm.ServerConfig {
   594  	// secure server config
   595  	secureOpts := comm.SecureOptions{
   596  		UseTLS:            conf.General.TLS.Enabled,
   597  		RequireClientCert: conf.General.TLS.ClientAuthRequired,
   598  		TimeShift:         conf.General.TLS.TLSHandshakeTimeShift,
   599  	}
   600  	// check to see if TLS is enabled
   601  	if secureOpts.UseTLS {
   602  		msg := "TLS"
   603  		// load crypto material from files
   604  		serverCertificate, err := ioutil.ReadFile(conf.General.TLS.Certificate)
   605  		if err != nil {
   606  			logger.Fatalf("Failed to load server Certificate file '%s' (%s)",
   607  				conf.General.TLS.Certificate, err)
   608  		}
   609  		serverKey, err := ioutil.ReadFile(conf.General.TLS.PrivateKey)
   610  		if err != nil {
   611  			logger.Fatalf("Failed to load PrivateKey file '%s' (%s)",
   612  				conf.General.TLS.PrivateKey, err)
   613  		}
   614  		var serverRootCAs, clientRootCAs [][]byte
   615  		for _, serverRoot := range conf.General.TLS.RootCAs {
   616  			root, err := ioutil.ReadFile(serverRoot)
   617  			if err != nil {
   618  				logger.Fatalf("Failed to load ServerRootCAs file '%s' (%s)",
   619  					err, serverRoot)
   620  			}
   621  			serverRootCAs = append(serverRootCAs, root)
   622  		}
   623  		if secureOpts.RequireClientCert {
   624  			for _, clientRoot := range conf.General.TLS.ClientRootCAs {
   625  				root, err := ioutil.ReadFile(clientRoot)
   626  				if err != nil {
   627  					logger.Fatalf("Failed to load ClientRootCAs file '%s' (%s)",
   628  						err, clientRoot)
   629  				}
   630  				clientRootCAs = append(clientRootCAs, root)
   631  			}
   632  			msg = "mutual TLS"
   633  		}
   634  		secureOpts.Key = serverKey
   635  		secureOpts.Certificate = serverCertificate
   636  		secureOpts.ServerRootCAs = serverRootCAs
   637  		secureOpts.ClientRootCAs = clientRootCAs
   638  		logger.Infof("Starting orderer with %s enabled", msg)
   639  	}
   640  	kaOpts := comm.DefaultKeepaliveOptions
   641  	// keepalive settings
   642  	// ServerMinInterval must be greater than 0
   643  	if conf.General.Keepalive.ServerMinInterval > time.Duration(0) {
   644  		kaOpts.ServerMinInterval = conf.General.Keepalive.ServerMinInterval
   645  	}
   646  	kaOpts.ServerInterval = conf.General.Keepalive.ServerInterval
   647  	kaOpts.ServerTimeout = conf.General.Keepalive.ServerTimeout
   648  
   649  	commLogger := flogging.MustGetLogger("core.comm").With("server", "Orderer")
   650  
   651  	if metricsProvider == nil {
   652  		metricsProvider = &disabled.Provider{}
   653  	}
   654  
   655  	return comm.ServerConfig{
   656  		SecOpts:            secureOpts,
   657  		KaOpts:             kaOpts,
   658  		Logger:             commLogger,
   659  		ServerStatsHandler: comm.NewServerStatsHandler(metricsProvider),
   660  		ConnectionTimeout:  conf.General.ConnectionTimeout,
   661  		StreamInterceptors: []grpc.StreamServerInterceptor{
   662  			grpcmetrics.StreamServerInterceptor(grpcmetrics.NewStreamMetrics(metricsProvider)),
   663  			grpclogging.StreamServerInterceptor(flogging.MustGetLogger("comm.grpc.server").Zap()),
   664  		},
   665  		UnaryInterceptors: []grpc.UnaryServerInterceptor{
   666  			grpcmetrics.UnaryServerInterceptor(grpcmetrics.NewUnaryMetrics(metricsProvider)),
   667  			grpclogging.UnaryServerInterceptor(
   668  				flogging.MustGetLogger("comm.grpc.server").Zap(),
   669  				grpclogging.WithLeveler(grpclogging.LevelerFunc(grpcLeveler)),
   670  			),
   671  		},
   672  		MaxRecvMsgSize: int(conf.General.MaxRecvMsgSize),
   673  		MaxSendMsgSize: int(conf.General.MaxSendMsgSize),
   674  	}
   675  }
   676  
   677  func grpcLeveler(ctx context.Context, fullMethod string) zapcore.Level {
   678  	switch fullMethod {
   679  	case "/orderer.Cluster/Step":
   680  		return flogging.DisabledLevel
   681  	default:
   682  		return zapcore.InfoLevel
   683  	}
   684  }
   685  
   686  func extractBootstrapBlock(conf *localconfig.TopLevel) *cb.Block {
   687  	var bootstrapBlock *cb.Block
   688  
   689  	// Select the bootstrapping mechanism
   690  	switch conf.General.BootstrapMethod {
   691  	case "file": // For now, "file" is the only supported genesis method
   692  		bootstrapBlock = file.New(conf.General.BootstrapFile).GenesisBlock()
   693  	case "none": // simply honor the configuration value
   694  		return nil
   695  	default:
   696  		logger.Panic("Unknown genesis method:", conf.General.BootstrapMethod)
   697  	}
   698  
   699  	return bootstrapBlock
   700  }
   701  
   702  func initializeBootstrapChannel(genesisBlock *cb.Block, lf blockledger.Factory) {
   703  	channelID, err := protoutil.GetChannelIDFromBlock(genesisBlock)
   704  	if err != nil {
   705  		logger.Fatal("Failed to parse channel ID from genesis block:", err)
   706  	}
   707  	gl, err := lf.GetOrCreate(channelID)
   708  	if err != nil {
   709  		logger.Fatal("Failed to create the system channel:", err)
   710  	}
   711  	if gl.Height() == 0 {
   712  		if err := gl.Append(genesisBlock); err != nil {
   713  			logger.Fatal("Could not write genesis block to ledger:", err)
   714  		}
   715  	}
   716  	logger.Infof("Initialized the system channel '%s' from bootstrap block", channelID)
   717  }
   718  
   719  func isClusterType(genesisBlock *cb.Block, bccsp bccsp.BCCSP) bool {
   720  	_, exists := clusterTypes[consensusType(genesisBlock, bccsp)]
   721  	return exists
   722  }
   723  
   724  func consensusType(genesisBlock *cb.Block, bccsp bccsp.BCCSP) string {
   725  	if genesisBlock == nil || genesisBlock.Data == nil || len(genesisBlock.Data.Data) == 0 {
   726  		logger.Fatalf("Empty genesis block")
   727  	}
   728  	env := &cb.Envelope{}
   729  	if err := proto.Unmarshal(genesisBlock.Data.Data[0], env); err != nil {
   730  		logger.Fatalf("Failed to unmarshal the genesis block's envelope: %v", err)
   731  	}
   732  	bundle, err := channelconfig.NewBundleFromEnvelope(env, bccsp)
   733  	if err != nil {
   734  		logger.Fatalf("Failed creating bundle from the genesis block: %v", err)
   735  	}
   736  	ordConf, exists := bundle.OrdererConfig()
   737  	if !exists {
   738  		logger.Fatalf("Orderer config doesn't exist in bundle derived from genesis block")
   739  	}
   740  	return ordConf.ConsensusType()
   741  }
   742  
   743  func initializeGrpcServer(conf *localconfig.TopLevel, serverConfig comm.ServerConfig) *comm.GRPCServer {
   744  	lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort))
   745  	if err != nil {
   746  		logger.Fatal("Failed to listen:", err)
   747  	}
   748  
   749  	// Create GRPC server - return if an error occurs
   750  	grpcServer, err := comm.NewGRPCServerFromListener(lis, serverConfig)
   751  	if err != nil {
   752  		logger.Fatal("Failed to return new GRPC server:", err)
   753  	}
   754  
   755  	return grpcServer
   756  }
   757  
   758  func loadLocalMSP(conf *localconfig.TopLevel) msp.MSP {
   759  	// MUST call GetLocalMspConfig first, so that default BCCSP is properly
   760  	// initialized prior to LoadByType.
   761  	mspConfig, err := msp.GetLocalMspConfig(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
   762  	if err != nil {
   763  		logger.Panicf("Failed to get local msp config: %v", err)
   764  	}
   765  
   766  	typ := msp.ProviderTypeToString(msp.FABRIC)
   767  	opts, found := msp.Options[typ]
   768  	if !found {
   769  		logger.Panicf("MSP option for type %s is not found", typ)
   770  	}
   771  
   772  	localmsp, err := msp.New(opts, factory.GetDefault())
   773  	if err != nil {
   774  		logger.Panicf("Failed to load local MSP: %v", err)
   775  	}
   776  
   777  	if err = localmsp.Setup(mspConfig); err != nil {
   778  		logger.Panicf("Failed to setup local msp with config: %v", err)
   779  	}
   780  
   781  	return localmsp
   782  }
   783  
   784  //go:generate counterfeiter -o mocks/health_checker.go -fake-name HealthChecker . healthChecker
   785  
   786  // HealthChecker defines the contract for health checker
   787  type healthChecker interface {
   788  	RegisterChecker(component string, checker healthz.HealthChecker) error
   789  }
   790  
   791  func initializeMultichannelRegistrar(
   792  	bootstrapBlock *cb.Block,
   793  	repInitiator *onboarding.ReplicationInitiator,
   794  	clusterDialer *cluster.PredicateDialer,
   795  	srvConf comm.ServerConfig,
   796  	srv *comm.GRPCServer,
   797  	conf *localconfig.TopLevel,
   798  	signer identity.SignerSerializer,
   799  	metricsProvider metrics.Provider,
   800  	healthChecker healthChecker,
   801  	lf blockledger.Factory,
   802  	bccsp bccsp.BCCSP,
   803  	callbacks ...channelconfig.BundleActor,
   804  ) *multichannel.Registrar {
   805  	registrar := multichannel.NewRegistrar(*conf, lf, signer, metricsProvider, bccsp, clusterDialer, callbacks...)
   806  
   807  	consenters := map[string]consensus.Consenter{}
   808  
   809  	var icr etcdraft.InactiveChainRegistry
   810  	if conf.General.BootstrapMethod == "file" || conf.General.BootstrapMethod == "none" {
   811  		if bootstrapBlock != nil && isClusterType(bootstrapBlock, bccsp) {
   812  			// with a system channel
   813  			etcdConsenter := initializeEtcdraftConsenter(consenters, conf, lf, clusterDialer, bootstrapBlock, repInitiator, srvConf, srv, registrar, metricsProvider, bccsp)
   814  			icr = etcdConsenter.InactiveChainRegistry
   815  		} else if bootstrapBlock == nil {
   816  			// without a system channel: assume cluster type, InactiveChainRegistry == nil, no go-routine.
   817  			consenters["etcdraft"] = etcdraft.New(clusterDialer, conf, srvConf, srv, registrar, nil, metricsProvider, bccsp)
   818  		}
   819  	}
   820  
   821  	consenters["solo"] = solo.New()
   822  	var kafkaMetrics *kafka.Metrics
   823  	consenters["kafka"], kafkaMetrics = kafka.New(conf.Kafka, metricsProvider, healthChecker, icr, registrar.CreateChain)
   824  
   825  	// Note, we pass a 'nil' channel here, we could pass a channel that
   826  	// closes if we wished to cleanup this routine on exit.
   827  	go kafkaMetrics.PollGoMetricsUntilStop(time.Minute, nil)
   828  	registrar.Initialize(consenters)
   829  	return registrar
   830  }
   831  
   832  func initializeEtcdraftConsenter(
   833  	consenters map[string]consensus.Consenter,
   834  	conf *localconfig.TopLevel,
   835  	lf blockledger.Factory,
   836  	clusterDialer *cluster.PredicateDialer,
   837  	bootstrapBlock *cb.Block,
   838  	ri *onboarding.ReplicationInitiator,
   839  	srvConf comm.ServerConfig,
   840  	srv *comm.GRPCServer,
   841  	registrar *multichannel.Registrar,
   842  	metricsProvider metrics.Provider,
   843  	bccsp bccsp.BCCSP,
   844  ) *etcdraft.Consenter {
   845  	systemChannelName, err := protoutil.GetChannelIDFromBlock(bootstrapBlock)
   846  	if err != nil {
   847  		logger.Panicf("Failed extracting system channel name from bootstrap block: %v", err)
   848  	}
   849  	systemLedger, err := lf.GetOrCreate(systemChannelName)
   850  	if err != nil {
   851  		logger.Panicf("Failed obtaining system channel (%s) ledger: %v", systemChannelName, err)
   852  	}
   853  	getConfigBlock := func() *cb.Block {
   854  		return multichannel.ConfigBlockOrPanic(systemLedger)
   855  	}
   856  
   857  	icr := onboarding.NewInactiveChainReplicator(ri, getConfigBlock, ri.RegisterChain, conf.General.Cluster.ReplicationBackgroundRefreshInterval)
   858  
   859  	// Use the inactiveChainReplicator as a channel lister, since it has knowledge
   860  	// of all inactive chains.
   861  	// This is to prevent us pulling the entire system chain when attempting to enumerate
   862  	// the channels in the system.
   863  	ri.ChannelLister = icr
   864  
   865  	go icr.Run()
   866  	raftConsenter := etcdraft.New(clusterDialer, conf, srvConf, srv, registrar, icr, metricsProvider, bccsp)
   867  	consenters["etcdraft"] = raftConsenter
   868  	return raftConsenter
   869  }
   870  
   871  func newOperationsSystem(ops localconfig.Operations, metrics localconfig.Metrics) *operations.System {
   872  	return operations.NewSystem(operations.Options{
   873  		Options: fabhttp.Options{
   874  			Logger:        flogging.MustGetLogger("orderer.operations"),
   875  			ListenAddress: ops.ListenAddress,
   876  			TLS: fabhttp.TLS{
   877  				Enabled:            ops.TLS.Enabled,
   878  				CertFile:           ops.TLS.Certificate,
   879  				KeyFile:            ops.TLS.PrivateKey,
   880  				ClientCertRequired: ops.TLS.ClientAuthRequired,
   881  				ClientCACertFiles:  ops.TLS.ClientRootCAs,
   882  			},
   883  		},
   884  		Metrics: operations.MetricsOptions{
   885  			Provider: metrics.Provider,
   886  			Statsd: &operations.Statsd{
   887  				Network:       metrics.Statsd.Network,
   888  				Address:       metrics.Statsd.Address,
   889  				WriteInterval: metrics.Statsd.WriteInterval,
   890  				Prefix:        metrics.Statsd.Prefix,
   891  			},
   892  		},
   893  		Version: metadata.Version,
   894  	})
   895  }
   896  
   897  func newAdminServer(admin localconfig.Admin) *fabhttp.Server {
   898  	return fabhttp.NewServer(fabhttp.Options{
   899  		Logger:        flogging.MustGetLogger("orderer.admin"),
   900  		ListenAddress: admin.ListenAddress,
   901  		TLS: fabhttp.TLS{
   902  			Enabled:            admin.TLS.Enabled,
   903  			CertFile:           admin.TLS.Certificate,
   904  			KeyFile:            admin.TLS.PrivateKey,
   905  			ClientCertRequired: admin.TLS.ClientAuthRequired,
   906  			ClientCACertFiles:  admin.TLS.ClientRootCAs,
   907  		},
   908  	})
   909  }
   910  
   911  // caMgr manages certificate authorities scoped by channel
   912  type caManager struct {
   913  	sync.Mutex
   914  	appRootCAsByChain     map[string][][]byte
   915  	ordererRootCAsByChain map[string][][]byte
   916  	clientRootCAs         [][]byte
   917  }
   918  
   919  func (mgr *caManager) updateTrustedRoots(
   920  	cm channelconfig.Resources,
   921  	servers ...*comm.GRPCServer,
   922  ) {
   923  	mgr.Lock()
   924  	defer mgr.Unlock()
   925  
   926  	appRootCAs := [][]byte{}
   927  	ordererRootCAs := [][]byte{}
   928  	appOrgMSPs := make(map[string]struct{})
   929  	ordOrgMSPs := make(map[string]struct{})
   930  
   931  	if ac, ok := cm.ApplicationConfig(); ok {
   932  		// loop through app orgs and build map of MSPIDs
   933  		for _, appOrg := range ac.Organizations() {
   934  			appOrgMSPs[appOrg.MSPID()] = struct{}{}
   935  		}
   936  	}
   937  
   938  	if ac, ok := cm.OrdererConfig(); ok {
   939  		// loop through orderer orgs and build map of MSPIDs
   940  		for _, ordOrg := range ac.Organizations() {
   941  			ordOrgMSPs[ordOrg.MSPID()] = struct{}{}
   942  		}
   943  	}
   944  
   945  	if cc, ok := cm.ConsortiumsConfig(); ok {
   946  		for _, consortium := range cc.Consortiums() {
   947  			// loop through consortium orgs and build map of MSPIDs
   948  			for _, consortiumOrg := range consortium.Organizations() {
   949  				appOrgMSPs[consortiumOrg.MSPID()] = struct{}{}
   950  			}
   951  		}
   952  	}
   953  
   954  	cid := cm.ConfigtxValidator().ChannelID()
   955  	logger.Debugf("updating root CAs for channel [%s]", cid)
   956  	msps, err := cm.MSPManager().GetMSPs()
   957  	if err != nil {
   958  		logger.Errorf("Error getting root CAs for channel %s (%s)", cid, err)
   959  		return
   960  	}
   961  	for k, v := range msps {
   962  		// check to see if this is a FABRIC MSP
   963  		if v.GetType() == msp.FABRIC {
   964  			for _, root := range v.GetTLSRootCerts() {
   965  				// check to see of this is an app org MSP
   966  				if _, ok := appOrgMSPs[k]; ok {
   967  					logger.Debugf("adding app root CAs for MSP [%s]", k)
   968  					appRootCAs = append(appRootCAs, root)
   969  				}
   970  				// check to see of this is an orderer org MSP
   971  				if _, ok := ordOrgMSPs[k]; ok {
   972  					logger.Debugf("adding orderer root CAs for MSP [%s]", k)
   973  					ordererRootCAs = append(ordererRootCAs, root)
   974  				}
   975  			}
   976  			for _, intermediate := range v.GetTLSIntermediateCerts() {
   977  				// check to see of this is an app org MSP
   978  				if _, ok := appOrgMSPs[k]; ok {
   979  					logger.Debugf("adding app root CAs for MSP [%s]", k)
   980  					appRootCAs = append(appRootCAs, intermediate)
   981  				}
   982  				// check to see of this is an orderer org MSP
   983  				if _, ok := ordOrgMSPs[k]; ok {
   984  					logger.Debugf("adding orderer root CAs for MSP [%s]", k)
   985  					ordererRootCAs = append(ordererRootCAs, intermediate)
   986  				}
   987  			}
   988  		}
   989  	}
   990  	mgr.appRootCAsByChain[cid] = appRootCAs
   991  	mgr.ordererRootCAsByChain[cid] = ordererRootCAs
   992  
   993  	// now iterate over all roots for all app and orderer chains
   994  	trustedRoots := [][]byte{}
   995  	for _, roots := range mgr.appRootCAsByChain {
   996  		trustedRoots = append(trustedRoots, roots...)
   997  	}
   998  	for _, roots := range mgr.ordererRootCAsByChain {
   999  		trustedRoots = append(trustedRoots, roots...)
  1000  	}
  1001  	// also need to append statically configured root certs
  1002  	if len(mgr.clientRootCAs) > 0 {
  1003  		trustedRoots = append(trustedRoots, mgr.clientRootCAs...)
  1004  	}
  1005  
  1006  	// now update the client roots for the gRPC server
  1007  	for _, srv := range servers {
  1008  		err = srv.SetClientRootCAs(trustedRoots)
  1009  		if err != nil {
  1010  			msg := "Failed to update trusted roots for orderer from latest config " +
  1011  				"block.  This orderer may not be able to communicate " +
  1012  				"with members of channel %s (%s)"
  1013  			logger.Warningf(msg, cm.ConfigtxValidator().ChannelID(), err)
  1014  		}
  1015  	}
  1016  }
  1017  
  1018  func (mgr *caManager) updateClusterDialer(
  1019  	clusterDialer *cluster.PredicateDialer,
  1020  	localClusterRootCAs [][]byte,
  1021  ) {
  1022  	mgr.Lock()
  1023  	defer mgr.Unlock()
  1024  
  1025  	// Iterate over all orderer root CAs for all chains and add them
  1026  	// to the root CAs
  1027  	clusterRootCAs := make(cluster.StringSet)
  1028  	for _, orgRootCAs := range mgr.ordererRootCAsByChain {
  1029  		for _, rootCA := range orgRootCAs {
  1030  			clusterRootCAs[string(rootCA)] = struct{}{}
  1031  		}
  1032  	}
  1033  
  1034  	// Add the local root CAs too
  1035  	for _, localRootCA := range localClusterRootCAs {
  1036  		clusterRootCAs[string(localRootCA)] = struct{}{}
  1037  	}
  1038  
  1039  	// Convert StringSet to byte slice
  1040  	var clusterRootCAsBytes [][]byte
  1041  	for root := range clusterRootCAs {
  1042  		clusterRootCAsBytes = append(clusterRootCAsBytes, []byte(root))
  1043  	}
  1044  
  1045  	// Update the cluster config with the new root CAs
  1046  	clusterDialer.UpdateRootCAs(clusterRootCAsBytes)
  1047  }
  1048  
  1049  func prettyPrintStruct(i interface{}) {
  1050  	params := localconfig.Flatten(i)
  1051  	var buffer bytes.Buffer
  1052  	for i := range params {
  1053  		buffer.WriteString("\n\t")
  1054  		buffer.WriteString(params[i])
  1055  	}
  1056  	logger.Infof("Orderer config values:%s\n", buffer.String())
  1057  }