github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/chaincode/shim/handler.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 shim 18 19 import ( 20 "errors" 21 "fmt" 22 "sync" 23 24 "github.com/golang/protobuf/proto" 25 pb "github.com/hyperledger/fabric/protos/peer" 26 "github.com/looplab/fsm" 27 ) 28 29 // PeerChaincodeStream interface for stream between Peer and chaincode instance. 30 type PeerChaincodeStream interface { 31 Send(*pb.ChaincodeMessage) error 32 Recv() (*pb.ChaincodeMessage, error) 33 CloseSend() error 34 } 35 36 type nextStateInfo struct { 37 msg *pb.ChaincodeMessage 38 sendToCC bool 39 } 40 41 func (handler *Handler) triggerNextState(msg *pb.ChaincodeMessage, send bool) { 42 handler.nextState <- &nextStateInfo{msg, send} 43 } 44 45 // Handler handler implementation for shim side of chaincode. 46 type Handler struct { 47 sync.RWMutex 48 //shim to peer grpc serializer. User only in serialSend 49 serialLock sync.Mutex 50 To string 51 ChatStream PeerChaincodeStream 52 FSM *fsm.FSM 53 cc Chaincode 54 // Multiple queries (and one transaction) with different txids can be executing in parallel for this chaincode 55 // responseChannel is the channel on which responses are communicated by the shim to the chaincodeStub. 56 responseChannel map[string]chan pb.ChaincodeMessage 57 nextState chan *nextStateInfo 58 } 59 60 func shorttxid(txid string) string { 61 if len(txid) < 8 { 62 return txid 63 } 64 return txid[0:8] 65 } 66 67 //serialSend serializes msgs so gRPC will be happy 68 func (handler *Handler) serialSend(msg *pb.ChaincodeMessage) error { 69 handler.serialLock.Lock() 70 defer handler.serialLock.Unlock() 71 72 err := handler.ChatStream.Send(msg) 73 74 return err 75 } 76 77 //serialSendAsync serves the same purpose as serialSend (serializ msgs so gRPC will 78 //be happy). In addition, it is also asynchronous so send-remoterecv--localrecv loop 79 //can be nonblocking. Only errors need to be handled and these are handled by 80 //communication on supplied error channel. A typical use will be a non-blocking or 81 //nil channel 82 func (handler *Handler) serialSendAsync(msg *pb.ChaincodeMessage, errc chan error) { 83 go func() { 84 err := handler.serialSend(msg) 85 if errc != nil { 86 errc <- err 87 } 88 }() 89 } 90 91 func (handler *Handler) createChannel(txid string) (chan pb.ChaincodeMessage, error) { 92 handler.Lock() 93 defer handler.Unlock() 94 if handler.responseChannel == nil { 95 return nil, fmt.Errorf("[%s]Cannot create response channel", shorttxid(txid)) 96 } 97 if handler.responseChannel[txid] != nil { 98 return nil, fmt.Errorf("[%s]Channel exists", shorttxid(txid)) 99 } 100 c := make(chan pb.ChaincodeMessage) 101 handler.responseChannel[txid] = c 102 return c, nil 103 } 104 105 func (handler *Handler) sendChannel(msg *pb.ChaincodeMessage) error { 106 handler.Lock() 107 defer handler.Unlock() 108 if handler.responseChannel == nil { 109 return fmt.Errorf("[%s]Cannot send message response channel", shorttxid(msg.Txid)) 110 } 111 if handler.responseChannel[msg.Txid] == nil { 112 return fmt.Errorf("[%s]sendChannel does not exist", shorttxid(msg.Txid)) 113 } 114 115 chaincodeLogger.Debugf("[%s]before send", shorttxid(msg.Txid)) 116 handler.responseChannel[msg.Txid] <- *msg 117 chaincodeLogger.Debugf("[%s]after send", shorttxid(msg.Txid)) 118 119 return nil 120 } 121 122 //sends a message and selects 123 func (handler *Handler) sendReceive(msg *pb.ChaincodeMessage, c chan pb.ChaincodeMessage) (pb.ChaincodeMessage, error) { 124 errc := make(chan error, 1) 125 handler.serialSendAsync(msg, errc) 126 127 //the serialsend above will send an err or nil 128 //the select filters that first error(or nil) 129 //and continues to wait for the response 130 //it is possible that the response triggers first 131 //in which case the errc obviously worked and is 132 //ignored 133 for { 134 select { 135 case err := <-errc: 136 if err == nil { 137 continue 138 } 139 //would have been logged, return false 140 return pb.ChaincodeMessage{}, err 141 case outmsg, val := <-c: 142 if !val { 143 return pb.ChaincodeMessage{}, fmt.Errorf("unexpected failure on receive") 144 } 145 return outmsg, nil 146 } 147 } 148 } 149 150 func (handler *Handler) deleteChannel(txid string) { 151 handler.Lock() 152 defer handler.Unlock() 153 if handler.responseChannel != nil { 154 delete(handler.responseChannel, txid) 155 } 156 } 157 158 // NewChaincodeHandler returns a new instance of the shim side handler. 159 func newChaincodeHandler(peerChatStream PeerChaincodeStream, chaincode Chaincode) *Handler { 160 v := &Handler{ 161 ChatStream: peerChatStream, 162 cc: chaincode, 163 } 164 v.responseChannel = make(map[string]chan pb.ChaincodeMessage) 165 v.nextState = make(chan *nextStateInfo) 166 167 // Create the shim side FSM 168 v.FSM = fsm.NewFSM( 169 "created", 170 fsm.Events{ 171 {Name: pb.ChaincodeMessage_REGISTERED.String(), Src: []string{"created"}, Dst: "established"}, 172 {Name: pb.ChaincodeMessage_READY.String(), Src: []string{"established"}, Dst: "ready"}, 173 {Name: pb.ChaincodeMessage_ERROR.String(), Src: []string{"init"}, Dst: "established"}, 174 {Name: pb.ChaincodeMessage_RESPONSE.String(), Src: []string{"init"}, Dst: "init"}, 175 {Name: pb.ChaincodeMessage_INIT.String(), Src: []string{"ready"}, Dst: "ready"}, 176 {Name: pb.ChaincodeMessage_TRANSACTION.String(), Src: []string{"ready"}, Dst: "ready"}, 177 {Name: pb.ChaincodeMessage_RESPONSE.String(), Src: []string{"ready"}, Dst: "ready"}, 178 {Name: pb.ChaincodeMessage_ERROR.String(), Src: []string{"ready"}, Dst: "ready"}, 179 {Name: pb.ChaincodeMessage_COMPLETED.String(), Src: []string{"init"}, Dst: "ready"}, 180 {Name: pb.ChaincodeMessage_COMPLETED.String(), Src: []string{"ready"}, Dst: "ready"}, 181 }, 182 fsm.Callbacks{ 183 "before_" + pb.ChaincodeMessage_REGISTERED.String(): func(e *fsm.Event) { v.beforeRegistered(e) }, 184 "after_" + pb.ChaincodeMessage_RESPONSE.String(): func(e *fsm.Event) { v.afterResponse(e) }, 185 "after_" + pb.ChaincodeMessage_ERROR.String(): func(e *fsm.Event) { v.afterError(e) }, 186 "before_" + pb.ChaincodeMessage_INIT.String(): func(e *fsm.Event) { v.enterInitState(e) }, 187 "before_" + pb.ChaincodeMessage_TRANSACTION.String(): func(e *fsm.Event) { v.enterTransactionState(e) }, 188 }, 189 ) 190 return v 191 } 192 193 // beforeRegistered is called to handle the REGISTERED message. 194 func (handler *Handler) beforeRegistered(e *fsm.Event) { 195 if _, ok := e.Args[0].(*pb.ChaincodeMessage); !ok { 196 e.Cancel(fmt.Errorf("Received unexpected message type")) 197 return 198 } 199 chaincodeLogger.Debugf("Received %s, ready for invocations", pb.ChaincodeMessage_REGISTERED) 200 } 201 202 // handleInit handles request to initialize chaincode. 203 func (handler *Handler) handleInit(msg *pb.ChaincodeMessage) { 204 // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition 205 // is completed before the next one is triggered. The previous state transition is deemed complete only when 206 // the beforeInit function is exited. Interesting bug fix!! 207 go func() { 208 var nextStateMsg *pb.ChaincodeMessage 209 210 send := true 211 212 defer func() { 213 handler.triggerNextState(nextStateMsg, send) 214 }() 215 216 // Get the function and args from Payload 217 input := &pb.ChaincodeInput{} 218 unmarshalErr := proto.Unmarshal(msg.Payload, input) 219 if unmarshalErr != nil { 220 payload := []byte(unmarshalErr.Error()) 221 // Send ERROR message to chaincode support and change state 222 chaincodeLogger.Debugf("[%s]Incorrect payload format. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) 223 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid} 224 return 225 } 226 227 // Call chaincode's Run 228 // Create the ChaincodeStub which the chaincode can use to callback 229 stub := new(ChaincodeStub) 230 err := stub.init(handler, msg.Txid, input, msg.Proposal) 231 if err != nil { 232 chaincodeLogger.Errorf("[%s]Init get error response [%s]. Sending %s", shorttxid(msg.Txid), err.Error(), pb.ChaincodeMessage_ERROR) 233 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 234 return 235 } 236 res := handler.cc.Init(stub) 237 chaincodeLogger.Debugf("[%s]Init get response status: %d", shorttxid(msg.Txid), res.Status) 238 239 if res.Status >= ERROR { 240 // Send ERROR message to chaincode support and change state 241 chaincodeLogger.Errorf("[%s]Init get error response [%s]. Sending %s", shorttxid(msg.Txid), res.Message, pb.ChaincodeMessage_ERROR) 242 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(res.Message), Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 243 return 244 } 245 246 resBytes, err := proto.Marshal(&res) 247 if err != nil { 248 payload := []byte(err.Error()) 249 chaincodeLogger.Errorf("[%s]Init marshal response error [%s]. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR) 250 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 251 return 252 } 253 254 // Send COMPLETED message to chaincode support and change state 255 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: resBytes, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 256 chaincodeLogger.Debugf("[%s]Init invoke succeeded. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_COMPLETED) 257 }() 258 } 259 260 // enterInitState will initialize the chaincode if entering init from established. 261 func (handler *Handler) enterInitState(e *fsm.Event) { 262 chaincodeLogger.Debugf("Entered state %s", handler.FSM.Current()) 263 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 264 if !ok { 265 e.Cancel(fmt.Errorf("Received unexpected message type")) 266 return 267 } 268 chaincodeLogger.Debugf("[%s]Received %s, initializing chaincode", shorttxid(msg.Txid), msg.Type.String()) 269 if msg.Type.String() == pb.ChaincodeMessage_INIT.String() { 270 // Call the chaincode's Run function to initialize 271 handler.handleInit(msg) 272 } 273 } 274 275 // handleTransaction Handles request to execute a transaction. 276 func (handler *Handler) handleTransaction(msg *pb.ChaincodeMessage) { 277 // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition 278 // is completed before the next one is triggered. The previous state transition is deemed complete only when 279 // the beforeInit function is exited. Interesting bug fix!! 280 go func() { 281 //better not be nil 282 var nextStateMsg *pb.ChaincodeMessage 283 284 send := true 285 286 defer func() { 287 handler.triggerNextState(nextStateMsg, send) 288 }() 289 290 // Get the function and args from Payload 291 input := &pb.ChaincodeInput{} 292 unmarshalErr := proto.Unmarshal(msg.Payload, input) 293 if unmarshalErr != nil { 294 payload := []byte(unmarshalErr.Error()) 295 // Send ERROR message to chaincode support and change state 296 chaincodeLogger.Debugf("[%s]Incorrect payload format. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) 297 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid} 298 return 299 } 300 301 // Call chaincode's Run 302 // Create the ChaincodeStub which the chaincode can use to callback 303 stub := new(ChaincodeStub) 304 err := stub.init(handler, msg.Txid, input, msg.Proposal) 305 if err != nil { 306 payload := []byte(err.Error()) 307 // Send ERROR message to chaincode support and change state 308 chaincodeLogger.Errorf("[%s]Transaction execution failed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) 309 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 310 return 311 } 312 res := handler.cc.Invoke(stub) 313 314 // Endorser will handle error contained in Response. 315 resBytes, err := proto.Marshal(&res) 316 if err != nil { 317 payload := []byte(err.Error()) 318 // Send ERROR message to chaincode support and change state 319 chaincodeLogger.Errorf("[%s]Transaction execution failed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR) 320 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 321 return 322 } 323 324 // Send COMPLETED message to chaincode support and change state 325 chaincodeLogger.Debugf("[%s]Transaction completed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_COMPLETED) 326 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: resBytes, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 327 }() 328 } 329 330 // enterTransactionState will execute chaincode's Run if coming from a TRANSACTION event. 331 func (handler *Handler) enterTransactionState(e *fsm.Event) { 332 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 333 if !ok { 334 e.Cancel(fmt.Errorf("Received unexpected message type")) 335 return 336 } 337 chaincodeLogger.Debugf("[%s]Received %s, invoking transaction on chaincode(Src:%s, Dst:%s)", shorttxid(msg.Txid), msg.Type.String(), e.Src, e.Dst) 338 if msg.Type.String() == pb.ChaincodeMessage_TRANSACTION.String() { 339 // Call the chaincode's Run function to invoke transaction 340 handler.handleTransaction(msg) 341 } 342 } 343 344 // afterCompleted will need to handle COMPLETED event by sending message to the peer 345 func (handler *Handler) afterCompleted(e *fsm.Event) { 346 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 347 if !ok { 348 e.Cancel(fmt.Errorf("Received unexpected message type")) 349 return 350 } 351 chaincodeLogger.Debugf("[%s]sending COMPLETED to validator for tid", shorttxid(msg.Txid)) 352 if err := handler.serialSend(msg); err != nil { 353 e.Cancel(fmt.Errorf("send COMPLETED failed %s", err)) 354 } 355 } 356 357 // afterResponse is called to deliver a response or error to the chaincode stub. 358 func (handler *Handler) afterResponse(e *fsm.Event) { 359 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 360 if !ok { 361 e.Cancel(fmt.Errorf("Received unexpected message type")) 362 return 363 } 364 365 if err := handler.sendChannel(msg); err != nil { 366 chaincodeLogger.Errorf("[%s]error sending %s (state:%s): %s", shorttxid(msg.Txid), msg.Type, handler.FSM.Current(), err) 367 } else { 368 chaincodeLogger.Debugf("[%s]Received %s, communicated (state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 369 } 370 } 371 372 func (handler *Handler) afterError(e *fsm.Event) { 373 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 374 if !ok { 375 e.Cancel(fmt.Errorf("Received unexpected message type")) 376 return 377 } 378 379 /* TODO- revisit. This may no longer be needed with the serialized/streamlined messaging model 380 * There are two situations in which the ERROR event can be triggered: 381 * 1. When an error is encountered within handleInit or handleTransaction - some issue at the chaincode side; In this case there will be no responseChannel and the message has been sent to the validator. 382 * 2. The chaincode has initiated a request (get/put/del state) to the validator and is expecting a response on the responseChannel; If ERROR is received from validator, this needs to be notified on the responseChannel. 383 */ 384 if err := handler.sendChannel(msg); err == nil { 385 chaincodeLogger.Debugf("[%s]Error received from validator %s, communicated(state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 386 } 387 } 388 389 // TODO: Implement method to get and put entire state map and not one key at a time? 390 // handleGetState communicates with the validator to fetch the requested state information from the ledger. 391 func (handler *Handler) handleGetState(key string, txid string) ([]byte, error) { 392 // Create the channel on which to communicate the response from validating peer 393 respChan, uniqueReqErr := handler.createChannel(txid) 394 if uniqueReqErr != nil { 395 chaincodeLogger.Debug("Another state request pending for this Txid. Cannot process.") 396 return nil, uniqueReqErr 397 } 398 399 defer handler.deleteChannel(txid) 400 401 // Send GET_STATE message to validator chaincode support 402 payload := []byte(key) 403 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: payload, Txid: txid} 404 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE) 405 responseMsg, err := handler.sendReceive(msg, respChan) 406 if err != nil { 407 chaincodeLogger.Errorf("[%s]error sending GET_STATE %s", shorttxid(txid), err) 408 return nil, errors.New("could not send msg") 409 } 410 411 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 412 // Success response 413 chaincodeLogger.Debugf("[%s]GetState received payload %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 414 return responseMsg.Payload, nil 415 } 416 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 417 // Error response 418 chaincodeLogger.Errorf("[%s]GetState received error %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 419 return nil, errors.New(string(responseMsg.Payload[:])) 420 } 421 422 // Incorrect chaincode message received 423 chaincodeLogger.Errorf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 424 return nil, errors.New("Incorrect chaincode message received") 425 } 426 427 // handlePutState communicates with the validator to put state information into the ledger. 428 func (handler *Handler) handlePutState(key string, value []byte, txid string) error { 429 // Check if this is a transaction 430 chaincodeLogger.Debugf("[%s]Inside putstate", shorttxid(txid)) 431 payload := &pb.PutStateInfo{Key: key, Value: value} 432 payloadBytes, err := proto.Marshal(payload) 433 if err != nil { 434 return errors.New("Failed to process put state request") 435 } 436 437 // Create the channel on which to communicate the response from validating peer 438 respChan, uniqueReqErr := handler.createChannel(txid) 439 if uniqueReqErr != nil { 440 chaincodeLogger.Errorf("[%s]Another state request pending for this Txid. Cannot process.", shorttxid(txid)) 441 return uniqueReqErr 442 } 443 444 defer handler.deleteChannel(txid) 445 446 // Send PUT_STATE message to validator chaincode support 447 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: payloadBytes, Txid: txid} 448 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_PUT_STATE) 449 responseMsg, err := handler.sendReceive(msg, respChan) 450 if err != nil { 451 chaincodeLogger.Errorf("[%s]error sending PUT_STATE %s", msg.Txid, err) 452 return errors.New("could not send msg") 453 } 454 455 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 456 // Success response 457 chaincodeLogger.Debugf("[%s]Received %s. Successfully updated state", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 458 return nil 459 } 460 461 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 462 // Error response 463 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR, responseMsg.Payload) 464 return errors.New(string(responseMsg.Payload[:])) 465 } 466 467 // Incorrect chaincode message received 468 chaincodeLogger.Errorf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 469 return errors.New("Incorrect chaincode message received") 470 } 471 472 // handleDelState communicates with the validator to delete a key from the state in the ledger. 473 func (handler *Handler) handleDelState(key string, txid string) error { 474 // Create the channel on which to communicate the response from validating peer 475 respChan, uniqueReqErr := handler.createChannel(txid) 476 if uniqueReqErr != nil { 477 chaincodeLogger.Errorf("[%s]Another state request pending for this Txid. Cannot process create createChannel.", shorttxid(txid)) 478 return uniqueReqErr 479 } 480 481 defer handler.deleteChannel(txid) 482 483 // Send DEL_STATE message to validator chaincode support 484 payload := []byte(key) 485 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_DEL_STATE, Payload: payload, Txid: txid} 486 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_DEL_STATE) 487 responseMsg, err := handler.sendReceive(msg, respChan) 488 if err != nil { 489 chaincodeLogger.Errorf("[%s]error sending DEL_STATE %s", shorttxid(msg.Txid), pb.ChaincodeMessage_DEL_STATE) 490 return errors.New("could not send msg") 491 } 492 493 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 494 // Success response 495 chaincodeLogger.Debugf("[%s]Received %s. Successfully deleted state", msg.Txid, pb.ChaincodeMessage_RESPONSE) 496 return nil 497 } 498 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 499 // Error response 500 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", msg.Txid, pb.ChaincodeMessage_ERROR, responseMsg.Payload) 501 return errors.New(string(responseMsg.Payload[:])) 502 } 503 504 // Incorrect chaincode message received 505 chaincodeLogger.Errorf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 506 return errors.New("Incorrect chaincode message received") 507 } 508 509 func (handler *Handler) handleGetStateByRange(startKey, endKey string, txid string) (*pb.QueryStateResponse, error) { 510 // Create the channel on which to communicate the response from validating peer 511 respChan, uniqueReqErr := handler.createChannel(txid) 512 if uniqueReqErr != nil { 513 chaincodeLogger.Debugf("[%s]Another state request pending for this Txid. Cannot process.", shorttxid(txid)) 514 return nil, uniqueReqErr 515 } 516 517 defer handler.deleteChannel(txid) 518 519 // Send GET_STATE_BY_RANGE message to validator chaincode support 520 payload := &pb.GetStateByRange{StartKey: startKey, EndKey: endKey} 521 payloadBytes, err := proto.Marshal(payload) 522 if err != nil { 523 return nil, errors.New("Failed to process range query state request") 524 } 525 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Payload: payloadBytes, Txid: txid} 526 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE_BY_RANGE) 527 responseMsg, err := handler.sendReceive(msg, respChan) 528 if err != nil { 529 chaincodeLogger.Errorf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE_BY_RANGE) 530 return nil, errors.New("could not send msg") 531 } 532 533 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 534 // Success response 535 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 536 537 rangeQueryResponse := &pb.QueryStateResponse{} 538 unmarshalErr := proto.Unmarshal(responseMsg.Payload, rangeQueryResponse) 539 if unmarshalErr != nil { 540 chaincodeLogger.Errorf("[%s]unmarshall error", shorttxid(responseMsg.Txid)) 541 return nil, errors.New("Error unmarshalling GetStateByRangeResponse.") 542 } 543 544 return rangeQueryResponse, nil 545 } 546 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 547 // Error response 548 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 549 return nil, errors.New(string(responseMsg.Payload[:])) 550 } 551 552 // Incorrect chaincode message received 553 chaincodeLogger.Errorf("Incorrect chaincode message %s recieved. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 554 return nil, errors.New("Incorrect chaincode message received") 555 } 556 557 func (handler *Handler) handleQueryStateNext(id, txid string) (*pb.QueryStateResponse, error) { 558 // Create the channel on which to communicate the response from validating peer 559 respChan, uniqueReqErr := handler.createChannel(txid) 560 if uniqueReqErr != nil { 561 chaincodeLogger.Debugf("[%s]Another state request pending for this Txid. Cannot process.", shorttxid(txid)) 562 return nil, uniqueReqErr 563 } 564 565 defer handler.deleteChannel(txid) 566 567 // Send QUERY_STATE_NEXT message to validator chaincode support 568 payload := &pb.QueryStateNext{Id: id} 569 payloadBytes, err := proto.Marshal(payload) 570 if err != nil { 571 return nil, errors.New("Failed to process query state next request") 572 } 573 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Payload: payloadBytes, Txid: txid} 574 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_NEXT) 575 responseMsg, err := handler.sendReceive(msg, respChan) 576 if err != nil { 577 chaincodeLogger.Errorf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_NEXT) 578 return nil, errors.New("could not send msg") 579 } 580 581 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 582 // Success response 583 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 584 585 queryResponse := &pb.QueryStateResponse{} 586 unmarshalErr := proto.Unmarshal(responseMsg.Payload, queryResponse) 587 if unmarshalErr != nil { 588 chaincodeLogger.Errorf("[%s]unmarshall error", shorttxid(responseMsg.Txid)) 589 return nil, errors.New("Error unmarshalling QueryStateResponse.") 590 } 591 592 return queryResponse, nil 593 } 594 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 595 // Error response 596 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 597 return nil, errors.New(string(responseMsg.Payload[:])) 598 } 599 600 // Incorrect chaincode message received 601 chaincodeLogger.Errorf("Incorrect chaincode message %s recieved. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 602 return nil, errors.New("Incorrect chaincode message received") 603 } 604 605 func (handler *Handler) handleQueryStateClose(id, txid string) (*pb.QueryStateResponse, error) { 606 // Create the channel on which to communicate the response from validating peer 607 respChan, uniqueReqErr := handler.createChannel(txid) 608 if uniqueReqErr != nil { 609 chaincodeLogger.Debugf("[%s]Another state request pending for this Txid. Cannot process.", shorttxid(txid)) 610 return nil, uniqueReqErr 611 } 612 613 defer handler.deleteChannel(txid) 614 615 // Send QUERY_STATE_CLOSE message to validator chaincode support 616 payload := &pb.QueryStateClose{Id: id} 617 payloadBytes, err := proto.Marshal(payload) 618 if err != nil { 619 return nil, errors.New("Failed to process query state close request") 620 } 621 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Payload: payloadBytes, Txid: txid} 622 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_CLOSE) 623 responseMsg, err := handler.sendReceive(msg, respChan) 624 if err != nil { 625 chaincodeLogger.Errorf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_CLOSE) 626 return nil, errors.New("could not send msg") 627 } 628 629 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 630 // Success response 631 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 632 633 queryResponse := &pb.QueryStateResponse{} 634 unmarshalErr := proto.Unmarshal(responseMsg.Payload, queryResponse) 635 if unmarshalErr != nil { 636 chaincodeLogger.Errorf("[%s]unmarshall error", shorttxid(responseMsg.Txid)) 637 return nil, errors.New("Error unmarshalling QueryStateResponse.") 638 } 639 640 return queryResponse, nil 641 } 642 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 643 // Error response 644 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 645 return nil, errors.New(string(responseMsg.Payload[:])) 646 } 647 648 // Incorrect chaincode message received 649 chaincodeLogger.Errorf("Incorrect chaincode message %s recieved. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 650 return nil, errors.New("Incorrect chaincode message received") 651 } 652 653 func (handler *Handler) handleGetQueryResult(query string, txid string) (*pb.QueryStateResponse, error) { 654 // Create the channel on which to communicate the response from validating peer 655 respChan, uniqueReqErr := handler.createChannel(txid) 656 if uniqueReqErr != nil { 657 chaincodeLogger.Debugf("[%s]Another state request pending for this Txid. Cannot process.", shorttxid(txid)) 658 return nil, uniqueReqErr 659 } 660 661 defer handler.deleteChannel(txid) 662 663 // Send GET_QUERY_RESULT message to validator chaincode support 664 payload := &pb.GetQueryResult{Query: query} 665 payloadBytes, err := proto.Marshal(payload) 666 if err != nil { 667 return nil, errors.New("Failed to process query state request") 668 } 669 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_QUERY_RESULT, Payload: payloadBytes, Txid: txid} 670 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_QUERY_RESULT) 671 responseMsg, err := handler.sendReceive(msg, respChan) 672 if err != nil { 673 chaincodeLogger.Errorf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_QUERY_RESULT) 674 return nil, errors.New("could not send msg") 675 } 676 677 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 678 // Success response 679 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 680 681 executeQueryResponse := &pb.QueryStateResponse{} 682 unmarshalErr := proto.Unmarshal(responseMsg.Payload, executeQueryResponse) 683 if unmarshalErr != nil { 684 chaincodeLogger.Errorf("[%s]unmarshall error", shorttxid(responseMsg.Txid)) 685 return nil, errors.New("Error unmarshalling QueryStateResponse.") 686 } 687 688 return executeQueryResponse, nil 689 } 690 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 691 // Error response 692 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 693 return nil, errors.New(string(responseMsg.Payload[:])) 694 } 695 696 // Incorrect chaincode message received 697 chaincodeLogger.Errorf("Incorrect chaincode message %s recieved. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 698 return nil, errors.New("Incorrect chaincode message received") 699 } 700 701 func (handler *Handler) handleGetHistoryForKey(key string, txid string) (*pb.QueryStateResponse, error) { 702 // Create the channel on which to communicate the response from validating peer 703 respChan, uniqueReqErr := handler.createChannel(txid) 704 if uniqueReqErr != nil { 705 chaincodeLogger.Debugf("[%s]Another state request pending for this Txid. Cannot process.", shorttxid(txid)) 706 return nil, uniqueReqErr 707 } 708 709 defer handler.deleteChannel(txid) 710 711 // Send GET_HISTORY_FOR_KEY message to validator chaincode support 712 payload := &pb.GetHistoryForKey{Key: key} 713 payloadBytes, err := proto.Marshal(payload) 714 if err != nil { 715 return nil, errors.New("Failed to process query state request") 716 } 717 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_HISTORY_FOR_KEY, Payload: payloadBytes, Txid: txid} 718 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_HISTORY_FOR_KEY) 719 responseMsg, err := handler.sendReceive(msg, respChan) 720 if err != nil { 721 chaincodeLogger.Errorf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_HISTORY_FOR_KEY) 722 return nil, errors.New("could not send msg") 723 } 724 725 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 726 // Success response 727 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 728 729 getHistoryForKeyResponse := &pb.QueryStateResponse{} 730 unmarshalErr := proto.Unmarshal(responseMsg.Payload, getHistoryForKeyResponse) 731 if unmarshalErr != nil { 732 chaincodeLogger.Errorf("[%s]unmarshall error", shorttxid(responseMsg.Txid)) 733 return nil, errors.New("Error unmarshalling QueryStateResponse.") 734 } 735 736 return getHistoryForKeyResponse, nil 737 } 738 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 739 // Error response 740 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 741 return nil, errors.New(string(responseMsg.Payload[:])) 742 } 743 744 // Incorrect chaincode message received 745 chaincodeLogger.Errorf("Incorrect chaincode message %s recieved. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 746 return nil, errors.New("Incorrect chaincode message received") 747 } 748 749 // handleInvokeChaincode communicates with the validator to invoke another chaincode. 750 func (handler *Handler) handleInvokeChaincode(chaincodeName string, args [][]byte, txid string) pb.Response { 751 chaincodeID := &pb.ChaincodeID{Name: chaincodeName} 752 input := &pb.ChaincodeInput{Args: args} 753 payload := &pb.ChaincodeSpec{ChaincodeId: chaincodeID, Input: input} 754 payloadBytes, err := proto.Marshal(payload) 755 if err != nil { 756 return pb.Response{ 757 Status: ERROR, 758 Payload: []byte("Failed to process invoke chaincode request"), 759 } 760 } 761 762 // Create the channel on which to communicate the response from validating peer 763 respChan, uniqueReqErr := handler.createChannel(txid) 764 if uniqueReqErr != nil { 765 chaincodeLogger.Errorf("[%s]Another request pending for this Txid. Cannot process.", txid) 766 return pb.Response{ 767 Status: ERROR, 768 Payload: []byte(uniqueReqErr.Error()), 769 } 770 } 771 772 defer handler.deleteChannel(txid) 773 774 // Send INVOKE_CHAINCODE message to validator chaincode support 775 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: payloadBytes, Txid: txid} 776 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_INVOKE_CHAINCODE) 777 responseMsg, err := handler.sendReceive(msg, respChan) 778 if err != nil { 779 chaincodeLogger.Errorf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_INVOKE_CHAINCODE) 780 return pb.Response{ 781 Status: ERROR, 782 Payload: []byte("could not send msg"), 783 } 784 } 785 786 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 787 // Success response 788 chaincodeLogger.Debugf("[%s]Received %s. Successfully invoked chaincode", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 789 respMsg := &pb.ChaincodeMessage{} 790 if err := proto.Unmarshal(responseMsg.Payload, respMsg); err != nil { 791 chaincodeLogger.Errorf("[%s]Error unmarshaling called chaincode response: %s", shorttxid(responseMsg.Txid), err) 792 return pb.Response{ 793 Status: ERROR, 794 Payload: []byte(err.Error()), 795 } 796 } 797 if respMsg.Type == pb.ChaincodeMessage_COMPLETED { 798 // Success response 799 chaincodeLogger.Debugf("[%s]Received %s. Successfully invoed chaincode", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 800 res := &pb.Response{} 801 if unmarshalErr := proto.Unmarshal(respMsg.Payload, res); unmarshalErr != nil { 802 chaincodeLogger.Errorf("[%s]Error unmarshaling payload of response: %s", shorttxid(responseMsg.Txid), unmarshalErr) 803 return pb.Response{ 804 Status: ERROR, 805 Payload: []byte(unmarshalErr.Error()), 806 } 807 } 808 return *res 809 } 810 chaincodeLogger.Errorf("[%s]Received %s. Error from chaincode", shorttxid(responseMsg.Txid), respMsg.Type.String()) 811 return pb.Response{ 812 Status: ERROR, 813 Payload: responseMsg.Payload, 814 } 815 } 816 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 817 // Error response 818 chaincodeLogger.Errorf("[%s]Received %s.", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 819 return pb.Response{ 820 Status: ERROR, 821 Payload: responseMsg.Payload, 822 } 823 } 824 825 // Incorrect chaincode message received 826 chaincodeLogger.Debugf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR) 827 return pb.Response{ 828 Status: ERROR, 829 Payload: []byte("Incorrect chaincode message received"), 830 } 831 } 832 833 // handleMessage message handles loop for shim side of chaincode/validator stream. 834 func (handler *Handler) handleMessage(msg *pb.ChaincodeMessage) error { 835 if msg.Type == pb.ChaincodeMessage_KEEPALIVE { 836 // Received a keep alive message, we don't do anything with it for now 837 // and it does not touch the state machine 838 return nil 839 } 840 chaincodeLogger.Debugf("[%s]Handling ChaincodeMessage of type: %s(state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 841 if handler.FSM.Cannot(msg.Type.String()) { 842 errStr := fmt.Sprintf("[%s]Chaincode handler FSM cannot handle message (%s) with payload size (%d) while in state: %s", msg.Txid, msg.Type.String(), len(msg.Payload), handler.FSM.Current()) 843 err := errors.New(errStr) 844 payload := []byte(err.Error()) 845 errorMsg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid} 846 handler.serialSend(errorMsg) 847 return err 848 } 849 err := handler.FSM.Event(msg.Type.String(), msg) 850 return filterError(err) 851 } 852 853 // filterError filters the errors to allow NoTransitionError and CanceledError to not propagate for cases where embedded Err == nil. 854 func filterError(errFromFSMEvent error) error { 855 if errFromFSMEvent != nil { 856 if noTransitionErr, ok := errFromFSMEvent.(*fsm.NoTransitionError); ok { 857 if noTransitionErr.Err != nil { 858 // Only allow NoTransitionError's, all others are considered true error. 859 return errFromFSMEvent 860 } 861 } 862 if canceledErr, ok := errFromFSMEvent.(*fsm.CanceledError); ok { 863 if canceledErr.Err != nil { 864 // Only allow NoTransitionError's, all others are considered true error. 865 return canceledErr 866 //t.Error("expected only 'NoTransitionError'") 867 } 868 chaincodeLogger.Debugf("Ignoring CanceledError: %s", canceledErr) 869 } 870 } 871 return nil 872 }