github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/core/chaincode/handler.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"fmt"
    11  	"io"
    12  	"strconv"
    13  	"strings"
    14  	"sync"
    15  	"time"
    16  
    17  	"github.com/golang/protobuf/proto"
    18  	pb "github.com/hyperledger/fabric-protos-go/peer"
    19  	"github.com/osdi23p228/fabric/common/channelconfig"
    20  	"github.com/osdi23p228/fabric/common/flogging"
    21  	commonledger "github.com/osdi23p228/fabric/common/ledger"
    22  	"github.com/osdi23p228/fabric/core/aclmgmt/resources"
    23  	"github.com/osdi23p228/fabric/core/common/ccprovider"
    24  	"github.com/osdi23p228/fabric/core/common/privdata"
    25  	"github.com/osdi23p228/fabric/core/common/sysccprovider"
    26  	"github.com/osdi23p228/fabric/core/container/ccintf"
    27  	"github.com/osdi23p228/fabric/core/ledger"
    28  	"github.com/osdi23p228/fabric/core/scc"
    29  	"github.com/pkg/errors"
    30  )
    31  
    32  var chaincodeLogger = flogging.MustGetLogger("chaincode")
    33  
    34  // An ACLProvider performs access control checks when invoking
    35  // chaincode.
    36  type ACLProvider interface {
    37  	CheckACL(resName string, channelID string, idinfo interface{}) error
    38  }
    39  
    40  // A Registry is responsible for tracking handlers.
    41  type Registry interface {
    42  	Register(*Handler) error
    43  	Ready(string)
    44  	Failed(string, error)
    45  	Deregister(string) error
    46  }
    47  
    48  // An Invoker invokes chaincode.
    49  type Invoker interface {
    50  	Invoke(txParams *ccprovider.TransactionParams, chaincodeName string, spec *pb.ChaincodeInput) (*pb.ChaincodeMessage, error)
    51  }
    52  
    53  // TransactionRegistry tracks active transactions for each channel.
    54  type TransactionRegistry interface {
    55  	Add(channelID, txID string) bool
    56  	Remove(channelID, txID string)
    57  }
    58  
    59  // A ContextRegistry is responsible for managing transaction contexts.
    60  type ContextRegistry interface {
    61  	Create(txParams *ccprovider.TransactionParams) (*TransactionContext, error)
    62  	Get(channelID, txID string) *TransactionContext
    63  	Delete(channelID, txID string)
    64  	Close()
    65  }
    66  
    67  // QueryResponseBuilder is responsible for building QueryResponse messages for query
    68  // transactions initiated by chaincode.
    69  type QueryResponseBuilder interface {
    70  	BuildQueryResponse(txContext *TransactionContext, iter commonledger.ResultsIterator,
    71  		iterID string, isPaginated bool, totalReturnLimit int32) (*pb.QueryResponse, error)
    72  }
    73  
    74  // LedgerGetter is used to get ledgers for chaincode.
    75  type LedgerGetter interface {
    76  	GetLedger(cid string) ledger.PeerLedger
    77  }
    78  
    79  // UUIDGenerator is responsible for creating unique query identifiers.
    80  type UUIDGenerator interface {
    81  	New() string
    82  }
    83  type UUIDGeneratorFunc func() string
    84  
    85  func (u UUIDGeneratorFunc) New() string { return u() }
    86  
    87  // ApplicationConfigRetriever to retrieve the application configuration for a channel
    88  type ApplicationConfigRetriever interface {
    89  	// GetApplicationConfig returns the channelconfig.Application for the channel
    90  	// and whether the Application config exists
    91  	GetApplicationConfig(cid string) (channelconfig.Application, bool)
    92  }
    93  
    94  // Handler implements the peer side of the chaincode stream.
    95  type Handler struct {
    96  	// Keepalive specifies the interval at which keep-alive messages are sent.
    97  	Keepalive time.Duration
    98  	// TotalQueryLimit specifies the maximum number of results to return for
    99  	// chaincode queries.
   100  	TotalQueryLimit int
   101  	// Invoker is used to invoke chaincode.
   102  	Invoker Invoker
   103  	// Registry is used to track active handlers.
   104  	Registry Registry
   105  	// ACLProvider is used to check if a chaincode invocation should be allowed.
   106  	ACLProvider ACLProvider
   107  	// TXContexts is a collection of TransactionContext instances
   108  	// that are accessed by channel name and transaction ID.
   109  	TXContexts ContextRegistry
   110  	// activeTransactions holds active transaction identifiers.
   111  	ActiveTransactions TransactionRegistry
   112  	// BuiltinSCCs can be used to determine if a name is associated with a system chaincode
   113  	BuiltinSCCs scc.BuiltinSCCs
   114  	// QueryResponseBuilder is used to build query responses
   115  	QueryResponseBuilder QueryResponseBuilder
   116  	// LedgerGetter is used to get the ledger associated with a channel
   117  	LedgerGetter LedgerGetter
   118  	// DeployedCCInfoProvider is used to initialize the Collection Store
   119  	DeployedCCInfoProvider ledger.DeployedChaincodeInfoProvider
   120  	// UUIDGenerator is used to generate UUIDs
   121  	UUIDGenerator UUIDGenerator
   122  	// AppConfig is used to retrieve the application config for a channel
   123  	AppConfig ApplicationConfigRetriever
   124  	// Metrics holds chaincode handler metrics
   125  	Metrics *HandlerMetrics
   126  
   127  	// state holds the current handler state. It will be created, established, or
   128  	// ready.
   129  	state State
   130  	// chaincodeID holds the ID of the chaincode that registered with the peer.
   131  	chaincodeID string
   132  
   133  	// serialLock is used to serialize sends across the grpc chat stream.
   134  	serialLock sync.Mutex
   135  	// chatStream is the bidirectional grpc stream used to communicate with the
   136  	// chaincode instance.
   137  	chatStream ccintf.ChaincodeStream
   138  	// errChan is used to communicate errors from the async send to the receive loop
   139  	errChan chan error
   140  	// mutex is used to serialze the stream closed chan.
   141  	mutex sync.Mutex
   142  	// streamDoneChan is closed when the chaincode stream terminates.
   143  	streamDoneChan chan struct{}
   144  }
   145  
   146  // handleMessage is called by ProcessStream to dispatch messages.
   147  func (h *Handler) handleMessage(msg *pb.ChaincodeMessage) error {
   148  	chaincodeLogger.Debugf("[%s] Fabric side handling ChaincodeMessage of type: %s in state %s", shorttxid(msg.Txid), msg.Type, h.state)
   149  
   150  	if msg.Type == pb.ChaincodeMessage_KEEPALIVE {
   151  		return nil
   152  	}
   153  
   154  	switch h.state {
   155  	case Created:
   156  		return h.handleMessageCreatedState(msg)
   157  	case Ready:
   158  		return h.handleMessageReadyState(msg)
   159  	default:
   160  		return errors.Errorf("handle message: invalid state %s for transaction %s", h.state, msg.Txid)
   161  	}
   162  }
   163  
   164  func (h *Handler) handleMessageCreatedState(msg *pb.ChaincodeMessage) error {
   165  	switch msg.Type {
   166  	case pb.ChaincodeMessage_REGISTER:
   167  		h.HandleRegister(msg)
   168  	default:
   169  		return fmt.Errorf("[%s] Fabric side handler cannot handle message (%s) while in created state", msg.Txid, msg.Type)
   170  	}
   171  	return nil
   172  }
   173  
   174  func (h *Handler) handleMessageReadyState(msg *pb.ChaincodeMessage) error {
   175  	switch msg.Type {
   176  	case pb.ChaincodeMessage_COMPLETED, pb.ChaincodeMessage_ERROR:
   177  		h.Notify(msg)
   178  
   179  	case pb.ChaincodeMessage_PUT_STATE:
   180  		go h.HandleTransaction(msg, h.HandlePutState)
   181  	case pb.ChaincodeMessage_DEL_STATE:
   182  		go h.HandleTransaction(msg, h.HandleDelState)
   183  	case pb.ChaincodeMessage_INVOKE_CHAINCODE:
   184  		go h.HandleTransaction(msg, h.HandleInvokeChaincode)
   185  	case pb.ChaincodeMessage_GET_STATE:
   186  		go h.HandleTransaction(msg, h.HandleGetState)
   187  	case pb.ChaincodeMessage_GET_STATE_BY_RANGE:
   188  		go h.HandleTransaction(msg, h.HandleGetStateByRange)
   189  	case pb.ChaincodeMessage_GET_QUERY_RESULT:
   190  		go h.HandleTransaction(msg, h.HandleGetQueryResult)
   191  	case pb.ChaincodeMessage_GET_HISTORY_FOR_KEY:
   192  		go h.HandleTransaction(msg, h.HandleGetHistoryForKey)
   193  	case pb.ChaincodeMessage_QUERY_STATE_NEXT:
   194  		go h.HandleTransaction(msg, h.HandleQueryStateNext)
   195  	case pb.ChaincodeMessage_QUERY_STATE_CLOSE:
   196  		go h.HandleTransaction(msg, h.HandleQueryStateClose)
   197  	case pb.ChaincodeMessage_GET_PRIVATE_DATA_HASH:
   198  		go h.HandleTransaction(msg, h.HandleGetPrivateDataHash)
   199  	case pb.ChaincodeMessage_GET_STATE_METADATA:
   200  		go h.HandleTransaction(msg, h.HandleGetStateMetadata)
   201  	case pb.ChaincodeMessage_PUT_STATE_METADATA:
   202  		go h.HandleTransaction(msg, h.HandlePutStateMetadata)
   203  	default:
   204  		return fmt.Errorf("[%s] Fabric side handler cannot handle message (%s) while in ready state", msg.Txid, msg.Type)
   205  	}
   206  
   207  	return nil
   208  }
   209  
   210  type MessageHandler interface {
   211  	Handle(*pb.ChaincodeMessage, *TransactionContext) (*pb.ChaincodeMessage, error)
   212  }
   213  
   214  type handleFunc func(*pb.ChaincodeMessage, *TransactionContext) (*pb.ChaincodeMessage, error)
   215  
   216  // HandleTransaction is a middleware function that obtains and verifies a transaction
   217  // context prior to forwarding the message to the provided delegate. Response messages
   218  // returned by the delegate are sent to the chat stream. Any errors returned by the
   219  // delegate are packaged as chaincode error messages.
   220  func (h *Handler) HandleTransaction(msg *pb.ChaincodeMessage, delegate handleFunc) {
   221  	chaincodeLogger.Debugf("[%s] handling %s from chaincode", shorttxid(msg.Txid), msg.Type.String())
   222  	if !h.registerTxid(msg) {
   223  		return
   224  	}
   225  
   226  	startTime := time.Now()
   227  	var txContext *TransactionContext
   228  	var err error
   229  	if msg.Type == pb.ChaincodeMessage_INVOKE_CHAINCODE {
   230  		txContext, err = h.getTxContextForInvoke(msg.ChannelId, msg.Txid, msg.Payload, "")
   231  	} else {
   232  		txContext, err = h.isValidTxSim(msg.ChannelId, msg.Txid, "no ledger context")
   233  	}
   234  
   235  	meterLabels := []string{
   236  		"type", msg.Type.String(),
   237  		"channel", msg.ChannelId,
   238  		"chaincode", h.chaincodeID,
   239  	}
   240  	h.Metrics.ShimRequestsReceived.With(meterLabels...).Add(1)
   241  
   242  	var resp *pb.ChaincodeMessage
   243  	if err == nil {
   244  		resp, err = delegate(msg, txContext)
   245  	}
   246  
   247  	if err != nil {
   248  		err = errors.Wrapf(err, "%s failed: transaction ID: %s", msg.Type, msg.Txid)
   249  		chaincodeLogger.Errorf("[%s] Failed to handle %s. error: %+v", shorttxid(msg.Txid), msg.Type, err)
   250  		resp = &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_ERROR, Payload: []byte(err.Error()), Txid: msg.Txid, ChannelId: msg.ChannelId}
   251  	}
   252  
   253  	chaincodeLogger.Debugf("[%s] Completed %s. Sending %s", shorttxid(msg.Txid), msg.Type, resp.Type)
   254  	h.ActiveTransactions.Remove(msg.ChannelId, msg.Txid)
   255  	h.serialSendAsync(resp)
   256  
   257  	meterLabels = append(meterLabels, "success", strconv.FormatBool(resp.Type != pb.ChaincodeMessage_ERROR))
   258  	h.Metrics.ShimRequestDuration.With(meterLabels...).Observe(time.Since(startTime).Seconds())
   259  	h.Metrics.ShimRequestsCompleted.With(meterLabels...).Add(1)
   260  }
   261  
   262  func shorttxid(txid string) string {
   263  	if len(txid) < 8 {
   264  		return txid
   265  	}
   266  	return txid[0:8]
   267  }
   268  
   269  // ParseName parses a chaincode name into a ChaincodeInstance. The name should
   270  // be of the form "chaincode-name:version/channel-name" with optional elements.
   271  func ParseName(ccName string) *sysccprovider.ChaincodeInstance {
   272  	ci := &sysccprovider.ChaincodeInstance{}
   273  
   274  	z := strings.SplitN(ccName, "/", 2)
   275  	if len(z) == 2 {
   276  		ci.ChannelID = z[1]
   277  	}
   278  	z = strings.SplitN(z[0], ":", 2)
   279  	if len(z) == 2 {
   280  		ci.ChaincodeVersion = z[1]
   281  	}
   282  	ci.ChaincodeName = z[0]
   283  
   284  	return ci
   285  }
   286  
   287  // serialSend serializes msgs so gRPC will be happy
   288  func (h *Handler) serialSend(msg *pb.ChaincodeMessage) error {
   289  	h.serialLock.Lock()
   290  	defer h.serialLock.Unlock()
   291  
   292  	if err := h.chatStream.Send(msg); err != nil {
   293  		err = errors.WithMessagef(err, "[%s] error sending %s", shorttxid(msg.Txid), msg.Type)
   294  		chaincodeLogger.Errorf("%+v", err)
   295  		return err
   296  	}
   297  
   298  	return nil
   299  }
   300  
   301  // serialSendAsync serves the same purpose as serialSend (serialize msgs so gRPC will
   302  // be happy). In addition, it is also asynchronous so send-remoterecv--localrecv loop
   303  // can be nonblocking. Only errors need to be handled and these are handled by
   304  // communication on supplied error channel. A typical use will be a non-blocking or
   305  // nil channel
   306  func (h *Handler) serialSendAsync(msg *pb.ChaincodeMessage) {
   307  	go func() {
   308  		if err := h.serialSend(msg); err != nil {
   309  			// provide an error response to the caller
   310  			resp := &pb.ChaincodeMessage{
   311  				Type:      pb.ChaincodeMessage_ERROR,
   312  				Payload:   []byte(err.Error()),
   313  				Txid:      msg.Txid,
   314  				ChannelId: msg.ChannelId,
   315  			}
   316  			h.Notify(resp)
   317  
   318  			// surface send error to stream processing
   319  			h.errChan <- err
   320  		}
   321  	}()
   322  }
   323  
   324  // Check if the transactor is allow to call this chaincode on this channel
   325  func (h *Handler) checkACL(signedProp *pb.SignedProposal, proposal *pb.Proposal, ccIns *sysccprovider.ChaincodeInstance) error {
   326  	// if we are here, all we know is that the invoked chaincode is either
   327  	// - a system chaincode that *is* invokable through a cc2cc
   328  	//   (but we may still have to determine whether the invoker can perform this invocation)
   329  	// - an application chaincode
   330  	//   (and we still need to determine whether the invoker can invoke it)
   331  
   332  	if h.BuiltinSCCs.IsSysCC(ccIns.ChaincodeName) {
   333  		// Allow this call
   334  		return nil
   335  	}
   336  
   337  	// A Nil signedProp will be rejected for non-system chaincodes
   338  	if signedProp == nil {
   339  		return errors.Errorf("signed proposal must not be nil from caller [%s]", ccIns.String())
   340  	}
   341  
   342  	return h.ACLProvider.CheckACL(resources.Peer_ChaincodeToChaincode, ccIns.ChannelID, signedProp)
   343  }
   344  
   345  func (h *Handler) deregister() {
   346  	h.Registry.Deregister(h.chaincodeID)
   347  }
   348  
   349  func (h *Handler) streamDone() <-chan struct{} {
   350  	h.mutex.Lock()
   351  	defer h.mutex.Unlock()
   352  	return h.streamDoneChan
   353  }
   354  
   355  func (h *Handler) ProcessStream(stream ccintf.ChaincodeStream) error {
   356  	defer h.deregister()
   357  
   358  	h.mutex.Lock()
   359  	h.streamDoneChan = make(chan struct{})
   360  	h.mutex.Unlock()
   361  	defer close(h.streamDoneChan)
   362  
   363  	h.chatStream = stream
   364  	h.errChan = make(chan error, 1)
   365  
   366  	var keepaliveCh <-chan time.Time
   367  	if h.Keepalive != 0 {
   368  		ticker := time.NewTicker(h.Keepalive)
   369  		defer ticker.Stop()
   370  		keepaliveCh = ticker.C
   371  	}
   372  
   373  	// holds return values from gRPC Recv below
   374  	type recvMsg struct {
   375  		msg *pb.ChaincodeMessage
   376  		err error
   377  	}
   378  	msgAvail := make(chan *recvMsg, 1)
   379  
   380  	receiveMessage := func() {
   381  		in, err := h.chatStream.Recv()
   382  		msgAvail <- &recvMsg{in, err}
   383  	}
   384  
   385  	go receiveMessage()
   386  	for {
   387  		select {
   388  		case rmsg := <-msgAvail:
   389  			switch {
   390  			// Defer the deregistering of the this handler.
   391  			case rmsg.err == io.EOF:
   392  				chaincodeLogger.Debugf("received EOF, ending chaincode support stream: %s", rmsg.err)
   393  				return rmsg.err
   394  			case rmsg.err != nil:
   395  				err := errors.Wrap(rmsg.err, "receive from chaincode support stream failed")
   396  				chaincodeLogger.Debugf("%+v", err)
   397  				return err
   398  			case rmsg.msg == nil:
   399  				err := errors.New("received nil message, ending chaincode support stream")
   400  				chaincodeLogger.Debugf("%+v", err)
   401  				return err
   402  			default:
   403  				err := h.handleMessage(rmsg.msg)
   404  				if err != nil {
   405  					err = errors.WithMessage(err, "error handling message, ending stream")
   406  					chaincodeLogger.Errorf("[%s] %+v", shorttxid(rmsg.msg.Txid), err)
   407  					return err
   408  				}
   409  
   410  				go receiveMessage()
   411  			}
   412  
   413  		case sendErr := <-h.errChan:
   414  			err := errors.Wrapf(sendErr, "received error while sending message, ending chaincode support stream")
   415  			chaincodeLogger.Errorf("%s", err)
   416  			return err
   417  		case <-keepaliveCh:
   418  			// if no error message from serialSend, KEEPALIVE happy, and don't care about error
   419  			// (maybe it'll work later)
   420  			h.serialSendAsync(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_KEEPALIVE})
   421  			continue
   422  		}
   423  	}
   424  }
   425  
   426  // sendReady sends READY to chaincode serially (just like REGISTER)
   427  func (h *Handler) sendReady() error {
   428  	chaincodeLogger.Debugf("sending READY for chaincode %s", h.chaincodeID)
   429  	ccMsg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_READY}
   430  
   431  	// if error in sending tear down the h
   432  	if err := h.serialSend(ccMsg); err != nil {
   433  		chaincodeLogger.Errorf("error sending READY (%s) for chaincode %s", err, h.chaincodeID)
   434  		return err
   435  	}
   436  
   437  	h.state = Ready
   438  
   439  	chaincodeLogger.Debugf("Changed to state ready for chaincode %s", h.chaincodeID)
   440  
   441  	return nil
   442  }
   443  
   444  // notifyRegistry will send ready on registration success and
   445  // update the launch state of the chaincode in the handler registry.
   446  func (h *Handler) notifyRegistry(err error) {
   447  	if err == nil {
   448  		err = h.sendReady()
   449  	}
   450  
   451  	if err != nil {
   452  		h.Registry.Failed(h.chaincodeID, err)
   453  		chaincodeLogger.Errorf("failed to start %s -- %s", h.chaincodeID, err)
   454  		return
   455  	}
   456  
   457  	h.Registry.Ready(h.chaincodeID)
   458  }
   459  
   460  // handleRegister is invoked when chaincode tries to register.
   461  func (h *Handler) HandleRegister(msg *pb.ChaincodeMessage) {
   462  	chaincodeLogger.Debugf("Received %s in state %s", msg.Type, h.state)
   463  	chaincodeID := &pb.ChaincodeID{}
   464  	err := proto.Unmarshal(msg.Payload, chaincodeID)
   465  	if err != nil {
   466  		chaincodeLogger.Errorf("Error in received %s, could NOT unmarshal registration info: %s", pb.ChaincodeMessage_REGISTER, err)
   467  		return
   468  	}
   469  
   470  	// Now register with the chaincodeSupport
   471  	// Note: chaincodeID.Name is actually of the form name:version for older chaincodes, and
   472  	// of the form label:hash for newer chaincodes.  Either way, it is the handle by which
   473  	// we track the chaincode's registration.
   474  	if chaincodeID.Name == "" {
   475  		h.notifyRegistry(errors.New("error in handling register chaincode, chaincodeID name is empty"))
   476  		return
   477  	}
   478  	h.chaincodeID = chaincodeID.Name
   479  	err = h.Registry.Register(h)
   480  	if err != nil {
   481  		h.notifyRegistry(err)
   482  		return
   483  	}
   484  
   485  	chaincodeLogger.Debugf("Got %s for chaincodeID = %s, sending back %s", pb.ChaincodeMessage_REGISTER, h.chaincodeID, pb.ChaincodeMessage_REGISTERED)
   486  	if err := h.serialSend(&pb.ChaincodeMessage{Type: pb.ChaincodeMessage_REGISTERED}); err != nil {
   487  		chaincodeLogger.Errorf("error sending %s: %s", pb.ChaincodeMessage_REGISTERED, err)
   488  		h.notifyRegistry(err)
   489  		return
   490  	}
   491  
   492  	h.state = Established
   493  
   494  	chaincodeLogger.Debugf("Changed state to established for %s", h.chaincodeID)
   495  
   496  	// for dev mode this will also move to ready automatically
   497  	h.notifyRegistry(nil)
   498  }
   499  
   500  func (h *Handler) Notify(msg *pb.ChaincodeMessage) {
   501  	tctx := h.TXContexts.Get(msg.ChannelId, msg.Txid)
   502  	if tctx == nil {
   503  		chaincodeLogger.Debugf("notifier Txid:%s, channelID:%s does not exist for handling message %s", msg.Txid, msg.ChannelId, msg.Type)
   504  		return
   505  	}
   506  
   507  	chaincodeLogger.Debugf("[%s] notifying Txid:%s, channelID:%s", shorttxid(msg.Txid), msg.Txid, msg.ChannelId)
   508  	tctx.ResponseNotifier <- msg
   509  	tctx.CloseQueryIterators()
   510  }
   511  
   512  // is this a txid for which there is a valid txsim
   513  func (h *Handler) isValidTxSim(channelID string, txid string, fmtStr string, args ...interface{}) (*TransactionContext, error) {
   514  	txContext := h.TXContexts.Get(channelID, txid)
   515  	if txContext == nil || txContext.TXSimulator == nil {
   516  		err := errors.Errorf(fmtStr, args...)
   517  		chaincodeLogger.Errorf("no ledger context: %s %s\n\n %+v", channelID, txid, err)
   518  		return nil, err
   519  	}
   520  	return txContext, nil
   521  }
   522  
   523  // register Txid to prevent overlapping handle messages from chaincode
   524  func (h *Handler) registerTxid(msg *pb.ChaincodeMessage) bool {
   525  	// Check if this is the unique state request from this chaincode txid
   526  	if h.ActiveTransactions.Add(msg.ChannelId, msg.Txid) {
   527  		return true
   528  	}
   529  
   530  	// Log the issue and drop the request
   531  	chaincodeLogger.Errorf("[%s] Another request pending for this CC: %s, Txid: %s, ChannelID: %s. Cannot process.", shorttxid(msg.Txid), h.chaincodeID, msg.Txid, msg.ChannelId)
   532  	return false
   533  }
   534  
   535  func (h *Handler) checkMetadataCap(msg *pb.ChaincodeMessage) error {
   536  	ac, exists := h.AppConfig.GetApplicationConfig(msg.ChannelId)
   537  	if !exists {
   538  		return errors.Errorf("application config does not exist for %s", msg.ChannelId)
   539  	}
   540  
   541  	if !ac.Capabilities().KeyLevelEndorsement() {
   542  		return errors.New("key level endorsement is not enabled, channel application capability of V1_3 or later is required")
   543  	}
   544  	return nil
   545  }
   546  
   547  func errorIfCreatorHasNoReadPermission(chaincodeName, collection string, txContext *TransactionContext) error {
   548  	rwPermission, err := getReadWritePermission(chaincodeName, collection, txContext)
   549  	if err != nil {
   550  		return err
   551  	}
   552  	if !rwPermission.read {
   553  		return errors.Errorf("tx creator does not have read access permission on privatedata in chaincodeName:%s collectionName: %s",
   554  			chaincodeName, collection)
   555  	}
   556  	return nil
   557  }
   558  
   559  func errorIfCreatorHasNoWritePermission(chaincodeName, collection string, txContext *TransactionContext) error {
   560  	rwPermission, err := getReadWritePermission(chaincodeName, collection, txContext)
   561  	if err != nil {
   562  		return err
   563  	}
   564  	if !rwPermission.write {
   565  		return errors.Errorf("tx creator does not have write access permission on privatedata in chaincodeName:%s collectionName: %s",
   566  			chaincodeName, collection)
   567  	}
   568  	return nil
   569  }
   570  
   571  func getReadWritePermission(chaincodeName, collection string, txContext *TransactionContext) (*readWritePermission, error) {
   572  	// check to see if read access has already been checked in the scope of this chaincode simulation
   573  	if rwPermission := txContext.CollectionACLCache.get(collection); rwPermission != nil {
   574  		return rwPermission, nil
   575  	}
   576  
   577  	cc := privdata.CollectionCriteria{
   578  		Channel:    txContext.ChannelID,
   579  		Namespace:  chaincodeName,
   580  		Collection: collection,
   581  	}
   582  
   583  	readP, writeP, err := txContext.CollectionStore.RetrieveReadWritePermission(cc, txContext.SignedProp, txContext.TXSimulator)
   584  	if err != nil {
   585  		return nil, err
   586  	}
   587  	rwPermission := &readWritePermission{read: readP, write: writeP}
   588  	txContext.CollectionACLCache.put(collection, rwPermission)
   589  
   590  	return rwPermission, nil
   591  }
   592  
   593  // Handles query to ledger to get state
   594  func (h *Handler) HandleGetState(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   595  	getState := &pb.GetState{}
   596  	err := proto.Unmarshal(msg.Payload, getState)
   597  	if err != nil {
   598  		return nil, errors.Wrap(err, "unmarshal failed")
   599  	}
   600  
   601  	var res []byte
   602  	namespaceID := txContext.NamespaceID
   603  	collection := getState.Collection
   604  	chaincodeLogger.Debugf("[%s] getting state for chaincode %s, key %s, channel %s", shorttxid(msg.Txid), namespaceID, getState.Key, txContext.ChannelID)
   605  
   606  	if isCollectionSet(collection) {
   607  		if txContext.IsInitTransaction {
   608  			return nil, errors.New("private data APIs are not allowed in chaincode Init()")
   609  		}
   610  		if err := errorIfCreatorHasNoReadPermission(namespaceID, collection, txContext); err != nil {
   611  			return nil, err
   612  		}
   613  		res, err = txContext.TXSimulator.GetPrivateData(namespaceID, collection, getState.Key)
   614  	} else {
   615  		res, err = txContext.TXSimulator.GetState(namespaceID, getState.Key)
   616  	}
   617  	if err != nil {
   618  		return nil, errors.WithStack(err)
   619  	}
   620  	if res == nil {
   621  		chaincodeLogger.Debugf("[%s] No state associated with key: %s. Sending %s with an empty payload", shorttxid(msg.Txid), getState.Key, pb.ChaincodeMessage_RESPONSE)
   622  	}
   623  
   624  	// Send response msg back to chaincode. GetState will not trigger event
   625  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: res, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   626  }
   627  
   628  func (h *Handler) HandleGetPrivateDataHash(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   629  	getState := &pb.GetState{}
   630  	err := proto.Unmarshal(msg.Payload, getState)
   631  	if err != nil {
   632  		return nil, errors.Wrap(err, "unmarshal failed")
   633  	}
   634  
   635  	var res []byte
   636  	namespaceID := txContext.NamespaceID
   637  	collection := getState.Collection
   638  	chaincodeLogger.Debugf("[%s] getting private data hash for chaincode %s, key %s, channel %s", shorttxid(msg.Txid), namespaceID, getState.Key, txContext.ChannelID)
   639  	if txContext.IsInitTransaction {
   640  		return nil, errors.New("private data APIs are not allowed in chaincode Init()")
   641  	}
   642  	res, err = txContext.TXSimulator.GetPrivateDataHash(namespaceID, collection, getState.Key)
   643  	if err != nil {
   644  		return nil, errors.WithStack(err)
   645  	}
   646  	if res == nil {
   647  		chaincodeLogger.Debugf("[%s] No state associated with key: %s. Sending %s with an empty payload", shorttxid(msg.Txid), getState.Key, pb.ChaincodeMessage_RESPONSE)
   648  	}
   649  	// Send response msg back to chaincode. GetState will not trigger event
   650  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: res, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   651  }
   652  
   653  // Handles query to ledger to get state metadata
   654  func (h *Handler) HandleGetStateMetadata(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   655  	err := h.checkMetadataCap(msg)
   656  	if err != nil {
   657  		return nil, err
   658  	}
   659  
   660  	getStateMetadata := &pb.GetStateMetadata{}
   661  	err = proto.Unmarshal(msg.Payload, getStateMetadata)
   662  	if err != nil {
   663  		return nil, errors.Wrap(err, "unmarshal failed")
   664  	}
   665  
   666  	namespaceID := txContext.NamespaceID
   667  	collection := getStateMetadata.Collection
   668  	chaincodeLogger.Debugf("[%s] getting state metadata for chaincode %s, key %s, channel %s", shorttxid(msg.Txid), namespaceID, getStateMetadata.Key, txContext.ChannelID)
   669  
   670  	var metadata map[string][]byte
   671  	if isCollectionSet(collection) {
   672  		if txContext.IsInitTransaction {
   673  			return nil, errors.New("private data APIs are not allowed in chaincode Init()")
   674  		}
   675  		if err := errorIfCreatorHasNoReadPermission(namespaceID, collection, txContext); err != nil {
   676  			return nil, err
   677  		}
   678  		metadata, err = txContext.TXSimulator.GetPrivateDataMetadata(namespaceID, collection, getStateMetadata.Key)
   679  	} else {
   680  		metadata, err = txContext.TXSimulator.GetStateMetadata(namespaceID, getStateMetadata.Key)
   681  	}
   682  	if err != nil {
   683  		return nil, errors.WithStack(err)
   684  	}
   685  	var metadataResult pb.StateMetadataResult
   686  	for metakey := range metadata {
   687  		md := &pb.StateMetadata{Metakey: metakey, Value: metadata[metakey]}
   688  		metadataResult.Entries = append(metadataResult.Entries, md)
   689  	}
   690  	res, err := proto.Marshal(&metadataResult)
   691  	if err != nil {
   692  		return nil, errors.WithStack(err)
   693  	}
   694  
   695  	// Send response msg back to chaincode. GetState will not trigger event
   696  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: res, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   697  }
   698  
   699  // Handles query to ledger to rage query state
   700  func (h *Handler) HandleGetStateByRange(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   701  	getStateByRange := &pb.GetStateByRange{}
   702  	err := proto.Unmarshal(msg.Payload, getStateByRange)
   703  	if err != nil {
   704  		return nil, errors.Wrap(err, "unmarshal failed")
   705  	}
   706  
   707  	metadata, err := getQueryMetadataFromBytes(getStateByRange.Metadata)
   708  	if err != nil {
   709  		return nil, err
   710  	}
   711  
   712  	totalReturnLimit := h.calculateTotalReturnLimit(metadata)
   713  	iterID := h.UUIDGenerator.New()
   714  	var rangeIter commonledger.ResultsIterator
   715  	isPaginated := false
   716  	namespaceID := txContext.NamespaceID
   717  	collection := getStateByRange.Collection
   718  	if isCollectionSet(collection) {
   719  		if txContext.IsInitTransaction {
   720  			return nil, errors.New("private data APIs are not allowed in chaincode Init()")
   721  		}
   722  		if err := errorIfCreatorHasNoReadPermission(namespaceID, collection, txContext); err != nil {
   723  			return nil, err
   724  		}
   725  		rangeIter, err = txContext.TXSimulator.GetPrivateDataRangeScanIterator(namespaceID, collection,
   726  			getStateByRange.StartKey, getStateByRange.EndKey)
   727  	} else if isMetadataSetForPagination(metadata) {
   728  		isPaginated = true
   729  		startKey := getStateByRange.StartKey
   730  		if isMetadataSetForPagination(metadata) {
   731  			if metadata.Bookmark != "" {
   732  				startKey = metadata.Bookmark
   733  			}
   734  		}
   735  		rangeIter, err = txContext.TXSimulator.GetStateRangeScanIteratorWithPagination(namespaceID,
   736  			startKey, getStateByRange.EndKey, metadata.PageSize)
   737  	} else {
   738  		rangeIter, err = txContext.TXSimulator.GetStateRangeScanIterator(namespaceID, getStateByRange.StartKey, getStateByRange.EndKey)
   739  	}
   740  	if err != nil {
   741  		return nil, errors.WithStack(err)
   742  	}
   743  	txContext.InitializeQueryContext(iterID, rangeIter)
   744  
   745  	payload, err := h.QueryResponseBuilder.BuildQueryResponse(txContext, rangeIter, iterID, isPaginated, totalReturnLimit)
   746  	if err != nil {
   747  		txContext.CleanupQueryContext(iterID)
   748  		return nil, errors.WithStack(err)
   749  	}
   750  
   751  	payloadBytes, err := proto.Marshal(payload)
   752  	if err != nil {
   753  		txContext.CleanupQueryContext(iterID)
   754  		return nil, errors.Wrap(err, "marshal failed")
   755  	}
   756  
   757  	chaincodeLogger.Debugf("Got keys and values. Sending %s", pb.ChaincodeMessage_RESPONSE)
   758  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   759  }
   760  
   761  // Handles query to ledger for query state next
   762  func (h *Handler) HandleQueryStateNext(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   763  	queryStateNext := &pb.QueryStateNext{}
   764  	err := proto.Unmarshal(msg.Payload, queryStateNext)
   765  	if err != nil {
   766  		return nil, errors.Wrap(err, "unmarshal failed")
   767  	}
   768  
   769  	queryIter := txContext.GetQueryIterator(queryStateNext.Id)
   770  	if queryIter == nil {
   771  		return nil, errors.New("query iterator not found")
   772  	}
   773  
   774  	totalReturnLimit := h.calculateTotalReturnLimit(nil)
   775  
   776  	payload, err := h.QueryResponseBuilder.BuildQueryResponse(txContext, queryIter, queryStateNext.Id, false, totalReturnLimit)
   777  	if err != nil {
   778  		txContext.CleanupQueryContext(queryStateNext.Id)
   779  		return nil, errors.WithStack(err)
   780  	}
   781  
   782  	payloadBytes, err := proto.Marshal(payload)
   783  	if err != nil {
   784  		txContext.CleanupQueryContext(queryStateNext.Id)
   785  		return nil, errors.Wrap(err, "marshal failed")
   786  	}
   787  
   788  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   789  }
   790  
   791  // Handles the closing of a state iterator
   792  func (h *Handler) HandleQueryStateClose(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   793  	queryStateClose := &pb.QueryStateClose{}
   794  	err := proto.Unmarshal(msg.Payload, queryStateClose)
   795  	if err != nil {
   796  		return nil, errors.Wrap(err, "unmarshal failed")
   797  	}
   798  
   799  	iter := txContext.GetQueryIterator(queryStateClose.Id)
   800  	if iter != nil {
   801  		txContext.CleanupQueryContext(queryStateClose.Id)
   802  	}
   803  
   804  	payload := &pb.QueryResponse{HasMore: false, Id: queryStateClose.Id}
   805  	payloadBytes, err := proto.Marshal(payload)
   806  	if err != nil {
   807  		return nil, errors.Wrap(err, "marshal failed")
   808  	}
   809  
   810  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   811  }
   812  
   813  // Handles query to ledger to execute query state
   814  func (h *Handler) HandleGetQueryResult(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   815  	iterID := h.UUIDGenerator.New()
   816  
   817  	getQueryResult := &pb.GetQueryResult{}
   818  	err := proto.Unmarshal(msg.Payload, getQueryResult)
   819  	if err != nil {
   820  		return nil, errors.Wrap(err, "unmarshal failed")
   821  	}
   822  
   823  	metadata, err := getQueryMetadataFromBytes(getQueryResult.Metadata)
   824  	if err != nil {
   825  		return nil, err
   826  	}
   827  
   828  	totalReturnLimit := h.calculateTotalReturnLimit(metadata)
   829  	isPaginated := false
   830  	var executeIter commonledger.ResultsIterator
   831  	namespaceID := txContext.NamespaceID
   832  	collection := getQueryResult.Collection
   833  	if isCollectionSet(collection) {
   834  		if txContext.IsInitTransaction {
   835  			return nil, errors.New("private data APIs are not allowed in chaincode Init()")
   836  		}
   837  		if err := errorIfCreatorHasNoReadPermission(namespaceID, collection, txContext); err != nil {
   838  			return nil, err
   839  		}
   840  		executeIter, err = txContext.TXSimulator.ExecuteQueryOnPrivateData(namespaceID, collection, getQueryResult.Query)
   841  	} else if isMetadataSetForPagination(metadata) {
   842  		isPaginated = true
   843  		executeIter, err = txContext.TXSimulator.ExecuteQueryWithPagination(namespaceID,
   844  			getQueryResult.Query, metadata.Bookmark, metadata.PageSize)
   845  
   846  	} else {
   847  		executeIter, err = txContext.TXSimulator.ExecuteQuery(namespaceID, getQueryResult.Query)
   848  	}
   849  	if err != nil {
   850  		return nil, errors.WithStack(err)
   851  	}
   852  
   853  	txContext.InitializeQueryContext(iterID, executeIter)
   854  
   855  	payload, err := h.QueryResponseBuilder.BuildQueryResponse(txContext, executeIter, iterID, isPaginated, totalReturnLimit)
   856  	if err != nil {
   857  		txContext.CleanupQueryContext(iterID)
   858  		return nil, errors.WithStack(err)
   859  	}
   860  
   861  	payloadBytes, err := proto.Marshal(payload)
   862  	if err != nil {
   863  		txContext.CleanupQueryContext(iterID)
   864  		return nil, errors.Wrap(err, "marshal failed")
   865  	}
   866  
   867  	chaincodeLogger.Debugf("Got keys and values. Sending %s", pb.ChaincodeMessage_RESPONSE)
   868  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   869  }
   870  
   871  // Handles query to ledger history db
   872  func (h *Handler) HandleGetHistoryForKey(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   873  	if txContext.HistoryQueryExecutor == nil {
   874  		return nil, errors.New("history database is not enabled")
   875  	}
   876  	iterID := h.UUIDGenerator.New()
   877  	namespaceID := txContext.NamespaceID
   878  
   879  	getHistoryForKey := &pb.GetHistoryForKey{}
   880  	err := proto.Unmarshal(msg.Payload, getHistoryForKey)
   881  	if err != nil {
   882  		return nil, errors.Wrap(err, "unmarshal failed")
   883  	}
   884  
   885  	historyIter, err := txContext.HistoryQueryExecutor.GetHistoryForKey(namespaceID, getHistoryForKey.Key)
   886  	if err != nil {
   887  		return nil, errors.WithStack(err)
   888  	}
   889  
   890  	totalReturnLimit := h.calculateTotalReturnLimit(nil)
   891  
   892  	txContext.InitializeQueryContext(iterID, historyIter)
   893  	payload, err := h.QueryResponseBuilder.BuildQueryResponse(txContext, historyIter, iterID, false, totalReturnLimit)
   894  	if err != nil {
   895  		txContext.CleanupQueryContext(iterID)
   896  		return nil, errors.WithStack(err)
   897  	}
   898  
   899  	payloadBytes, err := proto.Marshal(payload)
   900  	if err != nil {
   901  		txContext.CleanupQueryContext(iterID)
   902  		return nil, errors.Wrap(err, "marshal failed")
   903  	}
   904  
   905  	chaincodeLogger.Debugf("Got keys and values. Sending %s", pb.ChaincodeMessage_RESPONSE)
   906  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: payloadBytes, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
   907  }
   908  
   909  func isCollectionSet(collection string) bool {
   910  	return collection != ""
   911  }
   912  
   913  func isMetadataSetForPagination(metadata *pb.QueryMetadata) bool {
   914  	if metadata == nil {
   915  		return false
   916  	}
   917  
   918  	if metadata.PageSize == 0 && metadata.Bookmark == "" {
   919  		return false
   920  	}
   921  
   922  	return true
   923  }
   924  
   925  func getQueryMetadataFromBytes(metadataBytes []byte) (*pb.QueryMetadata, error) {
   926  	if metadataBytes != nil {
   927  		metadata := &pb.QueryMetadata{}
   928  		err := proto.Unmarshal(metadataBytes, metadata)
   929  		if err != nil {
   930  			return nil, errors.Wrap(err, "unmarshal failed")
   931  		}
   932  		return metadata, nil
   933  	}
   934  	return nil, nil
   935  }
   936  
   937  func (h *Handler) calculateTotalReturnLimit(metadata *pb.QueryMetadata) int32 {
   938  	totalReturnLimit := int32(h.TotalQueryLimit)
   939  	if metadata != nil {
   940  		pageSize := int32(metadata.PageSize)
   941  		if pageSize > 0 && pageSize < totalReturnLimit {
   942  			totalReturnLimit = pageSize
   943  		}
   944  	}
   945  	return totalReturnLimit
   946  }
   947  
   948  func (h *Handler) getTxContextForInvoke(channelID string, txid string, payload []byte, format string, args ...interface{}) (*TransactionContext, error) {
   949  	// if we have a channelID, just get the txsim from isValidTxSim
   950  	if channelID != "" {
   951  		return h.isValidTxSim(channelID, txid, "could not get valid transaction")
   952  	}
   953  
   954  	chaincodeSpec := &pb.ChaincodeSpec{}
   955  	err := proto.Unmarshal(payload, chaincodeSpec)
   956  	if err != nil {
   957  		return nil, errors.Wrap(err, "unmarshal failed")
   958  	}
   959  
   960  	// Get the chaincodeID to invoke. The chaincodeID to be called may
   961  	// contain composite info like "chaincode-name:version/channel-name"
   962  	// We are not using version now but default to the latest
   963  	targetInstance := ParseName(chaincodeSpec.ChaincodeId.Name)
   964  
   965  	// If targetInstance is not an SCC, isValidTxSim should be called which will return an err.
   966  	// We do not want to propagate calls to user CCs when the original call was to a SCC
   967  	// without a channel context (ie, no ledger context).
   968  	if !h.BuiltinSCCs.IsSysCC(targetInstance.ChaincodeName) {
   969  		// normal path - UCC invocation with an empty ("") channel: isValidTxSim will return an error
   970  		return h.isValidTxSim("", txid, "could not get valid transaction")
   971  	}
   972  
   973  	// Calling SCC without a ChannelID, then the assumption this is an external SCC called by the client (special case) and no UCC involved,
   974  	// so no Transaction Simulator validation needed as there are no commits to the ledger, get the txContext directly if it is not nil
   975  	txContext := h.TXContexts.Get(channelID, txid)
   976  	if txContext == nil {
   977  		return nil, errors.New("failed to get transaction context")
   978  	}
   979  
   980  	return txContext, nil
   981  }
   982  
   983  func (h *Handler) HandlePutState(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
   984  	putState := &pb.PutState{}
   985  	err := proto.Unmarshal(msg.Payload, putState)
   986  	if err != nil {
   987  		return nil, errors.Wrap(err, "unmarshal failed")
   988  	}
   989  
   990  	namespaceID := txContext.NamespaceID
   991  	collection := putState.Collection
   992  	if isCollectionSet(collection) {
   993  		if txContext.IsInitTransaction {
   994  			return nil, errors.New("private data APIs are not allowed in chaincode Init()")
   995  		}
   996  		if err := errorIfCreatorHasNoWritePermission(namespaceID, collection, txContext); err != nil {
   997  			return nil, err
   998  		}
   999  		err = txContext.TXSimulator.SetPrivateData(namespaceID, collection, putState.Key, putState.Value)
  1000  	} else {
  1001  		err = txContext.TXSimulator.SetState(namespaceID, putState.Key, putState.Value)
  1002  	}
  1003  	if err != nil {
  1004  		return nil, errors.WithStack(err)
  1005  	}
  1006  
  1007  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
  1008  }
  1009  
  1010  func (h *Handler) HandlePutStateMetadata(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
  1011  	err := h.checkMetadataCap(msg)
  1012  	if err != nil {
  1013  		return nil, err
  1014  	}
  1015  
  1016  	putStateMetadata := &pb.PutStateMetadata{}
  1017  	err = proto.Unmarshal(msg.Payload, putStateMetadata)
  1018  	if err != nil {
  1019  		return nil, errors.Wrap(err, "unmarshal failed")
  1020  	}
  1021  
  1022  	metadata := make(map[string][]byte)
  1023  	metadata[putStateMetadata.Metadata.Metakey] = putStateMetadata.Metadata.Value
  1024  
  1025  	namespaceID := txContext.NamespaceID
  1026  	collection := putStateMetadata.Collection
  1027  	if isCollectionSet(collection) {
  1028  		if txContext.IsInitTransaction {
  1029  			return nil, errors.New("private data APIs are not allowed in chaincode Init()")
  1030  		}
  1031  		if err := errorIfCreatorHasNoWritePermission(namespaceID, collection, txContext); err != nil {
  1032  			return nil, err
  1033  		}
  1034  		err = txContext.TXSimulator.SetPrivateDataMetadata(namespaceID, collection, putStateMetadata.Key, metadata)
  1035  	} else {
  1036  		err = txContext.TXSimulator.SetStateMetadata(namespaceID, putStateMetadata.Key, metadata)
  1037  	}
  1038  	if err != nil {
  1039  		return nil, errors.WithStack(err)
  1040  	}
  1041  
  1042  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
  1043  }
  1044  
  1045  func (h *Handler) HandleDelState(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
  1046  	delState := &pb.DelState{}
  1047  	err := proto.Unmarshal(msg.Payload, delState)
  1048  	if err != nil {
  1049  		return nil, errors.Wrap(err, "unmarshal failed")
  1050  	}
  1051  
  1052  	namespaceID := txContext.NamespaceID
  1053  	collection := delState.Collection
  1054  	if isCollectionSet(collection) {
  1055  		if txContext.IsInitTransaction {
  1056  			return nil, errors.New("private data APIs are not allowed in chaincode Init()")
  1057  		}
  1058  		if err := errorIfCreatorHasNoWritePermission(namespaceID, collection, txContext); err != nil {
  1059  			return nil, err
  1060  		}
  1061  		err = txContext.TXSimulator.DeletePrivateData(namespaceID, collection, delState.Key)
  1062  	} else {
  1063  		err = txContext.TXSimulator.DeleteState(namespaceID, delState.Key)
  1064  	}
  1065  	if err != nil {
  1066  		return nil, errors.WithStack(err)
  1067  	}
  1068  
  1069  	// Send response msg back to chaincode.
  1070  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
  1071  }
  1072  
  1073  // Handles requests that modify ledger state
  1074  func (h *Handler) HandleInvokeChaincode(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
  1075  	chaincodeLogger.Debugf("[%s] C-call-C", shorttxid(msg.Txid))
  1076  
  1077  	chaincodeSpec := &pb.ChaincodeSpec{}
  1078  	err := proto.Unmarshal(msg.Payload, chaincodeSpec)
  1079  	if err != nil {
  1080  		return nil, errors.Wrap(err, "unmarshal failed")
  1081  	}
  1082  
  1083  	// Get the chaincodeID to invoke. The chaincodeID to be called may
  1084  	// contain composite info like "chaincode-name:version/channel-name".
  1085  	// We are not using version now but default to the latest.
  1086  	targetInstance := ParseName(chaincodeSpec.ChaincodeId.Name)
  1087  	chaincodeSpec.ChaincodeId.Name = targetInstance.ChaincodeName
  1088  	if targetInstance.ChannelID == "" {
  1089  		// use caller's channel as the called chaincode is in the same channel
  1090  		targetInstance.ChannelID = txContext.ChannelID
  1091  	}
  1092  	chaincodeLogger.Debugf("[%s] C-call-C %s on channel %s", shorttxid(msg.Txid), targetInstance.ChaincodeName, targetInstance.ChannelID)
  1093  
  1094  	err = h.checkACL(txContext.SignedProp, txContext.Proposal, targetInstance)
  1095  	if err != nil {
  1096  		chaincodeLogger.Errorf(
  1097  			"[%s] C-call-C %s on channel %s failed check ACL [%v]: [%s]",
  1098  			shorttxid(msg.Txid),
  1099  			targetInstance.ChaincodeName,
  1100  			targetInstance.ChannelID,
  1101  			txContext.SignedProp,
  1102  			err,
  1103  		)
  1104  		return nil, errors.WithStack(err)
  1105  	}
  1106  
  1107  	// Set up a new context for the called chaincode if on a different channel
  1108  	// We grab the called channel's ledger simulator to hold the new state
  1109  	txParams := &ccprovider.TransactionParams{
  1110  		TxID:                 msg.Txid,
  1111  		ChannelID:            targetInstance.ChannelID,
  1112  		SignedProp:           txContext.SignedProp,
  1113  		Proposal:             txContext.Proposal,
  1114  		TXSimulator:          txContext.TXSimulator,
  1115  		HistoryQueryExecutor: txContext.HistoryQueryExecutor,
  1116  	}
  1117  
  1118  	if targetInstance.ChannelID != txContext.ChannelID {
  1119  		lgr := h.LedgerGetter.GetLedger(targetInstance.ChannelID)
  1120  		if lgr == nil {
  1121  			return nil, errors.Errorf("failed to find ledger for channel: %s", targetInstance.ChannelID)
  1122  		}
  1123  
  1124  		sim, err := lgr.NewTxSimulator(msg.Txid)
  1125  		if err != nil {
  1126  			return nil, errors.WithStack(err)
  1127  		}
  1128  		defer sim.Done()
  1129  
  1130  		hqe, err := lgr.NewHistoryQueryExecutor()
  1131  		if err != nil {
  1132  			return nil, errors.WithStack(err)
  1133  		}
  1134  
  1135  		txParams.TXSimulator = sim
  1136  		txParams.HistoryQueryExecutor = hqe
  1137  	}
  1138  
  1139  	// Execute the chaincode... this CANNOT be an init at least for now
  1140  	responseMessage, err := h.Invoker.Invoke(txParams, targetInstance.ChaincodeName, chaincodeSpec.Input)
  1141  	if err != nil {
  1142  		return nil, errors.Wrap(err, "execute failed")
  1143  	}
  1144  
  1145  	// payload is marshalled and sent to the calling chaincode's shim which unmarshals and
  1146  	// sends it to chaincode
  1147  	res, err := proto.Marshal(responseMessage)
  1148  	if err != nil {
  1149  		return nil, errors.Wrap(err, "marshal failed")
  1150  	}
  1151  
  1152  	return &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_RESPONSE, Payload: res, Txid: msg.Txid, ChannelId: msg.ChannelId}, nil
  1153  }
  1154  
  1155  func (h *Handler) Execute(txParams *ccprovider.TransactionParams, namespace string, msg *pb.ChaincodeMessage, timeout time.Duration) (*pb.ChaincodeMessage, error) {
  1156  	chaincodeLogger.Debugf("Entry")
  1157  	defer chaincodeLogger.Debugf("Exit")
  1158  
  1159  	txParams.CollectionStore = h.getCollectionStore(msg.ChannelId)
  1160  	txParams.IsInitTransaction = (msg.Type == pb.ChaincodeMessage_INIT)
  1161  	txParams.NamespaceID = namespace
  1162  
  1163  	txctx, err := h.TXContexts.Create(txParams)
  1164  	if err != nil {
  1165  		return nil, err
  1166  	}
  1167  	defer h.TXContexts.Delete(msg.ChannelId, msg.Txid)
  1168  
  1169  	if err := h.setChaincodeProposal(txParams.SignedProp, txParams.Proposal, msg); err != nil {
  1170  		return nil, err
  1171  	}
  1172  
  1173  	h.serialSendAsync(msg)
  1174  
  1175  	var ccresp *pb.ChaincodeMessage
  1176  	select {
  1177  	case ccresp = <-txctx.ResponseNotifier:
  1178  		// response is sent to user or calling chaincode. ChaincodeMessage_ERROR
  1179  		// are typically treated as error
  1180  	case <-time.After(timeout):
  1181  		err = errors.New("timeout expired while executing transaction")
  1182  		h.Metrics.ExecuteTimeouts.With("chaincode", h.chaincodeID).Add(1)
  1183  	case <-h.streamDone():
  1184  		err = errors.New("chaincode stream terminated")
  1185  	}
  1186  
  1187  	return ccresp, err
  1188  }
  1189  
  1190  func (h *Handler) setChaincodeProposal(signedProp *pb.SignedProposal, prop *pb.Proposal, msg *pb.ChaincodeMessage) error {
  1191  	if prop != nil && signedProp == nil {
  1192  		return errors.New("failed getting proposal context. Signed proposal is nil")
  1193  	}
  1194  	// TODO: This doesn't make a lot of sense. Feels like both are required or
  1195  	// neither should be set. Check with a knowledgeable expert.
  1196  	if prop != nil {
  1197  		msg.Proposal = signedProp
  1198  	}
  1199  	return nil
  1200  }
  1201  
  1202  func (h *Handler) getCollectionStore(channelID string) privdata.CollectionStore {
  1203  	return privdata.NewSimpleCollectionStore(
  1204  		h.LedgerGetter.GetLedger(channelID),
  1205  		h.DeployedCCInfoProvider,
  1206  	)
  1207  }
  1208  
  1209  func (h *Handler) State() State { return h.state }
  1210  func (h *Handler) Close()       { h.TXContexts.Close() }
  1211  
  1212  type State int
  1213  
  1214  const (
  1215  	Created State = iota
  1216  	Established
  1217  	Ready
  1218  )
  1219  
  1220  func (s State) String() string {
  1221  	switch s {
  1222  	case Created:
  1223  		return "created"
  1224  	case Established:
  1225  		return "established"
  1226  	case Ready:
  1227  		return "ready"
  1228  	default:
  1229  		return "UNKNOWN"
  1230  	}
  1231  }