github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/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 "fmt" 11 "net" 12 "net/http" 13 "os" 14 "os/signal" 15 "path/filepath" 16 "syscall" 17 "time" 18 19 "github.com/hyperledger/fabric/common/flogging" 20 "github.com/hyperledger/fabric/common/localmsp" 21 "github.com/hyperledger/fabric/core" 22 "github.com/hyperledger/fabric/core/chaincode" 23 "github.com/hyperledger/fabric/core/comm" 24 "github.com/hyperledger/fabric/core/common/ccprovider" 25 "github.com/hyperledger/fabric/core/config" 26 "github.com/hyperledger/fabric/core/endorser" 27 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 28 "github.com/hyperledger/fabric/core/peer" 29 "github.com/hyperledger/fabric/core/scc" 30 "github.com/hyperledger/fabric/events/producer" 31 "github.com/hyperledger/fabric/gossip/service" 32 "github.com/hyperledger/fabric/msp/mgmt" 33 "github.com/hyperledger/fabric/peer/common" 34 peergossip "github.com/hyperledger/fabric/peer/gossip" 35 "github.com/hyperledger/fabric/peer/version" 36 pb "github.com/hyperledger/fabric/protos/peer" 37 "github.com/spf13/cobra" 38 "github.com/spf13/viper" 39 "google.golang.org/grpc" 40 "google.golang.org/grpc/grpclog" 41 ) 42 43 var chaincodeDevMode bool 44 var peerDefaultChain bool 45 var orderingEndpoint string 46 47 // XXXDefaultChannelMSPID should not be defined in production code 48 // It should only be referenced in tests. However, it is necessary 49 // to support the 'default chain' setup so temporarily adding until 50 // this concept can be removed to testing scenarios only 51 const XXXDefaultChannelMSPID = "DEFAULT" 52 53 func startCmd() *cobra.Command { 54 // Set the flags on the node start command. 55 flags := nodeStartCmd.Flags() 56 flags.BoolVarP(&chaincodeDevMode, "peer-chaincodedev", "", false, 57 "Whether peer in chaincode development mode") 58 flags.BoolVarP(&peerDefaultChain, "peer-defaultchain", "", false, 59 "Whether to start peer with chain testchainid") 60 flags.StringVarP(&orderingEndpoint, "orderer", "o", "orderer:7050", "Ordering service endpoint") 61 62 return nodeStartCmd 63 } 64 65 var nodeStartCmd = &cobra.Command{ 66 Use: "start", 67 Short: "Starts the node.", 68 Long: `Starts a node that interacts with the network.`, 69 RunE: func(cmd *cobra.Command, args []string) error { 70 return serve(args) 71 }, 72 } 73 74 //start chaincodes 75 func initSysCCs() { 76 //deploy system chaincodes 77 scc.DeploySysCCs("") 78 logger.Infof("Deployed system chaincodess") 79 } 80 81 func serve(args []string) error { 82 logger.Infof("Starting %s", version.GetInfo()) 83 ledgermgmt.Initialize() 84 // Parameter overrides must be processed before any parameters are 85 // cached. Failures to cache cause the server to terminate immediately. 86 if chaincodeDevMode { 87 logger.Info("Running in chaincode development mode") 88 logger.Info("Disable loading validity system chaincode") 89 90 viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode) 91 92 } 93 94 if err := peer.CacheConfiguration(); err != nil { 95 return err 96 } 97 98 peerEndpoint, err := peer.GetPeerEndpoint() 99 if err != nil { 100 err = fmt.Errorf("Failed to get Peer Endpoint: %s", err) 101 return err 102 } 103 104 listenAddr := viper.GetString("peer.listenAddress") 105 106 secureConfig, err := peer.GetSecureConfig() 107 if err != nil { 108 logger.Fatalf("Error loading secure config for peer (%s)", err) 109 } 110 peerServer, err := peer.CreatePeerServer(listenAddr, secureConfig) 111 if err != nil { 112 logger.Fatalf("Failed to create peer server (%s)", err) 113 } 114 115 if secureConfig.UseTLS { 116 logger.Info("Starting peer with TLS enabled") 117 // set up CA support 118 caSupport := comm.GetCASupport() 119 caSupport.ServerRootCAs = secureConfig.ServerRootCAs 120 } 121 122 //TODO - do we need different SSL material for events ? 123 ehubGrpcServer, err := createEventHubServer(secureConfig) 124 if err != nil { 125 grpclog.Fatalf("Failed to create ehub server: %v", err) 126 } 127 128 // enable the cache of chaincode info 129 ccprovider.EnableCCInfoCache() 130 131 registerChaincodeSupport(peerServer.Server()) 132 133 logger.Debugf("Running peer") 134 135 // Register the Admin server 136 pb.RegisterAdminServer(peerServer.Server(), core.NewAdminServer()) 137 138 // Register the Endorser server 139 serverEndorser := endorser.NewEndorserServer() 140 pb.RegisterEndorserServer(peerServer.Server(), serverEndorser) 141 142 // Initialize gossip component 143 bootstrap := viper.GetStringSlice("peer.gossip.bootstrap") 144 145 serializedIdentity, err := mgmt.GetLocalSigningIdentityOrPanic().Serialize() 146 if err != nil { 147 logger.Panicf("Failed serializing self identity: %v", err) 148 } 149 150 messageCryptoService := peergossip.NewMCS( 151 peer.NewChannelPolicyManagerGetter(), 152 localmsp.NewSigner(), 153 mgmt.NewDeserializersManager()) 154 secAdv := peergossip.NewSecurityAdvisor(mgmt.NewDeserializersManager()) 155 156 // callback function for secure dial options for gossip service 157 secureDialOpts := func() []grpc.DialOption { 158 var dialOpts []grpc.DialOption 159 // set max send/recv msg sizes 160 dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(comm.MaxRecvMsgSize()), 161 grpc.MaxCallSendMsgSize(comm.MaxSendMsgSize()))) 162 // set the keepalive options 163 dialOpts = append(dialOpts, comm.ClientKeepaliveOptions()...) 164 165 if comm.TLSEnabled() { 166 tlsCert := peerServer.ServerCertificate() 167 dialOpts = append(dialOpts, grpc.WithTransportCredentials(comm.GetCASupport().GetPeerCredentials(tlsCert))) 168 } else { 169 dialOpts = append(dialOpts, grpc.WithInsecure()) 170 } 171 return dialOpts 172 } 173 service.InitGossipService(serializedIdentity, peerEndpoint.Address, peerServer.Server(), 174 messageCryptoService, secAdv, secureDialOpts, bootstrap...) 175 defer service.GetGossipService().Stop() 176 177 //initialize system chaincodes 178 initSysCCs() 179 180 //this brings up all the chains (including testchainid) 181 peer.Initialize(func(cid string) { 182 logger.Debugf("Deploying system CC, for chain <%s>", cid) 183 scc.DeploySysCCs(cid) 184 }) 185 186 logger.Infof("Starting peer with ID=[%s], network ID=[%s], address=[%s]", 187 peerEndpoint.Id, viper.GetString("peer.networkId"), peerEndpoint.Address) 188 189 // Start the grpc server. Done in a goroutine so we can deploy the 190 // genesis block if needed. 191 serve := make(chan error) 192 193 sigs := make(chan os.Signal, 1) 194 signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) 195 go func() { 196 sig := <-sigs 197 logger.Debugf("sig: %s", sig) 198 serve <- nil 199 }() 200 201 go func() { 202 var grpcErr error 203 if grpcErr = peerServer.Start(); grpcErr != nil { 204 grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr) 205 } else { 206 logger.Info("peer server exited") 207 } 208 serve <- grpcErr 209 }() 210 211 if err := writePid(config.GetPath("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil { 212 return err 213 } 214 215 // Start the event hub server 216 if ehubGrpcServer != nil { 217 go ehubGrpcServer.Start() 218 } 219 220 // Start profiling http endpoint if enabled 221 if viper.GetBool("peer.profile.enabled") { 222 go func() { 223 profileListenAddress := viper.GetString("peer.profile.listenAddress") 224 logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress) 225 if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil { 226 logger.Errorf("Error starting profiler: %s", profileErr) 227 } 228 }() 229 } 230 231 logger.Infof("Started peer with ID=[%s], network ID=[%s], address=[%s]", 232 peerEndpoint.Id, viper.GetString("peer.networkId"), peerEndpoint.Address) 233 234 // set the logging level for specific modules defined via environment 235 // variables or core.yaml 236 overrideLogModules := []string{"msp", "gossip", "ledger", "cauthdsl", "policies", "grpc"} 237 for _, module := range overrideLogModules { 238 err = common.SetLogLevelFromViper(module) 239 if err != nil { 240 logger.Warningf("Error setting log level for module '%s': %s", module, err.Error()) 241 } 242 } 243 244 flogging.SetPeerStartupModulesMap() 245 246 // Block until grpc server exits 247 return <-serve 248 } 249 250 //NOTE - when we implment JOIN we will no longer pass the chainID as param 251 //The chaincode support will come up without registering system chaincodes 252 //which will be registered only during join phase. 253 func registerChaincodeSupport(grpcServer *grpc.Server) { 254 //get user mode 255 userRunsCC := chaincode.IsDevMode() 256 257 //get chaincode startup timeout 258 ccStartupTimeout := viper.GetDuration("chaincode.startuptimeout") 259 if ccStartupTimeout < time.Duration(5)*time.Second { 260 logger.Warningf("Invalid chaincode startup timeout value %s (should be at least 5s); defaulting to 5s", ccStartupTimeout) 261 ccStartupTimeout = time.Duration(5) * time.Second 262 } else { 263 logger.Debugf("Chaincode startup timeout value set to %s", ccStartupTimeout) 264 } 265 266 ccSrv := chaincode.NewChaincodeSupport(peer.GetPeerEndpoint, userRunsCC, ccStartupTimeout) 267 268 //Now that chaincode is initialized, register all system chaincodes. 269 scc.RegisterSysCCs() 270 271 pb.RegisterChaincodeSupportServer(grpcServer, ccSrv) 272 } 273 274 func createEventHubServer(secureConfig comm.SecureServerConfig) (comm.GRPCServer, error) { 275 var lis net.Listener 276 var err error 277 lis, err = net.Listen("tcp", viper.GetString("peer.events.address")) 278 if err != nil { 279 return nil, fmt.Errorf("failed to listen: %v", err) 280 } 281 282 grpcServer, err := comm.NewGRPCServerFromListener(lis, secureConfig) 283 if err != nil { 284 logger.Errorf("Failed to return new GRPC server: %s", err) 285 return nil, err 286 } 287 ehServer := producer.NewEventsServer( 288 uint(viper.GetInt("peer.events.buffersize")), 289 viper.GetDuration("peer.events.timeout")) 290 291 pb.RegisterEventsServer(grpcServer.Server(), ehServer) 292 return grpcServer, nil 293 } 294 295 func writePid(fileName string, pid int) error { 296 err := os.MkdirAll(filepath.Dir(fileName), 0755) 297 if err != nil { 298 return err 299 } 300 301 fd, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644) 302 if err != nil { 303 return err 304 } 305 defer fd.Close() 306 if err := syscall.Flock(int(fd.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { 307 return fmt.Errorf("can't lock '%s', lock is held", fd.Name()) 308 } 309 310 if _, err := fd.Seek(0, 0); err != nil { 311 return err 312 } 313 314 if err := fd.Truncate(0); err != nil { 315 return err 316 } 317 318 if _, err := fmt.Fprintf(fd, "%d", pid); err != nil { 319 return err 320 } 321 322 if err := fd.Sync(); err != nil { 323 return err 324 } 325 326 if err := syscall.Flock(int(fd.Fd()), syscall.LOCK_UN); err != nil { 327 return fmt.Errorf("can't release lock '%s', lock is held", fd.Name()) 328 } 329 return nil 330 }