github.com/true-sqn/fabric@v2.1.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  }