github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/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 "math/big" 25 26 "encoding/json" 27 28 "strings" 29 30 "github.com/golang/protobuf/proto" 31 "github.com/inklabsfoundation/inkchain/core/wallet" 32 "github.com/inklabsfoundation/inkchain/protos/ledger/transet/kvtranset" 33 pb "github.com/inklabsfoundation/inkchain/protos/peer" 34 "github.com/looplab/fsm" 35 "strconv" 36 ) 37 38 // PeerChaincodeStream interface for stream between Peer and chaincode instance. 39 type PeerChaincodeStream interface { 40 Send(*pb.ChaincodeMessage) error 41 Recv() (*pb.ChaincodeMessage, error) 42 CloseSend() error 43 } 44 45 type nextStateInfo struct { 46 msg *pb.ChaincodeMessage 47 sendToCC bool 48 } 49 50 func (handler *Handler) triggerNextState(msg *pb.ChaincodeMessage, send bool) { 51 handler.nextState <- &nextStateInfo{msg, send} 52 } 53 54 // Handler handler implementation for shim side of chaincode. 55 type Handler struct { 56 sync.RWMutex 57 //shim to peer grpc serializer. User only in serialSend 58 serialLock sync.Mutex 59 To string 60 ChatStream PeerChaincodeStream 61 FSM *fsm.FSM 62 cc Chaincode 63 // Multiple queries (and one transaction) with different txids can be executing in parallel for this chaincode 64 // responseChannel is the channel on which responses are communicated by the shim to the chaincodeStub. 65 responseChannel map[string]chan pb.ChaincodeMessage 66 nextState chan *nextStateInfo 67 } 68 69 func shorttxid(txid string) string { 70 if len(txid) < 8 { 71 return txid 72 } 73 return txid[0:8] 74 } 75 76 //serialSend serializes msgs so gRPC will be happy 77 func (handler *Handler) serialSend(msg *pb.ChaincodeMessage) error { 78 handler.serialLock.Lock() 79 defer handler.serialLock.Unlock() 80 81 err := handler.ChatStream.Send(msg) 82 83 return err 84 } 85 86 //serialSendAsync serves the same purpose as serialSend (serializ msgs so gRPC will 87 //be happy). In addition, it is also asynchronous so send-remoterecv--localrecv loop 88 //can be nonblocking. Only errors need to be handled and these are handled by 89 //communication on supplied error channel. A typical use will be a non-blocking or 90 //nil channel 91 func (handler *Handler) serialSendAsync(msg *pb.ChaincodeMessage, errc chan error) { 92 go func() { 93 err := handler.serialSend(msg) 94 if errc != nil { 95 errc <- err 96 } 97 }() 98 } 99 100 func (handler *Handler) createChannel(txid string) (chan pb.ChaincodeMessage, error) { 101 handler.Lock() 102 defer handler.Unlock() 103 if handler.responseChannel == nil { 104 return nil, fmt.Errorf("[%s]Cannot create response channel", shorttxid(txid)) 105 } 106 if handler.responseChannel[txid] != nil { 107 return nil, fmt.Errorf("[%s]Channel exists", shorttxid(txid)) 108 } 109 c := make(chan pb.ChaincodeMessage) 110 handler.responseChannel[txid] = c 111 return c, nil 112 } 113 114 func (handler *Handler) sendChannel(msg *pb.ChaincodeMessage) error { 115 handler.Lock() 116 defer handler.Unlock() 117 if handler.responseChannel == nil { 118 return fmt.Errorf("[%s]Cannot send message response channel", shorttxid(msg.Txid)) 119 } 120 if handler.responseChannel[msg.Txid] == nil { 121 return fmt.Errorf("[%s]sendChannel does not exist", shorttxid(msg.Txid)) 122 } 123 124 chaincodeLogger.Debugf("[%s]before send", shorttxid(msg.Txid)) 125 handler.responseChannel[msg.Txid] <- *msg 126 chaincodeLogger.Debugf("[%s]after send", shorttxid(msg.Txid)) 127 128 return nil 129 } 130 131 //sends a message and selects 132 func (handler *Handler) sendReceive(msg *pb.ChaincodeMessage, c chan pb.ChaincodeMessage) (pb.ChaincodeMessage, error) { 133 errc := make(chan error, 1) 134 handler.serialSendAsync(msg, errc) 135 136 //the serialsend above will send an err or nil 137 //the select filters that first error(or nil) 138 //and continues to wait for the response 139 //it is possible that the response triggers first 140 //in which case the errc obviously worked and is 141 //ignored 142 for { 143 select { 144 case err := <-errc: 145 if err == nil { 146 continue 147 } 148 //would have been logged, return false 149 return pb.ChaincodeMessage{}, err 150 case outmsg, val := <-c: 151 if !val { 152 return pb.ChaincodeMessage{}, fmt.Errorf("unexpected failure on receive") 153 } 154 return outmsg, nil 155 } 156 } 157 } 158 159 func (handler *Handler) deleteChannel(txid string) { 160 handler.Lock() 161 defer handler.Unlock() 162 if handler.responseChannel != nil { 163 delete(handler.responseChannel, txid) 164 } 165 } 166 167 // NewChaincodeHandler returns a new instance of the shim side handler. 168 func newChaincodeHandler(peerChatStream PeerChaincodeStream, chaincode Chaincode) *Handler { 169 v := &Handler{ 170 ChatStream: peerChatStream, 171 cc: chaincode, 172 } 173 v.responseChannel = make(map[string]chan pb.ChaincodeMessage) 174 v.nextState = make(chan *nextStateInfo) 175 176 // Create the shim side FSM 177 v.FSM = fsm.NewFSM( 178 "created", 179 fsm.Events{ 180 {Name: pb.ChaincodeMessage_REGISTERED.String(), Src: []string{"created"}, Dst: "established"}, 181 {Name: pb.ChaincodeMessage_READY.String(), Src: []string{"established"}, Dst: "ready"}, 182 {Name: pb.ChaincodeMessage_ERROR.String(), Src: []string{"init"}, Dst: "established"}, 183 {Name: pb.ChaincodeMessage_RESPONSE.String(), Src: []string{"init"}, Dst: "init"}, 184 {Name: pb.ChaincodeMessage_INIT.String(), Src: []string{"ready"}, Dst: "ready"}, 185 {Name: pb.ChaincodeMessage_TRANSACTION.String(), Src: []string{"ready"}, Dst: "ready"}, 186 {Name: pb.ChaincodeMessage_RESPONSE.String(), Src: []string{"ready"}, Dst: "ready"}, 187 {Name: pb.ChaincodeMessage_ERROR.String(), Src: []string{"ready"}, Dst: "ready"}, 188 {Name: pb.ChaincodeMessage_COMPLETED.String(), Src: []string{"init"}, Dst: "ready"}, 189 {Name: pb.ChaincodeMessage_COMPLETED.String(), Src: []string{"ready"}, Dst: "ready"}, 190 }, 191 fsm.Callbacks{ 192 "before_" + pb.ChaincodeMessage_REGISTERED.String(): func(e *fsm.Event) { v.beforeRegistered(e) }, 193 "after_" + pb.ChaincodeMessage_RESPONSE.String(): func(e *fsm.Event) { v.afterResponse(e) }, 194 "after_" + pb.ChaincodeMessage_ERROR.String(): func(e *fsm.Event) { v.afterError(e) }, 195 "before_" + pb.ChaincodeMessage_INIT.String(): func(e *fsm.Event) { v.beforeInit(e) }, 196 "before_" + pb.ChaincodeMessage_TRANSACTION.String(): func(e *fsm.Event) { v.beforeTransaction(e) }, 197 }, 198 ) 199 return v 200 } 201 202 // beforeRegistered is called to handle the REGISTERED message. 203 func (handler *Handler) beforeRegistered(e *fsm.Event) { 204 if _, ok := e.Args[0].(*pb.ChaincodeMessage); !ok { 205 e.Cancel(fmt.Errorf("Received unexpected message type")) 206 return 207 } 208 chaincodeLogger.Debugf("Received %s, ready for invocations", pb.ChaincodeMessage_REGISTERED) 209 } 210 211 // handleInit handles request to initialize chaincode. 212 func (handler *Handler) handleInit(msg *pb.ChaincodeMessage) { 213 // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition 214 // is completed before the next one is triggered. The previous state transition is deemed complete only when 215 // the beforeInit function is exited. Interesting bug fix!! 216 go func() { 217 var nextStateMsg *pb.ChaincodeMessage 218 219 send := true 220 221 defer func() { 222 handler.triggerNextState(nextStateMsg, send) 223 }() 224 225 errFunc := func(err error, payload []byte, ce *pb.ChaincodeEvent, errFmt string, args ...string) *pb.ChaincodeMessage { 226 if err != nil { 227 // Send ERROR message to chaincode support and change state 228 if payload == nil { 229 payload = []byte(err.Error()) 230 } 231 chaincodeLogger.Errorf(errFmt, args) 232 return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid, ChaincodeEvent: ce} 233 } 234 return nil 235 } 236 // Get the function and args from Payload 237 input := &pb.ChaincodeInput{} 238 unmarshalErr := proto.Unmarshal(msg.Payload, input) 239 if nextStateMsg = errFunc(unmarshalErr, nil, nil, "[%s]Incorrect payload format. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 240 return 241 } 242 243 // Call chaincode's Run 244 // Create the ChaincodeStub which the chaincode can use to callback 245 stub := new(ChaincodeStub) 246 247 err := stub.init(handler, msg.Txid, input, msg.Proposal) 248 if nextStateMsg = errFunc(err, nil, stub.chaincodeEvent, "[%s]Init get error response [%s]. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 249 return 250 } 251 252 res := handler.cc.Init(stub) 253 chaincodeLogger.Debugf("[%s]Init get response status: %d", shorttxid(msg.Txid), res.Status) 254 255 if res.Status >= ERROR { 256 err = fmt.Errorf("%s", res.Message) 257 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 { 258 return 259 } 260 } 261 262 resBytes, err := proto.Marshal(&res) 263 if nextStateMsg = errFunc(err, nil, stub.chaincodeEvent, "[%s]Init marshal response error [%s]. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 264 return 265 } 266 267 // Send COMPLETED message to chaincode support and change state 268 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: resBytes, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 269 chaincodeLogger.Debugf("[%s]Init succeeded. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_COMPLETED) 270 }() 271 } 272 273 // beforeInit will initialize the chaincode if entering init from established. 274 func (handler *Handler) beforeInit(e *fsm.Event) { 275 chaincodeLogger.Debugf("Entered state %s", handler.FSM.Current()) 276 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 277 if !ok { 278 e.Cancel(fmt.Errorf("Received unexpected message type")) 279 return 280 } 281 chaincodeLogger.Debugf("[%s]Received %s, initializing chaincode", shorttxid(msg.Txid), msg.Type.String()) 282 if msg.Type.String() == pb.ChaincodeMessage_INIT.String() { 283 // Call the chaincode's Run function to initialize 284 handler.handleInit(msg) 285 } 286 } 287 288 // handleTransaction Handles request to execute a transaction. 289 func (handler *Handler) handleTransaction(msg *pb.ChaincodeMessage) { 290 // The defer followed by triggering a go routine dance is needed to ensure that the previous state transition 291 // is completed before the next one is triggered. The previous state transition is deemed complete only when 292 // the beforeInit function is exited. Interesting bug fix!! 293 go func() { 294 //better not be nil 295 var nextStateMsg *pb.ChaincodeMessage 296 297 send := true 298 299 defer func() { 300 handler.triggerNextState(nextStateMsg, send) 301 }() 302 303 errFunc := func(err error, ce *pb.ChaincodeEvent, errStr string, args ...string) *pb.ChaincodeMessage { 304 if err != nil { 305 payload := []byte(err.Error()) 306 chaincodeLogger.Errorf(errStr, args) 307 return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid, ChaincodeEvent: ce} 308 } 309 return nil 310 } 311 312 // Get the function and args from Payload 313 input := &pb.ChaincodeInput{} 314 unmarshalErr := proto.Unmarshal(msg.Payload, input) 315 if nextStateMsg = errFunc(unmarshalErr, nil, "[%s]Incorrect payload format. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 316 return 317 } 318 319 // Call chaincode's Run 320 // Create the ChaincodeStub which the chaincode can use to callback 321 stub := new(ChaincodeStub) 322 err := stub.init(handler, msg.Txid, input, msg.Proposal) 323 if nextStateMsg = errFunc(err, stub.chaincodeEvent, "[%s]Transaction execution failed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 324 return 325 } 326 327 res := handler.cc.Invoke(stub) 328 329 // Endorser will handle error contained in Response. 330 resBytes, err := proto.Marshal(&res) 331 if nextStateMsg = errFunc(err, stub.chaincodeEvent, "[%s]Transaction execution failed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR.String()); nextStateMsg != nil { 332 return 333 } 334 335 // Send COMPLETED message to chaincode support and change state 336 chaincodeLogger.Debugf("[%s]Transaction completed. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_COMPLETED) 337 nextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_COMPLETED, Payload: resBytes, Txid: msg.Txid, ChaincodeEvent: stub.chaincodeEvent} 338 }() 339 } 340 341 // beforeTransaction will execute chaincode's Run if coming from a TRANSACTION event. 342 func (handler *Handler) beforeTransaction(e *fsm.Event) { 343 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 344 if !ok { 345 e.Cancel(fmt.Errorf("Received unexpected message type")) 346 return 347 } 348 chaincodeLogger.Debugf("[%s]Received %s, invoking transaction on chaincode(Src:%s, Dst:%s)", shorttxid(msg.Txid), msg.Type.String(), e.Src, e.Dst) 349 if msg.Type.String() == pb.ChaincodeMessage_TRANSACTION.String() { 350 // Call the chaincode's Run function to invoke transaction 351 handler.handleTransaction(msg) 352 } 353 } 354 355 // afterResponse is called to deliver a response or error to the chaincode stub. 356 func (handler *Handler) afterResponse(e *fsm.Event) { 357 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 358 if !ok { 359 e.Cancel(fmt.Errorf("Received unexpected message type")) 360 return 361 } 362 363 if err := handler.sendChannel(msg); err != nil { 364 chaincodeLogger.Errorf("[%s]error sending %s (state:%s): %s", shorttxid(msg.Txid), msg.Type, handler.FSM.Current(), err) 365 } else { 366 chaincodeLogger.Debugf("[%s]Received %s, communicated (state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 367 } 368 } 369 370 func (handler *Handler) afterError(e *fsm.Event) { 371 msg, ok := e.Args[0].(*pb.ChaincodeMessage) 372 if !ok { 373 e.Cancel(fmt.Errorf("Received unexpected message type")) 374 return 375 } 376 377 /* TODO- revisit. This may no longer be needed with the serialized/streamlined messaging model 378 * There are two situations in which the ERROR event can be triggered: 379 * 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. 380 * 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. 381 */ 382 if err := handler.sendChannel(msg); err == nil { 383 chaincodeLogger.Debugf("[%s]Error received from validator %s, communicated(state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 384 } 385 } 386 387 // TODO: Implement method to get and put entire state map and not one key at a time? 388 // handleGetState communicates with the validator to fetch the requested state information from the ledger. 389 func (handler *Handler) handleGetState(key string, txid string) ([]byte, error) { 390 // Create the channel on which to communicate the response from validating peer 391 var respChan chan pb.ChaincodeMessage 392 var err error 393 if respChan, err = handler.createChannel(txid); err != nil { 394 return nil, err 395 } 396 397 defer handler.deleteChannel(txid) 398 399 // Send GET_STATE message to validator chaincode support 400 payload := []byte(key) 401 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: payload, Txid: txid} 402 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE) 403 404 var responseMsg pb.ChaincodeMessage 405 406 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 407 return nil, errors.New(fmt.Sprintf("[%s]error sending GET_STATE %s", shorttxid(txid), err)) 408 } 409 410 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 411 // Success response 412 chaincodeLogger.Debugf("[%s]GetState received payload %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 413 return responseMsg.Payload, nil 414 } 415 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 416 // Error response 417 chaincodeLogger.Errorf("[%s]GetState received error %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 418 return nil, errors.New(string(responseMsg.Payload[:])) 419 } 420 421 // Incorrect chaincode message received 422 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)) 423 } 424 425 // handlePutState communicates with the validator to put state information into the ledger. 426 func (handler *Handler) handlePutState(key string, value []byte, txid string) error { 427 // Check if this is a transaction 428 chaincodeLogger.Debugf("[%s]Inside putstate", shorttxid(txid)) 429 430 //we constructed a valid object. No need to check for error 431 payloadBytes, _ := proto.Marshal(&pb.PutStateInfo{Key: key, Value: value}) 432 433 // Create the channel on which to communicate the response from validating peer 434 var respChan chan pb.ChaincodeMessage 435 var err error 436 if respChan, err = handler.createChannel(txid); err != nil { 437 return err 438 } 439 440 defer handler.deleteChannel(txid) 441 442 // Send PUT_STATE message to validator chaincode support 443 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_PUT_STATE, Payload: payloadBytes, Txid: txid} 444 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_PUT_STATE) 445 446 var responseMsg pb.ChaincodeMessage 447 448 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 449 return errors.New(fmt.Sprintf("[%s]error sending PUT_STATE %s", msg.Txid, err)) 450 } 451 452 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 453 // Success response 454 chaincodeLogger.Debugf("[%s]Received %s. Successfully updated state", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 455 return nil 456 } 457 458 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 459 // Error response 460 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR, responseMsg.Payload) 461 return errors.New(string(responseMsg.Payload[:])) 462 } 463 464 // Incorrect chaincode message received 465 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)) 466 } 467 468 // handleDelState communicates with the validator to delete a key from the state in the ledger. 469 func (handler *Handler) handleDelState(key string, txid string) error { 470 // Create the channel on which to communicate the response from validating peer 471 var respChan chan pb.ChaincodeMessage 472 var err error 473 if respChan, err = handler.createChannel(txid); err != nil { 474 return err 475 } 476 477 defer handler.deleteChannel(txid) 478 479 // Send DEL_STATE message to validator chaincode support 480 payload := []byte(key) 481 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_DEL_STATE, Payload: payload, Txid: txid} 482 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_DEL_STATE) 483 484 var responseMsg pb.ChaincodeMessage 485 486 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 487 return errors.New(fmt.Sprintf("[%s]error sending DEL_STATE %s", shorttxid(msg.Txid), pb.ChaincodeMessage_DEL_STATE)) 488 } 489 490 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 491 // Success response 492 chaincodeLogger.Debugf("[%s]Received %s. Successfully deleted state", msg.Txid, pb.ChaincodeMessage_RESPONSE) 493 return nil 494 } 495 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 496 // Error response 497 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", msg.Txid, pb.ChaincodeMessage_ERROR, responseMsg.Payload) 498 return errors.New(string(responseMsg.Payload[:])) 499 } 500 501 // Incorrect chaincode message received 502 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)) 503 } 504 505 func (handler *Handler) handleGetStateByRange(startKey, endKey string, txid string) (*pb.QueryResponse, error) { 506 // Create the channel on which to communicate the response from validating peer 507 var respChan chan pb.ChaincodeMessage 508 var err error 509 if respChan, err = handler.createChannel(txid); err != nil { 510 return nil, err 511 } 512 513 defer handler.deleteChannel(txid) 514 515 // Send GET_STATE_BY_RANGE message to validator chaincode support 516 //we constructed a valid object. No need to check for error 517 payloadBytes, _ := proto.Marshal(&pb.GetStateByRange{StartKey: startKey, EndKey: endKey}) 518 519 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE_BY_RANGE, Payload: payloadBytes, Txid: txid} 520 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE_BY_RANGE) 521 522 var responseMsg pb.ChaincodeMessage 523 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 524 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE_BY_RANGE)) 525 } 526 527 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 528 // Success response 529 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 530 531 rangeQueryResponse := &pb.QueryResponse{} 532 if err = proto.Unmarshal(responseMsg.Payload, rangeQueryResponse); err != nil { 533 return nil, errors.New(fmt.Sprintf("[%s]GetStateByRangeResponse unmarshall error", shorttxid(responseMsg.Txid))) 534 } 535 536 return rangeQueryResponse, nil 537 } 538 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 539 // Error response 540 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 541 return nil, errors.New(string(responseMsg.Payload[:])) 542 } 543 544 // Incorrect chaincode message received 545 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 546 } 547 548 func (handler *Handler) handleQueryStateNext(id, txid string) (*pb.QueryResponse, error) { 549 // Create the channel on which to communicate the response from validating peer 550 var respChan chan pb.ChaincodeMessage 551 var err error 552 if respChan, err = handler.createChannel(txid); err != nil { 553 return nil, err 554 } 555 556 defer handler.deleteChannel(txid) 557 558 // Send QUERY_STATE_NEXT message to validator chaincode support 559 //we constructed a valid object. No need to check for error 560 payloadBytes, _ := proto.Marshal(&pb.QueryStateNext{Id: id}) 561 562 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_NEXT, Payload: payloadBytes, Txid: txid} 563 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_NEXT) 564 565 var responseMsg pb.ChaincodeMessage 566 567 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 568 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_NEXT)) 569 } 570 571 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 572 // Success response 573 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 574 575 queryResponse := &pb.QueryResponse{} 576 if err = proto.Unmarshal(responseMsg.Payload, queryResponse); err != nil { 577 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 578 } 579 580 return queryResponse, nil 581 } 582 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 583 // Error response 584 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 585 return nil, errors.New(string(responseMsg.Payload[:])) 586 } 587 588 // Incorrect chaincode message received 589 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 590 } 591 592 func (handler *Handler) handleQueryStateClose(id, txid string) (*pb.QueryResponse, error) { 593 // Create the channel on which to communicate the response from validating peer 594 var respChan chan pb.ChaincodeMessage 595 var err error 596 if respChan, err = handler.createChannel(txid); err != nil { 597 return nil, err 598 } 599 600 defer handler.deleteChannel(txid) 601 602 // Send QUERY_STATE_CLOSE message to validator chaincode support 603 //we constructed a valid object. No need to check for error 604 payloadBytes, _ := proto.Marshal(&pb.QueryStateClose{Id: id}) 605 606 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_QUERY_STATE_CLOSE, Payload: payloadBytes, Txid: txid} 607 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_CLOSE) 608 609 var responseMsg pb.ChaincodeMessage 610 611 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 612 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_QUERY_STATE_CLOSE)) 613 } 614 615 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 616 // Success response 617 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 618 619 queryResponse := &pb.QueryResponse{} 620 if err = proto.Unmarshal(responseMsg.Payload, queryResponse); err != nil { 621 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 622 } 623 624 return queryResponse, nil 625 } 626 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 627 // Error response 628 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 629 return nil, errors.New(string(responseMsg.Payload[:])) 630 } 631 632 // Incorrect chaincode message received 633 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 634 } 635 636 func (handler *Handler) handleGetQueryResult(query string, txid string) (*pb.QueryResponse, error) { 637 // Create the channel on which to communicate the response from validating peer 638 var respChan chan pb.ChaincodeMessage 639 var err error 640 if respChan, err = handler.createChannel(txid); err != nil { 641 return nil, err 642 } 643 644 defer handler.deleteChannel(txid) 645 646 // Send GET_QUERY_RESULT message to validator chaincode support 647 //we constructed a valid object. No need to check for error 648 payloadBytes, _ := proto.Marshal(&pb.GetQueryResult{Query: query}) 649 650 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_QUERY_RESULT, Payload: payloadBytes, Txid: txid} 651 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_QUERY_RESULT) 652 653 var responseMsg pb.ChaincodeMessage 654 655 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 656 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_QUERY_RESULT)) 657 } 658 659 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 660 // Success response 661 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 662 663 executeQueryResponse := &pb.QueryResponse{} 664 if err = proto.Unmarshal(responseMsg.Payload, executeQueryResponse); err != nil { 665 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 666 } 667 668 return executeQueryResponse, nil 669 } 670 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 671 // Error response 672 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 673 return nil, errors.New(string(responseMsg.Payload[:])) 674 } 675 676 // Incorrect chaincode message received 677 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 678 } 679 680 func (handler *Handler) handleGetHistoryForKey(key string, txid string) (*pb.QueryResponse, error) { 681 // Create the channel on which to communicate the response from validating peer 682 var respChan chan pb.ChaincodeMessage 683 var err error 684 if respChan, err = handler.createChannel(txid); err != nil { 685 return nil, err 686 } 687 688 defer handler.deleteChannel(txid) 689 690 // Send GET_HISTORY_FOR_KEY message to validator chaincode support 691 //we constructed a valid object. No need to check for error 692 payloadBytes, _ := proto.Marshal(&pb.GetHistoryForKey{Key: key}) 693 694 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_HISTORY_FOR_KEY, Payload: payloadBytes, Txid: txid} 695 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_HISTORY_FOR_KEY) 696 697 var responseMsg pb.ChaincodeMessage 698 699 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 700 return nil, errors.New(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_HISTORY_FOR_KEY)) 701 } 702 703 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 704 // Success response 705 chaincodeLogger.Debugf("[%s]Received %s. Successfully got range", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 706 707 getHistoryForKeyResponse := &pb.QueryResponse{} 708 if err = proto.Unmarshal(responseMsg.Payload, getHistoryForKeyResponse); err != nil { 709 return nil, errors.New(fmt.Sprintf("[%s]unmarshall error", shorttxid(responseMsg.Txid))) 710 } 711 712 return getHistoryForKeyResponse, nil 713 } 714 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 715 // Error response 716 chaincodeLogger.Errorf("[%s]Received %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 717 return nil, errors.New(string(responseMsg.Payload[:])) 718 } 719 720 // Incorrect chaincode message received 721 return nil, errors.New(fmt.Sprintf("Incorrect chaincode message %s received. Expecting %s or %s", responseMsg.Type, pb.ChaincodeMessage_RESPONSE, pb.ChaincodeMessage_ERROR)) 722 } 723 724 //----------------------------inkchain wallet 725 726 func (handler *Handler) handleTransfer(trans *kvtranset.KVTranSet, txid string) error { 727 // Check if this is a transaction 728 chaincodeLogger.Debugf("[%s]Inside transfer", shorttxid(txid)) 729 //we constructed a valid object. No need to check for error 730 var tranSet []*pb.Transfer 731 for _, tran := range trans.Trans { 732 protoTran := pb.Transfer{To: []byte(strings.ToLower(tran.To)), BalanceType: []byte(tran.BalanceType), Amount: tran.Amount} 733 tranSet = append(tranSet, &protoTran) 734 } 735 transferInfo := &pb.TransferInfo{TranSet: tranSet} 736 payloadBytes, err := proto.Marshal(transferInfo) 737 // Create the channel on which to communicate the response from validating peer 738 if err != nil { 739 return err 740 } 741 var respChan chan pb.ChaincodeMessage 742 if respChan, err = handler.createChannel(txid); err != nil { 743 return err 744 } 745 746 defer handler.deleteChannel(txid) 747 748 // Send Transfer message to validator chaincode support 749 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_TRANSFER, Payload: payloadBytes, Txid: txid} 750 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_TRANSFER) 751 752 var responseMsg pb.ChaincodeMessage 753 754 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 755 return errors.New(fmt.Sprintf("[%s]error sending TRANSFER %s", msg.Txid, err)) 756 } 757 758 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 759 // Success response 760 chaincodeLogger.Debugf("[%s]Received %s. Successfully transfered", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 761 return nil 762 } 763 764 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 765 // Error response 766 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR, responseMsg.Payload) 767 return errors.New(string(responseMsg.Payload[:])) 768 } 769 770 // Incorrect chaincode message received 771 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)) 772 } 773 774 func (handler *Handler) handleGetAccount(address string, txid string) (*wallet.Account, error) { 775 // Create the channel on which to communicate the response from validating peer 776 var respChan chan pb.ChaincodeMessage 777 var err error 778 if respChan, err = handler.createChannel(txid); err != nil { 779 return nil, err 780 } 781 defer handler.deleteChannel(txid) 782 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_ACCOUNT, Payload: []byte(address), Txid: txid} 783 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_ACCOUNT) 784 785 var responseMsg pb.ChaincodeMessage 786 787 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 788 return nil, errors.New(fmt.Sprintf("[%s]error sending GET_ACCOUNT %s", shorttxid(txid), err)) 789 } 790 791 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 792 // Success response 793 chaincodeLogger.Debugf("[%s]GetAccount received payload %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 794 account := &wallet.Account{} 795 if jsonErr := json.Unmarshal(responseMsg.Payload, account); jsonErr != nil { 796 return nil, jsonErr 797 } 798 return account, nil 799 } 800 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 801 // Error response 802 chaincodeLogger.Errorf("[%s]GetAccount received error %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 803 return nil, errors.New(string(responseMsg.Payload[:])) 804 } 805 806 // Incorrect chaincode message received 807 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)) 808 } 809 810 // handlePutState communicates with the validator to put state information into the ledger. 811 func (handler *Handler) handleIssueToken(address string, balanceType string, amount *big.Int, txid string) error { 812 // Check if this is a transaction 813 chaincodeLogger.Debugf("[%s]Inside issue token", shorttxid(txid)) 814 //we constructed a valid object. No need to check for error 815 payloadBytes, _ := proto.Marshal(&pb.IssueTokenInfo{Address: []byte(address), BalanceType: []byte(balanceType), Amount: amount.Bytes()}) 816 817 // Create the channel on which to communicate the response from validating peer 818 var respChan chan pb.ChaincodeMessage 819 var err error 820 if respChan, err = handler.createChannel(txid); err != nil { 821 return err 822 } 823 824 defer handler.deleteChannel(txid) 825 826 // Send PUT_STATE message to validator chaincode support 827 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ISSUE_TOKEN, Payload: payloadBytes, Txid: txid} 828 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ISSUE_TOKEN) 829 830 var responseMsg pb.ChaincodeMessage 831 832 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 833 return errors.New(fmt.Sprintf("[%s]error sending SET_BALANCE %s", msg.Txid, err)) 834 } 835 836 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 837 // Success response 838 chaincodeLogger.Debugf("[%s]Received %s. Successfully set balance", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 839 return nil 840 } 841 842 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 843 // Error response 844 chaincodeLogger.Errorf("[%s]Received %s. Payload: %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR, responseMsg.Payload) 845 return errors.New(string(responseMsg.Payload[:])) 846 } 847 848 // Incorrect chaincode message received 849 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)) 850 } 851 852 // handleCalcFee communicates to calculate the fee of content. 853 func (handler *Handler) handleCalcFee(content string, txId string) (*big.Int, error) { 854 // Create the channel on which to communicate the response from validating peer 855 var respChan chan pb.ChaincodeMessage 856 var err error 857 if respChan, err = handler.createChannel(txId); err != nil { 858 return nil, err 859 } 860 861 defer handler.deleteChannel(txId) 862 863 payload := []byte(content) 864 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_FEE, Payload: payload, Txid: txId} 865 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_FEE) 866 867 var responseMsg pb.ChaincodeMessage 868 869 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 870 return nil, errors.New(fmt.Sprintf("[%s]error sending GET_FEE %s", shorttxid(txId), err)) 871 } 872 873 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 874 // Success response 875 chaincodeLogger.Debugf("[%s]GetFee received payload %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 876 fee := big.NewInt(0) 877 fee.SetBytes(responseMsg.Payload[:]) 878 return fee, nil 879 } 880 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 881 // Error response 882 chaincodeLogger.Errorf("[%s]GetState received error %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 883 return nil, errors.New(string(responseMsg.Payload[:])) 884 } 885 886 // Incorrect chaincode message received 887 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)) 888 } 889 890 // handleSign communicates to get data signature. 891 func (handler *Handler) handleSign(data []byte, txId string) (string, error) { 892 // Create the channel on which to communicate the response from validating peer 893 var respChan chan pb.ChaincodeMessage 894 var err error 895 if respChan, err = handler.createChannel(txId); err != nil { 896 return "", err 897 } 898 899 defer handler.deleteChannel(txId) 900 901 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_SIGN, Payload: data, Txid: txId} 902 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_SIGN) 903 904 var responseMsg pb.ChaincodeMessage 905 906 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 907 return "", errors.New(fmt.Sprintf("[%s]error sending SIGN %s", shorttxid(txId), err)) 908 } 909 910 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 911 // Success response 912 chaincodeLogger.Debugf("[%s]Sign received payload %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 913 signStr := wallet.SignatureBytesToString(responseMsg.Payload[:]) 914 return signStr, nil 915 } 916 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 917 // Error response 918 chaincodeLogger.Errorf("[%s]Sign received error %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 919 return "", errors.New(string(responseMsg.Payload[:])) 920 } 921 922 // Incorrect chaincode message received 923 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)) 924 } 925 926 // handleGetSignCheck communicates to check signature from Sign 927 func (handler *Handler) handleVerify(signature string, data []byte, address string, txId string) (bool, error) { 928 //we constructed a valid object. No need to check for error 929 payloadBytes, _ := proto.Marshal(&pb.Verify{Signature: signature, Data: data, Address: address}) 930 // Create the channel on which to communicate the response from validating peer 931 var respChan chan pb.ChaincodeMessage 932 var err error 933 if respChan, err = handler.createChannel(txId); err != nil { 934 return false, err 935 } 936 937 defer handler.deleteChannel(txId) 938 939 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_VERIFY, Payload: payloadBytes, Txid: txId} 940 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_VERIFY) 941 942 var responseMsg pb.ChaincodeMessage 943 944 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 945 return false, errors.New(fmt.Sprintf("[%s]error sending VERIFY %s", shorttxid(txId), err)) 946 } 947 948 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 949 // Success response 950 chaincodeLogger.Debugf("[%s]Verify received payload %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 951 result, err := strconv.ParseBool(string(responseMsg.Payload[:])) 952 if err != nil { 953 return false, errors.New(fmt.Sprintf("[%s]error parse result from VERIFY response", shorttxid(txId))) 954 } 955 return result, nil 956 } 957 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 958 // Error response 959 chaincodeLogger.Errorf("[%s]Verify received error %s", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 960 return false, errors.New(string(responseMsg.Payload[:])) 961 } 962 963 // Incorrect chaincode message received 964 return false, 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)) 965 } 966 967 //--------------------------- 968 969 func (handler *Handler) createResponse(status int32, payload []byte) pb.Response { 970 return pb.Response{Status: status, Payload: payload} 971 } 972 973 // handleInvokeChaincode communicates with the validator to invoke another chaincode. 974 func (handler *Handler) handleInvokeChaincode(chaincodeName string, args [][]byte, txid string) pb.Response { 975 //we constructed a valid object. No need to check for error 976 payloadBytes, _ := proto.Marshal(&pb.ChaincodeSpec{ChaincodeId: &pb.ChaincodeID{Name: chaincodeName}, Input: &pb.ChaincodeInput{Args: args}}) 977 978 // Create the channel on which to communicate the response from validating peer 979 var respChan chan pb.ChaincodeMessage 980 var err error 981 if respChan, err = handler.createChannel(txid); err != nil { 982 return handler.createResponse(ERROR, []byte(err.Error())) 983 } 984 985 defer handler.deleteChannel(txid) 986 987 // Send INVOKE_CHAINCODE message to validator chaincode support 988 msg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_INVOKE_CHAINCODE, Payload: payloadBytes, Txid: txid} 989 chaincodeLogger.Debugf("[%s]Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_INVOKE_CHAINCODE) 990 991 var responseMsg pb.ChaincodeMessage 992 993 if responseMsg, err = handler.sendReceive(msg, respChan); err != nil { 994 return handler.createResponse(ERROR, []byte(fmt.Sprintf("[%s]error sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_INVOKE_CHAINCODE))) 995 } 996 997 if responseMsg.Type.String() == pb.ChaincodeMessage_RESPONSE.String() { 998 // Success response 999 chaincodeLogger.Debugf("[%s]Received %s. Successfully invoked chaincode", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 1000 respMsg := &pb.ChaincodeMessage{} 1001 if err = proto.Unmarshal(responseMsg.Payload, respMsg); err != nil { 1002 return handler.createResponse(ERROR, []byte(err.Error())) 1003 } 1004 if respMsg.Type == pb.ChaincodeMessage_COMPLETED { 1005 // Success response 1006 chaincodeLogger.Debugf("[%s]Received %s. Successfully invoed chaincode", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_RESPONSE) 1007 res := &pb.Response{} 1008 if err = proto.Unmarshal(respMsg.Payload, res); err != nil { 1009 return handler.createResponse(ERROR, []byte(err.Error())) 1010 } 1011 return *res 1012 } 1013 chaincodeLogger.Errorf("[%s]Received %s. Error from chaincode", shorttxid(responseMsg.Txid), respMsg.Type.String()) 1014 return handler.createResponse(ERROR, responseMsg.Payload) 1015 } 1016 if responseMsg.Type.String() == pb.ChaincodeMessage_ERROR.String() { 1017 // Error response 1018 chaincodeLogger.Errorf("[%s]Received %s.", shorttxid(responseMsg.Txid), pb.ChaincodeMessage_ERROR) 1019 return handler.createResponse(ERROR, responseMsg.Payload) 1020 } 1021 1022 // Incorrect chaincode message received 1023 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))) 1024 } 1025 1026 // handleMessage message handles loop for shim side of chaincode/validator stream. 1027 func (handler *Handler) handleMessage(msg *pb.ChaincodeMessage) error { 1028 if msg.Type == pb.ChaincodeMessage_KEEPALIVE { 1029 // Received a keep alive message, we don't do anything with it for now 1030 // and it does not touch the state machine 1031 return nil 1032 } 1033 chaincodeLogger.Debugf("[%s]Handling ChaincodeMessage of type: %s(state:%s)", shorttxid(msg.Txid), msg.Type, handler.FSM.Current()) 1034 if handler.FSM.Cannot(msg.Type.String()) { 1035 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())) 1036 handler.serialSend(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid}) 1037 return err 1038 } 1039 err := handler.FSM.Event(msg.Type.String(), msg) 1040 return filterError(err) 1041 } 1042 1043 // filterError filters the errors to allow NoTransitionError and CanceledError to not propagate for cases where embedded Err == nil. 1044 func filterError(errFromFSMEvent error) error { 1045 if errFromFSMEvent != nil { 1046 if noTransitionErr, ok := errFromFSMEvent.(*fsm.NoTransitionError); ok { 1047 if noTransitionErr.Err != nil { 1048 // Only allow NoTransitionError's, all others are considered true error. 1049 return errFromFSMEvent 1050 } 1051 } 1052 if canceledErr, ok := errFromFSMEvent.(*fsm.CanceledError); ok { 1053 if canceledErr.Err != nil { 1054 // Only allow NoTransitionError's, all others are considered true error. 1055 return canceledErr 1056 //t.Error("expected only 'NoTransitionError'") 1057 } 1058 chaincodeLogger.Debugf("Ignoring CanceledError: %s", canceledErr) 1059 } 1060 } 1061 return nil 1062 }