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