@@ -134,6 +134,10 @@ type Handler struct {
134134 UseWriteBatch bool
135135 // MaxSizeWriteBatch maximum batch size for the change segment
136136 MaxSizeWriteBatch uint32
137+ // UseGetMultipleKeys an indication that the peer can handle get multiple keys
138+ UseGetMultipleKeys bool
139+ // MaxSizeGetMultipleKeys maximum size of batches with get multiple keys
140+ MaxSizeGetMultipleKeys uint32
137141
138142 // stateLock is used to read and set State.
139143 stateLock sync.RWMutex
@@ -221,6 +225,8 @@ func (h *Handler) handleMessageReadyState(msg *pb.ChaincodeMessage) error {
221225 go h .HandleTransaction (msg , h .HandlePurgePrivateData )
222226 case pb .ChaincodeMessage_WRITE_BATCH_STATE :
223227 go h .HandleTransaction (msg , h .HandleWriteBatch )
228+ case pb .ChaincodeMessage_GET_STATE_MULTIPLE :
229+ go h .HandleTransaction (msg , h .HandleGetStateMultipleKeys )
224230 default :
225231 return fmt .Errorf ("[%s] Fabric side handler cannot handle message (%s) while in ready state" , msg .Txid , msg .Type )
226232 }
@@ -449,8 +455,10 @@ func (h *Handler) sendReady() error {
449455 chaincodeLogger .Debugf ("sending READY for chaincode %s" , h .chaincodeID )
450456
451457 chaincodeAdditionalParams := & pb.ChaincodeAdditionalParams {
452- UseWriteBatch : h .UseWriteBatch ,
453- MaxSizeWriteBatch : h .MaxSizeWriteBatch ,
458+ UseWriteBatch : h .UseWriteBatch ,
459+ MaxSizeWriteBatch : h .MaxSizeWriteBatch ,
460+ UseGetMultipleKeys : h .UseGetMultipleKeys ,
461+ MaxSizeGetMultipleKeys : h .MaxSizeGetMultipleKeys ,
454462 }
455463 payloadBytes , err := proto .Marshal (chaincodeAdditionalParams )
456464 if err != nil {
@@ -678,6 +686,46 @@ func (h *Handler) HandleGetState(msg *pb.ChaincodeMessage, txContext *Transactio
678686 return & pb.ChaincodeMessage {Type : pb .ChaincodeMessage_RESPONSE , Payload : res , Txid : msg .Txid , ChannelId : msg .ChannelId }, nil
679687}
680688
689+ // Handles query to ledger to get state
690+ func (h * Handler ) HandleGetStateMultipleKeys (msg * pb.ChaincodeMessage , txContext * TransactionContext ) (* pb.ChaincodeMessage , error ) {
691+ getState := & pb.GetStateMiltiple {}
692+ err := proto .Unmarshal (msg .Payload , getState )
693+ if err != nil {
694+ return nil , errors .Wrap (err , "unmarshal failed" )
695+ }
696+
697+ var res [][]byte
698+ namespaceID := txContext .NamespaceID
699+ collection := getState .GetCollection ()
700+ chaincodeLogger .Debugf ("[%s] getting state for chaincode %s, keys %v, channel %s" , shorttxid (msg .Txid ), namespaceID , getState .GetKeys (), txContext .ChannelID )
701+
702+ if isCollectionSet (collection ) {
703+ if txContext .IsInitTransaction {
704+ return nil , errors .New ("private data APIs are not allowed in chaincode Init()" )
705+ }
706+ if err = errorIfCreatorHasNoReadPermission (namespaceID , collection , txContext ); err != nil {
707+ return nil , err
708+ }
709+ res , err = txContext .TXSimulator .GetPrivateDataMultipleKeys (namespaceID , collection , getState .GetKeys ())
710+ } else {
711+ res , err = txContext .TXSimulator .GetStateMultipleKeys (namespaceID , getState .GetKeys ())
712+ }
713+ if err != nil {
714+ return nil , errors .WithStack (err )
715+ }
716+ if len (res ) == 0 {
717+ chaincodeLogger .Debugf ("[%s] No state associated with keys: %v. Sending %s with an empty payload" , shorttxid (msg .Txid ), getState .GetKeys (), pb .ChaincodeMessage_RESPONSE )
718+ }
719+
720+ payloadBytes , err := proto .Marshal (& pb.GetStateMiltipleResult {Values : res })
721+ if err != nil {
722+ return nil , errors .Wrap (err , "marshal failed" )
723+ }
724+
725+ // Send response msg back to chaincode. GetState will not trigger event
726+ return & pb.ChaincodeMessage {Type : pb .ChaincodeMessage_RESPONSE , Payload : payloadBytes , Txid : msg .Txid , ChannelId : msg .ChannelId }, nil
727+ }
728+
681729func (h * Handler ) HandleGetPrivateDataHash (msg * pb.ChaincodeMessage , txContext * TransactionContext ) (* pb.ChaincodeMessage , error ) {
682730 getState := & pb.GetState {}
683731 err := proto .Unmarshal (msg .Payload , getState )
0 commit comments