github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/kvledger/txmgmt/pvtstatepurgemgmt/expiry_schedule_builder.go (about) 1 /* 2 Copyright hechain. 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/hechain20/hechain/core/ledger/kvledger/txmgmt/privacyenabledstate" 13 "github.com/hechain20/hechain/core/ledger/kvledger/txmgmt/statedb" 14 "github.com/hechain20/hechain/core/ledger/pvtdatapolicy" 15 "github.com/hechain20/hechain/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 (builder *expiryScheduleBuilder) getExpiryInfo() []*expiryInfo { 47 var listExpinfo []*expiryInfo 48 for expinfoKey, pvtdataKeys := range builder.scheduleEntries { 49 expinfoKeyCopy := expinfoKey 50 listExpinfo = append(listExpinfo, &expiryInfo{expiryInfoKey: &expinfoKeyCopy, pvtdataKeys: pvtdataKeys}) 51 } 52 return listExpinfo 53 } 54 55 func buildExpirySchedule( 56 btlPolicy pvtdatapolicy.BTLPolicy, 57 pvtUpdates *privacyenabledstate.PvtUpdateBatch, 58 hashedUpdates *privacyenabledstate.HashedUpdateBatch) ([]*expiryInfo, error) { 59 hashedUpdateKeys := hashedUpdates.ToCompositeKeyMap() 60 expiryScheduleBuilder := newExpiryScheduleBuilder(btlPolicy) 61 62 logger.Debugf("Building the expiry schedules based on the update batch") 63 64 // Iterate through the private data updates and for each key add into the expiry schedule 65 // i.e., when these private data key and it's hashed-keys are going to be expired 66 // Note that the 'hashedUpdateKeys' may be superset of the pvtUpdates. This is because, 67 // the peer may not receive all the private data either because the peer is not eligible for certain private data 68 // or because we allow proceeding with the missing private data data 69 for pvtUpdateKey, vv := range pvtUpdates.ToCompositeKeyMap() { 70 keyHash := util.ComputeStringHash(pvtUpdateKey.Key) 71 hashedCompisiteKey := privacyenabledstate.HashedCompositeKey{ 72 Namespace: pvtUpdateKey.Namespace, 73 CollectionName: pvtUpdateKey.CollectionName, 74 KeyHash: string(keyHash), 75 } 76 logger.Debugf("Adding expiry schedule for key and key hash [%s]", &hashedCompisiteKey) 77 if err := expiryScheduleBuilder.add(pvtUpdateKey.Namespace, pvtUpdateKey.CollectionName, pvtUpdateKey.Key, keyHash, vv); err != nil { 78 return nil, err 79 } 80 delete(hashedUpdateKeys, hashedCompisiteKey) 81 } 82 83 // Add entries for the leftover key hashes i.e., the hashes corresponding to which there is not private key is present 84 for hashedUpdateKey, vv := range hashedUpdateKeys { 85 logger.Debugf("Adding expiry schedule for key hash [%s]", &hashedUpdateKey) 86 if err := expiryScheduleBuilder.add(hashedUpdateKey.Namespace, hashedUpdateKey.CollectionName, "", []byte(hashedUpdateKey.KeyHash), vv); err != nil { 87 return nil, err 88 } 89 } 90 return expiryScheduleBuilder.getExpiryInfo(), nil 91 } 92 93 func isDelete(versionedValue *statedb.VersionedValue) bool { 94 return versionedValue.Value == nil 95 } 96 97 func neverExpires(expiryBlk uint64) bool { 98 return expiryBlk == math.MaxUint64 99 }