Skip to content

Commit 1a8be5a

Browse files
ale-linuxyacovm
authored andcommitted
[FAB-5871] VSCC to ensure no collection exists
This change set completes the work for FAB-5871 by adding the check in VSCC to ensure that no prior collection exists for the deployed chaincode. Change-Id: I5046244ff9a8aa7a249fa79b0c8aafd263eabdb0 Signed-off-by: Alessandro Sorniotti <ale.linux@sopit.net>
1 parent ebd1a52 commit 1a8be5a

File tree

7 files changed

+92
-13
lines changed

7 files changed

+92
-13
lines changed

core/common/privdata/collection.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ type CollectionStore interface {
6868

6969
// GetCollectionAccessPolicy retrieves a collection's access policy
7070
RetrieveCollectionAccessPolicy(common.CollectionCriteria) (CollectionAccessPolicy, error)
71+
72+
// RetrieveCollectionConfigPackage retrieves the configuration
73+
// for the collection with the supplied criteria
74+
RetrieveCollectionConfigPackage(common.CollectionCriteria) (*common.CollectionConfigPackage, error)
7175
}
7276

7377
const (

core/common/privdata/store.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func NewSimpleCollectionStore(s Support) CollectionStore {
4848
return &simpleCollectionStore{s}
4949
}
5050

51-
func (c *simpleCollectionStore) retrieveSimpleCollection(cc common.CollectionCriteria) (*SimpleCollection, error) {
51+
func (c *simpleCollectionStore) retrieveCollectionConfigPackage(cc common.CollectionCriteria) (*common.CollectionConfigPackage, error) {
5252
qe, err := c.s.GetQueryExecutorForLedger(cc.Channel)
5353
if err != nil {
5454
return nil, errors.WithMessage(err, fmt.Sprintf("could not retrieve query executor for collection criteria %#v", cc))
@@ -69,6 +69,18 @@ func (c *simpleCollectionStore) retrieveSimpleCollection(cc common.CollectionCri
6969
return nil, errors.Wrapf(err, "invalid configuration for collection criteria %#v", cc)
7070
}
7171

72+
return collections, nil
73+
}
74+
75+
func (c *simpleCollectionStore) retrieveSimpleCollection(cc common.CollectionCriteria) (*SimpleCollection, error) {
76+
collections, err := c.retrieveCollectionConfigPackage(cc)
77+
if err != nil {
78+
return nil, err
79+
}
80+
if collections == nil {
81+
return nil, nil
82+
}
83+
7284
for _, cconf := range collections.Config {
7385
switch cconf := cconf.Payload.(type) {
7486
case *common.CollectionConfig_StaticCollectionConfig:
@@ -97,3 +109,7 @@ func (c *simpleCollectionStore) RetrieveCollection(cc common.CollectionCriteria)
97109
func (c *simpleCollectionStore) RetrieveCollectionAccessPolicy(cc common.CollectionCriteria) (CollectionAccessPolicy, error) {
98110
return c.retrieveSimpleCollection(cc)
99111
}
112+
113+
func (c *simpleCollectionStore) RetrieveCollectionConfigPackage(cc common.CollectionCriteria) (*common.CollectionConfigPackage, error) {
114+
return c.retrieveCollectionConfigPackage(cc)
115+
}

core/common/privdata/store_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,8 @@ func TestCollectionStore(t *testing.T) {
9393
c, err = cs.RetrieveCollection(common.CollectionCriteria{Channel: "ch", Namespace: "cc", Collection: "asd"})
9494
assert.Error(t, err)
9595
assert.Nil(t, c)
96+
97+
ccc, err := cs.RetrieveCollectionConfigPackage(ccr)
98+
assert.NoError(t, err)
99+
assert.NotNil(t, ccc)
96100
}

core/scc/vscc/validator_onevalidsignature.go

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/hyperledger/fabric/core/common/sysccprovider"
3131
"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil"
3232
"github.com/hyperledger/fabric/core/scc/lscc"
33+
m "github.com/hyperledger/fabric/msp"
3334
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
3435
"github.com/hyperledger/fabric/protos/common"
3536
"github.com/hyperledger/fabric/protos/ledger/rwset/kvrwset"
@@ -54,11 +55,29 @@ type ValidatorOneValidSignature struct {
5455
// methods of the system chaincode package without
5556
// import cycles
5657
sccprovider sysccprovider.SystemChaincodeProvider
58+
59+
// collectionStore provides support to retrieve
60+
// collections from the ledger
61+
collectionStore privdata.CollectionStore
62+
}
63+
64+
// collectionStoreSupport implements privdata.Support
65+
type collectionStoreSupport struct {
66+
sysccprovider.SystemChaincodeProvider
67+
}
68+
69+
func (c *collectionStoreSupport) GetCollectionKVSKey(cc common.CollectionCriteria) string {
70+
return privdata.BuildCollectionKVSKey(cc.Namespace)
71+
}
72+
73+
func (c *collectionStoreSupport) GetIdentityDeserializer(chainID string) m.IdentityDeserializer {
74+
return mspmgmt.GetIdentityDeserializer(chainID)
5775
}
5876

5977
// Init is called once when the chaincode started the first time
6078
func (vscc *ValidatorOneValidSignature) Init(stub shim.ChaincodeStubInterface) pb.Response {
6179
vscc.sccprovider = sysccprovider.GetSystemChaincodeProvider()
80+
vscc.collectionStore = privdata.NewSimpleCollectionStore(&collectionStoreSupport{vscc.sccprovider})
6281

6382
return shim.Success(nil)
6483
}
@@ -228,6 +247,7 @@ func (vscc *ValidatorOneValidSignature) validateDeployRWSetAndCollection(
228247
lsccrwset *kvrwset.KVRWSet,
229248
cdRWSet *ccprovider.ChaincodeData,
230249
lsccArgs [][]byte,
250+
chid, ccid string,
231251
) error {
232252
/********************************************/
233253
/* security check 0.a - validation of rwset */
@@ -261,9 +281,19 @@ func (vscc *ValidatorOneValidSignature) validateDeployRWSetAndCollection(
261281
cdRWSet.Name, cdRWSet.Version)
262282
}
263283

264-
// TODO: make sure there isn't any existing collection on the ledger for this chaincode
265-
// I'll take care of this as soon as we have implemented a collection store interface
266-
// to retrieve collection configuration data from the ledger (https://jira.hyperledger.org/browse/FAB-5872)
284+
ccp, err := vscc.collectionStore.RetrieveCollectionConfigPackage(common.CollectionCriteria{Channel: chid, Namespace: ccid})
285+
if err != nil {
286+
// fail if we get any error other than NoSuchCollectionError
287+
// because it means something went wrong while looking up the
288+
// older collection
289+
if _, ok := err.(privdata.NoSuchCollectionError); !ok {
290+
return errors.WithMessage(err, fmt.Sprintf("unable to check whether collection existed earlier for chaincode %s:%s",
291+
cdRWSet.Name, cdRWSet.Version))
292+
}
293+
}
294+
if ccp != nil {
295+
return errors.Errorf("collection data should not exist for chaincode %s:%s", cdRWSet.Name, cdRWSet.Version)
296+
}
267297

268298
if collectionsConfigArgs != nil {
269299
collections := &common.CollectionConfigPackage{}
@@ -413,7 +443,7 @@ func (vscc *ValidatorOneValidSignature) ValidateLSCCInvocation(
413443
/****************************************************************************/
414444
if ac.PrivateChannelData() {
415445
// do extra validation for collections
416-
err = vscc.validateDeployRWSetAndCollection(lsccrwset, cdRWSet, lsccArgs)
446+
err = vscc.validateDeployRWSetAndCollection(lsccrwset, cdRWSet, lsccArgs, chid, cdsArgs.ChaincodeSpec.ChaincodeId.Name)
417447
if err != nil {
418448
return err
419449
}

core/scc/vscc/validator_onevalidsignature_test.go

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1484,11 +1484,18 @@ func (c *mockPolicyChecker) CheckPolicyNoChannel(policyName string, signedProp *
14841484
}
14851485

14861486
func TestValidateDeployRWSetAndCollection(t *testing.T) {
1487+
chid := "ch"
1488+
ccid := "cc"
1489+
14871490
cd := &ccprovider.ChaincodeData{Name: "mycc"}
14881491

14891492
v := new(ValidatorOneValidSignature)
14901493
stub := shim.NewMockStub("validatoronevalidsignature", v)
14911494

1495+
State := make(map[string]map[string][]byte)
1496+
State["lscc"] = make(map[string][]byte)
1497+
sysccprovider.RegisterSystemChaincodeProviderFactory(&scc.MocksccProviderFactory{Qe: lm.NewMockQueryExecutor(State)})
1498+
14921499
r1 := stub.MockInit("1", [][]byte{})
14931500
if r1.Status != shim.OK {
14941501
fmt.Println("Init failed", string(r1.Message))
@@ -1497,38 +1504,38 @@ func TestValidateDeployRWSetAndCollection(t *testing.T) {
14971504

14981505
rwset := &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: "a"}, {Key: "b"}, {Key: "c"}}}
14991506

1500-
err := v.validateDeployRWSetAndCollection(rwset, nil, nil)
1507+
err := v.validateDeployRWSetAndCollection(rwset, nil, nil, chid, ccid)
15011508
assert.Error(t, err)
15021509

15031510
rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: "a"}, {Key: "b"}}}
15041511

1505-
err = v.validateDeployRWSetAndCollection(rwset, cd, nil)
1512+
err = v.validateDeployRWSetAndCollection(rwset, cd, nil, chid, ccid)
15061513
assert.Error(t, err)
15071514

15081515
rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: "a"}}}
15091516

1510-
err = v.validateDeployRWSetAndCollection(rwset, cd, nil)
1517+
err = v.validateDeployRWSetAndCollection(rwset, cd, nil, chid, ccid)
15111518
assert.NoError(t, err)
15121519

15131520
lsccargs := [][]byte{nil, nil, nil, nil, nil, nil}
15141521

1515-
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs)
1522+
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs, chid, ccid)
15161523
assert.NoError(t, err)
15171524

15181525
rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: "a"}, {Key: privdata.BuildCollectionKVSKey("mycc")}}}
15191526

