Skip to content

Commit 4e6f238

Browse files
committed
[FAB-9856] Create interfaces for external deps
Change-Id: I6fd3845799c7498471c04aeda186106323c41f31 Signed-off-by: Saad Karim <skarim@us.ibm.com> Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
1 parent f7e790a commit 4e6f238

File tree

3 files changed

+76
-47
lines changed

3 files changed

+76
-47
lines changed

core/chaincode/chaincode_support.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"time"
1212

1313
"github.com/golang/protobuf/proto"
14+
"github.com/hyperledger/fabric/common/util"
1415
"github.com/hyperledger/fabric/core/common/ccprovider"
1516
"github.com/hyperledger/fabric/core/common/sysccprovider"
1617
"github.com/hyperledger/fabric/core/container/ccintf"
@@ -139,8 +140,9 @@ func (cs *ChaincodeSupport) HandleChaincodeStream(ctxt context.Context, stream c
139140
ACLProvider: cs.ACLProvider,
140141
TXContexts: NewTransactionContexts(),
141142
ActiveTransactions: NewActiveTransactions(),
142-
143-
sccp: cs.sccp,
143+
SystemCCProvider: cs.sccp,
144+
SystemCCVersion: util.GetSysCCVersion(),
145+
PolicyChecker: CheckInstantiationPolicyFunc(ccprovider.CheckInstantiationPolicy),
144146
}
145147

146148
return handler.ProcessStream(stream)

core/chaincode/chaincode_support_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1088,7 +1088,7 @@ func TestStartAndWaitLaunchError(t *testing.T) {
10881088
}
10891089

