github.com/kaituanwang/hyperledger@v2.0.1+incompatible/msp/cache/cache.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package cache 8 9 import ( 10 pmsp "github.com/hyperledger/fabric-protos-go/msp" 11 "github.com/hyperledger/fabric/common/flogging" 12 "github.com/hyperledger/fabric/msp" 13 "github.com/pkg/errors" 14 ) 15 16 const ( 17 deserializeIdentityCacheSize = 100 18 validateIdentityCacheSize = 100 19 satisfiesPrincipalCacheSize = 100 20 ) 21 22 var mspLogger = flogging.MustGetLogger("msp") 23 24 func New(o msp.MSP) (msp.MSP, error) { 25 mspLogger.Debugf("Creating Cache-MSP instance") 26 if o == nil { 27 return nil, errors.Errorf("Invalid passed MSP. It must be different from nil.") 28 } 29 30 theMsp := &cachedMSP{MSP: o} 31 theMsp.deserializeIdentityCache = newSecondChanceCache(deserializeIdentityCacheSize) 32 theMsp.satisfiesPrincipalCache = newSecondChanceCache(satisfiesPrincipalCacheSize) 33 theMsp.validateIdentityCache = newSecondChanceCache(validateIdentityCacheSize) 34 35 return theMsp, nil 36 } 37 38 type cachedMSP struct { 39 msp.MSP 40 41 // cache for DeserializeIdentity. 42 deserializeIdentityCache *secondChanceCache 43 44 // cache for validateIdentity 45 validateIdentityCache *secondChanceCache 46 47 // basically a map of principals=>identities=>stringified to booleans 48 // specifying whether this identity satisfies this principal 49 satisfiesPrincipalCache *secondChanceCache 50 } 51 52 type cachedIdentity struct { 53 msp.Identity 54 cache *cachedMSP 55 } 56 57 func (id *cachedIdentity) SatisfiesPrincipal(principal *pmsp.MSPPrincipal) error { 58 return id.cache.SatisfiesPrincipal(id.Identity, principal) 59 } 60 61 func (id *cachedIdentity) Validate() error { 62 return id.cache.Validate(id.Identity) 63 } 64 65 func (c *cachedMSP) DeserializeIdentity(serializedIdentity []byte) (msp.Identity, error) { 66 id, ok := c.deserializeIdentityCache.get(string(serializedIdentity)) 67 if ok { 68 return &cachedIdentity{ 69 cache: c, 70 Identity: id.(msp.Identity), 71 }, nil 72 } 73 74 id, err := c.MSP.DeserializeIdentity(serializedIdentity) 75 if err == nil { 76 c.deserializeIdentityCache.add(string(serializedIdentity), id) 77 return &cachedIdentity{ 78 cache: c, 79 Identity: id.(msp.Identity), 80 }, nil 81 } 82 return nil, err 83 } 84 85 func (c *cachedMSP) Setup(config *pmsp.MSPConfig) error { 86 c.cleanCache() 87 88 return c.MSP.Setup(config) 89 } 90 91 func (c *cachedMSP) Validate(id msp.Identity) error { 92 identifier := id.GetIdentifier() 93 key := string(identifier.Mspid + ":" + identifier.Id) 94 95 _, ok := c.validateIdentityCache.get(key) 96 if ok { 97 // cache only stores if the identity is valid. 98 return nil 99 } 100 101 err := c.MSP.Validate(id) 102 if err == nil { 103 c.validateIdentityCache.add(key, true) 104 } 105 106 return err 107 } 108 109 func (c *cachedMSP) SatisfiesPrincipal(id msp.Identity, principal *pmsp.MSPPrincipal) error { 110 identifier := id.GetIdentifier() 111 identityKey := string(identifier.Mspid + ":" + identifier.Id) 112 principalKey := string(principal.PrincipalClassification) + string(principal.Principal) 113 key := identityKey + principalKey 114 115 v, ok := c.satisfiesPrincipalCache.get(key) 116 if ok { 117 if v == nil { 118 return nil 119 } 120 121 return v.(error) 122 } 123 124 err := c.MSP.SatisfiesPrincipal(id, principal) 125 126 c.satisfiesPrincipalCache.add(key, err) 127 return err 128 } 129 130 func (c *cachedMSP) cleanCache() error { 131 c.deserializeIdentityCache = newSecondChanceCache(deserializeIdentityCacheSize) 132 c.satisfiesPrincipalCache = newSecondChanceCache(satisfiesPrincipalCacheSize) 133 c.validateIdentityCache = newSecondChanceCache(validateIdentityCacheSize) 134 135 return nil 136 }