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 }