github.com/Hnampk/my-fabric@v0.0.0-20201028083322-75069da399c0/usable-inter-nal/peer/node/start.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package node
     8  
     9  import (
    10  	"context"
    11  	"fmt"
    12  	"io"
    13  	"io/ioutil"
    14  	"net"
    15  	"net/http"
    16  	"os"
    17  	"os/signal"
    18  	"path/filepath"
    19  	"sync"
    20  	"syscall"
    21  	"time"
    22  
    23  	docker "github.com/fsouza/go-dockerclient"
    24  	"github.com/golang/protobuf/proto"
    25  	"github.com/hyperledger/fabric-protos-go/common"
    26  	cb "github.com/hyperledger/fabric-protos-go/common"
    27  	discprotos "github.com/hyperledger/fabric-protos-go/discovery"
    28  	pb "github.com/hyperledger/fabric-protos-go/peer"
    29  	"github.com/hyperledger/fabric/bccsp/factory"
    30  	"github.com/hyperledger/fabric/common/cauthdsl"
    31  	ccdef "github.com/hyperledger/fabric/common/chaincode"
    32  	"github.com/hyperledger/fabric/common/crypto"
    33  	"github.com/hyperledger/fabric/common/crypto/tlsgen"
    34  	"github.com/hyperledger/fabric/common/deliver"
    35  	"github.com/hyperledger/fabric/common/flogging"
    36  	floggingmetrics "github.com/hyperledger/fabric/common/flogging/metrics"
    37  	"github.com/hyperledger/fabric/common/grpclogging"
    38  	"github.com/hyperledger/fabric/common/grpcmetrics"
    39  	"github.com/hyperledger/fabric/common/metadata"
    40  	"github.com/hyperledger/fabric/common/metrics"
    41  	"github.com/hyperledger/fabric/common/policies"
    42  	"github.com/hyperledger/fabric/common/policydsl"
    43  	"github.com/hyperledger/fabric/core/aclmgmt"
    44  	"github.com/hyperledger/fabric/core/cclifecycle"
    45  	"github.com/hyperledger/fabric/core/chaincode"
    46  	"github.com/hyperledger/fabric/core/chaincode/accesscontrol"
    47  	"github.com/hyperledger/fabric/core/chaincode/extcc"
    48  	"github.com/hyperledger/fabric/core/chaincode/lifecycle"
    49  	"github.com/hyperledger/fabric/core/chaincode/persistence"
    50  	"github.com/hyperledger/fabric/core/chaincode/platforms"
    51  	"github.com/hyperledger/fabric/core/committer/txvalidator/plugin"
    52  	"github.com/hyperledger/fabric/core/common/ccprovider"
    53  	"github.com/hyperledger/fabric/core/common/privdata"
    54  	coreconfig "github.com/hyperledger/fabric/core/config"
    55  	"github.com/hyperledger/fabric/core/container"
    56  	"github.com/hyperledger/fabric/core/container/dockercontroller"
    57  	"github.com/hyperledger/fabric/core/container/externalbuilder"
    58  	"github.com/hyperledger/fabric/core/deliverservice"
    59  	"github.com/hyperledger/fabric/core/dispatcher"
    60  	"github.com/hyperledger/fabric/core/endorser"
    61  	authHandler "github.com/hyperledger/fabric/core/handlers/auth"
    62  	endorsement2 "github.com/hyperledger/fabric/core/handlers/endorsement/api"
    63  	endorsement3 "github.com/hyperledger/fabric/core/handlers/endorsement/api/identities"
    64  	"github.com/hyperledger/fabric/core/handlers/library"
    65  	validation "github.com/hyperledger/fabric/core/handlers/validation/api"
    66  	"github.com/hyperledger/fabric/core/ledger"
    67  	"github.com/hyperledger/fabric/core/ledger/cceventmgmt"
    68  	"github.com/hyperledger/fabric/core/ledger/kvledger"
    69  	"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
    70  	"github.com/hyperledger/fabric/core/operations"
    71  	"github.com/hyperledger/fabric/core/peer"
    72  	"github.com/hyperledger/fabric/core/policy"
    73  	"github.com/hyperledger/fabric/core/scc"
    74  	"github.com/hyperledger/fabric/core/scc/cscc"
    75  	"github.com/hyperledger/fabric/core/scc/lscc"
    76  	"github.com/hyperledger/fabric/core/scc/qscc"
    77  	"github.com/hyperledger/fabric/core/transientstore"
    78  	"github.com/hyperledger/fabric/discovery"
    79  	"github.com/hyperledger/fabric/discovery/endorsement"
    80  	discsupport "github.com/hyperledger/fabric/discovery/support"
    81  	discacl "github.com/hyperledger/fabric/discovery/support/acl"
    82  	ccsupport "github.com/hyperledger/fabric/discovery/support/chaincode"
    83  	"github.com/hyperledger/fabric/discovery/support/config"
    84  	"github.com/hyperledger/fabric/discovery/support/gossip"
    85  	gossipcommon "github.com/hyperledger/fabric/gossip/common"
    86  	gossipgossip "github.com/hyperledger/fabric/gossip/gossip"
    87  	gossipmetrics "github.com/hyperledger/fabric/gossip/metrics"
    88  	gossipprivdata "github.com/hyperledger/fabric/gossip/privdata"
    89  	"github.com/hyperledger/fabric/gossip/service"
    90  	gossipservice "github.com/hyperledger/fabric/gossip/service"
    91  	"github.com/hyperledger/fabric/msp"
    92  	"github.com/hyperledger/fabric/msp/mgmt"
    93  	"github.com/hyperledger/fabric/protoutil"
    94  	peergossip "github.com/hyperledger/fabric/usable-inter-nal/peer/gossip"
    95  	"github.com/hyperledger/fabric/usable-inter-nal/peer/version"
    96  	"github.com/hyperledger/fabric/usable-inter-nal/pkg/comm"
    97  	"github.com/pkg/errors"
    98  	"github.com/spf13/cobra"
    99  	"github.com/spf13/viper"
   100  	"google.golang.org/grpc"
   101  )
   102  
   103  const (
   104  	chaincodeAddrKey       = "peer.chaincodeAddress"
   105  	chaincodeListenAddrKey = "peer.chaincodeListenAddress"
   106  	defaultChaincodePort   = 7052
   107  )
   108  
   109  var chaincodeDevMode bool
   110  
   111  func startCmd() *cobra.Command {
   112  	// Set the flags on the node start command.
   113  	flags := nodeStartCmd.Flags()
   114  	flags.BoolVarP(&chaincodeDevMode, "peer-chaincodedev", "", false, "start peer in chaincode development mode")
   115  	return nodeStartCmd
   116  }
   117  
   118  var nodeStartCmd = &cobra.Command{
   119  	Use:   "start",
   120  	Short: "Starts the node.",
   121  	Long:  `Starts a node that interacts with the network.`,
   122  	RunE: func(cmd *cobra.Command, args []string) error {
   123  		if len(args) != 0 {
   124  			return fmt.Errorf("trailing args detected")
   125  		}
   126  		// Parsing of the command line is done so silence cmd usage
   127  		cmd.SilenceUsage = true
   128  		return serve(args)
   129  	},
   130  }
   131  
   132  // externalVMAdapter adapts coerces the result of Build to the
   133  // container.Interface type expected by the VM interface.
   134  type externalVMAdapter struct {
   135  	detector *externalbuilder.Detector
   136  }
   137  
   138  func (e externalVMAdapter) Build(
   139  	ccid string,
   140  	mdBytes []byte,
   141  	codePackage io.Reader,
   142  ) (container.Instance, error) {
   143  	i, err := e.detector.Build(ccid, mdBytes, codePackage)
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  
   148  	// ensure <nil> is returned instead of (*externalbuilder.Instance)(nil)
   149  	if i == nil {
   150  		return nil, nil
   151  	}
   152  	return i, err
   153  }
   154  
   155  type disabledDockerBuilder struct{}
   156  
   157  func (disabledDockerBuilder) Build(string, *persistence.ChaincodePackageMetadata, io.Reader) (container.Instance, error) {
   158  	return nil, errors.New("docker build is disabled")
   159  }
   160  
   161  type endorserChannelAdapter struct {
   162  	peer *peer.Peer
   163  }
   164  
   165  func (e endorserChannelAdapter) Channel(channelID string) *endorser.Channel {
   166  	if peerChannel := e.peer.Channel(channelID); peerChannel != nil {
   167  		return &endorser.Channel{
   168  			IdentityDeserializer: peerChannel.MSPManager(),
   169  		}
   170  	}
   171  
   172  	return nil
   173  }
   174  
   175  type custodianLauncherAdapter struct {
   176  	launcher      chaincode.Launcher
   177  	streamHandler extcc.StreamHandler
   178  }
   179  
   180  func (c custodianLauncherAdapter) Launch(ccid string) error {
   181  	return c.launcher.Launch(ccid, c.streamHandler)
   182  }
   183  
   184  func (c custodianLauncherAdapter) Stop(ccid string) error {
   185  	return c.launcher.Stop(ccid)
   186  }
   187  
   188  func serve(args []string) error {
   189  	// currently the peer only works with the standard MSP
   190  	// because in certain scenarios the MSP has to make sure
   191  	// that from a single credential you only have a single 'identity'.
   192  	// Idemix does not support this *YET* but it can be easily
   193  	// fixed to support it. For now, we just make sure that
   194  	// the peer only comes up with the standard MSP
   195  	mspType := mgmt.GetLocalMSP(factory.GetDefault()).GetType()
   196  	if mspType != msp.FABRIC {
   197  		panic("Unsupported msp type " + msp.ProviderTypeToString(mspType))
   198  	}
   199  
   200  	// Trace RPCs with the golang.org/x/net/trace package. This was moved out of
   201  	// the deliver service connection factory as it has process wide implications
   202  	// and was racy with respect to initialization of gRPC clients and servers.
   203  	grpc.EnableTracing = true
   204  
   205  	logger.Infof("Starting %s", version.GetInfo())
   206  
   207  	//obtain coreConfiguration
   208  	coreConfig, err := peer.GlobalConfig()
   209  	if err != nil {
   210  		return err
   211  	}
   212  
   213  	platformRegistry := platforms.NewRegistry(platforms.SupportedPlatforms...)
   214  
   215  	identityDeserializerFactory := func(chainID string) msp.IdentityDeserializer {
   216  		return mgmt.GetManagerForChain(chainID)
   217  	}
   218  
   219  	opsSystem := newOperationsSystem(coreConfig)
   220  	err = opsSystem.Start()
   221  	if err != nil {
   222  		return errors.WithMessage(err, "failed to initialize operations subsystem")
   223  	}
   224  	defer opsSystem.Stop()
   225  
   226  	metricsProvider := opsSystem.Provider
   227  	logObserver := floggingmetrics.NewObserver(metricsProvider)
   228  	flogging.SetObserver(logObserver)
   229  
   230  	mspID := coreConfig.LocalMSPID
   231  
   232  	membershipInfoProvider := privdata.NewMembershipInfoProvider(mspID, createSelfSignedData(), identityDeserializerFactory)
   233  
   234  	chaincodeInstallPath := filepath.Join(coreconfig.GetPath("peer.fileSystemPath"), "lifecycle", "chaincodes")
   235  	ccStore := persistence.NewStore(chaincodeInstallPath)
   236  	ccPackageParser := &persistence.ChaincodePackageParser{
   237  		MetadataProvider: ccprovider.PersistenceAdapter(ccprovider.MetadataAsTarEntries),
   238  	}
   239  
   240  	peerHost, _, err := net.SplitHostPort(coreConfig.PeerAddress)
   241  	if err != nil {
   242  		return fmt.Errorf("peer address is not in the format of host:port: %v", err)
   243  	}
   244  
   245  	listenAddr := coreConfig.ListenAddress
   246  	serverConfig, err := peer.GetServerConfig()
   247  	if err != nil {
   248  		logger.Fatalf("Error loading secure config for peer (%s)", err)
   249  	}
   250  
   251  	serverConfig.Logger = flogging.MustGetLogger("core.comm").With("server", "PeerServer")
   252  	serverConfig.ServerStatsHandler = comm.NewServerStatsHandler(metricsProvider)
   253  	serverConfig.UnaryInterceptors = append(
   254  		serverConfig.UnaryInterceptors,
   255  		grpcmetrics.UnaryServerInterceptor(grpcmetrics.NewUnaryMetrics(metricsProvider)),
   256  		grpclogging.UnaryServerInterceptor(flogging.MustGetLogger("comm.grpc.server").Zap()),
   257  	)
   258  	serverConfig.StreamInterceptors = append(
   259  		serverConfig.StreamInterceptors,
   260  		grpcmetrics.StreamServerInterceptor(grpcmetrics.NewStreamMetrics(metricsProvider)),
   261  		grpclogging.StreamServerInterceptor(flogging.MustGetLogger("comm.grpc.server").Zap()),
   262  	)
   263  
   264  	semaphores := initGrpcSemaphores(coreConfig)
   265  	if len(semaphores) != 0 {
   266  		serverConfig.UnaryInterceptors = append(serverConfig.UnaryInterceptors, unaryGrpcLimiter(semaphores))
   267  		serverConfig.StreamInterceptors = append(serverConfig.StreamInterceptors, streamGrpcLimiter(semaphores))
   268  	}
   269  
   270  	cs := comm.NewCredentialSupport()
   271  	if serverConfig.SecOpts.UseTLS {
   272  		logger.Info("Starting peer with TLS enabled")
   273  		cs = comm.NewCredentialSupport(serverConfig.SecOpts.ServerRootCAs...)
   274  
   275  		// set the cert to use if client auth is requested by remote endpoints
   276  		clientCert, err := peer.GetClientCertificate()
   277  		if err != nil {
   278  			logger.Fatalf("Failed to set TLS client certificate (%s)", err)
   279  		}
   280  		cs.SetClientCertificate(clientCert)
   281  	}
   282  
   283  	transientStoreProvider, err := transientstore.NewStoreProvider(
   284  		filepath.Join(coreconfig.GetPath("peer.fileSystemPath"), "transientstore"),
   285  	)
   286  	if err != nil {
   287  		return errors.WithMessage(err, "failed to open transient store")
   288  	}
   289  
   290  	deliverServiceConfig := deliverservice.GlobalConfig()
   291  
   292  	peerInstance := &peer.Peer{
   293  		ServerConfig:             serverConfig,
   294  		CredentialSupport:        cs,
   295  		StoreProvider:            transientStoreProvider,
   296  		CryptoProvider:           factory.GetDefault(),
   297  		OrdererEndpointOverrides: deliverServiceConfig.OrdererEndpointOverrides,
   298  	}
   299  
   300  	localMSP := mgmt.GetLocalMSP(factory.GetDefault())
   301  	signingIdentity, err := localMSP.GetDefaultSigningIdentity()
   302  	if err != nil {
   303  		logger.Panicf("Could not get the default signing identity from the local MSP: [%+v]", err)
   304  	}
   305  
   306  	signingIdentityBytes, err := signingIdentity.Serialize()
   307  	if err != nil {
   308  		logger.Panicf("Failed to serialize the signing identity: %v", err)
   309  	}
   310  
   311  	expirationLogger := flogging.MustGetLogger("certmonitor")
   312  	crypto.TrackExpiration(
   313  		serverConfig.SecOpts.UseTLS,
   314  		serverConfig.SecOpts.Certificate,
   315  		cs.GetClientCertificate().Certificate,
   316  		signingIdentityBytes,
   317  		expirationLogger.Infof,
   318  		expirationLogger.Warnf, // This can be used to piggyback a metric event in the future
   319  		time.Now(),
   320  		time.AfterFunc)
   321  
   322  	policyMgr := policies.PolicyManagerGetterFunc(peerInstance.GetPolicyManager)
   323  
   324  	deliverGRPCClient, err := comm.NewGRPCClient(comm.ClientConfig{
   325  		Timeout: deliverServiceConfig.ConnectionTimeout,
   326  		KaOpts:  deliverServiceConfig.KeepaliveOptions,
   327  		SecOpts: deliverServiceConfig.SecOpts,
   328  	})
   329  	if err != nil {
   330  		logger.Panicf("Could not create the deliver grpc client: [%+v]", err)
   331  	}
   332  
   333  	policyChecker := policy.NewPolicyChecker(
   334  		policies.PolicyManagerGetterFunc(peerInstance.GetPolicyManager),
   335  		mgmt.GetLocalMSP(factory.GetDefault()),
   336  		mgmt.NewLocalMSPPrincipalGetter(factory.GetDefault()),
   337  	)
   338  
   339  	//startup aclmgmt with default ACL providers (resource based and default 1.0 policies based).
   340  	//Users can pass in their own ACLProvider to RegisterACLProvider (currently unit tests do this)
   341  	aclProvider := aclmgmt.NewACLProvider(
   342  		aclmgmt.ResourceGetter(peerInstance.GetStableChannelConfig),
   343  		policyChecker,
   344  	)
   345  
   346  	// TODO, unfortunately, the lifecycle initialization is very unclean at the
   347  	// moment. This is because ccprovider.SetChaincodePath only works after
   348  	// ledgermgmt.Initialize, but ledgermgmt.Initialize requires a reference to
   349  	// lifecycle.  Finally, lscc requires a reference to the system chaincode
   350  	// provider in order to be created, which requires chaincode support to be
   351  	// up, which also requires, you guessed it, lifecycle. Once we remove the
   352  	// v1.0 lifecycle, we should be good to collapse all of the init of lifecycle
   353  	// to this point.
   354  	lifecycleResources := &lifecycle.Resources{
   355  		Serializer:          &lifecycle.Serializer{},
   356  		ChannelConfigSource: peerInstance,
   357  		ChaincodeStore:      ccStore,
   358  		PackageParser:       ccPackageParser,
   359  	}
   360  
   361  	privdataConfig := gossipprivdata.GlobalConfig()
   362  	lifecycleValidatorCommitter := &lifecycle.ValidatorCommitter{
   363  		CoreConfig:                   coreConfig,
   364  		PrivdataConfig:               privdataConfig,
   365  		Resources:                    lifecycleResources,
   366  		LegacyDeployedCCInfoProvider: &lscc.DeployedCCInfoProvider{},
   367  	}
   368  
   369  	// Configure CC package storage before ccInfoFSImpl.ListInstalledChaincodes() gets called
   370  	lsccInstallPath := filepath.Join(coreconfig.GetPath("peer.fileSystemPath"), "chaincodes")
   371  	ccprovider.SetChaincodesPath(lsccInstallPath)
   372  
   373  	ccInfoFSImpl := &ccprovider.CCInfoFSImpl{GetHasher: factory.GetDefault()}
   374  
   375  	// legacyMetadataManager collects metadata information from the legacy
   376  	// lifecycle (lscc). This is expected to disappear with FAB-15061.
   377  	legacyMetadataManager, err := cclifecycle.NewMetadataManager(
   378  		cclifecycle.EnumerateFunc(
   379  			func() ([]ccdef.InstalledChaincode, error) {
   380  				return ccInfoFSImpl.ListInstalledChaincodes(ccInfoFSImpl.GetChaincodeInstallPath(), ioutil.ReadDir, ccprovider.LoadPackage)
   381  			},
   382  		),
   383  	)
   384  	if err != nil {
   385  		logger.Panicf("Failed creating LegacyMetadataManager: +%v", err)
   386  	}
   387  
   388  	// metadataManager aggregates metadata information from _lifecycle and
   389  	// the legacy lifecycle (lscc).
   390  	metadataManager := lifecycle.NewMetadataManager()
   391  
   392  	// the purpose of these two managers is to feed per-channel chaincode data
   393  	// into gossip owing to the fact that we are transitioning from lscc to
   394  	// _lifecycle, we still have two providers of such information until v2.1,
   395  	// in which we will remove the legacy.
   396  	//
   397  	// the flow of information is the following
   398  	//
   399  	// gossip <-- metadataManager <-- lifecycleCache  (for _lifecycle)
   400  	//                             \
   401  	//                              - legacyMetadataManager (for lscc)
   402  	//
   403  	// FAB-15061 tracks the work necessary to remove LSCC, at which point we
   404  	// will be able to simplify the flow to simply be
   405  	//
   406  	// gossip <-- lifecycleCache
   407  
   408  	chaincodeCustodian := lifecycle.NewChaincodeCustodian()
   409  
   410  	externalBuilderOutput := filepath.Join(coreconfig.GetPath("peer.fileSystemPath"), "externalbuilder", "builds")
   411  	if err := os.MkdirAll(externalBuilderOutput, 0700); err != nil {
   412  		logger.Panicf("could not create externalbuilder build output dir: %s", err)
   413  	}
   414  
   415  	ebMetadataProvider := &externalbuilder.MetadataProvider{
   416  		DurablePath: externalBuilderOutput,
   417  	}
   418  
   419  	lifecycleCache := lifecycle.NewCache(lifecycleResources, mspID, metadataManager, chaincodeCustodian, ebMetadataProvider)
   420  
   421  	txProcessors := map[common.HeaderType]ledger.CustomTxProcessor{
   422  		common.HeaderType_CONFIG: &peer.ConfigTxProcessor{},
   423  	}
   424  
   425  	peerInstance.LedgerMgr = ledgermgmt.NewLedgerMgr(
   426  		&ledgermgmt.Initializer{
   427  			CustomTxProcessors:              txProcessors,
   428  			DeployedChaincodeInfoProvider:   lifecycleValidatorCommitter,
   429  			MembershipInfoProvider:          membershipInfoProvider,
   430  			ChaincodeLifecycleEventProvider: lifecycleCache,
   431  			MetricsProvider:                 metricsProvider,
   432  			HealthCheckRegistry:             opsSystem,
   433  			StateListeners:                  []ledger.StateListener{lifecycleCache},
   434  			Config:                          ledgerConfig(),
   435  			Hasher:                          factory.GetDefault(),
   436  			EbMetadataProvider:              ebMetadataProvider,
   437  		},
   438  	)
   439  
   440  	peerServer, err := comm.NewGRPCServer(listenAddr, serverConfig)
   441  	if err != nil {
   442  		logger.Fatalf("Failed to create peer server (%s)", err)
   443  	}
   444  
   445  	// FIXME: Creating the gossip service has the side effect of starting a bunch
   446  	// of go routines and registration with the grpc server.
   447  	gossipService, err := initGossipService(
   448  		policyMgr,
   449  		metricsProvider,
   450  		peerServer,
   451  		signingIdentity,
   452  		cs,
   453  		coreConfig.PeerAddress,
   454  		deliverGRPCClient,
   455  		deliverServiceConfig,
   456  		privdataConfig,
   457  	)
   458  	if err != nil {
   459  		return errors.WithMessage(err, "failed to initialize gossip service")
   460  	}
   461  	defer gossipService.Stop()
   462  
   463  	peerInstance.GossipService = gossipService
   464  
   465  	if err := lifecycleCache.InitializeLocalChaincodes(); err != nil {
   466  		return errors.WithMessage(err, "could not initialize local chaincodes")
   467  	}
   468  
   469  	// Parameter overrides must be processed before any parameters are
   470  	// cached. Failures to cache cause the server to terminate immediately.
   471  	if chaincodeDevMode {
   472  		logger.Info("Running in chaincode development mode")
   473  		logger.Info("Disable loading validity system chaincode")
   474  
   475  		viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)
   476  	}
   477  
   478  	mutualTLS := serverConfig.SecOpts.UseTLS && serverConfig.SecOpts.RequireClientCert
   479  	policyCheckerProvider := func(resourceName string) deliver.PolicyCheckerFunc {
   480  		return func(env *cb.Envelope, channelID string) error {
   481  			return aclProvider.CheckACL(resourceName, channelID, env)
   482  		}
   483  	}
   484  
   485  	metrics := deliver.NewMetrics(metricsProvider)
   486  	abServer := &peer.DeliverServer{
   487  		DeliverHandler: deliver.NewHandler(
   488  			&peer.DeliverChainManager{Peer: peerInstance},
   489  			coreConfig.AuthenticationTimeWindow,
   490  			mutualTLS,
   491  			metrics,
   492  			false,
   493  		),
   494  		PolicyCheckerProvider: policyCheckerProvider,
   495  	}
   496  	pb.RegisterDeliverServer(peerServer.Server(), abServer)
   497  
   498  	// Create a self-signed CA for chaincode service
   499  	ca, err := tlsgen.NewCA()
   500  	if err != nil {
   501  		logger.Panic("Failed creating authentication layer:", err)
   502  	}
   503  	ccSrv, ccEndpoint, err := createChaincodeServer(coreConfig, ca, peerHost)
   504  	if err != nil {
   505  		logger.Panicf("Failed to create chaincode server: %s", err)
   506  	}
   507  
   508  	//get user mode
   509  	userRunsCC := chaincode.IsDevMode()
   510  	tlsEnabled := coreConfig.PeerTLSEnabled
   511  
   512  	// create chaincode specific tls CA
   513  	authenticator := accesscontrol.NewAuthenticator(ca)
   514  
   515  	chaincodeHandlerRegistry := chaincode.NewHandlerRegistry(userRunsCC)
   516  	lifecycleTxQueryExecutorGetter := &chaincode.TxQueryExecutorGetter{
   517  		CCID:            scc.ChaincodeID(lifecycle.LifecycleNamespace),
   518  		HandlerRegistry: chaincodeHandlerRegistry,
   519  	}
   520  
   521  	if coreConfig.VMEndpoint == "" && len(coreConfig.ExternalBuilders) == 0 {
   522  		logger.Panic("VMEndpoint not set and no ExternalBuilders defined")
   523  	}
   524  
   525  	chaincodeConfig := chaincode.GlobalConfig()
   526  
   527  	var dockerBuilder container.DockerBuilder
   528  	if coreConfig.VMEndpoint != "" {
   529  		client, err := createDockerClient(coreConfig)
   530  		if err != nil {
   531  			logger.Panicf("cannot create docker client: %s", err)
   532  		}
   533  
   534  		dockerVM := &dockercontroller.DockerVM{
   535  			PeerID:        coreConfig.PeerID,
   536  			NetworkID:     coreConfig.NetworkID,
   537  			BuildMetrics:  dockercontroller.NewBuildMetrics(opsSystem.Provider),
   538  			Client:        client,
   539  			AttachStdOut:  coreConfig.VMDockerAttachStdout,
   540  			HostConfig:    getDockerHostConfig(),
   541  			ChaincodePull: coreConfig.ChaincodePull,
   542  			NetworkMode:   coreConfig.VMNetworkMode,
   543  			PlatformBuilder: &platforms.Builder{
   544  				Registry: platformRegistry,
   545  				Client:   client,
   546  			},
   547  			// This field is superfluous for chaincodes built with v2.0+ binaries
   548  			// however, to prevent users from being forced to rebuild leaving for now
   549  			// but it should be removed in the future.
   550  			LoggingEnv: []string{
   551  				"CORE_CHAINCODE_LOGGING_LEVEL=" + chaincodeConfig.LogLevel,
   552  				"CORE_CHAINCODE_LOGGING_SHIM=" + chaincodeConfig.ShimLogLevel,
   553  				"CORE_CHAINCODE_LOGGING_FORMAT=" + chaincodeConfig.LogFormat,
   554  			},
   555  			MSPID: mspID,
   556  		}
   557  		if err := opsSystem.RegisterChecker("docker", dockerVM); err != nil {
   558  			logger.Panicf("failed to register docker health check: %s", err)
   559  		}
   560  		dockerBuilder = dockerVM
   561  	}
   562  
   563  	// docker is disabled when we're missing the docker config
   564  	if dockerBuilder == nil {
   565  		dockerBuilder = &disabledDockerBuilder{}
   566  	}
   567  
   568  	externalVM := &externalbuilder.Detector{
   569  		Builders:    externalbuilder.CreateBuilders(coreConfig.ExternalBuilders, mspID),
   570  		DurablePath: externalBuilderOutput,
   571  	}
   572  
   573  	buildRegistry := &container.BuildRegistry{}
   574  
   575  	containerRouter := &container.Router{
   576  		DockerBuilder:   dockerBuilder,
   577  		ExternalBuilder: externalVMAdapter{externalVM},
   578  		PackageProvider: &persistence.FallbackPackageLocator{
   579  			ChaincodePackageLocator: &persistence.ChaincodePackageLocator{
   580  				ChaincodeDir: chaincodeInstallPath,
   581  			},
   582  			LegacyCCPackageLocator: &ccprovider.CCInfoFSImpl{GetHasher: factory.GetDefault()},
   583  		},
   584  	}
   585  
   586  	builtinSCCs := map[string]struct{}{
   587  		"lscc":       {},
   588  		"qscc":       {},
   589  		"cscc":       {},
   590  		"_lifecycle": {},
   591  	}
   592  
   593  	lsccInst := &lscc.SCC{
   594  		BuiltinSCCs: builtinSCCs,
   595  		Support: &lscc.SupportImpl{
   596  			GetMSPIDs: peerInstance.GetMSPIDs,
   597  		},
   598  		SCCProvider:        &lscc.PeerShim{Peer: peerInstance},
   599  		ACLProvider:        aclProvider,
   600  		GetMSPIDs:          peerInstance.GetMSPIDs,
   601  		PolicyChecker:      policyChecker,
   602  		BCCSP:              factory.GetDefault(),
   603  		BuildRegistry:      buildRegistry,
   604  		ChaincodeBuilder:   containerRouter,
   605  		EbMetadataProvider: ebMetadataProvider,
   606  	}
   607  
   608  	chaincodeEndorsementInfo := &lifecycle.ChaincodeEndorsementInfoSource{
   609  		LegacyImpl:  lsccInst,
   610  		Resources:   lifecycleResources,
   611  		Cache:       lifecycleCache,
   612  		BuiltinSCCs: builtinSCCs,
   613  	}
   614  
   615  	containerRuntime := &chaincode.ContainerRuntime{
   616  		BuildRegistry:   buildRegistry,
   617  		ContainerRouter: containerRouter,
   618  	}
   619  
   620  	lifecycleFunctions := &lifecycle.ExternalFunctions{
   621  		Resources:                 lifecycleResources,
   622  		InstallListener:           lifecycleCache,
   623  		InstalledChaincodesLister: lifecycleCache,
   624  		ChaincodeBuilder:          containerRouter,
   625  		BuildRegistry:             buildRegistry,
   626  	}
   627  
   628  	lifecycleSCC := &lifecycle.SCC{
   629  		Dispatcher: &dispatcher.Dispatcher{
   630  			Protobuf: &dispatcher.ProtobufImpl{},
   631  		},
   632  		DeployedCCInfoProvider: lifecycleValidatorCommitter,
   633  		QueryExecutorProvider:  lifecycleTxQueryExecutorGetter,
   634  		Functions:              lifecycleFunctions,
   635  		OrgMSPID:               mspID,
   636  		ChannelConfigSource:    peerInstance,
   637  		ACLProvider:            aclProvider,
   638  	}
   639  
   640  	chaincodeLauncher := &chaincode.RuntimeLauncher{
   641  		Metrics:           chaincode.NewLaunchMetrics(opsSystem.Provider),
   642  		Registry:          chaincodeHandlerRegistry,
   643  		Runtime:           containerRuntime,
   644  		StartupTimeout:    chaincodeConfig.StartupTimeout,
   645  		CertGenerator:     authenticator,
   646  		CACert:            ca.CertBytes(),
   647  		PeerAddress:       ccEndpoint,
   648  		ConnectionHandler: &extcc.ExternalChaincodeRuntime{},
   649  	}
   650  
   651  	// Keep TestQueries working
   652  	if !chaincodeConfig.TLSEnabled {
   653  		chaincodeLauncher.CertGenerator = nil
   654  	}
   655  
   656  	chaincodeSupport := &chaincode.ChaincodeSupport{
   657  		ACLProvider:            aclProvider,
   658  		AppConfig:              peerInstance,
   659  		DeployedCCInfoProvider: lifecycleValidatorCommitter,
   660  		ExecuteTimeout:         chaincodeConfig.ExecuteTimeout,
   661  		InstallTimeout:         chaincodeConfig.InstallTimeout,
   662  		HandlerRegistry:        chaincodeHandlerRegistry,
   663  		HandlerMetrics:         chaincode.NewHandlerMetrics(opsSystem.Provider),
   664  		Keepalive:              chaincodeConfig.Keepalive,
   665  		Launcher:               chaincodeLauncher,
   666  		Lifecycle:              chaincodeEndorsementInfo,
   667  		Peer:                   peerInstance,
   668  		Runtime:                containerRuntime,
   669  		BuiltinSCCs:            builtinSCCs,
   670  		TotalQueryLimit:        chaincodeConfig.TotalQueryLimit,
   671  		UserRunsCC:             userRunsCC,
   672  	}
   673  
   674  	custodianLauncher := custodianLauncherAdapter{
   675  		launcher:      chaincodeLauncher,
   676  		streamHandler: chaincodeSupport,
   677  	}
   678  	go chaincodeCustodian.Work(buildRegistry, containerRouter, custodianLauncher)
   679  
   680  	ccSupSrv := pb.ChaincodeSupportServer(chaincodeSupport)
   681  	if tlsEnabled {
   682  		ccSupSrv = authenticator.Wrap(ccSupSrv)
   683  	}
   684  
   685  	csccInst := cscc.New(
   686  		aclProvider,
   687  		lifecycleValidatorCommitter,
   688  		lsccInst,
   689  		lifecycleValidatorCommitter,
   690  		policyChecker,
   691  		peerInstance,
   692  		factory.GetDefault(),
   693  	)
   694  	qsccInst := scc.SelfDescribingSysCC(qscc.New(aclProvider, peerInstance))
   695  
   696  	pb.RegisterChaincodeSupportServer(ccSrv.Server(), ccSupSrv)
   697  
   698  	// start the chaincode specific gRPC listening service
   699  	go ccSrv.Start()
   700  
   701  	logger.Debugf("Running peer")
   702  
   703  	libConf, err := library.LoadConfig()
   704  	if err != nil {
   705  		return errors.WithMessage(err, "could not decode peer handlers configuration")
   706  	}
   707  
   708  	reg := library.InitRegistry(libConf)
   709  
   710  	authFilters := reg.Lookup(library.Auth).([]authHandler.Filter)
   711  	endorserSupport := &endorser.SupportImpl{
   712  		SignerSerializer: signingIdentity,
   713  		Peer:             peerInstance,
   714  		ChaincodeSupport: chaincodeSupport,
   715  		ACLProvider:      aclProvider,
   716  		BuiltinSCCs:      builtinSCCs,
   717  	}
   718  	endorsementPluginsByName := reg.Lookup(library.Endorsement).(map[string]endorsement2.PluginFactory)
   719  	validationPluginsByName := reg.Lookup(library.Validation).(map[string]validation.PluginFactory)
   720  	signingIdentityFetcher := (endorsement3.SigningIdentityFetcher)(endorserSupport)
   721  	channelStateRetriever := endorser.ChannelStateRetriever(endorserSupport)
   722  	pluginMapper := endorser.MapBasedPluginMapper(endorsementPluginsByName)
   723  	pluginEndorser := endorser.NewPluginEndorser(&endorser.PluginSupport{
   724  		ChannelStateRetriever:   channelStateRetriever,
   725  		TransientStoreRetriever: peerInstance,
   726  		PluginMapper:            pluginMapper,
   727  		SigningIdentityFetcher:  signingIdentityFetcher,
   728  	})
   729  	endorserSupport.PluginEndorser = pluginEndorser
   730  	channelFetcher := endorserChannelAdapter{
   731  		peer: peerInstance,
   732  	}
   733  	serverEndorser := &endorser.Endorser{
   734  		PrivateDataDistributor: gossipService,
   735  		ChannelFetcher:         channelFetcher,
   736  		LocalMSP:               localMSP,
   737  		Support:                endorserSupport,
   738  		Metrics:                endorser.NewMetrics(metricsProvider),
   739  	}
   740  
   741  	// deploy system chaincodes
   742  	for _, cc := range []scc.SelfDescribingSysCC{lsccInst, csccInst, qsccInst, lifecycleSCC} {
   743  		if enabled, ok := chaincodeConfig.SCCWhitelist[cc.Name()]; !ok || !enabled {
   744  			logger.Infof("not deploying chaincode %s as it is not enabled", cc.Name())
   745  			continue
   746  		}
   747  		scc.DeploySysCC(cc, chaincodeSupport)
   748  	}
   749  
   750  	logger.Infof("Deployed system chaincodes")
   751  
   752  	// register the lifecycleMetadataManager to get updates from the legacy
   753  	// chaincode; lifecycleMetadataManager will aggregate these updates with
   754  	// the ones from the new lifecycle and deliver both
   755  	// this is expected to disappear with FAB-15061
   756  	legacyMetadataManager.AddListener(metadataManager)
   757  
   758  	// register gossip as a listener for updates from lifecycleMetadataManager
   759  	metadataManager.AddListener(lifecycle.HandleMetadataUpdateFunc(func(channel string, chaincodes ccdef.MetadataSet) {
   760  		gossipService.UpdateChaincodes(chaincodes.AsChaincodes(), gossipcommon.ChannelID(channel))
   761  	}))
   762  
   763  	// this brings up all the channels
   764  	peerInstance.Initialize(
   765  		func(cid string) {
   766  			// initialize the metadata for this channel.
   767  			// This call will pre-populate chaincode information for this
   768  			// channel but it won't fire any updates to its listeners
   769  			lifecycleCache.InitializeMetadata(cid)
   770  
   771  			// initialize the legacyMetadataManager for this channel.
   772  			// This call will pre-populate chaincode information from
   773  			// the legacy lifecycle for this channel; it will also fire
   774  			// the listener, which will cascade to metadataManager
   775  			// and eventually to gossip to pre-populate data structures.
   776  			// this is expected to disappear with FAB-15061
   777  			sub, err := legacyMetadataManager.NewChannelSubscription(cid, cclifecycle.QueryCreatorFunc(func() (cclifecycle.Query, error) {
   778  				return peerInstance.GetLedger(cid).NewQueryExecutor()
   779  			}))
   780  			if err != nil {
   781  				logger.Panicf("Failed subscribing to chaincode lifecycle updates")
   782  			}
   783  
   784  			// register this channel's legacyMetadataManager (sub) to get ledger updates
   785  			// this is expected to disappear with FAB-15061
   786  			cceventmgmt.GetMgr().Register(cid, sub)
   787  		},
   788  		peerServer,
   789  		plugin.MapBasedMapper(validationPluginsByName),
   790  		lifecycleValidatorCommitter,
   791  		lsccInst,
   792  		lifecycleValidatorCommitter,
   793  		coreConfig.ValidatorPoolSize,
   794  	)
   795  
   796  	if coreConfig.DiscoveryEnabled {
   797  		registerDiscoveryService(
   798  			coreConfig,
   799  			peerInstance,
   800  			peerServer,
   801  			policyMgr,
   802  			lifecycle.NewMetadataProvider(
   803  				lifecycleCache,
   804  				legacyMetadataManager,
   805  				peerInstance,
   806  			),
   807  			gossipService,
   808  		)
   809  	}
   810  
   811  	logger.Infof("Starting peer with ID=[%s], network ID=[%s], address=[%s]", coreConfig.PeerID, coreConfig.NetworkID, coreConfig.PeerAddress)
   812  
   813  	// Get configuration before starting go routines to avoid
   814  	// racing in tests
   815  	profileEnabled := coreConfig.ProfileEnabled
   816  	profileListenAddress := coreConfig.ProfileListenAddress
   817  
   818  	// Start the grpc server. Done in a goroutine so we can deploy the
   819  	// genesis block if needed.
   820  	serve := make(chan error)
   821  
   822  	// Start profiling http endpoint if enabled
   823  	if profileEnabled {
   824  		go func() {
   825  			logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress)
   826  			if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil {
   827  				logger.Errorf("Error starting profiler: %s", profileErr)
   828  			}
   829  		}()
   830  	}
   831  
   832  	handleSignals(addPlatformSignals(map[os.Signal]func(){
   833  		syscall.SIGINT:  func() { serve <- nil },
   834  		syscall.SIGTERM: func() { serve <- nil },
   835  	}))
   836  
   837  	logger.Infof("Started peer with ID=[%s], network ID=[%s], address=[%s]", coreConfig.PeerID, coreConfig.NetworkID, coreConfig.PeerAddress)
   838  
   839  	// get a list of ledger IDs and load preResetHeight files for these ledger IDs
   840  	ledgerIDs, err := peerInstance.LedgerMgr.GetLedgerIDs()
   841  	if err != nil {
   842  		return errors.WithMessage(err, "failed to get ledger IDs")
   843  	}
   844  
   845  	// check to see if the peer ledgers have been reset
   846  	rootFSPath := filepath.Join(coreconfig.GetPath("peer.fileSystemPath"), "ledgersData")
   847  	preResetHeights, err := kvledger.LoadPreResetHeight(rootFSPath, ledgerIDs)
   848  	if err != nil {
   849  		return fmt.Errorf("error loading prereset height: %s", err)
   850  	}
   851  
   852  	for cid, height := range preResetHeights {
   853  		logger.Infof("Ledger rebuild: channel [%s]: preresetHeight: [%d]", cid, height)
   854  	}
   855  
   856  	if len(preResetHeights) > 0 {
   857  		logger.Info("Ledger rebuild: Entering loop to check if current ledger heights surpass prereset ledger heights. Endorsement request processing will be disabled.")
   858  		resetFilter := &reset{
   859  			reject: true,
   860  		}
   861  		authFilters = append(authFilters, resetFilter)
   862  		go resetLoop(resetFilter, preResetHeights, ledgerIDs, peerInstance.GetLedger, 10*time.Second)
   863  	}
   864  
   865  	// start the peer server
   866  	auth := authHandler.ChainFilters(serverEndorser, authFilters...)
   867  	// Register the Endorser server
   868  	pb.RegisterEndorserServer(peerServer.Server(), auth)
   869  
   870  	go func() {
   871  		var grpcErr error
   872  		if grpcErr = peerServer.Start(); grpcErr != nil {
   873  			grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr)
   874  		}
   875  		serve <- grpcErr
   876  	}()
   877  
   878  	// Block until grpc server exits
   879  	return <-serve
   880  }
   881  
   882  func handleSignals(handlers map[os.Signal]func()) {
   883  	var signals []os.Signal
   884  	for sig := range handlers {
   885  		signals = append(signals, sig)
   886  	}
   887  
   888  	signalChan := make(chan os.Signal, 1)
   889  	signal.Notify(signalChan, signals...)
   890  
   891  	go func() {
   892  		for sig := range signalChan {
   893  			logger.Infof("Received signal: %d (%s)", sig, sig)
   894  			handlers[sig]()
   895  		}
   896  	}()
   897  }
   898  
   899  func localPolicy(policyObject proto.Message) policies.Policy {
   900  	localMSP := mgmt.GetLocalMSP(factory.GetDefault())
   901  	pp := cauthdsl.NewPolicyProvider(localMSP)
   902  	policy, _, err := pp.NewPolicy(protoutil.MarshalOrPanic(policyObject))
   903  	if err != nil {
   904  		logger.Panicf("Failed creating local policy: +%v", err)
   905  	}
   906  	return policy
   907  }
   908  
   909  func createSelfSignedData() protoutil.SignedData {
   910  	sID := mgmt.GetLocalSigningIdentityOrPanic(factory.GetDefault())
   911  	msg := make([]byte, 32)
   912  	sig, err := sID.Sign(msg)
   913  	if err != nil {
   914  		logger.Panicf("Failed creating self signed data because message signing failed: %v", err)
   915  	}
   916  	peerIdentity, err := sID.Serialize()
   917  	if err != nil {
   918  		logger.Panicf("Failed creating self signed data because peer identity couldn't be serialized: %v", err)
   919  	}
   920  	return protoutil.SignedData{
   921  		Data:      msg,
   922  		Signature: sig,
   923  		Identity:  peerIdentity,
   924  	}
   925  }
   926  
   927  func registerDiscoveryService(
   928  	coreConfig *peer.Config,
   929  	peerInstance *peer.Peer,
   930  	peerServer *comm.GRPCServer,
   931  	polMgr policies.ChannelPolicyManagerGetter,
   932  	metadataProvider *lifecycle.MetadataProvider,
   933  	gossipService *gossipservice.GossipService,
   934  ) {
   935  	mspID := coreConfig.LocalMSPID
   936  	localAccessPolicy := localPolicy(policydsl.SignedByAnyAdmin([]string{mspID}))
   937  	if coreConfig.DiscoveryOrgMembersAllowed {
   938  		localAccessPolicy = localPolicy(policydsl.SignedByAnyMember([]string{mspID}))
   939  	}
   940  	channelVerifier := discacl.NewChannelVerifier(policies.ChannelApplicationWriters, polMgr)
   941  	acl := discacl.NewDiscoverySupport(channelVerifier, localAccessPolicy, discacl.ChannelConfigGetterFunc(peerInstance.GetStableChannelConfig))
   942  	gSup := gossip.NewDiscoverySupport(gossipService)
   943  	ccSup := ccsupport.NewDiscoverySupport(metadataProvider)
   944  	ea := endorsement.NewEndorsementAnalyzer(gSup, ccSup, acl, metadataProvider)
   945  	confSup := config.NewDiscoverySupport(config.CurrentConfigBlockGetterFunc(func(channelID string) *common.Block {
   946  		channel := peerInstance.Channel(channelID)
   947  		if channel == nil {
   948  			return nil
   949  		}
   950  		block, err := peer.ConfigBlockFromLedger(channel.Ledger())
   951  		if err != nil {
   952  			logger.Error("failed to get config block", err)
   953  			return nil
   954  		}
   955  		return block
   956  	}))
   957  	support := discsupport.NewDiscoverySupport(acl, gSup, ea, confSup, acl)
   958  	svc := discovery.NewService(discovery.Config{
   959  		TLS:                          peerServer.TLSEnabled(),
   960  		AuthCacheEnabled:             coreConfig.DiscoveryAuthCacheEnabled,
   961  		AuthCacheMaxSize:             coreConfig.DiscoveryAuthCacheMaxSize,
   962  		AuthCachePurgeRetentionRatio: coreConfig.DiscoveryAuthCachePurgeRetentionRatio,
   963  	}, support)
   964  	logger.Info("Discovery service activated")
   965  	discprotos.RegisterDiscoveryServer(peerServer.Server(), svc)
   966  }
   967  
   968  // create a CC listener using peer.chaincodeListenAddress (and if that's not set use peer.peerAddress)
   969  func createChaincodeServer(coreConfig *peer.Config, ca tlsgen.CA, peerHostname string) (srv *comm.GRPCServer, ccEndpoint string, err error) {
   970  	// before potentially setting chaincodeListenAddress, compute chaincode endpoint at first
   971  	ccEndpoint, err = computeChaincodeEndpoint(coreConfig.ChaincodeAddress, coreConfig.ChaincodeListenAddress, peerHostname)
   972  	if err != nil {
   973  		if chaincode.IsDevMode() {
   974  			// if any error for dev mode, we use 0.0.0.0:7052
   975  			ccEndpoint = fmt.Sprintf("%s:%d", "0.0.0.0", defaultChaincodePort)
   976  			logger.Warningf("use %s as chaincode endpoint because of error in computeChaincodeEndpoint: %s", ccEndpoint, err)
   977  		} else {
   978  			// for non-dev mode, we have to return error
   979  			logger.Errorf("Error computing chaincode endpoint: %s", err)
   980  			return nil, "", err
   981  		}
   982  	}
   983  
   984  	host, _, err := net.SplitHostPort(ccEndpoint)
   985  	if err != nil {
   986  		logger.Panic("Chaincode service host", ccEndpoint, "isn't a valid hostname:", err)
   987  	}
   988  
   989  	cclistenAddress := coreConfig.ChaincodeListenAddress
   990  	if cclistenAddress == "" {
   991  		cclistenAddress = fmt.Sprintf("%s:%d", peerHostname, defaultChaincodePort)
   992  		logger.Warningf("%s is not set, using %s", chaincodeListenAddrKey, cclistenAddress)
   993  		coreConfig.ChaincodeListenAddress = cclistenAddress
   994  	}
   995  
   996  	config, err := peer.GetServerConfig()
   997  	if err != nil {
   998  		logger.Errorf("Error getting server config: %s", err)
   999  		return nil, "", err
  1000  	}
  1001  
  1002  	// set the logger for the server
  1003  	config.Logger = flogging.MustGetLogger("core.comm").With("server", "ChaincodeServer")
  1004  
  1005  	// Override TLS configuration if TLS is applicable
  1006  	if config.SecOpts.UseTLS {
  1007  		// Create a self-signed TLS certificate with a SAN that matches the computed chaincode endpoint
  1008  		certKeyPair, err := ca.NewServerCertKeyPair(host)
  1009  		if err != nil {
  1010  			logger.Panicf("Failed generating TLS certificate for chaincode service: +%v", err)
  1011  		}
  1012  		config.SecOpts = comm.SecureOptions{
  1013  			UseTLS: true,
  1014  			// Require chaincode shim to authenticate itself
  1015  			RequireClientCert: true,
  1016  			// Trust only client certificates signed by ourselves
  1017  			ClientRootCAs: [][]byte{ca.CertBytes()},
  1018  			// Use our own self-signed TLS certificate and key
  1019  			Certificate: certKeyPair.Cert,
  1020  			Key:         certKeyPair.Key,
  1021  			// No point in specifying server root CAs since this TLS config is only used for
  1022  			// a gRPC server and not a client
  1023  			ServerRootCAs: nil,
  1024  		}
  1025  	}
  1026  
  1027  	// Chaincode keepalive options - static for now
  1028  	chaincodeKeepaliveOptions := comm.KeepaliveOptions{
  1029  		ServerInterval:    time.Duration(2) * time.Hour,    // 2 hours - gRPC default
  1030  		ServerTimeout:     time.Duration(20) * time.Second, // 20 sec - gRPC default
  1031  		ServerMinInterval: time.Duration(1) * time.Minute,  // match ClientInterval
  1032  	}
  1033  	config.KaOpts = chaincodeKeepaliveOptions
  1034  	config.HealthCheckEnabled = true
  1035  
  1036  	srv, err = comm.NewGRPCServer(cclistenAddress, config)
  1037  	if err != nil {
  1038  		logger.Errorf("Error creating GRPC server: %s", err)
  1039  		return nil, "", err
  1040  	}
  1041  
  1042  	return srv, ccEndpoint, nil
  1043  }
  1044  
  1045  // computeChaincodeEndpoint will utilize chaincode address, chaincode listen
  1046  // address (these two are from viper) and peer address to compute chaincode endpoint.
  1047  // There could be following cases of computing chaincode endpoint:
  1048  // Case A: if chaincodeAddrKey is set, use it if not "0.0.0.0" (or "::")
  1049  // Case B: else if chaincodeListenAddressKey is set and not "0.0.0.0" or ("::"), use it
  1050  // Case C: else use peer address if not "0.0.0.0" (or "::")
  1051  // Case D: else return error
  1052  func computeChaincodeEndpoint(chaincodeAddress string, chaincodeListenAddress string, peerHostname string) (ccEndpoint string, err error) {
  1053  	logger.Infof("Entering computeChaincodeEndpoint with peerHostname: %s", peerHostname)
  1054  	// Case A: the chaincodeAddrKey is set
  1055  	if chaincodeAddress != "" {
  1056  		host, _, err := net.SplitHostPort(chaincodeAddress)
  1057  		if err != nil {
  1058  			logger.Errorf("Fail to split chaincodeAddress: %s", err)
  1059  			return "", err
  1060  		}
  1061  		ccIP := net.ParseIP(host)
  1062  		if ccIP != nil && ccIP.IsUnspecified() {
  1063  			logger.Errorf("ChaincodeAddress' IP cannot be %s in non-dev mode", ccIP)
  1064  			return "", errors.New("invalid endpoint for chaincode to connect")
  1065  		}
  1066  		logger.Infof("Exit with ccEndpoint: %s", chaincodeAddress)
  1067  		return chaincodeAddress, nil
  1068  	}
  1069  
  1070  	// Case B: chaincodeListenAddrKey is set
  1071  	if chaincodeListenAddress != "" {
  1072  		ccEndpoint = chaincodeListenAddress
  1073  		host, port, err := net.SplitHostPort(ccEndpoint)
  1074  		if err != nil {
  1075  			logger.Errorf("ChaincodeAddress is nil and fail to split chaincodeListenAddress: %s", err)
  1076  			return "", err
  1077  		}
  1078  
  1079  		ccListenerIP := net.ParseIP(host)
  1080  		// ignoring other values such as Multicast address etc ...as the server
  1081  		// wouldn't start up with this address anyway
  1082  		if ccListenerIP != nil && ccListenerIP.IsUnspecified() {
  1083  			// Case C: if "0.0.0.0" or "::", we have to use peer address with the listen port
  1084  			peerIP := net.ParseIP(peerHostname)
  1085  			if peerIP != nil && peerIP.IsUnspecified() {
  1086  				// Case D: all we have is "0.0.0.0" or "::" which chaincode cannot connect to
  1087  				logger.Error("ChaincodeAddress is nil while both chaincodeListenAddressIP and peerIP are 0.0.0.0")
  1088  				return "", errors.New("invalid endpoint for chaincode to connect")
  1089  			}
  1090  			ccEndpoint = fmt.Sprintf("%s:%s", peerHostname, port)
  1091  		}
  1092  		logger.Infof("Exit with ccEndpoint: %s", ccEndpoint)
  1093  		return ccEndpoint, nil
  1094  	}
  1095  
  1096  	// Case C: chaincodeListenAddrKey is not set, use peer address
  1097  	peerIP := net.ParseIP(peerHostname)
  1098  	if peerIP != nil && peerIP.IsUnspecified() {
  1099  		// Case D: all we have is "0.0.0.0" or "::" which chaincode cannot connect to
  1100  		logger.Errorf("ChaincodeAddress and chaincodeListenAddress are nil and peerIP is %s", peerIP)
  1101  		return "", errors.New("invalid endpoint for chaincode to connect")
  1102  	}
  1103  
  1104  	// use peerAddress:defaultChaincodePort
  1105  	ccEndpoint = fmt.Sprintf("%s:%d", peerHostname, defaultChaincodePort)
  1106  
  1107  	logger.Infof("Exit with ccEndpoint: %s", ccEndpoint)
  1108  	return ccEndpoint, nil
  1109  }
  1110  
  1111  func createDockerClient(coreConfig *peer.Config) (*docker.Client, error) {
  1112  	if coreConfig.VMDockerTLSEnabled {
  1113  		return docker.NewTLSClient(coreConfig.VMEndpoint, coreConfig.DockerCert, coreConfig.DockerKey, coreConfig.DockerCA)
  1114  	}
  1115  	return docker.NewClient(coreConfig.VMEndpoint)
  1116  }
  1117  
  1118  // secureDialOpts is the callback function for secure dial options for gossip service
  1119  func secureDialOpts(credSupport *comm.CredentialSupport) func() []grpc.DialOption {
  1120  	return func() []grpc.DialOption {
  1121  		var dialOpts []grpc.DialOption
  1122  		// set max send/recv msg sizes
  1123  		dialOpts = append(
  1124  			dialOpts,
  1125  			grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(comm.MaxRecvMsgSize), grpc.MaxCallSendMsgSize(comm.MaxSendMsgSize)),
  1126  		)
  1127  		// set the keepalive options
  1128  		kaOpts := comm.DefaultKeepaliveOptions
  1129  		if viper.IsSet("peer.keepalive.client.interval") {
  1130  			kaOpts.ClientInterval = viper.GetDuration("peer.keepalive.client.interval")
  1131  		}
  1132  		if viper.IsSet("peer.keepalive.client.timeout") {
  1133  			kaOpts.ClientTimeout = viper.GetDuration("peer.keepalive.client.timeout")
  1134  		}
  1135  		dialOpts = append(dialOpts, comm.ClientKeepaliveOptions(kaOpts)...)
  1136  
  1137  		if viper.GetBool("peer.tls.enabled") {
  1138  			dialOpts = append(dialOpts, grpc.WithTransportCredentials(credSupport.GetPeerCredentials()))
  1139  		} else {
  1140  			dialOpts = append(dialOpts, grpc.WithInsecure())
  1141  		}
  1142  		return dialOpts
  1143  	}
  1144  }
  1145  
  1146  // initGossipService will initialize the gossip service by:
  1147  // 1. Enable TLS if configured;
  1148  // 2. Init the message crypto service;
  1149  // 3. Init the security advisor;
  1150  // 4. Init gossip related struct.
  1151  func initGossipService(
  1152  	policyMgr policies.ChannelPolicyManagerGetter,
  1153  	metricsProvider metrics.Provider,
  1154  	peerServer *comm.GRPCServer,
  1155  	signer msp.SigningIdentity,
  1156  	credSupport *comm.CredentialSupport,
  1157  	peerAddress string,
  1158  	deliverGRPCClient *comm.GRPCClient,
  1159  	deliverServiceConfig *deliverservice.DeliverServiceConfig,
  1160  	privdataConfig *gossipprivdata.PrivdataConfig,
  1161  ) (*gossipservice.GossipService, error) {
  1162  
  1163  	var certs *gossipcommon.TLSCertificates
  1164  	if peerServer.TLSEnabled() {
  1165  		serverCert := peerServer.ServerCertificate()
  1166  		clientCert, err := peer.GetClientCertificate()
  1167  		if err != nil {
  1168  			return nil, errors.Wrap(err, "failed obtaining client certificates")
  1169  		}
  1170  		certs = &gossipcommon.TLSCertificates{}
  1171  		certs.TLSServerCert.Store(&serverCert)
  1172  		certs.TLSClientCert.Store(&clientCert)
  1173  	}
  1174  
  1175  	messageCryptoService := peergossip.NewMCS(
  1176  		policyMgr,
  1177  		signer,
  1178  		mgmt.NewDeserializersManager(factory.GetDefault()),
  1179  		factory.GetDefault(),
  1180  	)
  1181  	secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager(factory.GetDefault()))
  1182  	bootstrap := viper.GetStringSlice("peer.gossip.bootstrap")
  1183  
  1184  	serviceConfig := service.GlobalConfig()
  1185  	if serviceConfig.Endpoint != "" {
  1186  		peerAddress = serviceConfig.Endpoint
  1187  	}
  1188  	gossipConfig, err := gossipgossip.GlobalConfig(peerAddress, certs, bootstrap...)
  1189  	if err != nil {
  1190  		return nil, errors.Wrap(err, "failed obtaining gossip config")
  1191  	}
  1192  
  1193  	return gossipservice.New(
  1194  		signer,
  1195  		gossipmetrics.NewGossipMetrics(metricsProvider),
  1196  		peerAddress,
  1197  		peerServer.Server(),
  1198  		messageCryptoService,
  1199  		secAdv,
  1200  		secureDialOpts(credSupport),
  1201  		credSupport,
  1202  		deliverGRPCClient,
  1203  		gossipConfig,
  1204  		serviceConfig,
  1205  		privdataConfig,
  1206  		deliverServiceConfig,
  1207  	)
  1208  }
  1209  
  1210  func newOperationsSystem(coreConfig *peer.Config) *operations.System {
  1211  	return operations.NewSystem(operations.Options{
  1212  		Logger:        flogging.MustGetLogger("peer.operations"),
  1213  		ListenAddress: coreConfig.OperationsListenAddress,
  1214  		Metrics: operations.MetricsOptions{
  1215  			Provider: coreConfig.MetricsProvider,
  1216  			Statsd: &operations.Statsd{
  1217  				Network:       coreConfig.StatsdNetwork,
  1218  				Address:       coreConfig.StatsdAaddress,
  1219  				WriteInterval: coreConfig.StatsdWriteInterval,
  1220  				Prefix:        coreConfig.StatsdPrefix,
  1221  			},
  1222  		},
  1223  		TLS: operations.TLS{
  1224  			Enabled:            coreConfig.OperationsTLSEnabled,
  1225  			CertFile:           coreConfig.OperationsTLSCertFile,
  1226  			KeyFile:            coreConfig.OperationsTLSKeyFile,
  1227  			ClientCertRequired: coreConfig.OperationsTLSClientAuthRequired,
  1228  			ClientCACertFiles:  coreConfig.OperationsTLSClientRootCAs,
  1229  		},
  1230  		Version: metadata.Version,
  1231  	})
  1232  }
  1233  
  1234  func getDockerHostConfig() *docker.HostConfig {
  1235  	dockerKey := func(key string) string { return "vm.docker.hostConfig." + key }
  1236  	getInt64 := func(key string) int64 { return int64(viper.GetInt(dockerKey(key))) }
  1237  
  1238  	var logConfig docker.LogConfig
  1239  	err := viper.UnmarshalKey(dockerKey("LogConfig"), &logConfig)
  1240  	if err != nil {
  1241  		logger.Panicf("unable to parse Docker LogConfig: %s", err)
  1242  	}
  1243  
  1244  	networkMode := viper.GetString(dockerKey("NetworkMode"))
  1245  	if networkMode == "" {
  1246  		networkMode = "host"
  1247  	}
  1248  
  1249  	memorySwappiness := getInt64("MemorySwappiness")
  1250  	oomKillDisable := viper.GetBool(dockerKey("OomKillDisable"))
  1251  
  1252  	return &docker.HostConfig{
  1253  		CapAdd:  viper.GetStringSlice(dockerKey("CapAdd")),
  1254  		CapDrop: viper.GetStringSlice(dockerKey("CapDrop")),
  1255  
  1256  		DNS:         viper.GetStringSlice(dockerKey("Dns")),
  1257  		DNSSearch:   viper.GetStringSlice(dockerKey("DnsSearch")),
  1258  		ExtraHosts:  viper.GetStringSlice(dockerKey("ExtraHosts")),
  1259  		NetworkMode: networkMode,
  1260  		IpcMode:     viper.GetString(dockerKey("IpcMode")),
  1261  		PidMode:     viper.GetString(dockerKey("PidMode")),
  1262  		UTSMode:     viper.GetString(dockerKey("UTSMode")),
  1263  		LogConfig:   logConfig,
  1264  
  1265  		ReadonlyRootfs:   viper.GetBool(dockerKey("ReadonlyRootfs")),
  1266  		SecurityOpt:      viper.GetStringSlice(dockerKey("SecurityOpt")),
  1267  		CgroupParent:     viper.GetString(dockerKey("CgroupParent")),
  1268  		Memory:           getInt64("Memory"),
  1269  		MemorySwap:       getInt64("MemorySwap"),
  1270  		MemorySwappiness: &memorySwappiness,
  1271  		OOMKillDisable:   &oomKillDisable,
  1272  		CPUShares:        getInt64("CpuShares"),
  1273  		CPUSet:           viper.GetString(dockerKey("Cpuset")),
  1274  		CPUSetCPUs:       viper.GetString(dockerKey("CpusetCPUs")),
  1275  		CPUSetMEMs:       viper.GetString(dockerKey("CpusetMEMs")),
  1276  		CPUQuota:         getInt64("CpuQuota"),
  1277  		CPUPeriod:        getInt64("CpuPeriod"),
  1278  		BlkioWeight:      getInt64("BlkioWeight"),
  1279  	}
  1280  }
  1281  
  1282  //go:generate counterfeiter -o mock/get_ledger.go -fake-name GetLedger . getLedger
  1283  //go:generate counterfeiter -o mock/peer_ledger.go -fake-name PeerLedger . peerLedger
  1284  
  1285  type peerLedger interface {
  1286  	ledger.PeerLedger
  1287  }
  1288  
  1289  type getLedger func(string) ledger.PeerLedger
  1290  
  1291  func resetLoop(
  1292  	resetFilter *reset,
  1293  	preResetHeights map[string]uint64,
  1294  	ledgerIDs []string,
  1295  	pLedger getLedger,
  1296  	interval time.Duration,
  1297  ) {
  1298  	// periodically check to see if current ledger height(s) surpass prereset height(s)
  1299  	ticker := time.NewTicker(interval)
  1300  
  1301  	defer ticker.Stop()
  1302  	for {
  1303  		select {
  1304  		case <-ticker.C:
  1305  			logger.Info("Ledger rebuild: Checking if current ledger heights surpass prereset ledger heights")
  1306  			logger.Debugf("Ledger rebuild: Number of ledgers still rebuilding before check: %d", len(preResetHeights))
  1307  			for cid, height := range preResetHeights {
  1308  				var l peerLedger
  1309  				l = pLedger(cid)
  1310  				if l == nil {
  1311  					logger.Warningf("No ledger found for channel [%s]", cid)
  1312  					continue
  1313  				}
  1314  				bcInfo, err := l.GetBlockchainInfo()
  1315  				if bcInfo != nil {
  1316  					logger.Debugf("Ledger rebuild: channel [%s]: currentHeight [%d] : preresetHeight [%d]", cid, bcInfo.GetHeight(), height)
  1317  					if bcInfo.GetHeight() >= height {
  1318  						delete(preResetHeights, cid)
  1319  					} else {
  1320  						break
  1321  					}
  1322  				} else {
  1323  					if err != nil {
  1324  						logger.Warningf("Ledger rebuild: could not retrieve info for channel [%s]: %s", cid, err.Error())
  1325  					}
  1326  				}
  1327  			}
  1328  
  1329  			logger.Debugf("Ledger rebuild: Number of ledgers still rebuilding after check: %d", len(preResetHeights))
  1330  			if len(preResetHeights) == 0 {
  1331  				logger.Infof("Ledger rebuild: Complete, all ledgers surpass prereset heights. Endorsement request processing will be enabled.")
  1332  				rootFSPath := filepath.Join(coreconfig.GetPath("peer.fileSystemPath"), "ledgersData")
  1333  				err := kvledger.ClearPreResetHeight(rootFSPath, ledgerIDs)
  1334  				if err != nil {
  1335  					logger.Warningf("Ledger rebuild: could not clear off prerest files: error=%s", err)
  1336  				}
  1337  				resetFilter.setReject(false)
  1338  				return
  1339  			}
  1340  		}
  1341  	}
  1342  }
  1343  
  1344  //implements the auth.Filter interface
  1345  type reset struct {
  1346  	sync.RWMutex
  1347  	next   pb.EndorserServer
  1348  	reject bool
  1349  }
  1350  
  1351  func (r *reset) setReject(reject bool) {
  1352  	r.Lock()
  1353  	defer r.Unlock()
  1354  	r.reject = reject
  1355  }
  1356  
  1357  // Init initializes Reset with the next EndorserServer
  1358  func (r *reset) Init(next pb.EndorserServer) {
  1359  	r.next = next
  1360  }
  1361  
  1362  // ProcessProposal processes a signed proposal
  1363  func (r *reset) ProcessProposal(ctx context.Context, signedProp *pb.SignedProposal) (*pb.ProposalResponse, error) {
  1364  	r.RLock()
  1365  	defer r.RUnlock()
  1366  	if r.reject {
  1367  		return nil, errors.New("endorse requests are blocked while ledgers are being rebuilt")
  1368  	}
  1369  	return r.next.ProcessProposal(ctx, signedProp)
  1370  }