Skip to content

Commit b99e963

Browse files
committed
[FAB-6229] validator support for cfg tree cc lifecycle
This change set introduces support at the committer side for the config-tree-based chaincode lifecycle management. Change-Id: Id75460a58347f29dd407361e8a77947993c6237d Signed-off-by: Alessandro Sorniotti <ale.linux@sopit.net>
1 parent 3974f15 commit b99e963

File tree

10 files changed

+41
-53
lines changed

10 files changed

+41
-53
lines changed

core/chaincode/ccproviderimpl.go

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"github.com/hyperledger/fabric/core/common/ccprovider"
2323
"github.com/hyperledger/fabric/core/ledger"
2424
pb "github.com/hyperledger/fabric/protos/peer"
25-
"github.com/pkg/errors"
2625
)
2726

2827
// ccProviderFactory implements the ccprovider.ChaincodeProviderFactory
@@ -70,29 +69,6 @@ func (c *ccProviderImpl) GetCCContext(cid, name, version, txid string, syscc boo
7069
return &ccProviderContextImpl{ctx: ctx}
7170
}
7271

73-
// GetCCValidationInfoFromLSCC returns the VSCC and the policy listed in LSCC for the supplied chaincode
74-
func (c *ccProviderImpl) GetCCValidationInfoFromLSCC(ctxt context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (string, []byte, error) {
75-
// LSCC does not have any notion about its own
76-
// endorsing policy - we should never call this
77-
// function with lscc as the chaincodeID
78-
if chaincodeID == "lscc" {
79-
panic("GetCCValidationInfoFromLSCC invoke for LSCC")
80-
}
81-
82-
data, err := GetChaincodeDefinition(ctxt, txid, signedProp, prop, chainID, chaincodeID)
83-
if err != nil {
84-
return "", nil, err
85-
}
86-
87-
valcc, valarg := data.Validation()
88-
89-
if data == nil || valcc == "" || valarg == nil {
90-
return "", nil, errors.New("incorrect validation info in LSCC")
91-
}
92-
93-
return valcc, valarg, nil
94-
}
95-
9672
// ExecuteChaincode executes the chaincode specified in the context with the specified arguments
9773
func (c *ccProviderImpl) ExecuteChaincode(ctxt context.Context, cccid interface{}, args [][]byte) (*pb.Response, *pb.ChaincodeEvent, error) {
9874
return ExecuteChaincode(ctxt, cccid.(*ccProviderContextImpl).ctx, args)

core/chaincode/chaincode_support.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -680,13 +680,13 @@ func (chaincodeSupport *ChaincodeSupport) Launch(context context.Context, cccid
680680
var depPayload []byte
681681

682682
//hopefully we are restarting from existing image and the deployed transaction exists
683-
//this will also validate the ID from the LSCC
683+
//(this will also validate the ID from the LSCC if we're not using the config-tree approach)
684684
depPayload, err = GetCDS(context, cccid.TxID, cccid.SignedProposal, cccid.Proposal, cccid.ChainID, cID.Name)
685685
if err != nil {
686-
return cID, cMsg, errors.WithMessage(err, fmt.Sprintf("could not get deployment transaction from LSCC for %s", canName))
686+
return cID, cMsg, errors.WithMessage(err, fmt.Sprintf("could not get ChaincodeDeploymentSpec for %s", canName))
687687
}
688688
if depPayload == nil {
689-
return cID, cMsg, errors.WithMessage(err, fmt.Sprintf("failed to get deployment payload %s", canName))
689+
return cID, cMsg, errors.WithMessage(err, fmt.Sprintf("nil ChaincodeDeploymentSpec for %s", canName))
690690
}
691691

692692
cds = &pb.ChaincodeDeploymentSpec{}

core/chaincode/chaincode_support_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -636,10 +636,6 @@ func cc2cc(t *testing.T, chainID, chainID2, ccname string, ccSide *mockpeer.Mock
636636
mockAclProvider.On("CheckACL", aclmgmt.LSCC_GETCCDATA, chainID, sprop).Return(nil)
637637
mockAclProvider.On("CheckACL", aclmgmt.PROPOSE, chainID, sprop).Return(nil)
638638

639-
if _, _, err := ccprovider.GetChaincodeProvider().GetCCValidationInfoFromLSCC(ctxt, "getccdata", sprop, prop, chainID, calledCC); err != nil {
640-
t.Fatalf("Could not get chaincode data from lscc for %s: %s", calledCC, err)
641-
}
642-
643639
sysCCVers := util.GetSysCCVersion()
644640
//call a callable system CC, a regular cc, a regular but different cc on a different chain, a regular but same cc on a different chain, and an uncallable system cc and expect an error inthe last one
645641
respSet := &mockpeer.MockResponseSet{errorFunc, nil, []*mockpeer.MockResponse{

core/chaincode/handler.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,18 +1309,15 @@ func (handler *Handler) enterBusyState(e *fsm.Event, state string) {
13091309
ctxt = context.WithValue(ctxt, TXSimulatorKey, txsim)
13101310
ctxt = context.WithValue(ctxt, HistoryQueryExecutorKey, historyQueryExecutor)
13111311

1312-
chaincodeLogger.Debugf("[%s] calling lscc to get chaincode data for %s on channel %s",
1312+
chaincodeLogger.Debugf("[%s] getting chaincode data for %s on channel %s",
13131313
shorttxid(msg.Txid), calledCcIns.ChaincodeName, calledCcIns.ChainID)
13141314

1315-
//Call LSCC to get the called chaincode artifacts
1316-
13171315
//is the chaincode a system chaincode ?
13181316
isscc := sysccprovider.GetSystemChaincodeProvider().IsSysCC(calledCcIns.ChaincodeName)
13191317

13201318
var version string
13211319
if !isscc {
1322-
//if its a user chaincode, get the details from LSCC
1323-
//Call LSCC to get the called chaincode artifacts
1320+
//if its a user chaincode, get the details
13241321
cd, err := GetChaincodeDefinition(ctxt, msg.Txid, txContext.signedProp, txContext.proposal, calledCcIns.ChainID, calledCcIns.ChaincodeName)
13251322
if err != nil {
13261323
errHandler([]byte(err.Error()), "[%s]Failed to get chaincode data (%s) for invoked chaincode. Sending %s", shorttxid(msg.Txid), err, pb.ChaincodeMessage_ERROR)

core/committer/txvalidator/validator.go

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030

3131
"github.com/hyperledger/fabric/common/cauthdsl"
3232
"github.com/hyperledger/fabric/common/channelconfig"
33+
"github.com/hyperledger/fabric/common/resourcesconfig"
3334
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil"
3435
)
3536

@@ -56,6 +57,10 @@ type Support interface {
5657

5758
// Capabilities defines the capabilities for the application portion of this channel
5859
Capabilities() channelconfig.ApplicationCapabilities
60+
61+
// ChaincodeByName returns the definition (and whether they exist)
62+
// for a chaincode in a specific channel
63+
ChaincodeByName(chainname, ccname string) (resourcesconfig.ChaincodeDefinition, bool)
5964
}
6065

6166
//Validator interface which defines API to validate block transactions
@@ -612,17 +617,16 @@ func (v *vsccValidatorImpl) GetInfoForValidate(txid, chID, ccID string) (*sysccp
612617
// system CC, we need to ask the CC to give us the name
613618
// of VSCC and of the policy that should be used
614619

615-
// obtain name of the VSCC and the policy from LSCC
616-
cd, err := v.getCDataForCC(ccID)
620+
// obtain name of the VSCC and the policy
621+
cd, err := v.getCDataForCC(chID, ccID)
617622
if err != nil {
618623
msg := fmt.Sprintf("Unable to get chaincode data from ledger for txid %s, due to %s", txid, err)
619624
logger.Errorf(msg)
620625
return nil, nil, nil, err
621626
}
622-
cc.ChaincodeName = cd.Name
623-
cc.ChaincodeVersion = cd.Version
624-
vscc.ChaincodeName = cd.Vscc
625-
policy = cd.Policy
627+
cc.ChaincodeName = cd.CCName()
628+
cc.ChaincodeVersion = cd.CCVersion()
629+
vscc.ChaincodeName, policy = cd.Validation()
626630
} else {
627631
// when we are validating a system CC, we use the default
628632
// VSCC and a default policy that requires one signature
@@ -715,6 +719,15 @@ func (v *vsccValidatorImpl) VSCCValidateTx(payload *common.Payload, envBytes []b
715719
return err, peer.TxValidationCode_INVALID_OTHER_REASON
716720
}
717721

722+
// if we are using the config-tree-based cc lifecycle approach
723+
// there's no legitimate reason why a transaction would write to
724+
// lscc so we're going to block it
725+
if v.support.Capabilities().LifecycleViaConfig() && writesToLSCC {
726+
err := fmt.Errorf("lifecycle via config forbids writes to the lscc namespace")
727+
logger.Errorf("%s", err)
728+
return err, peer.TxValidationCode_ILLEGAL_WRITESET
729+
}
730+
718731
// we've gathered all the info required to proceed to validation;
719732
// validation will behave differently depending on the type of
720733
// chaincode (system vs. application)
@@ -843,7 +856,16 @@ func (v *vsccValidatorImpl) VSCCValidateTxForCC(envBytes []byte, txid, chid, vsc
843856
return nil
844857
}
845858

846-
func (v *vsccValidatorImpl) getCDataForCC(ccid string) (*ccprovider.ChaincodeData, error) {
859+
func (v *vsccValidatorImpl) getCDataForCC(chid, ccid string) (resourcesconfig.ChaincodeDefinition, error) {
860+
if v.support.Capabilities().LifecycleViaConfig() {
861+
cd, exists := v.support.ChaincodeByName(chid, ccid)
862+
if !exists {
863+
return nil, &VSCCInfoLookupFailureError{fmt.Sprintf("Could not retrieve state for chaincode %s on channel %s", ccid, chid)}
864+
}
865+
866+
return cd, nil
867+
}
868+
847869
l := v.support.Ledger()
848870
if l == nil {
849871
return nil, fmt.Errorf("nil ledger instance")

core/common/ccprovider/ccprovider.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,6 @@ type ChaincodeProvider interface {
461461
GetContext(ledger ledger.PeerLedger, txid string) (context.Context, ledger.TxSimulator, error)
462462
// GetCCContext returns an opaque chaincode context
463463
GetCCContext(cid, name, version, txid string, syscc bool, signedProp *pb.SignedProposal, prop *pb.Proposal) interface{}
464-
// GetCCValidationInfoFromLSCC returns the VSCC and the policy listed by LSCC for the supplied chaincode
465-
GetCCValidationInfoFromLSCC(ctxt context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (string, []byte, error)
466464
// ExecuteChaincode executes the chaincode given context and args
467465
ExecuteChaincode(ctxt context.Context, cccid interface{}, args [][]byte) (*pb.Response, *pb.ChaincodeEvent, error)
468466
// Execute executes the chaincode given context and spec (invocation or deploy)

core/endorser/endorser.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,6 @@ func (e *Endorser) endorseProposal(ctx context.Context, chainID string, txid str
296296
var escc string
297297
//ie, not "lscc" or system chaincodes
298298
if isSysCC {
299-
// FIXME: getCDSFromLSCC seems to fail for lscc - not sure this is expected?
300-
// TODO: who should endorse a call to LSCC?
301299
escc = "escc"
302300
} else {
303301
escc = cd.Endorsement()

core/mocks/ccprovider/ccprovider.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,6 @@ func (c *mockCcProviderImpl) GetCCContext(cid, name, version, txid string, syscc
130130
return &mockCcProviderContextImpl{}
131131
}
132132

133-
// GetCCValidationInfoFromLSCC does nothing
134-
func (c *mockCcProviderImpl) GetCCValidationInfoFromLSCC(ctxt context.Context, txid string, signedProp *peer.SignedProposal, prop *peer.Proposal, chainID string, chaincodeID string) (string, []byte, error) {
135-
return "vscc", nil, nil
136-
}
137-
138133
// ExecuteChaincode does nothing
139134
func (c *mockCcProviderImpl) ExecuteChaincode(ctxt context.Context, cccid interface{}, args [][]byte) (*peer.Response, *peer.ChaincodeEvent, error) {
140135
if c.executeResultProvider != nil {

core/mocks/txvalidator/support.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/hyperledger/fabric/common/channelconfig"
2121
mockpolicies "github.com/hyperledger/fabric/common/mocks/policies"
2222
"github.com/hyperledger/fabric/common/policies"
23+
"github.com/hyperledger/fabric/common/resourcesconfig"
2324
"github.com/hyperledger/fabric/core/ledger"
2425
"github.com/hyperledger/fabric/msp"
2526
"github.com/hyperledger/fabric/protos/common"
@@ -32,6 +33,10 @@ type Support struct {
3233
ACVal channelconfig.ApplicationCapabilities
3334
}
3435

36+
func (ms *Support) ChaincodeByName(chainname, ccname string) (resourcesconfig.ChaincodeDefinition, bool) {
37+
return nil, false
38+
}
39+
3540
func (ms *Support) Capabilities() channelconfig.ApplicationCapabilities {
3641
return ms.ACVal
3742
}

core/peer/peer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error {
328328
vcs := struct {
329329
*chainSupport
330330
*semaphore.Weighted
331-
}{cs, validationWorkersSemaphore}
331+
Support
332+
}{cs, validationWorkersSemaphore, GetSupport()}
332333
validator := txvalidator.NewTxValidator(vcs)
333334
c := committer.NewLedgerCommitterReactive(ledger, func(block *common.Block) error {
334335
chainID, err := utils.GetChainIDFromBlock(block)

0 commit comments

Comments
 (0)