10901090
func TestGetTxContextFromHandler(t *testing.T) {
1091-
h := Handler{TXContexts: NewTransactionContexts(), sccp: &scc.Provider{Peer: peer.Default, PeerSupport: peer.DefaultSupport, Registrar: inproccontroller.NewRegistry()}}
1091+
h := Handler{TXContexts: NewTransactionContexts(), SystemCCProvider: &scc.Provider{Peer: peer.Default, PeerSupport: peer.DefaultSupport, Registrar: inproccontroller.NewRegistry()}}
10921092

10931093
chnl := "test"
10941094
txid := "1"
@@ -1300,7 +1300,7 @@ func TestCCFramework(t *testing.T) {
13001300
initializeCC(t, chainID, ccname, ccSide, chaincodeSupport)
13011301

13021302
//chaincode support should not allow dups
1303-
handler := &Handler{chaincodeID: &pb.ChaincodeID{Name: ccname + ":0"}, sccp: chaincodeSupport.sccp}
1303+
handler := &Handler{chaincodeID: &pb.ChaincodeID{Name: ccname + ":0"}, SystemCCProvider: chaincodeSupport.sccp}
13041304
if err := chaincodeSupport.HandlerRegistry.Register(handler); err == nil {
13051305
t.Fatalf("expected re-register to fail")
13061306
}

core/chaincode/handler.go

+70-43
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,6 @@ import (
2727
"golang.org/x/net/context"
2828
)
2929

30-
type state int
31-
32-
const (
33-
created state = iota
34-
established
35-
ready
36-
)
37-
38-
func (s state) String() string {
39-
switch s {
40-
case created:
41-
return "created"
42-
case established:
43-
return "established"
44-
case ready:
45-
return "ready"
46-
default:
47-
return "UNKNOWN"
48-
}
49-
}
50-
5130
var chaincodeLogger = flogging.MustGetLogger("chaincode")
5231

5332
// ACLProvider is responsible for performing access control checks when invoking
@@ -56,20 +35,41 @@ type ACLProvider interface {
5635
CheckACL(resName string, channelID string, idinfo interface{}) error
5736
}
5837

38+
// Registry is responsible for tracking handlers.
5939
type Registry interface {
6040
Register(*Handler) error
6141
Ready(cname string)
6242
Deregister(cname string) error
6343
}
6444

45+
// SystemCCProvider provides system chaincode metadata.
46+
type SystemCCProvider interface {
47+
IsSysCC(name string) bool
48+
IsSysCCAndNotInvokableCC2CC(name string) bool
49+
}
50+
51+
// PolicyChecker is used to evaluate instantiation policies.
52+
type PolicyChecker interface {
53+
CheckInstantiationPolicy(name, version string, cd *ccprovider.ChaincodeData) error
54+
}
55+
56+
// Adapter from function to PolicyChecker interface.
57+
type CheckInstantiationPolicyFunc func(name, version string, cd *ccprovider.ChaincodeData) error
58+
59+
func (c CheckInstantiationPolicyFunc) CheckInstantiationPolicy(name, version string, cd *ccprovider.ChaincodeData) error {
60+
return c(name, version, cd)
61+
}
62+
6563
// Handler implements the peer side of the chaincode stream.
6664
type Handler struct {
65+
// Keepalive specifies the interval at which keep-alive messages are sent.
66+
Keepalive time.Duration
67+
// SystemCCVersion specifies the current system chaincode version
68+
SystemCCVersion string
6769
// Lifecycle is used to access the Lifecycle System Chaincode.
6870
Lifecycle *Lifecycle
6971
// Executor is used to invoke chaincode.
7072
Executor Executor
71-
// Keepalive specifies the interval at which keep-alive messages are sent.
72-
Keepalive time.Duration
7373
// Registry is used to track active handlers.
7474
Registry Registry
7575
// ACLProvider is used to check if a chaincode invocation should be allowed.
@@ -79,15 +79,27 @@ type Handler struct {
7979
TXContexts *TransactionContexts
8080
// activeTransactions holds active transaction identifiers.
8181
ActiveTransactions *ActiveTransactions
82-
83-
sccp sysccprovider.SystemChaincodeProvider
84-
85-
state state
82+
// SystemCCProvider provides access to system chaincode metadata
83+
SystemCCProvider SystemCCProvider
84+
// PolicyChecker is used to evaluate the chaincode instantiation policies.
85+
PolicyChecker PolicyChecker
86+
87+
// state holds the current handler state. It will be created, established, or
88+
// ready.
89+
state state
90+
// chaincodeID holds the ID of the chaincode that registered with the peer.
8691
chaincodeID *pb.ChaincodeID
87-
ccInstance *sysccprovider.ChaincodeInstance
88-
serialLock sync.Mutex // serialLock is used to serialize sends across the grpc chat stream.
89-
chatStream ccintf.ChaincodeStream
90-
errChan chan error // chan to pass error in sync and nonsync mode
92+
// ccInstances holds information about the chaincode instance associated with
93+
// the peer.
94+
ccInstance *sysccprovider.ChaincodeInstance
95+
96+
// serialLock is used to serialize sends across the grpc chat stream.
97+
serialLock sync.Mutex
98+
// chatStream is the bidirectional grpc stream used to communicate with the
99+
// chaincode instance.
100+
chatStream ccintf.ChaincodeStream
101+
// errChan is used to communicate errors from the async send to the receive loop
102+
errChan chan error
91103
}
92104

93105
// HandleMessage is the entry point Chaincode messages.
@@ -239,7 +251,7 @@ func (h *Handler) serialSendAsync(msg *pb.ChaincodeMessage, sendErr bool) {
239251
func (h *Handler) checkACL(signedProp *pb.SignedProposal, proposal *pb.Proposal, ccIns *sysccprovider.ChaincodeInstance) error {
240252
// ensure that we don't invoke a system chaincode
241253
// that is not invokable through a cc2cc invocation
242-
if h.sccp.IsSysCCAndNotInvokableCC2CC(ccIns.ChaincodeName) {
254+
if h.SystemCCProvider.IsSysCCAndNotInvokableCC2CC(ccIns.ChaincodeName) {
243255
return errors.Errorf("system chaincode %s cannot be invoked with a cc2cc invocation", ccIns.ChaincodeName)
244256
}
245257

@@ -250,7 +262,7 @@ func (h *Handler) checkACL(signedProp *pb.SignedProposal, proposal *pb.Proposal,
250262
// - an application chaincode (and we still need to determine
251263
// whether the invoker can invoke it)
252264

253-
if h.sccp.IsSysCC(ccIns.ChaincodeName) {
265+
if h.SystemCCProvider.IsSysCC(ccIns.ChaincodeName) {
254266
// Allow this call
255267
return nil
256268
}
@@ -717,7 +729,7 @@ func (h *Handler) getTxContextForInvoke(channelID string, txid string, payload [
717729
// If targetInstance is not an SCC, isValidTxSim should be called which will return an err.
718730
// We do not want to propagate calls to user CCs when the original call was to a SCC
719731
// without a channel context (ie, no ledger context).
720-
if isscc := h.sccp.IsSysCC(targetInstance.ChaincodeName); !isscc {
732+
if isscc := h.SystemCCProvider.IsSysCC(targetInstance.ChaincodeName); !isscc {
721733
// normal path - UCC invocation with an empty ("") channel: isValidTxSim will return an error
722734
return h.isValidTxSim("", txid, "could not get valid transaction")
723735
}
@@ -831,11 +843,8 @@ func (h *Handler) handleInvokeChaincode(msg *pb.ChaincodeMessage, txContext *Tra
831843

832844
chaincodeLogger.Debugf("[%s] getting chaincode data for %s on channel %s", shorttxid(msg.Txid), targetInstance.ChaincodeName, targetInstance.ChainID)
833845

834-
// is the chaincode a system chaincode ?
835-
isscc := h.sccp.IsSysCC(targetInstance.ChaincodeName)
836-
837-
var version string
838-
if !isscc {
846+
version := h.SystemCCVersion
847+
if !h.SystemCCProvider.IsSysCC(targetInstance.ChaincodeName) {
839848
// if its a user chaincode, get the details
840849
cd, err := h.Lifecycle.GetChaincodeDefinition(ctxt, msg.Txid, txContext.signedProp, txContext.proposal, targetInstance.ChainID, targetInstance.ChaincodeName)
841850
if err != nil {
@@ -844,13 +853,10 @@ func (h *Handler) handleInvokeChaincode(msg *pb.ChaincodeMessage, txContext *Tra
844853

845854
version = cd.CCVersion()
846855

847-
err = ccprovider.CheckInstantiationPolicy(targetInstance.ChaincodeName, version, cd.(*ccprovider.ChaincodeData))
856+
err = h.PolicyChecker.CheckInstantiationPolicy(targetInstance.ChaincodeName, version, cd.(*ccprovider.ChaincodeData))
848857
if err != nil {
849858
return nil, errors.WithStack(err)
850859
}
851-
} else {
852-
// this is a system cc, just call it directly
853-
version = util.GetSysCCVersion()
854860
}
855861

856862
// Launch the new chaincode if not already running
@@ -935,3 +941,24 @@ func (h *Handler) sendExecuteMessage(ctxt context.Context, chainID string, msg *
935941
func (h *Handler) Close() {
936942
h.TXContexts.Close()
937943
}
944+
945+
type state int
946+
947+
const (
948+
created state = iota
949+
established
950+
ready
951+
)
952+
953+
func (s state) String() string {
954+
switch s {
955+
case created:
956+
return "created"
957+
case established:
958+
return "established"
959+
case ready:
960+
return "ready"
961+
default:
962+
return "UNKNOWN"
963+
}
964+
}

0 commit comments

Comments
 (0)