github.com/renegr87/renegr87@v2.1.1+incompatible/core/ledger/kvledger/txmgmt/pvtstatepurgemgmt/expiry_schedule_builder.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package pvtstatepurgemgmt 8 9 import ( 10 math "math" 11 12 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/privacyenabledstate" 13 "github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/statedb" 14 "github.com/hyperledger/fabric/core/ledger/pvtdatapolicy" 15 "github.com/hyperledger/fabric/core/ledger/util" 16 ) 17 18 type expiryScheduleBuilder struct { 19 btlPolicy pvtdatapolicy.BTLPolicy 20 scheduleEntries map[expiryInfoKey]*PvtdataKeys 21 } 22 23 func newExpiryScheduleBuilder(btlPolicy pvtdatapolicy.BTLPolicy) *expiryScheduleBuilder { 24 return &expiryScheduleBuilder{btlPolicy, make(map[expiryInfoKey]*PvtdataKeys)} 25 } 26 27 func (builder *expiryScheduleBuilder) add(ns, coll, key string, keyHash []byte, versionedValue *statedb.VersionedValue) error { 28 committingBlk := versionedValue.Version.BlockNum 29 expiryBlk, err := builder.btlPolicy.GetExpiringBlock(ns, coll, committingBlk) 30 if err != nil { 31 return err 32 } 33 if isDelete(versionedValue) || neverExpires(expiryBlk) { 34 return nil 35 } 36 expinfoKey := expiryInfoKey{committingBlk: committingBlk, expiryBlk: expiryBlk} 37 pvtdataKeys, ok := builder.scheduleEntries[expinfoKey] 38 if !ok { 39 pvtdataKeys = newPvtdataKeys() 40 builder.scheduleEntries[expinfoKey] = pvtdataKeys 41 } 42 pvtdataKeys.add(ns, coll, key, keyHash) 43 return nil 44 } 45 46 func isDelete(versionedValue *statedb.VersionedValue) bool { 47 return versionedValue.Value == nil 48 } 49 50 func neverExpires(expiryBlk uint64) bool { 51 return expiryBlk == math.MaxUint64 52 } 53 54 func (builder *expiryScheduleBuilder) getExpiryInfo() []*expiryInfo { 55 var listExpinfo []*expiryInfo 56 for expinfoKey, pvtdataKeys := range builder.scheduleEntries { 57 expinfoKeyCopy := expinfoKey 58 listExpinfo = append(listExpinfo, &expiryInfo{expiryInfoKey: &expinfoKeyCopy, pvtdataKeys: pvtdataKeys}) 59 } 60 return listExpinfo 61 } 62 63 func buildExpirySchedule( 64 btlPolicy pvtdatapolicy.BTLPolicy, 65 pvtUpdates *privacyenabledstate.PvtUpdateBatch, 66 hashedUpdates *privacyenabledstate.HashedUpdateBatch) ([]*expiryInfo, error) { 67 68 hashedUpdateKeys := hashedUpdates.ToCompositeKeyMap() 69 expiryScheduleBuilder := newExpiryScheduleBuilder(btlPolicy) 70 71 logger.Debugf("Building the expiry schedules based on the update batch") 72 73 // Iterate through the private data updates and for each key add into the expiry schedule 74 // i.e., when these private data key and it's hashed-keys are going to be expired 75 // Note that the 'hashedUpdateKeys' may be superset of the pvtUpdates. This is because, 76 // the peer may not receive all the private data either because the peer is not eligible for certain private data 77 // or because we allow proceeding with the missing private data data 78 for pvtUpdateKey, vv := range pvtUpdates.ToCompositeKeyMap() { 79 keyHash := util.ComputeStringHash(pvtUpdateKey.Key) 80 hashedCompisiteKey := privacyenabledstate.HashedCompositeKey{ 81 Namespace: pvtUpdateKey.Namespace, 82 CollectionName: pvtUpdateKey.CollectionName, 83 KeyHash: string(keyHash), 84 } 85 logger.Debugf("Adding expiry schedule for key and key hash [%s]", &hashedCompisiteKey) 86 if err := expiryScheduleBuilder.add(pvtUpdateKey.Namespace, pvtUpdateKey.CollectionName, pvtUpdateKey.Key, keyHash, vv); err != nil { 87 return nil, err 88 } 89 delete(hashedUpdateKeys, hashedCompisiteKey) 90 } 91 92 // Add entries for the leftover key hashes i.e., the hashes corresponding to which there is not private key is present 93 for hashedUpdateKey, vv := range hashedUpdateKeys { 94 logger.Debugf("Adding expiry schedule for key hash [%s]", &hashedUpdateKey) 95 if err := expiryScheduleBuilder.add(hashedUpdateKey.Namespace, hashedUpdateKey.CollectionName, "", []byte(hashedUpdateKey.KeyHash), vv); err != nil { 96 return nil, err 97 } 98 } 99 return expiryScheduleBuilder.getExpiryInfo(), nil 100 }