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