github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/orderer/common/server/main.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package server
     8  
     9  import (
    10  	"fmt"
    11  	"io/ioutil"
    12  	"log"
    13  	"net"
    14  	"net/http"
    15  	_ "net/http/pprof"
    16  	"os"
    17  
    18  	genesisconfig "github.com/hyperledger/fabric/common/configtx/tool/localconfig"
    19  	"github.com/hyperledger/fabric/common/configtx/tool/provisional"
    20  	"github.com/hyperledger/fabric/common/crypto"
    21  	"github.com/hyperledger/fabric/common/flogging"
    22  	"github.com/hyperledger/fabric/core/comm"
    23  	"github.com/hyperledger/fabric/orderer/common/bootstrap/file"
    24  	"github.com/hyperledger/fabric/orderer/common/ledger"
    25  	"github.com/hyperledger/fabric/orderer/common/localconfig"
    26  	"github.com/hyperledger/fabric/orderer/common/metadata"
    27  	"github.com/hyperledger/fabric/orderer/common/multichannel"
    28  	"github.com/hyperledger/fabric/orderer/consensus/kafka"
    29  	"github.com/hyperledger/fabric/orderer/consensus/solo"
    30  	cb "github.com/hyperledger/fabric/protos/common"
    31  	ab "github.com/hyperledger/fabric/protos/orderer"
    32  	"github.com/hyperledger/fabric/protos/utils"
    33  
    34  	"github.com/Shopify/sarama"
    35  	"github.com/hyperledger/fabric/common/localmsp"
    36  	mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
    37  	logging "github.com/op/go-logging"
    38  	"gopkg.in/alecthomas/kingpin.v2"
    39  )
    40  
    41  var logger = logging.MustGetLogger("orderer/server/main")
    42  
    43  //command line flags
    44  var (
    45  	app = kingpin.New("orderer", "Hyperledger Fabric orderer node")
    46  
    47  	start   = app.Command("start", "Start the orderer node").Default()
    48  	version = app.Command("version", "Show version information")
    49  )
    50  
    51  func Main() {
    52  
    53  	kingpin.Version("0.0.1")
    54  	switch kingpin.MustParse(app.Parse(os.Args[1:])) {
    55  
    56  	// "start" command
    57  	case start.FullCommand():
    58  		logger.Infof("Starting %s", metadata.GetVersionInfo())
    59  		conf := config.Load()
    60  		initializeLoggingLevel(conf)
    61  		initializeProfilingService(conf)
    62  		grpcServer := initializeGrpcServer(conf)
    63  		initializeLocalMsp(conf)
    64  		signer := localmsp.NewSigner()
    65  		manager := initializeMultiChainManager(conf, signer)
    66  		server := NewServer(manager, signer)
    67  		ab.RegisterAtomicBroadcastServer(grpcServer.Server(), server)
    68  		logger.Info("Beginning to serve requests")
    69  		grpcServer.Start()
    70  	// "version" command
    71  	case version.FullCommand():
    72  		fmt.Println(metadata.GetVersionInfo())
    73  	}
    74  
    75  }
    76  
    77  // Set the logging level
    78  func initializeLoggingLevel(conf *config.TopLevel) {
    79  	flogging.InitFromSpec(conf.General.LogLevel)
    80  	if conf.Kafka.Verbose {
    81  		sarama.Logger = log.New(os.Stdout, "[sarama] ", log.Ldate|log.Lmicroseconds|log.Lshortfile)
    82  	}
    83  }
    84  
    85  // Start the profiling service if enabled.
    86  func initializeProfilingService(conf *config.TopLevel) {
    87  	if conf.General.Profile.Enabled {
    88  		go func() {
    89  			logger.Info("Starting Go pprof profiling service on:", conf.General.Profile.Address)
    90  			// The ListenAndServe() call does not return unless an error occurs.
    91  			logger.Panic("Go pprof service failed:", http.ListenAndServe(conf.General.Profile.Address, nil))
    92  		}()
    93  	}
    94  }
    95  
    96  func initializeSecureServerConfig(conf *config.TopLevel) comm.SecureServerConfig {
    97  	// secure server config
    98  	secureConfig := comm.SecureServerConfig{
    99  		UseTLS:            conf.General.TLS.Enabled,
   100  		RequireClientCert: conf.General.TLS.ClientAuthEnabled,
   101  	}
   102  	// check to see if TLS is enabled
   103  	if secureConfig.UseTLS {
   104  		logger.Info("Starting orderer with TLS enabled")
   105  		// load crypto material from files
   106  		serverCertificate, err := ioutil.ReadFile(conf.General.TLS.Certificate)
   107  		if err != nil {
   108  			logger.Fatalf("Failed to load ServerCertificate file '%s' (%s)",
   109  				conf.General.TLS.Certificate, err)
   110  		}
   111  		serverKey, err := ioutil.ReadFile(conf.General.TLS.PrivateKey)
   112  		if err != nil {
   113  			logger.Fatalf("Failed to load PrivateKey file '%s' (%s)",
   114  				conf.General.TLS.PrivateKey, err)
   115  		}
   116  		var serverRootCAs, clientRootCAs [][]byte
   117  		for _, serverRoot := range conf.General.TLS.RootCAs {
   118  			root, err := ioutil.ReadFile(serverRoot)
   119  			if err != nil {
   120  				logger.Fatalf("Failed to load ServerRootCAs file '%s' (%s)",
   121  					err, serverRoot)
   122  			}
   123  			serverRootCAs = append(serverRootCAs, root)
   124  		}
   125  		if secureConfig.RequireClientCert {
   126  			for _, clientRoot := range conf.General.TLS.ClientRootCAs {
   127  				root, err := ioutil.ReadFile(clientRoot)
   128  				if err != nil {
   129  					logger.Fatalf("Failed to load ClientRootCAs file '%s' (%s)",
   130  						err, clientRoot)
   131  				}
   132  				clientRootCAs = append(clientRootCAs, root)
   133  			}
   134  		}
   135  		secureConfig.ServerKey = serverKey
   136  		secureConfig.ServerCertificate = serverCertificate
   137  		secureConfig.ServerRootCAs = serverRootCAs
   138  		secureConfig.ClientRootCAs = clientRootCAs
   139  	}
   140  	return secureConfig
   141  }
   142  
   143  func initializeBootstrapChannel(conf *config.TopLevel, lf ledger.Factory) {
   144  	var genesisBlock *cb.Block
   145  
   146  	// Select the bootstrapping mechanism
   147  	switch conf.General.GenesisMethod {
   148  	case "provisional":
   149  		genesisBlock = provisional.New(genesisconfig.Load(conf.General.GenesisProfile)).GenesisBlock()
   150  	case "file":
   151  		genesisBlock = file.New(conf.General.GenesisFile).GenesisBlock()
   152  	default:
   153  		logger.Panic("Unknown genesis method:", conf.General.GenesisMethod)
   154  	}
   155  
   156  	chainID, err := utils.GetChainIDFromBlock(genesisBlock)
   157  	if err != nil {
   158  		logger.Fatal("Failed to parse chain ID from genesis block:", err)
   159  	}
   160  	gl, err := lf.GetOrCreate(chainID)
   161  	if err != nil {
   162  		logger.Fatal("Failed to create the system chain:", err)
   163  	}
   164  
   165  	err = gl.Append(genesisBlock)
   166  	if err != nil {
   167  		logger.Fatal("Could not write genesis block to ledger:", err)
   168  	}
   169  }
   170  
   171  func initializeGrpcServer(conf *config.TopLevel) comm.GRPCServer {
   172  	secureConfig := initializeSecureServerConfig(conf)
   173  
   174  	lis, err := net.Listen("tcp", fmt.Sprintf("%s:%d", conf.General.ListenAddress, conf.General.ListenPort))
   175  	if err != nil {
   176  		logger.Fatal("Failed to listen:", err)
   177  	}
   178  
   179  	// Create GRPC server - return if an error occurs
   180  	grpcServer, err := comm.NewGRPCServerFromListener(lis, secureConfig)
   181  	if err != nil {
   182  		logger.Fatal("Failed to return new GRPC server:", err)
   183  	}
   184  
   185  	return grpcServer
   186  }
   187  
   188  func initializeLocalMsp(conf *config.TopLevel) {
   189  	// Load local MSP
   190  	err := mspmgmt.LoadLocalMsp(conf.General.LocalMSPDir, conf.General.BCCSP, conf.General.LocalMSPID)
   191  	if err != nil { // Handle errors reading the config file
   192  		logger.Fatal("Failed to initialize local MSP:", err)
   193  	}
   194  }
   195  
   196  func initializeMultiChainManager(conf *config.TopLevel, signer crypto.LocalSigner) multichannel.Manager {
   197  	lf, _ := createLedgerFactory(conf)
   198  	// Are we bootstrapping?
   199  	if len(lf.ChainIDs()) == 0 {
   200  		initializeBootstrapChannel(conf, lf)
   201  	} else {
   202  		logger.Info("Not bootstrapping because of existing chains")
   203  	}
   204  
   205  	consenters := make(map[string]multichannel.Consenter)
   206  	consenters["solo"] = solo.New()
   207  	consenters["kafka"] = kafka.New(conf.Kafka.TLS, conf.Kafka.Retry, conf.Kafka.Version)
   208  
   209  	return multichannel.NewManagerImpl(lf, consenters, signer)
   210  }