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