github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/ledger/pvtdatapolicy/btlpolicy.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package pvtdatapolicy
     8  
     9  import (
    10  	"math"
    11  	"sync"
    12  
    13  	"github.com/hechain20/hechain/core/common/privdata"
    14  	"github.com/hyperledger/fabric-protos-go/peer"
    15  )
    16  
    17  var defaultBTL uint64 = math.MaxUint64
    18  
    19  // BTLPolicy BlockToLive policy for the pvt data
    20  type BTLPolicy interface {
    21  	// GetBTL returns BlockToLive for a given namespace and collection
    22  	GetBTL(ns string, coll string) (uint64, error)
    23  	// GetExpiringBlock returns the block number by which the pvtdata for given namespace,collection, and committingBlock should expire
    24  	GetExpiringBlock(namespace string, collection string, committingBlock uint64) (uint64, error)
    25  }
    26  
    27  // LSCCBasedBTLPolicy implements interface BTLPolicy.
    28  // This implementation loads the BTL policy from lscc namespace which is populated
    29  // with the collection configuration during chaincode initialization
    30  type LSCCBasedBTLPolicy struct {
    31  	collInfoProvider collectionInfoProvider
    32  	cache            map[btlkey]uint64
    33  	lock             sync.Mutex
    34  }
    35  
    36  type btlkey struct {
    37  	ns   string
    38  	coll string
    39  }
    40  
    41  // ConstructBTLPolicy constructs an instance of LSCCBasedBTLPolicy
    42  func ConstructBTLPolicy(collInfoProvider collectionInfoProvider) BTLPolicy {
    43  	return &LSCCBasedBTLPolicy{
    44  		collInfoProvider: collInfoProvider,
    45  		cache:            make(map[btlkey]uint64),
    46  	}
    47  }
    48  
    49  // GetBTL implements corresponding function in interface `BTLPolicyMgr`
    50  func (p *LSCCBasedBTLPolicy) GetBTL(namespace string, collection string) (uint64, error) {
    51  	var btl uint64
    52  	var ok bool
    53  	key := btlkey{namespace, collection}
    54  	p.lock.Lock()
    55  	defer p.lock.Unlock()
    56  	btl, ok = p.cache[key]
    57  	if !ok {
    58  		collConfig, err := p.collInfoProvider.CollectionInfo(namespace, collection)
    59  		if err != nil {
    60  			return 0, err
    61  		}
    62  		if collConfig == nil {
    63  			return 0, privdata.NoSuchCollectionError{Namespace: namespace, Collection: collection}
    64  		}
    65  		btlConfigured := collConfig.BlockToLive
    66  		if btlConfigured > 0 {
    67  			btl = uint64(btlConfigured)
    68  		} else {
    69  			btl = defaultBTL
    70  		}
    71  		p.cache[key] = btl
    72  	}
    73  	return btl, nil
    74  }
    75  
    76  // GetExpiringBlock implements function from the interface `BTLPolicy`
    77  func (p *LSCCBasedBTLPolicy) GetExpiringBlock(namespace string, collection string, committingBlock uint64) (uint64, error) {
    78  	btl, err := p.GetBTL(namespace, collection)
    79  	if err != nil {
    80  		return 0, err
    81  	}
    82  	return ComputeExpiringBlock(namespace, collection, committingBlock, btl), nil
    83  }
    84  
    85  func ComputeExpiringBlock(namespace, collection string, committingBlock, btl uint64) uint64 {
    86  	expiryBlk := committingBlock + btl + uint64(1)
    87  	if expiryBlk <= committingBlock { // committingBlk + btl overflows uint64-max
    88  		expiryBlk = math.MaxUint64
    89  	}
    90  	return expiryBlk
    91  }
    92  
    93  type collectionInfoProvider interface {
    94  	CollectionInfo(chaincodeName, collectionName string) (*peer.StaticCollectionConfig, error)
    95  }
    96  
    97  //go:generate counterfeiter -o mock/coll_info_provider.go -fake-name CollectionInfoProvider . collectionInfoProvider