github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/peer/node/start.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package node 18 19 import ( 20 "fmt" 21 "net" 22 "net/http" 23 "os" 24 "os/signal" 25 "path/filepath" 26 "strconv" 27 "syscall" 28 "time" 29 30 "github.com/hyperledger/fabric/common/configtx" 31 "github.com/hyperledger/fabric/common/configtx/test" 32 "github.com/hyperledger/fabric/common/configvalues/channel/application" 33 "github.com/hyperledger/fabric/common/configvalues/msp" 34 "github.com/hyperledger/fabric/common/genesis" 35 "github.com/hyperledger/fabric/common/policies" 36 "github.com/hyperledger/fabric/common/util" 37 "github.com/hyperledger/fabric/core" 38 "github.com/hyperledger/fabric/core/chaincode" 39 "github.com/hyperledger/fabric/core/comm" 40 "github.com/hyperledger/fabric/core/endorser" 41 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 42 "github.com/hyperledger/fabric/core/peer" 43 "github.com/hyperledger/fabric/core/scc" 44 "github.com/hyperledger/fabric/events/producer" 45 "github.com/hyperledger/fabric/gossip/service" 46 "github.com/hyperledger/fabric/msp/mgmt" 47 "github.com/hyperledger/fabric/peer/common" 48 "github.com/hyperledger/fabric/peer/gossip/mcs" 49 pb "github.com/hyperledger/fabric/protos/peer" 50 "github.com/spf13/cobra" 51 "github.com/spf13/viper" 52 "google.golang.org/grpc" 53 "google.golang.org/grpc/grpclog" 54 ) 55 56 var chaincodeDevMode bool 57 var peerDefaultChain bool 58 59 func startCmd() *cobra.Command { 60 // Set the flags on the node start command. 61 flags := nodeStartCmd.Flags() 62 flags.BoolVarP(&chaincodeDevMode, "peer-chaincodedev", "", false, 63 "Whether peer in chaincode development mode") 64 flags.BoolVarP(&peerDefaultChain, "peer-defaultchain", "", true, 65 "Whether to start peer with chain testchainid") 66 67 return nodeStartCmd 68 } 69 70 var nodeStartCmd = &cobra.Command{ 71 Use: "start", 72 Short: "Starts the node.", 73 Long: `Starts a node that interacts with the network.`, 74 RunE: func(cmd *cobra.Command, args []string) error { 75 return serve(args) 76 }, 77 } 78 79 //start chaincodes 80 func initSysCCs() { 81 //deploy system chaincodes 82 scc.DeploySysCCs("") 83 logger.Infof("Deployed system chaincodess") 84 } 85 86 func serve(args []string) error { 87 ledgermgmt.Initialize() 88 // Parameter overrides must be processed before any paramaters are 89 // cached. Failures to cache cause the server to terminate immediately. 90 if chaincodeDevMode { 91 logger.Info("Running in chaincode development mode") 92 logger.Info("Disable loading validity system chaincode") 93 94 viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode) 95 96 } 97 98 if err := peer.CacheConfiguration(); err != nil { 99 return err 100 } 101 102 peerEndpoint, err := peer.GetPeerEndpoint() 103 if err != nil { 104 err = fmt.Errorf("Failed to get Peer Endpoint: %s", err) 105 return err 106 } 107 108 listenAddr := viper.GetString("peer.listenAddress") 109 110 if "" == listenAddr { 111 logger.Debug("Listen address not specified, using peer endpoint address") 112 listenAddr = peerEndpoint.Address 113 } 114 115 lis, err := net.Listen("tcp", listenAddr) 116 if err != nil { 117 grpclog.Fatalf("Failed to listen: %v", err) 118 } 119 120 logger.Infof("Security enabled status: %t", core.SecurityEnabled()) 121 122 //Create GRPC server - return if an error occurs 123 secureConfig := comm.SecureServerConfig{ 124 UseTLS: viper.GetBool("peer.tls.enabled"), 125 } 126 grpcServer, err := comm.NewGRPCServerFromListener(lis, secureConfig) 127 if err != nil { 128 fmt.Println("Failed to return new GRPC server: ", err) 129 return err 130 } 131 132 //TODO - do we need different SSL material for events ? 133 ehubGrpcServer, err := createEventHubServer(secureConfig) 134 if err != nil { 135 grpclog.Fatalf("Failed to create ehub server: %v", err) 136 } 137 138 registerChaincodeSupport(grpcServer.Server()) 139 140 logger.Debugf("Running peer") 141 142 // Register the Admin server 143 pb.RegisterAdminServer(grpcServer.Server(), core.NewAdminServer()) 144 145 // Register the Endorser server 146 serverEndorser := endorser.NewEndorserServer() 147 pb.RegisterEndorserServer(grpcServer.Server(), serverEndorser) 148 149 // Initialize gossip component 150 bootstrap := viper.GetStringSlice("peer.gossip.bootstrap") 151 152 serializedIdentity, err := mgmt.GetLocalSigningIdentityOrPanic().Serialize() 153 if err != nil { 154 panic(fmt.Sprintf("Failed serializing self identity: %v", err)) 155 } 156 157 messageCryptoService := mcs.New(peer.GetPolicyManagerMgmt()) 158 service.InitGossipService(serializedIdentity, peerEndpoint.Address, grpcServer.Server(), messageCryptoService, bootstrap...) 159 defer service.GetGossipService().Stop() 160 161 //initialize system chaincodes 162 initSysCCs() 163 164 // Begin startup of default chain 165 if peerDefaultChain { 166 chainID := util.GetTestChainID() 167 168 // add readers, writers and admin policies for the default chain 169 policyTemplate := configtx.NewSimpleTemplate( 170 policies.TemplateImplicitMetaAnyPolicy([]string{application.GroupKey}, msp.ReadersPolicyKey), 171 policies.TemplateImplicitMetaAnyPolicy([]string{application.GroupKey}, msp.WritersPolicyKey), 172 policies.TemplateImplicitMetaMajorityPolicy([]string{application.GroupKey}, msp.AdminsPolicyKey), 173 ) 174 175 // We create a genesis block for the test 176 // chain with its MSP so that we can transact 177 block, err := genesis.NewFactoryImpl( 178 configtx.NewCompositeTemplate( 179 test.ApplicationOrgTemplate(), 180 policyTemplate)).Block(chainID) 181 if nil != err { 182 panic(fmt.Sprintf("Unable to create genesis block for [%s] due to [%s]", chainID, err)) 183 } 184 185 //this creates testchainid and sets up gossip 186 if err = peer.CreateChainFromBlock(block); err == nil { 187 fmt.Printf("create chain [%s]", chainID) 188 scc.DeploySysCCs(chainID) 189 logger.Infof("Deployed system chaincodes on %s", chainID) 190 } else { 191 fmt.Printf("create default chain [%s] failed with %s", chainID, err) 192 } 193 } 194 195 //this brings up all the chains (including testchainid) 196 peer.Initialize(func(cid string) { 197 logger.Debugf("Deploying system CC, for chain <%s>", cid) 198 scc.DeploySysCCs(cid) 199 }) 200 201 logger.Infof("Starting peer with ID=[%s], network ID=[%s], address=[%s]", 202 peerEndpoint.Id, viper.GetString("peer.networkId"), peerEndpoint.Address) 203 204 // Start the grpc server. Done in a goroutine so we can deploy the 205 // genesis block if needed. 206 serve := make(chan error) 207 208 sigs := make(chan os.Signal, 1) 209 signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) 210 go func() { 211 sig := <-sigs 212 fmt.Println() 213 fmt.Println(sig) 214 serve <- nil 215 }() 216 217 go func() { 218 var grpcErr error 219 if grpcErr = grpcServer.Start(); grpcErr != nil { 220 grpcErr = fmt.Errorf("grpc server exited with error: %s", grpcErr) 221 } else { 222 logger.Info("grpc server exited") 223 } 224 serve <- grpcErr 225 }() 226 227 if err := writePid(viper.GetString("peer.fileSystemPath")+"/peer.pid", os.Getpid()); err != nil { 228 return err 229 } 230 231 // Start the event hub server 232 if ehubGrpcServer != nil { 233 go ehubGrpcServer.Start() 234 } 235 236 // Start profiling http endpoint if enabled 237 if viper.GetBool("peer.profile.enabled") { 238 go func() { 239 profileListenAddress := viper.GetString("peer.profile.listenAddress") 240 logger.Infof("Starting profiling server with listenAddress = %s", profileListenAddress) 241 if profileErr := http.ListenAndServe(profileListenAddress, nil); profileErr != nil { 242 logger.Errorf("Error starting profiler: %s", profileErr) 243 } 244 }() 245 } 246 247 logger.Infof("Started peer with ID=[%s], network ID=[%s], address=[%s]", 248 peerEndpoint.Id, viper.GetString("peer.networkId"), peerEndpoint.Address) 249 250 // sets the logging level for the 'error' and 'msp' modules to the 251 // values from core.yaml. they can also be updated dynamically using 252 // "peer logging setlevel <module-name> <log-level>" 253 common.SetLogLevelFromViper("error") 254 common.SetLogLevelFromViper("msp") 255 256 // Block until grpc server exits 257 return <-serve 258 } 259 260 //NOTE - when we implment JOIN we will no longer pass the chainID as param 261 //The chaincode support will come up without registering system chaincodes 262 //which will be registered only during join phase. 263 func registerChaincodeSupport(grpcServer *grpc.Server) { 264 //get user mode 265 userRunsCC := chaincode.IsDevMode() 266 267 //get chaincode startup timeout 268 tOut, err := strconv.Atoi(viper.GetString("chaincode.startuptimeout")) 269 if err != nil { //what went wrong ? 270 fmt.Printf("could not retrive timeout var...setting to 5secs\n") 271 tOut = 5000 272 } 273 ccStartupTimeout := time.Duration(tOut) * time.Millisecond 274 275 ccSrv := chaincode.NewChaincodeSupport(peer.GetPeerEndpoint, userRunsCC, ccStartupTimeout) 276 277 //Now that chaincode is initialized, register all system chaincodes. 278 scc.RegisterSysCCs() 279 280 pb.RegisterChaincodeSupportServer(grpcServer, ccSrv) 281 } 282 283 func createEventHubServer(secureConfig comm.SecureServerConfig) (comm.GRPCServer, error) { 284 var lis net.Listener 285 var err error 286 lis, err = net.Listen("tcp", viper.GetString("peer.events.address")) 287 if err != nil { 288 return nil, fmt.Errorf("failed to listen: %v", err) 289 } 290 291 grpcServer, err := comm.NewGRPCServerFromListener(lis, secureConfig) 292 if err != nil { 293 fmt.Println("Failed to return new GRPC server: ", err) 294 return nil, err 295 } 296 ehServer := producer.NewEventsServer( 297 uint(viper.GetInt("peer.events.buffersize")), 298 viper.GetInt("peer.events.timeout")) 299 300 pb.RegisterEventsServer(grpcServer.Server(), ehServer) 301 return grpcServer, nil 302 } 303 304 func writePid(fileName string, pid int) error { 305 err := os.MkdirAll(filepath.Dir(fileName), 0755) 306 if err != nil { 307 return err 308 } 309 310 fd, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644) 311 if err != nil { 312 return err 313 } 314 defer fd.Close() 315 if err := syscall.Flock(int(fd.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { 316 return fmt.Errorf("can't lock '%s', lock is held", fd.Name()) 317 } 318 319 if _, err := fd.Seek(0, 0); err != nil { 320 return err 321 } 322 323 if err := fd.Truncate(0); err != nil { 324 return err 325 } 326 327 if _, err := fmt.Fprintf(fd, "%d", pid); err != nil { 328 return err 329 } 330 331 if err := fd.Sync(); err != nil { 332 return err 333 } 334 335 if err := syscall.Flock(int(fd.Fd()), syscall.LOCK_UN); err != nil { 336 return fmt.Errorf("can't release lock '%s', lock is held", fd.Name()) 337 } 338 return nil 339 }