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