-
Notifications
You must be signed in to change notification settings - Fork 6
/
invoker_stub.go
52 lines (41 loc) · 1.67 KB
/
invoker_stub.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package gateway
import (
"errors"
"fmt"
"github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger-labs/cckit/router"
"github.com/hyperledger-labs/cckit/serialize"
)
var ErrInvokeMethodNotAllowed = errors.New(`invoke method not allowed`)
type (
ChaincodeLocatorResolver func(ctx router.Context, serviceName string) (*ChaincodeLocator, error)
// ChaincodeStubInvoker for cross chaincode calls - only query (read) methods
// context argument is router.Context, not context.Context
ChaincodeStubInvoker interface {
Query(stub shim.ChaincodeStubInterface, fn string, args []interface{}, target interface{}) (interface{}, error)
}
LocatorChaincodeStubInvoker struct {
Locator *ChaincodeLocator
Serializer serialize.Serializer
}
)
func (c *LocatorChaincodeStubInvoker) Query(
stub shim.ChaincodeStubInterface, fn string, args []interface{}, target interface{}) (interface{}, error) {
// todo: remove hack
if c.Serializer == nil {
c.Serializer = serialize.DefaultSerializer
}
argsBytes, err := invokerArgs(fn, args, c.Serializer)
if err != nil {
return nil, fmt.Errorf(`query via stub: %w`, err)
}
// if target chaincode is encrypted we can only access to target chaincode via dummy `StateGet`,
// without method name and arg decryption on target chaincode side
// because transient data cannot be passed via stub.InvokeChaincode call
response := stub.InvokeChaincode(c.Locator.Chaincode, argsBytes, c.Locator.Channel)
if response.Status != shim.OK {
return nil, fmt.Errorf(`cross chaincode=%s, channel=%s invoke: %w`,
c.Locator.Chaincode, c.Locator.Channel, errors.New(response.Message))
}
return ccOutput(&response, target, c.Serializer)
}