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  }