Skip to content

Commit ab40a49

Browse files
committed
add support GetMultipleKeys
Signed-off-by: Fedor Partanskiy <fedor.partanskiy@atme.com>
1 parent cc24ab3 commit ab40a49

File tree

22 files changed

+1426
-272
lines changed

22 files changed

+1426
-272
lines changed

core/chaincode/chaincode_support.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ type ChaincodeSupport struct {
7575
UserRunsCC bool
7676
UseWriteBatch bool
7777
MaxSizeWriteBatch uint32
78+
UseGetMultipleKeys bool
79+
MaxSizeGetMultipleKeys uint32
7880
}
7981

8082
// Launch starts executing chaincode if it is not already running. This method
@@ -130,6 +132,8 @@ func (cs *ChaincodeSupport) HandleChaincodeStream(stream ccintf.ChaincodeStream)
130132
TotalQueryLimit: cs.TotalQueryLimit,
131133
UseWriteBatch: cs.UseWriteBatch,
132134
MaxSizeWriteBatch: cs.MaxSizeWriteBatch,
135+
UseGetMultipleKeys: cs.UseGetMultipleKeys,
136+
MaxSizeGetMultipleKeys: cs.MaxSizeGetMultipleKeys,
133137
}
134138

135139
return handler.ProcessStream(stream)

core/chaincode/config.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,27 @@ import (
1616
)
1717

1818
const (
19-
defaultExecutionTimeout = 30 * time.Second
20-
minimumStartupTimeout = 5 * time.Second
21-
defaultMaxSizeWriteBatch = 1000
19+
defaultExecutionTimeout = 30 * time.Second
20+
minimumStartupTimeout = 5 * time.Second
21+
defaultMaxSizeWriteBatch = 1000
22+
defaultMaxSizeGetMultipleKeys = 1000
2223
)
2324

2425
type Config struct {
25-
TotalQueryLimit int
26-
TLSEnabled bool
27-
Keepalive time.Duration
28-
ExecuteTimeout time.Duration
29-
InstallTimeout time.Duration
30-
StartupTimeout time.Duration
31-
LogFormat string
32-
LogLevel string
33-
ShimLogLevel string
34-
SCCAllowlist map[string]bool
35-
UseWriteBatch bool
36-
MaxSizeWriteBatch uint32
26+
TotalQueryLimit int
27+
TLSEnabled bool
28+
Keepalive time.Duration
29+
ExecuteTimeout time.Duration
30+
InstallTimeout time.Duration
31+
StartupTimeout time.Duration
32+
LogFormat string
33+
LogLevel string
34+
ShimLogLevel string
35+
SCCAllowlist map[string]bool
36+
UseWriteBatch bool
37+
MaxSizeWriteBatch uint32
38+
UseGetMultipleKeys bool
39+
MaxSizeGetMultipleKeys uint32
3740
}
3841

3942
func GlobalConfig() *Config {
@@ -81,6 +84,13 @@ func (c *Config) load() {
8184
if c.MaxSizeWriteBatch <= 0 {
8285
c.MaxSizeWriteBatch = defaultMaxSizeWriteBatch
8386
}
87+
if viper.IsSet("chaincode.runtimeParams.useGetMultipleKeys") {
88+
c.UseGetMultipleKeys = viper.GetBool("chaincode.runtimeParams.useGetMultipleKeys")
89+
}
90+
c.MaxSizeGetMultipleKeys = viper.GetUint32("chaincode.runtimeParams.maxSizeGetMultipleKeys")
91+
if c.MaxSizeGetMultipleKeys <= 0 {
92+
c.MaxSizeGetMultipleKeys = defaultMaxSizeGetMultipleKeys
93+
}
8494
}
8595

8696
func parseBool(s string) bool {

core/chaincode/handler.go

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
681729
func (h *Handler) HandleGetPrivateDataHash(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {
682730
getState := &pb.GetState{}
683731
err := proto.Unmarshal(msg.Payload, getState)

core/chaincode/handler_test.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,12 @@ var _ = Describe("Handler", func() {
123123
UUIDGenerator: chaincode.UUIDGeneratorFunc(func() string {
124124
return "generated-query-id"
125125
}),
126-
AppConfig: fakeApplicationConfigRetriever,
127-
Metrics: chaincodeMetrics,
128-
UseWriteBatch: true,
129-
MaxSizeWriteBatch: 1000,
126+
AppConfig: fakeApplicationConfigRetriever,
127+
Metrics: chaincodeMetrics,
128+
UseWriteBatch: true,
129+
MaxSizeWriteBatch: 1000,
130+
UseGetMultipleKeys: true,
131+
MaxSizeGetMultipleKeys: 1000,
130132
}
131133
chaincode.SetHandlerChatStream(handler, fakeChatStream)
132134
chaincode.SetHandlerChaincodeID(handler, "test-handler-name:1.0")
@@ -2786,8 +2788,10 @@ var _ = Describe("Handler", func() {
27862788
}))
27872789

27882790
chaincodeAdditionalParams := &pb.ChaincodeAdditionalParams{
2789-
UseWriteBatch: true,
2790-
MaxSizeWriteBatch: 1000,
2791+
UseWriteBatch: true,
2792+
MaxSizeWriteBatch: 1000,
2793+
UseGetMultipleKeys: true,
2794+
MaxSizeGetMultipleKeys: 1000,
27912795
}
27922796
payloadBytes, err := proto.Marshal(chaincodeAdditionalParams)
27932797
Expect(err).NotTo(HaveOccurred())

core/chaincode/lifecycle/mock/chaincode_stub.go

Lines changed: 170 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)