func serve(args []string) error { // Parameter overrides must be processed before any paramaters are // cached. Failures to cache cause the server to terminate immediately. if chaincodeDevMode { logger.Info("Running in chaincode development mode") logger.Info("Set consensus to NOOPS and user starts chaincode") logger.Info("Disable loading validity system chaincode") viper.Set("peer.validator.enabled", "true") viper.Set("peer.validator.consensus", "noops") viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode) } if err := peer.CacheConfiguration(); err != nil { return err } peerEndpoint, err := peer.GetPeerEndpoint() if err != nil { err = fmt.Errorf("Failed to get Peer Endpoint: %s", err) return err } listenAddr := viper.GetString("peer.listenAddress") if "" == listenAddr { logger.Debug("Listen address not specified, using peer endpoint address") listenAddr = peerEndpoint.Address } lis, err := net.Listen("tcp", listenAddr) if err != nil { grpclog.Fatalf("Failed to listen: %v", err) } ehubLis, ehubGrpcServer, err := createEventHubServer() if err != nil { grpclog.Fatalf("Failed to create ehub server: %v", err) } logger.Infof("Security enabled status: %t", core.SecurityEnabled()) if viper.GetBool("security.privacy") { if core.SecurityEnabled() { logger.Infof("Privacy enabled status: true") } else { panic(errors.New("Privacy cannot be enabled as requested because security is disabled")) } } else { logger.Infof("Privacy enabled status: false") } var opts []grpc.ServerOption if comm.TLSEnabled() { creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"), viper.GetString("peer.tls.key.file")) if err != nil { grpclog.Fatalf("Failed to generate credentials %v", err) } opts = []grpc.ServerOption{grpc.Creds(creds)} } grpcServer := grpc.NewServer(opts...) registerChaincodeSupport(grpcServer) logger.Debugf("Running peer") // Register the Admin server pb.RegisterAdminServer(grpcServer, core.NewAdminServer()) // Register the Endorser server serverEndorser := endorser.NewEndorserServer() pb.RegisterEndorserServer(grpcServer, serverEndorser) // Initialize gossip component bootstrap := viper.GetStringSlice("peer.gossip.bootstrap") service.InitGossipService(peerEndpoint.Address, grpcServer, bootstrap...) defer service.GetGossipService().Stop() //initialize the env for chainless startup initChainless() // Begin startup of default chain if peerDefaultChain { chainID := util.GetTestChainID() block, err := pbutils.MakeConfigurationBlock(chainID) if nil != err { panic(fmt.Sprintf("Unable to create genesis block for [%s] due to [%s]", chainID, err)) } //this creates block and calls JoinChannel on gossip service if err = peer.CreateChainFromBlock(block); err != nil { panic(fmt.Sprintf("Unable to create chain block for [%s] due to [%s]", chainID, err)) } chaincode.DeploySysCCs(chainID) logger.Infof("Deployed system chaincodes on %s", chainID) commit := peer.GetCommitter(chainID) if commit == nil { panic(fmt.Sprintf("Unable to get committer for [%s]", chainID)) } //this shoul not need the chainID. Delivery should be //split up into network part and chain part. This should //only init the network part...TBD, part of Join work deliverService := noopssinglechain.NewDeliverService(chainID) deliverService.Start(commit) defer noopssinglechain.StopDeliveryService(deliverService) } logger.Infof("Starting peer with ID=%s, network ID=%s, address=%s, rootnodes=%v, validator=%v", peerEndpoint.ID, viper.GetString("peer.networkId"), peerEndpoint.Address, viper.GetString("peer.discovery.rootnode"), peer.ValidatorEnabled()) // Start the grpc server. Done in a goroutine so we can deploy the // genesis block if needed. serve := make(chan error) sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) go func() { sig := <-sigs fmt.Println() fmt.Println(sig) serve <- nil }() go func() { var grpcErr error if grpcErr = grpcServer.Serve(lis); grpcErr != nil { grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr) } else { logger.Info("grpc server exited") } serve <- grpcErr }() if err := writePid(viper.GetString("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil { return err } // Start the event hub server if ehubGrpcServer != nil && ehubLis != nil { go ehubGrpcServer.Serve(ehubLis) } if viper.GetBool("peer.profile.enabled") { go func() { profileListenAddress := viper.GetString("peer.profile.listenAddress") logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress) if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil { logger.Errorf("Error starting profiler: %s", profileErr) } }() } // sets the logging level for the 'error' module to the default value from // core.yaml. it can also be updated dynamically using // "peer logging setlevel error <log-level>" common.SetErrorLoggingLevel() // Block until grpc server exits return <-serve }
func (d *DeliverService) readUntilClose() { for { msg, err := d.client.Recv() if err != nil { logger.Warningf("Receive error: %s", err.Error()) return } switch t := msg.Type.(type) { case *orderer.DeliverResponse_Error: if t.Error == common.Status_SUCCESS { logger.Warning("ERROR! Received success in error field") return } logger.Warning("Got error ", t) case *orderer.DeliverResponse_Block: seqNum := t.Block.Header.Number block := &common.Block{} block.Header = t.Block.Header // Copy and initialize peer metadata putils.CopyBlockMetadata(t.Block, block) block.Data = &common.BlockData{} for _, d := range t.Block.Data.Data { if d != nil { if env, err := putils.GetEnvelopeFromBlock(d); err != nil { fmt.Printf("Error getting tx from block(%s)\n", err) } else if env != nil { // validate the transaction: here we check that the transaction // is properly formed, properly signed and that the security // chain binding proposal to endorsements to tx holds. We do // NOT check the validity of endorsements, though. That's a // job for VSCC below payload, _, err := peer.ValidateTransaction(env) if err != nil { // TODO: this code needs to receive a bit more attention and discussion: // it's not clear what it means if a transaction which causes a failure // in validation is just dropped on the floor logger.Errorf("Invalid transaction, error %s", err) } else { //the payload is used to get headers err = isTxValidForVscc(payload, d) if err != nil { // TODO: this code needs to receive a bit more attention and discussion: // it's not clear what it means if a transaction which causes a failure // in validation is just dropped on the floor logger.Errorf("isTxValidForVscc returned error %s", err) continue } if t, err := proto.Marshal(env); err == nil { block.Data.Data = append(block.Data.Data, t) } else { fmt.Printf("Cannot marshal transactoins %s\n", err) } } } else { logger.Warning("Nil tx from block") } } } numberOfPeers := len(service.GetGossipService().GetPeers()) // Create payload with a block received payload := createPayload(seqNum, block) // Use payload to create gossip message gossipMsg := createGossipMsg(payload) logger.Debugf("Adding payload locally, buffer seqNum = [%d], peers number [%d]", seqNum, numberOfPeers) // Add payload to local state payloads buffer service.GetGossipService().AddPayload(d.chainID, payload) // Gossip messages with other nodes logger.Debugf("Gossiping block [%d], peers number [%d]", seqNum, numberOfPeers) service.GetGossipService().Gossip(gossipMsg) if err = producer.SendProducerBlockEvent(block); err != nil { logger.Errorf("Error sending block event %s", err) } d.unAcknowledged++ if d.unAcknowledged >= d.windowSize/2 { logger.Warningf("Sending acknowledgement [%d]", t.Block.Header.Number) err = d.client.Send(&orderer.DeliverUpdate{ Type: &orderer.DeliverUpdate_Acknowledgement{ Acknowledgement: &orderer.Acknowledgement{ Number: seqNum, }, }, }) if err != nil { return } d.unAcknowledged = 0 } default: logger.Warning("Received unknown: ", t) return } } }