forked from hyperledger/fabric
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scc.go
84 lines (67 loc) · 3.05 KB
/
scc.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package scc
import (
"github.com/hyperledger/fabric-chaincode-go/shim"
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/core/container/ccintf"
)
// SysCCVersion is a constant used for the version field of system chaincodes.
// Historically, the version of a system chaincode was implicitly tied to the exact
// build version of a peer, which does not work for collecting endorsements across
// sccs across peers. Until there is a need for separate SCC versions, we use
// this constant here.
const SysCCVersion = "syscc"
// ChaincodeID returns the chaincode ID of a system chaincode of a given name.
func ChaincodeID(ccName string) string {
return ccName + "." + SysCCVersion
}
// XXX should we change this name to actually match the package name? Leaving now for historical consistency
var sysccLogger = flogging.MustGetLogger("sccapi")
// BuiltinSCCs are special system chaincodes, differentiated from other (plugin)
// system chaincodes. These chaincodes do not need to be initialized in '_lifecycle'
// and may be invoked without a channel context. It is expected that '_lifecycle'
// will eventually be the only builtin SCCs.
// Note, this field should only be used on _endorsement_ side, never in validation
// as it might change.
type BuiltinSCCs map[string]struct{}
func (bccs BuiltinSCCs) IsSysCC(name string) bool {
_, ok := bccs[name]
return ok
}
// A ChaincodeStreamHandler is responsible for handling the ChaincodeStream
// communication between a per and chaincode.
type ChaincodeStreamHandler interface {
HandleChaincodeStream(ccintf.ChaincodeStream) error
LaunchInProc(packageID string) <-chan struct{}
}
type SelfDescribingSysCC interface {
//Unique name of the system chaincode
Name() string
// Chaincode returns the underlying chaincode
Chaincode() shim.Chaincode
}
// DeploySysCC is the hook for system chaincodes where system chaincodes are registered with the fabric.
// This call directly registers the chaincode with the chaincode handler and bypasses the other usercc constructs.
func DeploySysCC(sysCC SelfDescribingSysCC, chaincodeStreamHandler ChaincodeStreamHandler) {
sysccLogger.Infof("deploying system chaincode '%s'", sysCC.Name())
ccid := ChaincodeID(sysCC.Name())
done := chaincodeStreamHandler.LaunchInProc(ccid)
peerRcvCCSend := make(chan *pb.ChaincodeMessage)
ccRcvPeerSend := make(chan *pb.ChaincodeMessage)
// TODO, these go routines leak in test.
go func() {
sysccLogger.Debugf("starting chaincode-support stream for %s", ccid)
err := chaincodeStreamHandler.HandleChaincodeStream(newInProcStream(peerRcvCCSend, ccRcvPeerSend))
sysccLogger.Criticalf("shim stream ended with err: %v", err)
}()
go func(sysCC SelfDescribingSysCC) {
sysccLogger.Debugf("chaincode started for %s", ccid)
err := shim.StartInProc(ccid, newInProcStream(ccRcvPeerSend, peerRcvCCSend), sysCC.Chaincode())
sysccLogger.Criticalf("system chaincode ended with err: %v", err)
}(sysCC)
<-done
}