github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/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.beforeInit(e) }, 187 "before_" + pb.ChaincodeMessage_TRANSACTION.String(): func(e *fsm.Event) { v.beforeTransaction(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 errFunc := func(err error, payload []byte, ce *pb.ChaincodeEvent, errFmt string, args ...string) *pb.ChaincodeMessage { 217 if err != nil { 218 // Send ERROR message to chaincode support and change state 219 if payload == nil { 220 payload = []byte(err.Error()) 221 } 222 chaincodeLogger.Errorf(errFmt, args) 223 return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid, ChaincodeEvent: ce} 224 } 225 return nil 226 } 227 // Get the function and args from Payload 228 input := &pb.ChaincodeInput{} 229 unmarshalErr := proto.Unmarshal(msg.Payload, input) 230 if nextStateMsg = errFunc(unmarshalErr, nil, nil, "[%s]Incorrect payload format. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 231 return 232 } 233 234 // Call chaincode's Run 235 // Create the ChaincodeStub which the chaincode can use to callback 236 stub := new(ChaincodeStub) 237 err := stub.init(handler, msg.Txid, input, msg.Proposal) 238 if nextStateMsg = errFunc(err, nil, stub.chaincodeEvent, "[%s]Init get error response [%s]. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 239 return 240 } 241 242 res := handler.cc.Init(stub) 243 chaincodeLogger.Debugf("[%s]Init get response status: %d", shorttxid(msg.Txid), res.Status) 244 245 if res.Status >= ERROR { 246 err = fmt.Errorf("%s", res.Message) 247 if nextStateMsg = errFunc(err, []byte(res.Message), stub.chaincodeEvent, "[%s]Init get error response [%s]. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 248 return 249 } 250 } 251 252 resBytes, err := proto.Marshal(&res) 253 if nextStateMsg = errFunc(err, nil, stub.chaincodeEvent, "[%s]Init marshal response error [%s]. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 254 return 255 } 256 257 // Send COMPLETED message to chaincode support and change state 258 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: resBytes, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 259 chaincodeLogger.Debugf("[%s]Init succeeded. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_COMPLETED) 260 }() 261 } 262 263 // beforeInit will initialize the chaincode if entering init from established. 264 func (handler *Handler) beforeInit(e *fsm.Event) { 265 chaincodeLogger.Debugf("Entered state %s", handler.FSM.Current()) 266 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 267 if !ok { 268 e.Cancel(fmt.Errorf("Received unexpected message type")) 269 return 270 } 271 chaincodeLogger.Debugf("[%s]Received %s, initializing chaincode", shorttxid(msg.Txid), msg.Type.String()) 272 if msg.Type.String() == pb.ChaincodeMessage_INIT.String() { 273 // Call the chaincode's Run function to initialize 274 handler.handleInit(msg) 275 } 276 } 277 278 // handleTransaction Handles request to execute a transaction. 279 func (handler *Handler) handleTransaction(msg *pb.ChaincodeMessage) { 280 // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition 281 // is completed before the next one is triggered. The previous state transition is deemed complete only when 282 // the beforeInit function is exited. Interesting bug fix!! 283 go func() { 284 //better not be nil 285 var nextStateMsg *pb.ChaincodeMessage 286 287 send := true 288 289 defer func() { 290 handler.triggerNextState(nextStateMsg, send) 291 }() 292 293 errFunc := func(err error, ce *pb.ChaincodeEvent, errStr string, args ...string) *pb.ChaincodeMessage { 294 if err != nil { 295 payload := []byte(err.Error()) 296 chaincodeLogger.Errorf(errStr, args) 297 return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid, ChaincodeEvent: ce} 298 } 299 return nil 300 } 301 302 // Get the function and args from Payload 303 input := &pb.ChaincodeInput{} 304 unmarshalErr := proto.Unmarshal(msg.Payload, input) 305 if nextStateMsg = errFunc(unmarshalErr, nil, "[%s]Incorrect payload format. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 306 return 307 } 308 309 // Call chaincode's Run 310 // Create the ChaincodeStub which the chaincode can use to callback 311 stub := new(ChaincodeStub) 312 err := stub.init(handler, msg.Txid, input, msg.Proposal) 313 if nextStateMsg = errFunc(err, stub.chaincodeEvent, "[%s]Transaction execution failed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 314 return 315 } 316 317 res := handler.cc.Invoke(stub) 318 319 // Endorser will handle error contained in Response. 320 resBytes, err := proto.Marshal(&res) 321 if nextStateMsg = errFunc(err, stub.chaincodeEvent, "[%s]Transaction execution failed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 322 return 323 } 324 325 // Send COMPLETED message to chaincode support and change state 326 chaincodeLogger.Debugf("[%s]Transaction completed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_COMPLETED) 327 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: resBytes, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 328 }() 329 } 330 331 // beforeTransaction will execute chaincode's Run if coming from a TRANSACTION event. 332 func (handler *Handler) beforeTransaction(e *fsm.Event) { 333 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 334 if !ok { 335 e.Cancel(fmt.Errorf("Received unexpected message type")) 336 return 337 } 338 chaincodeLogger.Debugf("[%s]Received %s, invoking transaction on chaincode(Src:%s, Dst:%s)", shorttxid(msg.Txid), msg.Type.String(), e.Src, e.Dst) 339 if msg.Type.String() == pb.ChaincodeMessage_TRANSACTION.String() { 340 // Call the chaincode's Run function to invoke transaction 341 handler.handleTransaction(msg) 342 } 343 } 344 345 // afterResponse is called to deliver a response or error to the chaincode stub. 346 func (handler *Handler) afterResponse(e *fsm.Event) { 347 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 348 if !ok { 349 e.Cancel(fmt.Errorf("Received unexpected message type")) 350 return 351 } 352 353 if err := handler.sendChannel(msg); err != nil { 354 chaincodeLogger.Errorf("[%s]error sending %s (state:%s): %s", shorttxid(msg.Txid), msg.Type, handler.FSM.Current(), err) 355 } else { 356 chaincodeLogger.Debugf("[%s]Received %s, communicated (state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 357 } 358 } 359 360 func (handler *Handler) afterError(e *fsm.Event) { 361 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 362 if !ok { 363 e.Cancel(fmt.Errorf("Received unexpected message type")) 364 return 365 } 366 367 /* TODO- revisit. This may no longer be needed with the serialized/streamlined messaging model 368 * There are two situations in which the ERROR event can be triggered: 369 * 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. 370 * 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. 371 */ 372 if err := handler.sendChannel(msg); err == nil { 373 chaincodeLogger.Debugf("[%s]Error received from validator %s, communicated(state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 374 } 375 } 376 377 // TODO: Implement method to get and put entire state map and not one key at a time? 378 // handleGetState communicates with the validator to fetch the requested state information from the ledger. 379 func (handler *Handler) handleGetState(key string, txid string) ([]byte, error) { 380 // Create the channel on which to communicate the response from validating peer 381 var respChan chan pb.ChaincodeMessage 382 var err error 383 if respChan, err = handler.createChannel(txid); err != nil { 384 return nil, err 385 } 386 387 defer handler.deleteChannel(txid) 388 389 // Send GET_STATE message to validator chaincode support 390 payload := []byte(key) 391 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: payload, Txid: txid} 392 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE) 393 394 var responseMsg pb.ChaincodeMessage 395 396 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 397 return nil, errors.New(fmt.Sprintf("[%s]error sending GET_STATE %s", shorttxid(txid), err)) 398 } 399 400 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 401 // Success response 402 chaincodeLogger.Debugf("[%s]GetState received payload %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 403 return responseMsg.Payload, nil 404 } 405 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 406 // Error response 407 chaincodeLogger.Errorf("[%s]GetState received error %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 408 return nil, errors.New(string(responseMsg.Payload[:])) 409 } 410 411 // Incorrect chaincode message received 412 return nil, errors.New(fmt.Sprintf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 413 } 414 415 // handlePutState communicates with the validator to put state information into the ledger. 416 func (handler *Handler) handlePutState(key string, value []byte, txid string) error { 417 // Check if this is a transaction 418 chaincodeLogger.Debugf("[%s]Inside putstate", shorttxid(txid)) 419 420 //we constructed a valid object. No need to check for error 421 payloadBytes, _ := proto.Marshal(&pb.PutStateInfo{Key: key, Value: value}) 422 423 // Create the channel on which to communicate the response from validating peer 424 var respChan chan pb.ChaincodeMessage 425 var err error 426 if respChan, err = handler.createChannel(txid); err != nil { 427 return err 428 } 429 430 defer handler.deleteChannel(txid) 431 432 // Send PUT_STATE message to validator chaincode support 433 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: payloadBytes, Txid: txid} 434 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_PUT_STATE) 435 436 var responseMsg pb.ChaincodeMessage 437 438 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 439 return errors.New(fmt.Sprintf("[%s]error sending PUT_STATE %s", msg.Txid, err)) 440 } 441 442 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 443 // Success response 444 chaincodeLogger.Debugf("[%s]Received %s. Successfully updated state", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 445 return nil 446 } 447 448 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 449 // Error response 450 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR, responseMsg.Payload) 451 return errors.New(string(responseMsg.Payload[:])) 452 } 453 454 // Incorrect chaincode message received 455 return errors.New(fmt.Sprintf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 456 } 457 458 // handleDelState communicates with the validator to delete a key from the state in the ledger. 459 func (handler *Handler) handleDelState(key string, txid string) error { 460 // Create the channel on which to communicate the response from validating peer 461 var respChan chan pb.ChaincodeMessage 462 var err error 463 if respChan, err = handler.createChannel(txid); err != nil { 464 return err 465 } 466 467 defer handler.deleteChannel(txid) 468 469 // Send DEL_STATE message to validator chaincode support 470 payload := []byte(key) 471 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_DEL_STATE, Payload: payload, Txid: txid} 472 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_DEL_STATE) 473 474 var responseMsg pb.ChaincodeMessage 475 476 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 477 return errors.New(fmt.Sprintf("[%s]error sending DEL_STATE %s", shorttxid(msg.Txid), pb.ChaincodeMessage_DEL_STATE)) 478 } 479 480 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 481 // Success response 482 chaincodeLogger.Debugf("[%s]Received %s. Successfully deleted state", msg.Txid, pb.ChaincodeMessage_RESPONSE) 483 return nil 484 } 485 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 486 // Error response 487 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", msg.Txid, pb.ChaincodeMessage_ERROR, responseMsg.Payload) 488 return errors.New(string(responseMsg.Payload[:])) 489 } 490 491 // Incorrect chaincode message received 492 return errors.New(fmt.Sprintf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 493 } 494 495 func (handler *Handler) handleGetStateByRange(startKey, endKey string, txid string) (*pb.QueryResponse, error) { 496 // Create the channel on which to communicate the response from validating peer 497 var respChan chan pb.ChaincodeMessage 498 var err error 499 if respChan, err = handler.createChannel(txid); err != nil { 500 return nil, err 501 } 502 503 defer handler.deleteChannel(txid) 504 505 // Send GET_STATE_BY_RANGE message to validator chaincode support 506 //we constructed a valid object. No need to check for error 507 payloadBytes, _ := proto.Marshal(&pb.GetStateByRange{StartKey: startKey, EndKey: endKey}) 508 509 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Payload: payloadBytes, Txid: txid} 510 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE_BY_RANGE) 511 512 var responseMsg pb.ChaincodeMessage 513 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 514 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE_BY_RANGE)) 515 } 516 517 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 518 // Success response 519 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 520 521 rangeQueryResponse := &pb.QueryResponse{} 522 if err = proto.Unmarshal(responseMsg.Payload, rangeQueryResponse); err != nil { 523 return nil, errors.New(fmt.Sprintf("[%s]GetStateByRangeResponse unmarshall error", shorttxid(responseMsg.Txid))) 524 } 525 526 return rangeQueryResponse, nil 527 } 528 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 529 // Error response 530 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 531 return nil, errors.New(string(responseMsg.Payload[:])) 532 } 533 534 // Incorrect chaincode message received 535 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 536 } 537 538 func (handler *Handler) handleQueryStateNext(id, txid string) (*pb.QueryResponse, error) { 539 // Create the channel on which to communicate the response from validating peer 540 var respChan chan pb.ChaincodeMessage 541 var err error 542 if respChan, err = handler.createChannel(txid); err != nil { 543 return nil, err 544 } 545 546 defer handler.deleteChannel(txid) 547 548 // Send QUERY_STATE_NEXT message to validator chaincode support 549 //we constructed a valid object. No need to check for error 550 payloadBytes, _ := proto.Marshal(&pb.QueryStateNext{Id: id}) 551 552 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Payload: payloadBytes, Txid: txid} 553 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_NEXT) 554 555 var responseMsg pb.ChaincodeMessage 556 557 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 558 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_NEXT)) 559 } 560 561 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 562 // Success response 563 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 564 565 queryResponse := &pb.QueryResponse{} 566 if err = proto.Unmarshal(responseMsg.Payload, queryResponse); err != nil { 567 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 568 } 569 570 return queryResponse, nil 571 } 572 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 573 // Error response 574 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 575 return nil, errors.New(string(responseMsg.Payload[:])) 576 } 577 578 // Incorrect chaincode message received 579 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 580 } 581 582 func (handler *Handler) handleQueryStateClose(id, txid string) (*pb.QueryResponse, error) { 583 // Create the channel on which to communicate the response from validating peer 584 var respChan chan pb.ChaincodeMessage 585 var err error 586 if respChan, err = handler.createChannel(txid); err != nil { 587 return nil, err 588 } 589 590 defer handler.deleteChannel(txid) 591 592 // Send QUERY_STATE_CLOSE message to validator chaincode support 593 //we constructed a valid object. No need to check for error 594 payloadBytes, _ := proto.Marshal(&pb.QueryStateClose{Id: id}) 595 596 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Payload: payloadBytes, Txid: txid} 597 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_CLOSE) 598 599 var responseMsg pb.ChaincodeMessage 600 601 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 602 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_CLOSE)) 603 } 604 605 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 606 // Success response 607 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 608 609 queryResponse := &pb.QueryResponse{} 610 if err = proto.Unmarshal(responseMsg.Payload, queryResponse); err != nil { 611 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 612 } 613 614 return queryResponse, nil 615 } 616 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 617 // Error response 618 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 619 return nil, errors.New(string(responseMsg.Payload[:])) 620 } 621 622 // Incorrect chaincode message received 623 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 624 } 625 626 func (handler *Handler) handleGetQueryResult(query string, txid string) (*pb.QueryResponse, error) { 627 // Create the channel on which to communicate the response from validating peer 628 var respChan chan pb.ChaincodeMessage 629 var err error 630 if respChan, err = handler.createChannel(txid); err != nil { 631 return nil, err 632 } 633 634 defer handler.deleteChannel(txid) 635 636 // Send GET_QUERY_RESULT message to validator chaincode support 637 //we constructed a valid object. No need to check for error 638 payloadBytes, _ := proto.Marshal(&pb.GetQueryResult{Query: query}) 639 640 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_QUERY_RESULT, Payload: payloadBytes, Txid: txid} 641 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_QUERY_RESULT) 642 643 var responseMsg pb.ChaincodeMessage 644 645 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 646 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_QUERY_RESULT)) 647 } 648 649 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 650 // Success response 651 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 652 653 executeQueryResponse := &pb.QueryResponse{} 654 if err = proto.Unmarshal(responseMsg.Payload, executeQueryResponse); err != nil { 655 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 656 } 657 658 return executeQueryResponse, nil 659 } 660 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 661 // Error response 662 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 663 return nil, errors.New(string(responseMsg.Payload[:])) 664 } 665 666 // Incorrect chaincode message received 667 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 668 } 669 670 func (handler *Handler) handleGetHistoryForKey(key string, txid string) (*pb.QueryResponse, error) { 671 // Create the channel on which to communicate the response from validating peer 672 var respChan chan pb.ChaincodeMessage 673 var err error 674 if respChan, err = handler.createChannel(txid); err != nil { 675 return nil, err 676 } 677 678 defer handler.deleteChannel(txid) 679 680 // Send GET_HISTORY_FOR_KEY message to validator chaincode support 681 //we constructed a valid object. No need to check for error 682 payloadBytes, _ := proto.Marshal(&pb.GetHistoryForKey{Key: key}) 683 684 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_HISTORY_FOR_KEY, Payload: payloadBytes, Txid: txid} 685 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_HISTORY_FOR_KEY) 686 687 var responseMsg pb.ChaincodeMessage 688 689 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 690 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_HISTORY_FOR_KEY)) 691 } 692 693 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 694 // Success response 695 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 696 697 getHistoryForKeyResponse := &pb.QueryResponse{} 698 if err = proto.Unmarshal(responseMsg.Payload, getHistoryForKeyResponse); err != nil { 699 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 700 } 701 702 return getHistoryForKeyResponse, nil 703 } 704 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 705 // Error response 706 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 707 return nil, errors.New(string(responseMsg.Payload[:])) 708 } 709 710 // Incorrect chaincode message received 711 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 712 } 713 714 func (handler *Handler) createResponse(status int32, payload []byte) pb.Response { 715 return pb.Response{Status: status, Payload: payload} 716 } 717 718 // handleInvokeChaincode communicates with the validator to invoke another chaincode. 719 func (handler *Handler) handleInvokeChaincode(chaincodeName string, args [][]byte, txid string) pb.Response { 720 //we constructed a valid object. No need to check for error 721 payloadBytes, _ := proto.Marshal(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: chaincodeName}, Input: &pb.ChaincodeInput{Args: args}}) 722 723 // Create the channel on which to communicate the response from validating peer 724 var respChan chan pb.ChaincodeMessage 725 var err error 726 if respChan, err = handler.createChannel(txid); err != nil { 727 return handler.createResponse(ERROR, []byte(err.Error())) 728 } 729 730 defer handler.deleteChannel(txid) 731 732 // Send INVOKE_CHAINCODE message to validator chaincode support 733 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: payloadBytes, Txid: txid} 734 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_INVOKE_CHAINCODE) 735 736 var responseMsg pb.ChaincodeMessage 737 738 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 739 return handler.createResponse(ERROR, []byte(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_INVOKE_CHAINCODE))) 740 } 741 742 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 743 // Success response 744 chaincodeLogger.Debugf("[%s]Received %s. Successfully invoked chaincode", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 745 respMsg := &pb.ChaincodeMessage{} 746 if err = proto.Unmarshal(responseMsg.Payload, respMsg); err != nil { 747 return handler.createResponse(ERROR, []byte(err.Error())) 748 } 749 if respMsg.Type == pb.ChaincodeMessage_COMPLETED { 750 // Success response 751 chaincodeLogger.Debugf("[%s]Received %s. Successfully invoed chaincode", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 752 res := &pb.Response{} 753 if err = proto.Unmarshal(respMsg.Payload, res); err != nil { 754 return handler.createResponse(ERROR, []byte(err.Error())) 755 } 756 return *res 757 } 758 chaincodeLogger.Errorf("[%s]Received %s. Error from chaincode", shorttxid(responseMsg.Txid), respMsg.Type.String()) 759 return handler.createResponse(ERROR, responseMsg.Payload) 760 } 761 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 762 // Error response 763 chaincodeLogger.Errorf("[%s]Received %s.", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 764 return handler.createResponse(ERROR, responseMsg.Payload) 765 } 766 767 // Incorrect chaincode message received 768 return handler.createResponse(ERROR, []byte(fmt.Sprintf("[%s]Incorrect chaincode message %s received. Expecting %s or %s", shorttxid(responseMsg.Txid), responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR))) 769 } 770 771 // handleMessage message handles loop for shim side of chaincode/validator stream. 772 func (handler *Handler) handleMessage(msg *pb.ChaincodeMessage) error { 773 if msg.Type == pb.ChaincodeMessage_KEEPALIVE { 774 // Received a keep alive message, we don't do anything with it for now 775 // and it does not touch the state machine 776 return nil 777 } 778 chaincodeLogger.Debugf("[%s]Handling ChaincodeMessage of type: %s(state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 779 if handler.FSM.Cannot(msg.Type.String()) { 780 err := errors.New(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())) 781 handler.serialSend(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid}) 782 return err 783 } 784 err := handler.FSM.Event(msg.Type.String(), msg) 785 return filterError(err) 786 } 787 788 // filterError filters the errors to allow NoTransitionError and CanceledError to not propagate for cases where embedded Err == nil. 789 func filterError(errFromFSMEvent error) error { 790 if errFromFSMEvent != nil { 791 if noTransitionErr, ok := errFromFSMEvent.(*fsm.NoTransitionError); ok { 792 if noTransitionErr.Err != nil { 793 // Only allow NoTransitionError's, all others are considered true error. 794 return errFromFSMEvent 795 } 796 } 797 if canceledErr, ok := errFromFSMEvent.(*fsm.CanceledError); ok { 798 if canceledErr.Err != nil { 799 // Only allow NoTransitionError's, all others are considered true error. 800 return canceledErr 801 //t.Error("expected only 'NoTransitionError'") 802 } 803 chaincodeLogger.Debugf("Ignoring CanceledError: %s", canceledErr) 804 } 805 } 806 return nil 807 }