github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/chaincode/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 chaincode
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"sync"
    24  	"time"
    25  
    26  	"github.com/golang/protobuf/proto"
    27  	commonledger "github.com/hyperledger/fabric/common/ledger"
    28  	"github.com/hyperledger/fabric/common/util"
    29  	"github.com/hyperledger/fabric/core/common/ccprovider"
    30  	ccintf "github.com/hyperledger/fabric/core/container/ccintf"
    31  	"github.com/hyperledger/fabric/core/ledger"
    32  	"github.com/hyperledger/fabric/core/peer"
    33  	pb "github.com/hyperledger/fabric/protos/peer"
    34  	"github.com/looplab/fsm"
    35  	logging "github.com/op/go-logging"
    36  	"golang.org/x/net/context"
    37  )
    38  
    39  const (
    40  	createdstate     = "created"     //start state
    41  	establishedstate = "established" //in: CREATED, rcv:  REGISTER, send: REGISTERED, INIT
    42  	readystate       = "ready"       //in:ESTABLISHED,TRANSACTION, rcv:COMPLETED
    43  	endstate         = "end"         //in:INIT,ESTABLISHED, rcv: error, terminate container
    44  
    45  )
    46  
    47  var chaincodeLogger = logging.MustGetLogger("chaincode")
    48  
    49  // MessageHandler interface for handling chaincode messages (common between Peer chaincode support and chaincode)
    50  type MessageHandler interface {
    51  	HandleMessage(msg *pb.ChaincodeMessage) error
    52  	SendMessage(msg *pb.ChaincodeMessage) error
    53  }
    54  
    55  type transactionContext struct {
    56  	chainID          string
    57  	signedProp       *pb.SignedProposal
    58  	proposal         *pb.Proposal
    59  	responseNotifier chan *pb.ChaincodeMessage
    60  
    61  	// tracks open iterators used for range queries
    62  	queryIteratorMap map[string]commonledger.ResultsIterator
    63  
    64  	txsimulator          ledger.TxSimulator
    65  	historyQueryExecutor ledger.HistoryQueryExecutor
    66  }
    67  
    68  type nextStateInfo struct {
    69  	msg      *pb.ChaincodeMessage
    70  	sendToCC bool
    71  
    72  	//the only time we need to send synchronously is
    73  	//when launching the chaincode to take it to ready
    74  	//state (look for the panic when sending serial)
    75  	sendSync bool
    76  }
    77  
    78  //chaincode registered name is of the form
    79  //    <name>:<version>/<suffix>
    80  type ccParts struct {
    81  	name    string //the main name of the chaincode
    82  	version string //the version param if any (used for upgrade)
    83  	suffix  string //for now just the chain name
    84  }
    85  
    86  // Handler responsbile for management of Peer's side of chaincode stream
    87  type Handler struct {
    88  	sync.RWMutex
    89  	//peer to shim grpc serializer. User only in serialSend
    90  	serialLock  sync.Mutex
    91  	ChatStream  ccintf.ChaincodeStream
    92  	FSM         *fsm.FSM
    93  	ChaincodeID *pb.ChaincodeID
    94  	ccCompParts *ccParts
    95  
    96  	chaincodeSupport *ChaincodeSupport
    97  	registered       bool
    98  	readyNotify      chan bool
    99  	// Map of tx txid to either invoke tx. Each tx will be
   100  	// added prior to execute and remove when done execute
   101  	txCtxs map[string]*transactionContext
   102  
   103  	txidMap map[string]bool
   104  
   105  	// used to do Send after making sure the state transition is complete
   106  	nextState chan *nextStateInfo
   107  }
   108  
   109  func shorttxid(txid string) string {
   110  	if len(txid) < 8 {
   111  		return txid
   112  	}
   113  	return txid[0:8]
   114  }
   115  
   116  //gets component parts from the canonical name of the chaincode.
   117  //Called exactly once per chaincode when registering chaincode.
   118  //This is needed for the "one-instance-per-chain" model when
   119  //starting up the chaincode for each chain. It will still
   120  //work for the "one-instance-for-all-chains" as the version
   121  //and suffix will just be absent (also note that LCCC reserves
   122  //"/:[]${}" as special chars mainly for such namespace uses)
   123  func (handler *Handler) decomposeRegisteredName(cid *pb.ChaincodeID) {
   124  	handler.ccCompParts = chaincodeIDParts(cid.Name)
   125  }
   126  
   127  func chaincodeIDParts(ccName string) *ccParts {
   128  	b := []byte(ccName)
   129  	p := &ccParts{}
   130  
   131  	//compute suffix (ie, chain name)
   132  	i := bytes.IndexByte(b, '/')
   133  	if i >= 0 {
   134  		if i < len(b)-1 {
   135  			p.suffix = string(b[i+1:])
   136  		}
   137  		b = b[:i]
   138  	}
   139  
   140  	//compute version
   141  	i = bytes.IndexByte(b, ':')
   142  	if i >= 0 {
   143  		if i < len(b)-1 {
   144  			p.version = string(b[i+1:])
   145  		}
   146  		b = b[:i]
   147  	}
   148  	// remaining is the chaincode name
   149  	p.name = string(b)
   150  
   151  	return p
   152  }
   153  
   154  func (handler *Handler) getCCRootName() string {
   155  	return handler.ccCompParts.name
   156  }
   157  
   158  //serialSend serializes msgs so gRPC will be happy
   159  func (handler *Handler) serialSend(msg *pb.ChaincodeMessage) error {
   160  	handler.serialLock.Lock()
   161  	defer handler.serialLock.Unlock()
   162  
   163  	var err error
   164  	if err = handler.ChatStream.Send(msg); err != nil {
   165  		err = fmt.Errorf("[%s]Error sending %s: %s", shorttxid(msg.Txid), msg.Type.String(), err)
   166  		chaincodeLogger.Errorf("%s", err)
   167  	}
   168  	return err
   169  }
   170  
   171  //serialSendAsync serves the same purpose as serialSend (serializ msgs so gRPC will
   172  //be happy). In addition, it is also asynchronous so send-remoterecv--localrecv loop
   173  //can be nonblocking. Only errors need to be handled and these are handled by
   174  //communication on supplied error channel. A typical use will be a non-blocking or
   175  //nil channel
   176  func (handler *Handler) serialSendAsync(msg *pb.ChaincodeMessage, errc chan error) {
   177  	go func() {
   178  		err := handler.serialSend(msg)
   179  		if errc != nil {
   180  			errc <- err
   181  		}
   182  	}()
   183  }
   184  
   185  func (handler *Handler) createTxContext(ctxt context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal) (*transactionContext, error) {
   186  	if handler.txCtxs == nil {
   187  		return nil, fmt.Errorf("cannot create notifier for txid:%s", txid)
   188  	}
   189  	handler.Lock()
   190  	defer handler.Unlock()
   191  	if handler.txCtxs[txid] != nil {
   192  		return nil, fmt.Errorf("txid:%s exists", txid)
   193  	}
   194  	txctx := &transactionContext{chainID: chainID, signedProp: signedProp, proposal: prop, responseNotifier: make(chan *pb.ChaincodeMessage, 1),
   195  		queryIteratorMap: make(map[string]commonledger.ResultsIterator)}
   196  	handler.txCtxs[txid] = txctx
   197  	txctx.txsimulator = getTxSimulator(ctxt)
   198  	txctx.historyQueryExecutor = getHistoryQueryExecutor(ctxt)
   199  
   200  	return txctx, nil
   201  }
   202  
   203  func (handler *Handler) getTxContext(txid string) *transactionContext {
   204  	handler.Lock()
   205  	defer handler.Unlock()
   206  	return handler.txCtxs[txid]
   207  }
   208  
   209  func (handler *Handler) deleteTxContext(txid string) {
   210  	handler.Lock()
   211  	defer handler.Unlock()
   212  	if handler.txCtxs != nil {
   213  		delete(handler.txCtxs, txid)
   214  	}
   215  }
   216  
   217  func (handler *Handler) putQueryIterator(txContext *transactionContext, txid string,
   218  	queryIterator commonledger.ResultsIterator) {
   219  	handler.Lock()
   220  	defer handler.Unlock()
   221  	txContext.queryIteratorMap[txid] = queryIterator
   222  }
   223  
   224  func (handler *Handler) getQueryIterator(txContext *transactionContext, txid string) commonledger.ResultsIterator {
   225  	handler.Lock()
   226  	defer handler.Unlock()
   227  	return txContext.queryIteratorMap[txid]
   228  }
   229  
   230  func (handler *Handler) deleteQueryIterator(txContext *transactionContext, txid string) {
   231  	handler.Lock()
   232  	defer handler.Unlock()
   233  	delete(txContext.queryIteratorMap, txid)
   234  }
   235  
   236  // Check if the transactor is allow to call this chaincode on this channel
   237  func (handler *Handler) checkACL(signedProp *pb.SignedProposal, proposal *pb.Proposal, calledCC *ccParts) *pb.ChaincodeMessage {
   238  	// TODO: Decide what to pass in to verify that this transactor can access this
   239  	// channel (chID) and chaincode (ccID). Very likely we need the signedProposal
   240  	// which contains the sig and creator cert
   241  
   242  	// If error, return ChaincodeMessage with type ChaincodeMessage_ERROR
   243  	return nil
   244  }
   245  
   246  //THIS CAN BE REMOVED ONCE WE FULL SUPPORT (Invoke) CONFIDENTIALITY WITH CC-CALLING-CC
   247  //Only invocation are allowed
   248  func (handler *Handler) canCallChaincode(txid string, isQuery bool) *pb.ChaincodeMessage {
   249  	var errMsg string
   250  	txctx := handler.getTxContext(txid)
   251  	if txctx == nil {
   252  		errMsg = fmt.Sprintf("[%s]Error no context while checking for confidentiality. Sending %s", shorttxid(txid), pb.ChaincodeMessage_ERROR)
   253  	}
   254  
   255  	if errMsg != "" {
   256  		return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(errMsg), Txid: txid}
   257  	}
   258  
   259  	//not CONFIDENTIAL transaction, OK to call CC
   260  	return nil
   261  }
   262  
   263  func (handler *Handler) deregister() error {
   264  	if handler.registered {
   265  		handler.chaincodeSupport.deregisterHandler(handler)
   266  	}
   267  	return nil
   268  }
   269  
   270  func (handler *Handler) triggerNextState(msg *pb.ChaincodeMessage, send bool) {
   271  	//this will send Async
   272  	handler.nextState <- &nextStateInfo{msg: msg, sendToCC: send, sendSync: false}
   273  }
   274  
   275  func (handler *Handler) triggerNextStateSync(msg *pb.ChaincodeMessage) {
   276  	//this will send sync
   277  	handler.nextState <- &nextStateInfo{msg: msg, sendToCC: true, sendSync: true}
   278  }
   279  
   280  func (handler *Handler) waitForKeepaliveTimer() <-chan time.Time {
   281  	if handler.chaincodeSupport.keepalive > 0 {
   282  		c := time.After(handler.chaincodeSupport.keepalive)
   283  		return c
   284  	}
   285  	//no one will signal this channel, listner blocks forever
   286  	c := make(chan time.Time, 1)
   287  	return c
   288  }
   289  
   290  func (handler *Handler) processStream() error {
   291  	defer handler.deregister()
   292  	msgAvail := make(chan *pb.ChaincodeMessage)
   293  	var nsInfo *nextStateInfo
   294  	var in *pb.ChaincodeMessage
   295  	var err error
   296  
   297  	//recv is used to spin Recv routine after previous received msg
   298  	//has been processed
   299  	recv := true
   300  
   301  	//catch send errors and bail now that sends aren't synchronous
   302  	errc := make(chan error, 1)
   303  	for {
   304  		in = nil
   305  		err = nil
   306  		nsInfo = nil
   307  		if recv {
   308  			recv = false
   309  			go func() {
   310  				var in2 *pb.ChaincodeMessage
   311  				in2, err = handler.ChatStream.Recv()
   312  				msgAvail <- in2
   313  			}()
   314  		}
   315  		select {
   316  		case sendErr := <-errc:
   317  			if sendErr != nil {
   318  				return sendErr
   319  			}
   320  			//send was successful, just continue
   321  			continue
   322  		case in = <-msgAvail:
   323  			// Defer the deregistering of the this handler.
   324  			if err == io.EOF {
   325  				chaincodeLogger.Debugf("Received EOF, ending chaincode support stream, %s", err)
   326  				return err
   327  			} else if err != nil {
   328  				chaincodeLogger.Errorf("Error handling chaincode support stream: %s", err)
   329  				return err
   330  			} else if in == nil {
   331  				err = fmt.Errorf("Received nil message, ending chaincode support stream")
   332  				chaincodeLogger.Debug("Received nil message, ending chaincode support stream")
   333  				return err
   334  			}
   335  			chaincodeLogger.Debugf("[%s]Received message %s from shim", shorttxid(in.Txid), in.Type.String())
   336  			if in.Type.String() == pb.ChaincodeMessage_ERROR.String() {
   337  				chaincodeLogger.Errorf("Got error: %s", string(in.Payload))
   338  			}
   339  
   340  			// we can spin off another Recv again
   341  			recv = true
   342  
   343  			if in.Type == pb.ChaincodeMessage_KEEPALIVE {
   344  				chaincodeLogger.Debug("Received KEEPALIVE Response")
   345  				// Received a keep alive message, we don't do anything with it for now
   346  				// and it does not touch the state machine
   347  				continue
   348  			}
   349  		case nsInfo = <-handler.nextState:
   350  			in = nsInfo.msg
   351  			if in == nil {
   352  				err = fmt.Errorf("Next state nil message, ending chaincode support stream")
   353  				chaincodeLogger.Debug("Next state nil message, ending chaincode support stream")
   354  				return err
   355  			}
   356  			chaincodeLogger.Debugf("[%s]Move state message %s", shorttxid(in.Txid), in.Type.String())
   357  		case <-handler.waitForKeepaliveTimer():
   358  			if handler.chaincodeSupport.keepalive <= 0 {
   359  				chaincodeLogger.Errorf("Invalid select: keepalive not on (keepalive=%d)", handler.chaincodeSupport.keepalive)
   360  				continue
   361  			}
   362  
   363  			//if no error message from serialSend, KEEPALIVE happy, and don't care about error
   364  			//(maybe it'll work later)
   365  			handler.serialSendAsync(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_KEEPALIVE}, nil)
   366  			continue
   367  		}
   368  
   369  		err = handler.HandleMessage(in)
   370  		if err != nil {
   371  			chaincodeLogger.Errorf("[%s]Error handling message, ending stream: %s", shorttxid(in.Txid), err)
   372  			return fmt.Errorf("Error handling message, ending stream: %s", err)
   373  		}
   374  
   375  		if nsInfo != nil && nsInfo.sendToCC {
   376  			chaincodeLogger.Debugf("[%s]sending state message %s", shorttxid(in.Txid), in.Type.String())
   377  			//ready messages are sent sync
   378  			if nsInfo.sendSync {
   379  				if in.Type.String() != pb.ChaincodeMessage_READY.String() {
   380  					panic(fmt.Sprintf("[%s]Sync send can only be for READY state %s\n", shorttxid(in.Txid), in.Type.String()))
   381  				}
   382  				if err = handler.serialSend(in); err != nil {
   383  					return fmt.Errorf("[%s]Error sending ready  message, ending stream: %s", shorttxid(in.Txid), err)
   384  				}
   385  			} else {
   386  				//if error bail in select
   387  				handler.serialSendAsync(in, errc)
   388  			}
   389  		}
   390  	}
   391  }
   392  
   393  // HandleChaincodeStream Main loop for handling the associated Chaincode stream
   394  func HandleChaincodeStream(chaincodeSupport *ChaincodeSupport, ctxt context.Context, stream ccintf.ChaincodeStream) error {
   395  	deadline, ok := ctxt.Deadline()
   396  	chaincodeLogger.Debugf("Current context deadline = %s, ok = %v", deadline, ok)
   397  	handler := newChaincodeSupportHandler(chaincodeSupport, stream)
   398  	return handler.processStream()
   399  }
   400  
   401  func newChaincodeSupportHandler(chaincodeSupport *ChaincodeSupport, peerChatStream ccintf.ChaincodeStream) *Handler {
   402  	v := &Handler{
   403  		ChatStream: peerChatStream,
   404  	}
   405  	v.chaincodeSupport = chaincodeSupport
   406  	//we want this to block
   407  	v.nextState = make(chan *nextStateInfo)
   408  
   409  	v.FSM = fsm.NewFSM(
   410  		createdstate,
   411  		fsm.Events{
   412  			//Send REGISTERED, then, if deploy { trigger INIT(via INIT) } else { trigger READY(via COMPLETED) }
   413  			{Name: pb.ChaincodeMessage_REGISTER.String(), Src: []string{createdstate}, Dst: establishedstate},
   414  			{Name: pb.ChaincodeMessage_READY.String(), Src: []string{establishedstate}, Dst: readystate},
   415  			{Name: pb.ChaincodeMessage_PUT_STATE.String(), Src: []string{readystate}, Dst: readystate},
   416  			{Name: pb.ChaincodeMessage_DEL_STATE.String(), Src: []string{readystate}, Dst: readystate},
   417  			{Name: pb.ChaincodeMessage_INVOKE_CHAINCODE.String(), Src: []string{readystate}, Dst: readystate},
   418  			{Name: pb.ChaincodeMessage_COMPLETED.String(), Src: []string{readystate}, Dst: readystate},
   419  			{Name: pb.ChaincodeMessage_GET_STATE.String(), Src: []string{readystate}, Dst: readystate},
   420  			{Name: pb.ChaincodeMessage_GET_STATE_BY_RANGE.String(), Src: []string{readystate}, Dst: readystate},
   421  			{Name: pb.ChaincodeMessage_GET_QUERY_RESULT.String(), Src: []string{readystate}, Dst: readystate},
   422  			{Name: pb.ChaincodeMessage_GET_HISTORY_FOR_KEY.String(), Src: []string{readystate}, Dst: readystate},
   423  			{Name: pb.ChaincodeMessage_QUERY_STATE_NEXT.String(), Src: []string{readystate}, Dst: readystate},
   424  			{Name: pb.ChaincodeMessage_QUERY_STATE_CLOSE.String(), Src: []string{readystate}, Dst: readystate},
   425  			{Name: pb.ChaincodeMessage_ERROR.String(), Src: []string{readystate}, Dst: readystate},
   426  			{Name: pb.ChaincodeMessage_RESPONSE.String(), Src: []string{readystate}, Dst: readystate},
   427  			{Name: pb.ChaincodeMessage_INIT.String(), Src: []string{readystate}, Dst: readystate},
   428  			{Name: pb.ChaincodeMessage_TRANSACTION.String(), Src: []string{readystate}, Dst: readystate},
   429  		},
   430  		fsm.Callbacks{
   431  			"before_" + pb.ChaincodeMessage_REGISTER.String():           func(e *fsm.Event) { v.beforeRegisterEvent(e, v.FSM.Current()) },
   432  			"before_" + pb.ChaincodeMessage_COMPLETED.String():          func(e *fsm.Event) { v.beforeCompletedEvent(e, v.FSM.Current()) },
   433  			"after_" + pb.ChaincodeMessage_GET_STATE.String():           func(e *fsm.Event) { v.afterGetState(e, v.FSM.Current()) },
   434  			"after_" + pb.ChaincodeMessage_GET_STATE_BY_RANGE.String():  func(e *fsm.Event) { v.afterGetStateByRange(e, v.FSM.Current()) },
   435  			"after_" + pb.ChaincodeMessage_GET_QUERY_RESULT.String():    func(e *fsm.Event) { v.afterGetQueryResult(e, v.FSM.Current()) },
   436  			"after_" + pb.ChaincodeMessage_GET_HISTORY_FOR_KEY.String(): func(e *fsm.Event) { v.afterGetHistoryForKey(e, v.FSM.Current()) },
   437  			"after_" + pb.ChaincodeMessage_QUERY_STATE_NEXT.String():    func(e *fsm.Event) { v.afterQueryStateNext(e, v.FSM.Current()) },
   438  			"after_" + pb.ChaincodeMessage_QUERY_STATE_CLOSE.String():   func(e *fsm.Event) { v.afterQueryStateClose(e, v.FSM.Current()) },
   439  			"after_" + pb.ChaincodeMessage_PUT_STATE.String():           func(e *fsm.Event) { v.enterBusyState(e, v.FSM.Current()) },
   440  			"after_" + pb.ChaincodeMessage_DEL_STATE.String():           func(e *fsm.Event) { v.enterBusyState(e, v.FSM.Current()) },
   441  			"after_" + pb.ChaincodeMessage_INVOKE_CHAINCODE.String():    func(e *fsm.Event) { v.enterBusyState(e, v.FSM.Current()) },
   442  			"enter_" + establishedstate:                                 func(e *fsm.Event) { v.enterEstablishedState(e, v.FSM.Current()) },
   443  			"enter_" + readystate:                                       func(e *fsm.Event) { v.enterReadyState(e, v.FSM.Current()) },
   444  			"enter_" + endstate:                                         func(e *fsm.Event) { v.enterEndState(e, v.FSM.Current()) },
   445  		},
   446  	)
   447  
   448  	return v
   449  }
   450  
   451  func (handler *Handler) createTXIDEntry(txid string) bool {
   452  	if handler.txidMap == nil {
   453  		return false
   454  	}
   455  	handler.Lock()
   456  	defer handler.Unlock()
   457  	if handler.txidMap[txid] {
   458  		return false
   459  	}
   460  	handler.txidMap[txid] = true
   461  	return handler.txidMap[txid]
   462  }
   463  
   464  func (handler *Handler) deleteTXIDEntry(txid string) {
   465  	handler.Lock()
   466  	defer handler.Unlock()
   467  	if handler.txidMap != nil {
   468  		delete(handler.txidMap, txid)
   469  	} else {
   470  		chaincodeLogger.Warningf("TXID %s not found!", txid)
   471  	}
   472  }
   473  
   474  func (handler *Handler) notifyDuringStartup(val bool) {
   475  	//if USER_RUNS_CC readyNotify will be nil
   476  	if handler.readyNotify != nil {
   477  		chaincodeLogger.Debug("Notifying during startup")
   478  		handler.readyNotify <- val
   479  	} else {
   480  		chaincodeLogger.Debug("nothing to notify (dev mode ?)")
   481  	}
   482  }
   483  
   484  // beforeRegisterEvent is invoked when chaincode tries to register.
   485  func (handler *Handler) beforeRegisterEvent(e *fsm.Event, state string) {
   486  	chaincodeLogger.Debugf("Received %s in state %s", e.Event, state)
   487  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
   488  	if !ok {
   489  		e.Cancel(fmt.Errorf("Received unexpected message type"))
   490  		return
   491  	}
   492  	chaincodeID := &pb.ChaincodeID{}
   493  	err := proto.Unmarshal(msg.Payload, chaincodeID)
   494  	if err != nil {
   495  		e.Cancel(fmt.Errorf("Error in received %s, could NOT unmarshal registration info: %s", pb.ChaincodeMessage_REGISTER, err))
   496  		return
   497  	}
   498  
   499  	// Now register with the chaincodeSupport
   500  	handler.ChaincodeID = chaincodeID
   501  	err = handler.chaincodeSupport.registerHandler(handler)
   502  	if err != nil {
   503  		e.Cancel(err)
   504  		handler.notifyDuringStartup(false)
   505  		return
   506  	}
   507  
   508  	//get the component parts so we can use the root chaincode
   509  	//name in keys
   510  	handler.decomposeRegisteredName(handler.ChaincodeID)
   511  
   512  	chaincodeLogger.Debugf("Got %s for chaincodeID = %s, sending back %s", e.Event, chaincodeID, pb.ChaincodeMessage_REGISTERED)
   513  	if err := handler.serialSend(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTERED}); err != nil {
   514  		e.Cancel(fmt.Errorf("Error sending %s: %s", pb.ChaincodeMessage_REGISTERED, err))
   515  		handler.notifyDuringStartup(false)
   516  		return
   517  	}
   518  }
   519  
   520  func (handler *Handler) notify(msg *pb.ChaincodeMessage) {
   521  	handler.Lock()
   522  	defer handler.Unlock()
   523  	tctx := handler.txCtxs[msg.Txid]
   524  	if tctx == nil {
   525  		chaincodeLogger.Debugf("notifier Txid:%s does not exist", msg.Txid)
   526  	} else {
   527  		chaincodeLogger.Debugf("notifying Txid:%s", msg.Txid)
   528  		tctx.responseNotifier <- msg
   529  
   530  		// clean up queryIteratorMap
   531  		for _, v := range tctx.queryIteratorMap {
   532  			v.Close()
   533  		}
   534  	}
   535  }
   536  
   537  // beforeCompletedEvent is invoked when chaincode has completed execution of init, invoke.
   538  func (handler *Handler) beforeCompletedEvent(e *fsm.Event, state string) {
   539  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
   540  	if !ok {
   541  		e.Cancel(fmt.Errorf("Received unexpected message type"))
   542  		return
   543  	}
   544  	// Notify on channel once into READY state
   545  	chaincodeLogger.Debugf("[%s]beforeCompleted - not in ready state will notify when in readystate", shorttxid(msg.Txid))
   546  	return
   547  }
   548  
   549  // afterGetState handles a GET_STATE request from the chaincode.
   550  func (handler *Handler) afterGetState(e *fsm.Event, state string) {
   551  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
   552  	if !ok {
   553  		e.Cancel(fmt.Errorf("Received unexpected message type"))
   554  		return
   555  	}
   556  	chaincodeLogger.Debugf("[%s]Received %s, invoking get state from ledger", shorttxid(msg.Txid), pb.ChaincodeMessage_GET_STATE)
   557  
   558  	// Query ledger for state
   559  	handler.handleGetState(msg)
   560  }
   561  
   562  // is this a txid for which there is a valid txsim
   563  func (handler *Handler) isValidTxSim(txid string, fmtStr string, args ...interface{}) (*transactionContext, *pb.ChaincodeMessage) {
   564  	txContext := handler.getTxContext(txid)
   565  	if txContext == nil || txContext.txsimulator == nil {
   566  		// Send error msg back to chaincode. No ledger context
   567  		errStr := fmt.Sprintf(fmtStr, args...)
   568  		chaincodeLogger.Errorf(errStr)
   569  		return nil, &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(errStr), Txid: txid}
   570  	}
   571  	return txContext, nil
   572  }
   573  
   574  // Handles query to ledger to get state
   575  func (handler *Handler) handleGetState(msg *pb.ChaincodeMessage) {
   576  	// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
   577  	// is completed before the next one is triggered. The previous state transition is deemed complete only when
   578  	// the afterGetState function is exited. Interesting bug fix!!
   579  	go func() {
   580  		// Check if this is the unique state request from this chaincode txid
   581  		uniqueReq := handler.createTXIDEntry(msg.Txid)
   582  		if !uniqueReq {
   583  			// Drop this request
   584  			chaincodeLogger.Error("Another state request pending for this Txid. Cannot process.")
   585  			return
   586  		}
   587  
   588  		var serialSendMsg *pb.ChaincodeMessage
   589  		var txContext *transactionContext
   590  		txContext, serialSendMsg = handler.isValidTxSim(msg.Txid,
   591  			"[%s]No ledger context for GetState. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR)
   592  
   593  		defer func() {
   594  			handler.deleteTXIDEntry(msg.Txid)
   595  			if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
   596  				chaincodeLogger.Debugf("[%s]handleGetState serial send %s",
   597  					shorttxid(serialSendMsg.Txid), serialSendMsg.Type)
   598  			}
   599  			handler.serialSendAsync(serialSendMsg, nil)
   600  		}()
   601  
   602  		if txContext == nil {
   603  			return
   604  		}
   605  
   606  		key := string(msg.Payload)
   607  		chaincodeID := handler.getCCRootName()
   608  		if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
   609  			chaincodeLogger.Debugf("[%s] getting state for chaincode %s, key %s, channel %s",
   610  				shorttxid(msg.Txid), chaincodeID, key, txContext.chainID)
   611  		}
   612  
   613  		var res []byte
   614  		var err error
   615  		res, err = txContext.txsimulator.GetState(chaincodeID, key)
   616  
   617  		if err != nil {
   618  			// Send error msg back to chaincode. GetState will not trigger event
   619  			payload := []byte(err.Error())
   620  			chaincodeLogger.Errorf("[%s]Failed to get chaincode state(%s). Sending %s",
   621  				shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR)
   622  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   623  		} else if res == nil {
   624  			//The state object being requested does not exist
   625  			chaincodeLogger.Debugf("[%s]No state associated with key: %s. Sending %s with an empty payload",
   626  				shorttxid(msg.Txid), key, pb.ChaincodeMessage_RESPONSE)
   627  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: res, Txid: msg.Txid}
   628  		} else {
   629  			// Send response msg back to chaincode. GetState will not trigger event
   630  			if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
   631  				chaincodeLogger.Debugf("[%s]Got state. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_RESPONSE)
   632  			}
   633  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: res, Txid: msg.Txid}
   634  		}
   635  
   636  	}()
   637  }
   638  
   639  const maxGetStateByRangeLimit = 100
   640  
   641  // afterGetStateByRange handles a GET_STATE_BY_RANGE request from the chaincode.
   642  func (handler *Handler) afterGetStateByRange(e *fsm.Event, state string) {
   643  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
   644  	if !ok {
   645  		e.Cancel(fmt.Errorf("Received unexpected message type"))
   646  		return
   647  	}
   648  	chaincodeLogger.Debugf("Received %s, invoking get state from ledger", pb.ChaincodeMessage_GET_STATE_BY_RANGE)
   649  
   650  	// Query ledger for state
   651  	handler.handleGetStateByRange(msg)
   652  	chaincodeLogger.Debug("Exiting GET_STATE")
   653  }
   654  
   655  // Handles query to ledger to rage query state
   656  func (handler *Handler) handleGetStateByRange(msg *pb.ChaincodeMessage) {
   657  	// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
   658  	// is completed before the next one is triggered. The previous state transition is deemed complete only when
   659  	// the afterGetStateByRange function is exited. Interesting bug fix!!
   660  	go func() {
   661  		// Check if this is the unique state request from this chaincode txid
   662  		uniqueReq := handler.createTXIDEntry(msg.Txid)
   663  		if !uniqueReq {
   664  			// Drop this request
   665  			chaincodeLogger.Error("Another state request pending for this Txid. Cannot process.")
   666  			return
   667  		}
   668  
   669  		var serialSendMsg *pb.ChaincodeMessage
   670  
   671  		defer func() {
   672  			handler.deleteTXIDEntry(msg.Txid)
   673  			chaincodeLogger.Debugf("[%s]handleGetStateByRange serial send %s", shorttxid(serialSendMsg.Txid), serialSendMsg.Type)
   674  			handler.serialSendAsync(serialSendMsg, nil)
   675  		}()
   676  
   677  		getStateByRange := &pb.GetStateByRange{}
   678  		unmarshalErr := proto.Unmarshal(msg.Payload, getStateByRange)
   679  		if unmarshalErr != nil {
   680  			payload := []byte(unmarshalErr.Error())
   681  			chaincodeLogger.Errorf("Failed to unmarshall range query request. Sending %s", pb.ChaincodeMessage_ERROR)
   682  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   683  			return
   684  		}
   685  
   686  		iterID := util.GenerateUUID()
   687  
   688  		var txContext *transactionContext
   689  
   690  		txContext, serialSendMsg = handler.isValidTxSim(msg.Txid, "[%s]No ledger context for GetStateByRange. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR)
   691  		if txContext == nil {
   692  			return
   693  		}
   694  		chaincodeID := handler.getCCRootName()
   695  
   696  		rangeIter, err := txContext.txsimulator.GetStateRangeScanIterator(chaincodeID, getStateByRange.StartKey, getStateByRange.EndKey)
   697  		if err != nil {
   698  			// Send error msg back to chaincode. GetState will not trigger event
   699  			payload := []byte(err.Error())
   700  			chaincodeLogger.Errorf("Failed to get ledger scan iterator. Sending %s", pb.ChaincodeMessage_ERROR)
   701  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   702  			return
   703  		}
   704  
   705  		handler.putQueryIterator(txContext, iterID, rangeIter)
   706  
   707  		var keysAndValues []*pb.QueryStateKeyValue
   708  		var i = uint32(0)
   709  		var qresult commonledger.QueryResult
   710  		for ; i < maxGetStateByRangeLimit; i++ {
   711  			qresult, err = rangeIter.Next()
   712  			if err != nil {
   713  				chaincodeLogger.Errorf("Failed to get query result from iterator. Sending %s", pb.ChaincodeMessage_ERROR)
   714  				return
   715  			}
   716  			if qresult == nil {
   717  				break
   718  			}
   719  			kv := qresult.(*ledger.KV)
   720  			keyAndValue := pb.QueryStateKeyValue{Key: kv.Key, Value: kv.Value}
   721  			keysAndValues = append(keysAndValues, &keyAndValue)
   722  		}
   723  
   724  		if qresult != nil {
   725  			rangeIter.Close()
   726  			handler.deleteQueryIterator(txContext, iterID)
   727  		}
   728  
   729  		payload := &pb.QueryStateResponse{KeysAndValues: keysAndValues, HasMore: qresult != nil, Id: iterID}
   730  		payloadBytes, err := proto.Marshal(payload)
   731  		if err != nil {
   732  			rangeIter.Close()
   733  			handler.deleteQueryIterator(txContext, iterID)
   734  
   735  			// Send error msg back to chaincode. GetState will not trigger event
   736  			payload := []byte(err.Error())
   737  			chaincodeLogger.Errorf("Failed marshall resopnse. Sending %s", pb.ChaincodeMessage_ERROR)
   738  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   739  			return
   740  		}
   741  
   742  		chaincodeLogger.Debugf("Got keys and values. Sending %s", pb.ChaincodeMessage_RESPONSE)
   743  		serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid}
   744  
   745  	}()
   746  }
   747  
   748  // afterQueryStateNext handles a QUERY_STATE_NEXT request from the chaincode.
   749  func (handler *Handler) afterQueryStateNext(e *fsm.Event, state string) {
   750  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
   751  	if !ok {
   752  		e.Cancel(fmt.Errorf("Received unexpected message type"))
   753  		return
   754  	}
   755  	chaincodeLogger.Debugf("Received %s, invoking get state from ledger", pb.ChaincodeMessage_GET_STATE_BY_RANGE)
   756  
   757  	// Query ledger for state
   758  	handler.handleQueryStateNext(msg)
   759  	chaincodeLogger.Debug("Exiting QUERY_STATE_NEXT")
   760  }
   761  
   762  // Handles query to ledger for query state next
   763  func (handler *Handler) handleQueryStateNext(msg *pb.ChaincodeMessage) {
   764  	// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
   765  	// is completed before the next one is triggered. The previous state transition is deemed complete only when
   766  	// the afterGetStateByRange function is exited. Interesting bug fix!!
   767  	go func() {
   768  		// Check if this is the unique state request from this chaincode txid
   769  		uniqueReq := handler.createTXIDEntry(msg.Txid)
   770  		if !uniqueReq {
   771  			// Drop this request
   772  			chaincodeLogger.Debug("Another state request pending for this Txid. Cannot process.")
   773  			return
   774  		}
   775  
   776  		var serialSendMsg *pb.ChaincodeMessage
   777  
   778  		defer func() {
   779  			handler.deleteTXIDEntry(msg.Txid)
   780  			chaincodeLogger.Debugf("[%s]handleGetStateByRange serial send %s", shorttxid(serialSendMsg.Txid), serialSendMsg.Type)
   781  			handler.serialSendAsync(serialSendMsg, nil)
   782  		}()
   783  
   784  		queryStateNext := &pb.QueryStateNext{}
   785  		unmarshalErr := proto.Unmarshal(msg.Payload, queryStateNext)
   786  		if unmarshalErr != nil {
   787  			payload := []byte(unmarshalErr.Error())
   788  			chaincodeLogger.Errorf("Failed to unmarshall state next query request. Sending %s", pb.ChaincodeMessage_ERROR)
   789  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   790  			return
   791  		}
   792  
   793  		txContext := handler.getTxContext(msg.Txid)
   794  		queryIter := handler.getQueryIterator(txContext, queryStateNext.Id)
   795  
   796  		if queryIter == nil {
   797  			payload := []byte("query iterator not found")
   798  			chaincodeLogger.Errorf("query iterator not found. Sending %s", pb.ChaincodeMessage_ERROR)
   799  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   800  			return
   801  		}
   802  
   803  		var keysAndValues []*pb.QueryStateKeyValue
   804  		var i = uint32(0)
   805  
   806  		var qresult commonledger.QueryResult
   807  		var err error
   808  		for ; i < maxGetStateByRangeLimit; i++ {
   809  			qresult, err = queryIter.Next()
   810  			if err != nil {
   811  				chaincodeLogger.Errorf("Failed to get query result from iterator. Sending %s", pb.ChaincodeMessage_ERROR)
   812  				return
   813  			}
   814  			if qresult != nil {
   815  				break
   816  			}
   817  			kv := qresult.(*ledger.KV)
   818  			keyAndValue := pb.QueryStateKeyValue{Key: kv.Key, Value: kv.Value}
   819  			keysAndValues = append(keysAndValues, &keyAndValue)
   820  		}
   821  
   822  		if qresult != nil {
   823  			queryIter.Close()
   824  			handler.deleteQueryIterator(txContext, queryStateNext.Id)
   825  		}
   826  
   827  		payload := &pb.QueryStateResponse{KeysAndValues: keysAndValues, HasMore: qresult != nil, Id: queryStateNext.Id}
   828  		payloadBytes, err := proto.Marshal(payload)
   829  		if err != nil {
   830  			queryIter.Close()
   831  			handler.deleteQueryIterator(txContext, queryStateNext.Id)
   832  
   833  			// Send error msg back to chaincode. GetState will not trigger event
   834  			payload := []byte(err.Error())
   835  			chaincodeLogger.Errorf("Failed marshall resopnse. Sending %s", pb.ChaincodeMessage_ERROR)
   836  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   837  			return
   838  		}
   839  
   840  		chaincodeLogger.Debugf("Got keys and values. Sending %s", pb.ChaincodeMessage_RESPONSE)
   841  		serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid}
   842  
   843  	}()
   844  }
   845  
   846  // afterGetStateByRange handles a QUERY_STATE_CLOSE request from the chaincode.
   847  func (handler *Handler) afterQueryStateClose(e *fsm.Event, state string) {
   848  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
   849  	if !ok {
   850  		e.Cancel(fmt.Errorf("Received unexpected message type"))
   851  		return
   852  	}
   853  	chaincodeLogger.Debugf("Received %s, invoking get state from ledger", pb.ChaincodeMessage_GET_STATE_BY_RANGE)
   854  
   855  	// Query ledger for state
   856  	handler.handleQueryStateClose(msg)
   857  	chaincodeLogger.Debug("Exiting QUERY_STATE_CLOSE")
   858  }
   859  
   860  // Handles the closing of a state iterator
   861  func (handler *Handler) handleQueryStateClose(msg *pb.ChaincodeMessage) {
   862  	// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
   863  	// is completed before the next one is triggered. The previous state transition is deemed complete only when
   864  	// the afterGetStateByRange function is exited. Interesting bug fix!!
   865  	go func() {
   866  		// Check if this is the unique state request from this chaincode txid
   867  		uniqueReq := handler.createTXIDEntry(msg.Txid)
   868  		if !uniqueReq {
   869  			// Drop this request
   870  			chaincodeLogger.Error("Another state request pending for this Txid. Cannot process.")
   871  			return
   872  		}
   873  
   874  		var serialSendMsg *pb.ChaincodeMessage
   875  
   876  		defer func() {
   877  			handler.deleteTXIDEntry(msg.Txid)
   878  			chaincodeLogger.Debugf("[%s]handleGetStateByRange serial send %s", shorttxid(serialSendMsg.Txid), serialSendMsg.Type)
   879  			handler.serialSendAsync(serialSendMsg, nil)
   880  		}()
   881  
   882  		queryStateClose := &pb.QueryStateClose{}
   883  		unmarshalErr := proto.Unmarshal(msg.Payload, queryStateClose)
   884  		if unmarshalErr != nil {
   885  			payload := []byte(unmarshalErr.Error())
   886  			chaincodeLogger.Errorf("Failed to unmarshall state query close request. Sending %s", pb.ChaincodeMessage_ERROR)
   887  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   888  			return
   889  		}
   890  
   891  		txContext := handler.getTxContext(msg.Txid)
   892  		iter := handler.getQueryIterator(txContext, queryStateClose.Id)
   893  		if iter != nil {
   894  			iter.Close()
   895  			handler.deleteQueryIterator(txContext, queryStateClose.Id)
   896  		}
   897  
   898  		payload := &pb.QueryStateResponse{HasMore: false, Id: queryStateClose.Id}
   899  		payloadBytes, err := proto.Marshal(payload)
   900  		if err != nil {
   901  
   902  			// Send error msg back to chaincode. GetState will not trigger event
   903  			payload := []byte(err.Error())
   904  			chaincodeLogger.Errorf("Failed marshall resopnse. Sending %s", pb.ChaincodeMessage_ERROR)
   905  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   906  			return
   907  		}
   908  
   909  		chaincodeLogger.Debugf("Closed. Sending %s", pb.ChaincodeMessage_RESPONSE)
   910  		serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid}
   911  
   912  	}()
   913  }
   914  
   915  const maxGetQueryResultLimit = 100
   916  
   917  // afterGetQueryResult handles a GET_QUERY_RESULT request from the chaincode.
   918  func (handler *Handler) afterGetQueryResult(e *fsm.Event, state string) {
   919  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
   920  	if !ok {
   921  		e.Cancel(fmt.Errorf("Received unexpected message type"))
   922  		return
   923  	}
   924  	chaincodeLogger.Debugf("Received %s, invoking get state from ledger", pb.ChaincodeMessage_GET_QUERY_RESULT)
   925  
   926  	// Query ledger for state
   927  	handler.handleGetQueryResult(msg)
   928  	chaincodeLogger.Debug("Exiting GET_QUERY_RESULT")
   929  }
   930  
   931  // Handles query to ledger to execute query state
   932  func (handler *Handler) handleGetQueryResult(msg *pb.ChaincodeMessage) {
   933  	// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
   934  	// is completed before the next one is triggered. The previous state transition is deemed complete only when
   935  	// the afterQueryState function is exited. Interesting bug fix!!
   936  	go func() {
   937  		// Check if this is the unique state request from this chaincode txid
   938  		uniqueReq := handler.createTXIDEntry(msg.Txid)
   939  		if !uniqueReq {
   940  			// Drop this request
   941  			chaincodeLogger.Error("Another state request pending for this Txid. Cannot process.")
   942  			return
   943  		}
   944  
   945  		var serialSendMsg *pb.ChaincodeMessage
   946  
   947  		defer func() {
   948  			handler.deleteTXIDEntry(msg.Txid)
   949  			chaincodeLogger.Debugf("[%s]handleGetQueryResult serial send %s", shorttxid(serialSendMsg.Txid), serialSendMsg.Type)
   950  			handler.serialSendAsync(serialSendMsg, nil)
   951  		}()
   952  
   953  		getQueryResult := &pb.GetQueryResult{}
   954  		unmarshalErr := proto.Unmarshal(msg.Payload, getQueryResult)
   955  		if unmarshalErr != nil {
   956  			payload := []byte(unmarshalErr.Error())
   957  			chaincodeLogger.Errorf("Failed to unmarshall query request. Sending %s", pb.ChaincodeMessage_ERROR)
   958  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   959  			return
   960  		}
   961  
   962  		iterID := util.GenerateUUID()
   963  
   964  		var txContext *transactionContext
   965  
   966  		txContext, serialSendMsg = handler.isValidTxSim(msg.Txid, "[%s]No ledger context for GetQueryResult. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR)
   967  		if txContext == nil {
   968  			return
   969  		}
   970  
   971  		chaincodeID := handler.getCCRootName()
   972  
   973  		executeIter, err := txContext.txsimulator.ExecuteQuery(chaincodeID, getQueryResult.Query)
   974  		if err != nil {
   975  			// Send error msg back to chaincode. GetState will not trigger event
   976  			payload := []byte(err.Error())
   977  			chaincodeLogger.Errorf("Failed to get ledger query iterator. Sending %s", pb.ChaincodeMessage_ERROR)
   978  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
   979  			return
   980  		}
   981  
   982  		handler.putQueryIterator(txContext, iterID, executeIter)
   983  
   984  		var keysAndValues []*pb.QueryStateKeyValue
   985  		var i = uint32(0)
   986  		var qresult commonledger.QueryResult
   987  		for ; i < maxGetQueryResultLimit; i++ {
   988  			qresult, err = executeIter.Next()
   989  			if err != nil {
   990  				chaincodeLogger.Errorf("Failed to get query result from iterator. Sending %s", pb.ChaincodeMessage_ERROR)
   991  				return
   992  			}
   993  			if qresult == nil {
   994  				break
   995  			}
   996  			queryRecord := qresult.(*ledger.QueryRecord)
   997  			keyAndValue := pb.QueryStateKeyValue{Key: queryRecord.Key, Value: queryRecord.Record}
   998  			keysAndValues = append(keysAndValues, &keyAndValue)
   999  		}
  1000  
  1001  		if qresult != nil {
  1002  			executeIter.Close()
  1003  			handler.deleteQueryIterator(txContext, iterID)
  1004  		}
  1005  
  1006  		var payloadBytes []byte
  1007  		payload := &pb.QueryStateResponse{KeysAndValues: keysAndValues, HasMore: qresult != nil, Id: iterID}
  1008  		payloadBytes, err = proto.Marshal(payload)
  1009  		if err != nil {
  1010  			executeIter.Close()
  1011  			handler.deleteQueryIterator(txContext, iterID)
  1012  
  1013  			// Send error msg back to chaincode. GetState will not trigger event
  1014  			payload := []byte(err.Error())
  1015  			chaincodeLogger.Errorf("Failed marshall resopnse. Sending %s", pb.ChaincodeMessage_ERROR)
  1016  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1017  			return
  1018  		}
  1019  
  1020  		chaincodeLogger.Debugf("Got keys and values. Sending %s", pb.ChaincodeMessage_RESPONSE)
  1021  		serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid}
  1022  
  1023  	}()
  1024  }
  1025  
  1026  const maxGetHistoryForKeyLimit = 100
  1027  
  1028  // afterGetHistoryForKey handles a GET_HISTORY_FOR_KEY request from the chaincode.
  1029  func (handler *Handler) afterGetHistoryForKey(e *fsm.Event, state string) {
  1030  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
  1031  	if !ok {
  1032  		e.Cancel(fmt.Errorf("Received unexpected message type"))
  1033  		return
  1034  	}
  1035  	chaincodeLogger.Debugf("Received %s, invoking get state from ledger", pb.ChaincodeMessage_GET_HISTORY_FOR_KEY)
  1036  
  1037  	// Query ledger history db
  1038  	handler.handleGetHistoryForKey(msg)
  1039  	chaincodeLogger.Debug("Exiting GET_HISTORY_FOR_KEY")
  1040  }
  1041  
  1042  // Handles query to ledger history db
  1043  func (handler *Handler) handleGetHistoryForKey(msg *pb.ChaincodeMessage) {
  1044  	// The defer followed by triggering a go routine dance is needed to ensure that the previous state transition
  1045  	// is completed before the next one is triggered. The previous state transition is deemed complete only when
  1046  	// the afterQueryState function is exited. Interesting bug fix!!
  1047  	go func() {
  1048  		// Check if this is the unique state request from this chaincode txid
  1049  		uniqueReq := handler.createTXIDEntry(msg.Txid)
  1050  		if !uniqueReq {
  1051  			// Drop this request
  1052  			chaincodeLogger.Error("Another state request pending for this Txid. Cannot process.")
  1053  			return
  1054  		}
  1055  
  1056  		var serialSendMsg *pb.ChaincodeMessage
  1057  
  1058  		defer func() {
  1059  			handler.deleteTXIDEntry(msg.Txid)
  1060  			chaincodeLogger.Debugf("[%s]handleGetHistoryForKey serial send %s", shorttxid(serialSendMsg.Txid), serialSendMsg.Type)
  1061  			handler.serialSendAsync(serialSendMsg, nil)
  1062  		}()
  1063  
  1064  		getHistoryForKey := &pb.GetHistoryForKey{}
  1065  		unmarshalErr := proto.Unmarshal(msg.Payload, getHistoryForKey)
  1066  		if unmarshalErr != nil {
  1067  			payload := []byte(unmarshalErr.Error())
  1068  			chaincodeLogger.Errorf("Failed to unmarshall query request. Sending %s", pb.ChaincodeMessage_ERROR)
  1069  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1070  			return
  1071  		}
  1072  
  1073  		iterID := util.GenerateUUID()
  1074  
  1075  		var txContext *transactionContext
  1076  
  1077  		txContext, serialSendMsg = handler.isValidTxSim(msg.Txid, "[%s]No ledger context for GetHistoryForKey. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR)
  1078  		if txContext == nil {
  1079  			return
  1080  		}
  1081  		chaincodeID := handler.getCCRootName()
  1082  
  1083  		historyIter, err := txContext.historyQueryExecutor.GetHistoryForKey(chaincodeID, getHistoryForKey.Key)
  1084  		if err != nil {
  1085  			// Send error msg back to chaincode. GetState will not trigger event
  1086  			payload := []byte(err.Error())
  1087  			chaincodeLogger.Errorf("Failed to get ledger history iterator. Sending %s", pb.ChaincodeMessage_ERROR)
  1088  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1089  			return
  1090  		}
  1091  
  1092  		handler.putQueryIterator(txContext, iterID, historyIter)
  1093  
  1094  		// TODO QueryStateKeyValue can be re-used for now since history records have a string (TxID)
  1095  		// and value (value).  But we'll need to use another structure if we add other fields like timestamp.
  1096  		var keysAndValues []*pb.QueryStateKeyValue
  1097  		var i = uint32(0)
  1098  		var qresult commonledger.QueryResult
  1099  		for ; i < maxGetHistoryForKeyLimit; i++ {
  1100  			qresult, err = historyIter.Next()
  1101  			if err != nil {
  1102  				chaincodeLogger.Errorf("Failed to get query result from iterator. Sending %s", pb.ChaincodeMessage_ERROR)
  1103  				return
  1104  			}
  1105  			if qresult == nil {
  1106  				break
  1107  			}
  1108  			queryRecord := qresult.(*ledger.KeyModification)
  1109  			keyAndValue := pb.QueryStateKeyValue{Key: queryRecord.TxID, Value: queryRecord.Value}
  1110  			keysAndValues = append(keysAndValues, &keyAndValue)
  1111  		}
  1112  
  1113  		if qresult != nil {
  1114  			historyIter.Close()
  1115  			handler.deleteQueryIterator(txContext, iterID)
  1116  		}
  1117  
  1118  		var payloadBytes []byte
  1119  		payload := &pb.QueryStateResponse{KeysAndValues: keysAndValues, HasMore: qresult != nil, Id: iterID}
  1120  		payloadBytes, err = proto.Marshal(payload)
  1121  		if err != nil {
  1122  			historyIter.Close()
  1123  			handler.deleteQueryIterator(txContext, iterID)
  1124  
  1125  			// Send error msg back to chaincode. GetState will not trigger event
  1126  			payload := []byte(err.Error())
  1127  			chaincodeLogger.Errorf("Failed marshall resopnse. Sending %s", pb.ChaincodeMessage_ERROR)
  1128  			serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1129  			return
  1130  		}
  1131  
  1132  		chaincodeLogger.Debugf("Got keys and values. Sending %s", pb.ChaincodeMessage_RESPONSE)
  1133  		serialSendMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid}
  1134  
  1135  	}()
  1136  }
  1137  
  1138  // afterPutState handles a PUT_STATE request from the chaincode.
  1139  func (handler *Handler) afterPutState(e *fsm.Event, state string) {
  1140  	_, ok := e.Args[0].(*pb.ChaincodeMessage)
  1141  	if !ok {
  1142  		e.Cancel(fmt.Errorf("Received unexpected message type"))
  1143  		return
  1144  	}
  1145  	chaincodeLogger.Debugf("Received %s in state %s, invoking put state to ledger", pb.ChaincodeMessage_PUT_STATE, state)
  1146  
  1147  	// Put state into ledger handled within enterBusyState
  1148  }
  1149  
  1150  // afterDelState handles a DEL_STATE request from the chaincode.
  1151  func (handler *Handler) afterDelState(e *fsm.Event, state string) {
  1152  	_, ok := e.Args[0].(*pb.ChaincodeMessage)
  1153  	if !ok {
  1154  		e.Cancel(fmt.Errorf("Received unexpected message type"))
  1155  		return
  1156  	}
  1157  	chaincodeLogger.Debugf("Received %s, invoking delete state from ledger", pb.ChaincodeMessage_DEL_STATE)
  1158  
  1159  	// Delete state from ledger handled within enterBusyState
  1160  }
  1161  
  1162  // afterInvokeChaincode handles an INVOKE_CHAINCODE request from the chaincode.
  1163  func (handler *Handler) afterInvokeChaincode(e *fsm.Event, state string) {
  1164  	_, ok := e.Args[0].(*pb.ChaincodeMessage)
  1165  	if !ok {
  1166  		e.Cancel(fmt.Errorf("Received unexpected message type"))
  1167  		return
  1168  	}
  1169  	chaincodeLogger.Debugf("Received %s in state %s, invoking another chaincode", pb.ChaincodeMessage_INVOKE_CHAINCODE, state)
  1170  
  1171  	// Invoke another chaincode handled within enterBusyState
  1172  }
  1173  
  1174  // Handles request to ledger to put state
  1175  func (handler *Handler) enterBusyState(e *fsm.Event, state string) {
  1176  	go func() {
  1177  		msg, _ := e.Args[0].(*pb.ChaincodeMessage)
  1178  		if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1179  			chaincodeLogger.Debugf("[%s]state is %s", shorttxid(msg.Txid), state)
  1180  		}
  1181  		// Check if this is the unique request from this chaincode txid
  1182  		uniqueReq := handler.createTXIDEntry(msg.Txid)
  1183  		if !uniqueReq {
  1184  			// Drop this request
  1185  			chaincodeLogger.Debug("Another request pending for this Txid. Cannot process.")
  1186  			return
  1187  		}
  1188  
  1189  		var triggerNextStateMsg *pb.ChaincodeMessage
  1190  		var txContext *transactionContext
  1191  		txContext, triggerNextStateMsg = handler.isValidTxSim(msg.Txid, "[%s]No ledger context for %s. Sending %s",
  1192  			shorttxid(msg.Txid), msg.Type.String(), pb.ChaincodeMessage_ERROR)
  1193  
  1194  		defer func() {
  1195  			handler.deleteTXIDEntry(msg.Txid)
  1196  			if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1197  				chaincodeLogger.Debugf("[%s]enterBusyState trigger event %s",
  1198  					shorttxid(triggerNextStateMsg.Txid), triggerNextStateMsg.Type)
  1199  			}
  1200  			handler.triggerNextState(triggerNextStateMsg, true)
  1201  		}()
  1202  
  1203  		if txContext == nil {
  1204  			return
  1205  		}
  1206  
  1207  		chaincodeID := handler.getCCRootName()
  1208  		var err error
  1209  		var res []byte
  1210  
  1211  		if msg.Type.String() == pb.ChaincodeMessage_PUT_STATE.String() {
  1212  			putStateInfo := &pb.PutStateInfo{}
  1213  			unmarshalErr := proto.Unmarshal(msg.Payload, putStateInfo)
  1214  			if unmarshalErr != nil {
  1215  				payload := []byte(unmarshalErr.Error())
  1216  				chaincodeLogger.Debugf("[%s]Unable to decipher payload. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR)
  1217  				triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1218  				return
  1219  			}
  1220  
  1221  			err = txContext.txsimulator.SetState(chaincodeID, putStateInfo.Key, putStateInfo.Value)
  1222  		} else if msg.Type.String() == pb.ChaincodeMessage_DEL_STATE.String() {
  1223  			// Invoke ledger to delete state
  1224  			key := string(msg.Payload)
  1225  			err = txContext.txsimulator.DeleteState(chaincodeID, key)
  1226  		} else if msg.Type.String() == pb.ChaincodeMessage_INVOKE_CHAINCODE.String() {
  1227  			if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1228  				chaincodeLogger.Debugf("[%s] C-call-C", shorttxid(msg.Txid))
  1229  			}
  1230  			chaincodeSpec := &pb.ChaincodeSpec{}
  1231  			unmarshalErr := proto.Unmarshal(msg.Payload, chaincodeSpec)
  1232  			if unmarshalErr != nil {
  1233  				payload := []byte(unmarshalErr.Error())
  1234  				chaincodeLogger.Debugf("[%s]Unable to decipher payload. Sending %s", shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR)
  1235  				triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1236  				return
  1237  			}
  1238  
  1239  			// Get the chaincodeID to invoke. The chaincodeID to be called may
  1240  			// contain composite info like "chaincode-name:version/channel-name"
  1241  			// We are not using version now but default to the latest
  1242  			calledCcParts := chaincodeIDParts(chaincodeSpec.ChaincodeId.Name)
  1243  			chaincodeSpec.ChaincodeId.Name = calledCcParts.name
  1244  			if calledCcParts.suffix == "" {
  1245  				// use caller's channel as the called chaincode is in the same channel
  1246  				calledCcParts.suffix = txContext.chainID
  1247  			}
  1248  			if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1249  				chaincodeLogger.Debugf("[%s] C-call-C %s on channel %s",
  1250  					shorttxid(msg.Txid), calledCcParts.name, calledCcParts.suffix)
  1251  			}
  1252  
  1253  			triggerNextStateMsg = handler.checkACL(txContext.signedProp, txContext.proposal, calledCcParts)
  1254  			if triggerNextStateMsg != nil {
  1255  				return
  1256  			}
  1257  
  1258  			// Set up a new context for the called chaincode if on a different channel
  1259  			// We grab the called channel's ledger simulator to hold the new state
  1260  			ctxt := context.Background()
  1261  			txsim := txContext.txsimulator
  1262  			historyQueryExecutor := txContext.historyQueryExecutor
  1263  			if calledCcParts.suffix != txContext.chainID {
  1264  				lgr := peer.GetLedger(calledCcParts.suffix)
  1265  				if lgr == nil {
  1266  					payload := "Failed to find ledger for called channel " + calledCcParts.suffix
  1267  					triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR,
  1268  						Payload: []byte(payload), Txid: msg.Txid}
  1269  					return
  1270  				}
  1271  				txsim2, err2 := lgr.NewTxSimulator()
  1272  				if err2 != nil {
  1273  					triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR,
  1274  						Payload: []byte(err2.Error()), Txid: msg.Txid}
  1275  					return
  1276  				}
  1277  				defer txsim2.Done()
  1278  				txsim = txsim2
  1279  			}
  1280  			ctxt = context.WithValue(ctxt, TXSimulatorKey, txsim)
  1281  			ctxt = context.WithValue(ctxt, HistoryQueryExecutorKey, historyQueryExecutor)
  1282  
  1283  			if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1284  				chaincodeLogger.Debugf("[%s] calling lccc to get chaincode data for %s on channel %s",
  1285  					shorttxid(msg.Txid), calledCcParts.name, calledCcParts.suffix)
  1286  			}
  1287  
  1288  			//Call LCCC to get the called chaincode artifacts
  1289  			var cd *ccprovider.ChaincodeData
  1290  			cd, err = GetChaincodeDataFromLCCC(ctxt, msg.Txid, txContext.signedProp, txContext.proposal, calledCcParts.suffix, calledCcParts.name)
  1291  			if err != nil {
  1292  				payload := []byte(err.Error())
  1293  				chaincodeLogger.Debugf("[%s]Failed to get chaincoed data (%s) for invoked chaincode. Sending %s",
  1294  					shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR)
  1295  				triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1296  				return
  1297  			}
  1298  			cccid := ccprovider.NewCCContext(calledCcParts.suffix, calledCcParts.name, cd.Version, msg.Txid, false, txContext.signedProp, txContext.proposal)
  1299  
  1300  			// Launch the new chaincode if not already running
  1301  			if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1302  				chaincodeLogger.Debugf("[%s] launching chaincode %s on channel %s",
  1303  					shorttxid(msg.Txid), calledCcParts.name, calledCcParts.suffix)
  1304  			}
  1305  			cciSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: chaincodeSpec}
  1306  			_, chaincodeInput, launchErr := handler.chaincodeSupport.Launch(ctxt, cccid, cciSpec)
  1307  			if launchErr != nil {
  1308  				payload := []byte(launchErr.Error())
  1309  				chaincodeLogger.Debugf("[%s]Failed to launch invoked chaincode. Sending %s",
  1310  					shorttxid(msg.Txid), pb.ChaincodeMessage_ERROR)
  1311  				triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1312  				return
  1313  			}
  1314  
  1315  			// TODO: Need to handle timeout correctly
  1316  			timeout := time.Duration(30000) * time.Millisecond
  1317  
  1318  			ccMsg, _ := createCCMessage(pb.ChaincodeMessage_TRANSACTION, msg.Txid, chaincodeInput)
  1319  
  1320  			// Execute the chaincode... this CANNOT be an init at least for now
  1321  			response, execErr := handler.chaincodeSupport.Execute(ctxt, cccid, ccMsg, timeout)
  1322  
  1323  			//payload is marshalled and send to the calling chaincode's shim which unmarshals and
  1324  			//sends it to chaincode
  1325  			res = nil
  1326  			if execErr != nil {
  1327  				err = execErr
  1328  			} else {
  1329  				res, err = proto.Marshal(response)
  1330  			}
  1331  		}
  1332  
  1333  		if err != nil {
  1334  			// Send error msg back to chaincode and trigger event
  1335  			payload := []byte(err.Error())
  1336  			chaincodeLogger.Errorf("[%s]Failed to handle %s. Sending %s", shorttxid(msg.Txid), msg.Type.String(), pb.ChaincodeMessage_ERROR)
  1337  			triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: payload, Txid: msg.Txid}
  1338  			return
  1339  		}
  1340  
  1341  		// Send response msg back to chaincode.
  1342  		if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1343  			chaincodeLogger.Debugf("[%s]Completed %s. Sending %s", shorttxid(msg.Txid), msg.Type.String(), pb.ChaincodeMessage_RESPONSE)
  1344  		}
  1345  		triggerNextStateMsg = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: res, Txid: msg.Txid}
  1346  	}()
  1347  }
  1348  
  1349  func (handler *Handler) enterEstablishedState(e *fsm.Event, state string) {
  1350  	handler.notifyDuringStartup(true)
  1351  }
  1352  
  1353  func (handler *Handler) enterReadyState(e *fsm.Event, state string) {
  1354  	// Now notify
  1355  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
  1356  	if !ok {
  1357  		e.Cancel(fmt.Errorf("Received unexpected message type"))
  1358  		return
  1359  	}
  1360  	chaincodeLogger.Debugf("[%s]Entered state %s", shorttxid(msg.Txid), state)
  1361  	handler.notify(msg)
  1362  }
  1363  
  1364  func (handler *Handler) enterEndState(e *fsm.Event, state string) {
  1365  	defer handler.deregister()
  1366  	// Now notify
  1367  	msg, ok := e.Args[0].(*pb.ChaincodeMessage)
  1368  	if !ok {
  1369  		e.Cancel(fmt.Errorf("Received unexpected message type"))
  1370  		return
  1371  	}
  1372  	chaincodeLogger.Debugf("[%s]Entered state %s", shorttxid(msg.Txid), state)
  1373  	handler.notify(msg)
  1374  	e.Cancel(fmt.Errorf("Entered end state"))
  1375  }
  1376  
  1377  func (handler *Handler) setChaincodeProposal(signedProp *pb.SignedProposal, prop *pb.Proposal, msg *pb.ChaincodeMessage) error {
  1378  	chaincodeLogger.Debug("Setting chaincode proposal context...")
  1379  	if prop != nil {
  1380  		chaincodeLogger.Debug("Proposal different from nil. Creating chaincode proposal context...")
  1381  
  1382  		// Check that also signedProp is different from nil
  1383  		if signedProp == nil {
  1384  			return fmt.Errorf("Failed getting proposal context. Signed proposal is nil.")
  1385  		}
  1386  
  1387  		msg.Proposal = prop
  1388  	}
  1389  	return nil
  1390  }
  1391  
  1392  //move to ready
  1393  func (handler *Handler) ready(ctxt context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal) (chan *pb.ChaincodeMessage, error) {
  1394  	txctx, funcErr := handler.createTxContext(ctxt, chainID, txid, signedProp, prop)
  1395  	if funcErr != nil {
  1396  		return nil, funcErr
  1397  	}
  1398  
  1399  	chaincodeLogger.Debug("sending READY")
  1400  	ccMsg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY, Txid: txid}
  1401  
  1402  	//if security is disabled the context elements will just be nil
  1403  	if err := handler.setChaincodeProposal(signedProp, prop, ccMsg); err != nil {
  1404  		return nil, err
  1405  	}
  1406  
  1407  	//send the ready synchronously as the
  1408  	//ready message is during launch and needs
  1409  	//to happen before any init/invokes can sneak in
  1410  	handler.triggerNextStateSync(ccMsg)
  1411  
  1412  	return txctx.responseNotifier, nil
  1413  }
  1414  
  1415  // HandleMessage implementation of MessageHandler interface.  Peer's handling of Chaincode messages.
  1416  func (handler *Handler) HandleMessage(msg *pb.ChaincodeMessage) error {
  1417  	chaincodeLogger.Debugf("[%s]Fabric side Handling ChaincodeMessage of type: %s in state %s", shorttxid(msg.Txid), msg.Type, handler.FSM.Current())
  1418  
  1419  	if (msg.Type == pb.ChaincodeMessage_COMPLETED || msg.Type == pb.ChaincodeMessage_ERROR) && handler.FSM.Current() == "ready" {
  1420  		chaincodeLogger.Debugf("[%s]HandleMessage- COMPLETED. Notify", msg.Txid)
  1421  		handler.notify(msg)
  1422  		return nil
  1423  	}
  1424  	if handler.FSM.Cannot(msg.Type.String()) {
  1425  		// Other errors
  1426  		return fmt.Errorf("[%s]Chaincode handler validator FSM cannot handle message (%s) with payload size (%d) while in state: %s", msg.Txid, msg.Type.String(), len(msg.Payload), handler.FSM.Current())
  1427  	}
  1428  	eventErr := handler.FSM.Event(msg.Type.String(), msg)
  1429  	filteredErr := filterError(eventErr)
  1430  	if filteredErr != nil {
  1431  		chaincodeLogger.Errorf("[%s]Failed to trigger FSM event %s: %s", msg.Txid, msg.Type.String(), filteredErr)
  1432  	}
  1433  
  1434  	return filteredErr
  1435  }
  1436  
  1437  // Filter the Errors to allow NoTransitionError and CanceledError to not propagate for cases where embedded Err == nil
  1438  func filterError(errFromFSMEvent error) error {
  1439  	if errFromFSMEvent != nil {
  1440  		if noTransitionErr, ok := errFromFSMEvent.(*fsm.NoTransitionError); ok {
  1441  			if noTransitionErr.Err != nil {
  1442  				// Squash the NoTransitionError
  1443  				return errFromFSMEvent
  1444  			}
  1445  			chaincodeLogger.Debugf("Ignoring NoTransitionError: %s", noTransitionErr)
  1446  		}
  1447  		if canceledErr, ok := errFromFSMEvent.(*fsm.CanceledError); ok {
  1448  			if canceledErr.Err != nil {
  1449  				// Squash the CanceledError
  1450  				return canceledErr
  1451  			}
  1452  			chaincodeLogger.Debugf("Ignoring CanceledError: %s", canceledErr)
  1453  		}
  1454  	}
  1455  	return nil
  1456  }
  1457  
  1458  func (handler *Handler) sendExecuteMessage(ctxt context.Context, chainID string, msg *pb.ChaincodeMessage, signedProp *pb.SignedProposal, prop *pb.Proposal) (chan *pb.ChaincodeMessage, error) {
  1459  	txctx, err := handler.createTxContext(ctxt, chainID, msg.Txid, signedProp, prop)
  1460  	if err != nil {
  1461  		return nil, err
  1462  	}
  1463  	if chaincodeLogger.IsEnabledFor(logging.DEBUG) {
  1464  		chaincodeLogger.Debugf("[%s]Inside sendExecuteMessage. Message %s", shorttxid(msg.Txid), msg.Type.String())
  1465  	}
  1466  
  1467  	//if security is disabled the context elements will just be nil
  1468  	if err = handler.setChaincodeProposal(signedProp, prop, msg); err != nil {
  1469  		return nil, err
  1470  	}
  1471  
  1472  	chaincodeLogger.Debugf("[%s]sendExecuteMsg trigger event %s", shorttxid(msg.Txid), msg.Type)
  1473  	handler.triggerNextState(msg, true)
  1474  
  1475  	return txctx.responseNotifier, nil
  1476  }
  1477  
  1478  func (handler *Handler) isRunning() bool {
  1479  	switch handler.FSM.Current() {
  1480  	case createdstate:
  1481  		fallthrough
  1482  	case establishedstate:
  1483  		fallthrough
  1484  	default:
  1485  		return true
  1486  	}
  1487  }