1520-
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs)
1527+
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs, chid, ccid)
15211528
assert.NoError(t, err)
15221529

15231530
lsccargs = [][]byte{nil, nil, nil, nil, nil, []byte("barf")}
15241531

1525-
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs)
1532+
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs, chid, ccid)
15261533
assert.Error(t, err)
15271534

15281535
lsccargs = [][]byte{nil, nil, nil, nil, nil, []byte("barf")}
15291536
rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: "a"}, {Key: privdata.BuildCollectionKVSKey("mycc"), Value: []byte("barf")}}}
15301537

1531-
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs)
1538+
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs, chid, ccid)
15321539
assert.Error(t, err)
15331540

15341541
cc := &common.CollectionConfig{Payload: &common.CollectionConfig_StaticCollectionConfig{&common.StaticCollectionConfig{Name: "mycollection"}}}
@@ -1540,8 +1547,18 @@ func TestValidateDeployRWSetAndCollection(t *testing.T) {
15401547
lsccargs = [][]byte{nil, nil, nil, nil, nil, ccpBytes}
15411548
rwset = &kvrwset.KVRWSet{Writes: []*kvrwset.KVWrite{{Key: "a"}, {Key: privdata.BuildCollectionKVSKey("mycc"), Value: ccpBytes}}}
15421549

1543-
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs)
1550+
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs, chid, ccid)
15441551
assert.NoError(t, err)
1552+
1553+
State["lscc"][(&collectionStoreSupport{v.sccprovider}).GetCollectionKVSKey(common.CollectionCriteria{Channel: chid, Namespace: ccid})] = []byte("barf")
1554+
1555+
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs, chid, ccid)
1556+
assert.Error(t, err)
1557+
1558+
State["lscc"][(&collectionStoreSupport{v.sccprovider}).GetCollectionKVSKey(common.CollectionCriteria{Channel: chid, Namespace: ccid})] = ccpBytes
1559+
1560+
err = v.validateDeployRWSetAndCollection(rwset, cd, lsccargs, chid, ccid)
1561+
assert.Error(t, err)
15451562
}
15461563

15471564
var lccctestpath = "/tmp/lscc-validation-test"

gossip/privdata/coordinator_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ func (cs *collectionStore) RetrieveCollection(common.CollectionCriteria) (privda
325325
panic("implement me")
326326
}
327327

328+
func (cs *collectionStore) RetrieveCollectionConfigPackage(common.CollectionCriteria) (*common.CollectionConfigPackage, error) {
329+
panic("implement me")
330+
}
331+
328332
type collectionAccessPolicy struct {
329333
cs *collectionStore
330334
n uint64

gossip/privdata/pull_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ func (cs mockCollectionStore) RetrieveCollection(fcommon.CollectionCriteria) (pr
5959
panic("implement me")
6060
}
6161

62+
func (cs mockCollectionStore) RetrieveCollectionConfigPackage(fcommon.CollectionCriteria) (*fcommon.CollectionConfigPackage, error) {
63+
panic("implement me")
64+
}
65+
6266
type mockCollectionAccess struct {
6367
cs *mockCollectionStore
6468
}

0 commit comments

Comments
 (0)