github.com/ewagmig/fabric@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  }