Example #1
0
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
}
Example #2
0
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
		}
	}
}