github.com/defanghe/fabric@v2.1.1+incompatible/core/ledger/pvtdatapolicy/btlpolicy.go (about) 1 /* 2 Copyright IBM Corp. 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/hyperledger/fabric-protos-go/peer" 14 "github.com/hyperledger/fabric/core/common/privdata" 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(namesapce 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(namesapce string, collection string) (uint64, error) { 51 var btl uint64 52 var ok bool 53 key := btlkey{namesapce, 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(namesapce, collection) 59 if err != nil { 60 return 0, err 61 } 62 if collConfig == nil { 63 return 0, privdata.NoSuchCollectionError{Namespace: namesapce, 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(namesapce string, collection string, committingBlock uint64) (uint64, error) { 78 btl, err := p.GetBTL(namesapce, collection) 79 if err != nil { 80 return 0, err 81 } 82 expiryBlk := committingBlock + btl + uint64(1) 83 if expiryBlk <= committingBlock { // committingBlk + btl overflows uint64-max 84 expiryBlk = math.MaxUint64 85 } 86 return expiryBlk, nil 87 } 88 89 type collectionInfoProvider interface { 90 CollectionInfo(chaincodeName, collectionName string) (*peer.StaticCollectionConfig, error) 91 } 92 93 //go:generate counterfeiter -o mock/coll_info_provider.go -fake-name CollectionInfoProvider . collectionInfoProvider