github.com/yimialmonte/fabric@v2.1.1+incompatible/core/peer/channel.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package peer
     8  
     9  import (
    10  	"sync"
    11  
    12  	"github.com/hyperledger/fabric-protos-go/common"
    13  	"github.com/hyperledger/fabric/bccsp"
    14  	"github.com/hyperledger/fabric/common/channelconfig"
    15  	"github.com/hyperledger/fabric/common/ledger/blockledger"
    16  	"github.com/hyperledger/fabric/common/ledger/blockledger/fileledger"
    17  	"github.com/hyperledger/fabric/common/policies"
    18  	"github.com/hyperledger/fabric/core/ledger"
    19  	"github.com/hyperledger/fabric/core/transientstore"
    20  	"github.com/hyperledger/fabric/msp"
    21  )
    22  
    23  // Channel manages objects and configuration associated with a Channel.
    24  type Channel struct {
    25  	ledger         ledger.PeerLedger
    26  	store          *transientstore.Store
    27  	cryptoProvider bccsp.BCCSP
    28  
    29  	// applyLock is used to serialize calls to Apply and bundle update processing.
    30  	applyLock sync.Mutex
    31  	// bundleSource is used to validate and apply channel configuration updates.
    32  	// This should not be used for retrieving resources.
    33  	bundleSource *channelconfig.BundleSource
    34  
    35  	// lock is used to serialize access to resources
    36  	lock sync.RWMutex
    37  	// resources is used to acquire configuration bundle resources. The reference
    38  	// is maintained by callbacks from the bundleSource.
    39  	resources channelconfig.Resources
    40  }
    41  
    42  // Apply is used to validate and apply configuration transactions for a channel.
    43  func (c *Channel) Apply(configtx *common.ConfigEnvelope) error {
    44  	c.applyLock.Lock()
    45  	defer c.applyLock.Unlock()
    46  
    47  	configTxValidator := c.Resources().ConfigtxValidator()
    48  	err := configTxValidator.Validate(configtx)
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	bundle, err := channelconfig.NewBundle(configTxValidator.ChannelID(), configtx.Config, c.cryptoProvider)
    54  	if err != nil {
    55  		return err
    56  	}
    57  
    58  	channelconfig.LogSanityChecks(bundle)
    59  	err = c.bundleSource.ValidateNew(bundle)
    60  	if err != nil {
    61  		return err
    62  	}
    63  
    64  	capabilitiesSupportedOrPanic(bundle)
    65  
    66  	c.bundleSource.Update(bundle)
    67  	return nil
    68  }
    69  
    70  // bundleUpdate is called by the bundleSource when the channel configuration
    71  // changes.
    72  func (c *Channel) bundleUpdate(b *channelconfig.Bundle) {
    73  	c.lock.Lock()
    74  	c.resources = b
    75  	c.lock.Unlock()
    76  }
    77  
    78  // Resources returns the active channel configuration bundle.
    79  func (c *Channel) Resources() channelconfig.Resources {
    80  	c.lock.RLock()
    81  	res := c.resources
    82  	c.lock.RUnlock()
    83  	return res
    84  }
    85  
    86  // Sequence returns the current config sequence number of the channel.
    87  func (c *Channel) Sequence() uint64 {
    88  	return c.Resources().ConfigtxValidator().Sequence()
    89  }
    90  
    91  // PolicyManager returns the policies.Manager for the channel that reflects the
    92  // current channel configuration. Users should not memoize references to this object.
    93  func (c *Channel) PolicyManager() policies.Manager {
    94  	return c.Resources().PolicyManager()
    95  }
    96  
    97  // Capabilities gets the application capabilities for the current channel
    98  // configuration.
    99  func (c *Channel) Capabilities() channelconfig.ApplicationCapabilities {
   100  	ac, ok := c.Resources().ApplicationConfig()
   101  	if !ok {
   102  		return nil
   103  	}
   104  	return ac.Capabilities()
   105  }
   106  
   107  // GetMSPIDs retrieves the MSP IDs of the organziations in the current channel
   108  // configuration.
   109  func (c *Channel) GetMSPIDs() []string {
   110  	ac, ok := c.Resources().ApplicationConfig()
   111  	if !ok || ac.Organizations() == nil {
   112  		return nil
   113  	}
   114  
   115  	var mspIDs []string
   116  	for _, org := range ac.Organizations() {
   117  		mspIDs = append(mspIDs, org.MSPID())
   118  	}
   119  
   120  	return mspIDs
   121  }
   122  
   123  // MSPManager returns the msp.MSPManager that reflects the current channel
   124  // configuration. Users should not memoize references to this object.
   125  func (c *Channel) MSPManager() msp.MSPManager {
   126  	return c.Resources().MSPManager()
   127  }
   128  
   129  // Ledger returns the ledger associated with this channel.
   130  func (c *Channel) Ledger() ledger.PeerLedger {
   131  	return c.ledger
   132  }
   133  
   134  // Store returns the transient store associated with this channel.
   135  func (c *Channel) Store() *transientstore.Store {
   136  	return c.store
   137  }
   138  
   139  // Reader returns a blockledger.Reader backed by the ledger associated with
   140  // this channel.
   141  func (c *Channel) Reader() blockledger.Reader {
   142  	return fileledger.NewFileLedger(fileLedgerBlockStore{c.ledger})
   143  }
   144  
   145  // Errored returns a channel that can be used to determine if a backing
   146  // resource has errored. At this point in time, the peer does not have any
   147  // error conditions that lead to this function signaling that an error has
   148  // occurred.
   149  func (c *Channel) Errored() <-chan struct{} {
   150  	// If this is ever updated to return a real channel, the error message
   151  	// in deliver.go around this channel closing should be updated.
   152  	return nil
   153  }
   154  
   155  func capabilitiesSupportedOrPanic(res channelconfig.Resources) {
   156  	ac, ok := res.ApplicationConfig()
   157  	if !ok {
   158  		peerLogger.Panicf("[channel %s] does not have application config so is incompatible", res.ConfigtxValidator().ChannelID())
   159  	}
   160  
   161  	if err := ac.Capabilities().Supported(); err != nil {
   162  		peerLogger.Panicf("[channel %s] incompatible: %s", res.ConfigtxValidator().ChannelID(), err)
   163  	}
   164  
   165  	if err := res.ChannelConfig().Capabilities().Supported(); err != nil {
   166  		peerLogger.Panicf("[channel %s] incompatible: %s", res.ConfigtxValidator().ChannelID(), err)
   167  	}
   168  }