github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/orderer/common/msgprocessor/configupdate/configupdate.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  // Package configupdate is an implementation of the broadcast.Proccessor interface
     8  // It facilitates the preprocessing of CONFIG_UPDATE transactions which can
     9  // generate either new CONFIG transactions or new channel creation
    10  // ORDERER_TRANSACTION messages.
    11  package configupdate
    12  
    13  import (
    14  	"fmt"
    15  
    16  	configtxapi "github.com/hyperledger/fabric/common/configtx/api"
    17  	"github.com/hyperledger/fabric/common/crypto"
    18  	cb "github.com/hyperledger/fabric/protos/common"
    19  	"github.com/hyperledger/fabric/protos/utils"
    20  
    21  	"github.com/op/go-logging"
    22  )
    23  
    24  var logger = logging.MustGetLogger("orderer/configupdate")
    25  
    26  const (
    27  	// These should eventually be derived from the channel support once enabled
    28  	msgVersion = int32(0)
    29  	epoch      = 0
    30  )
    31  
    32  // SupportManager provides a way for the Handler to look up the Support for a chain
    33  type SupportManager interface {
    34  	// GetChain gets the chain support for a given ChannelId
    35  	GetChain(chainID string) (Support, bool)
    36  
    37  	// NewChannelConfig returns a bare bones configuration ready for channel
    38  	// creation request to be applied on top of it
    39  	NewChannelConfig(envConfigUpdate *cb.Envelope) (configtxapi.Manager, error)
    40  }
    41  
    42  // Support enumerates a subset of the full channel support function which is required for this package
    43  type Support interface {
    44  	// ProposeConfigUpdate applies a CONFIG_UPDATE to an existing config to produce a *cb.ConfigEnvelope
    45  	ProposeConfigUpdate(env *cb.Envelope) (*cb.ConfigEnvelope, error)
    46  }
    47  
    48  // Processor implements the broadcast.ConfigProcessor interface.
    49  type Processor struct {
    50  	signer               crypto.LocalSigner
    51  	manager              SupportManager
    52  	systemChannelID      string
    53  	systemChannelSupport Support
    54  }
    55  
    56  // New creates a new instance of *Processor.
    57  func New(systemChannelID string, supportManager SupportManager, signer crypto.LocalSigner) *Processor {
    58  	support, ok := supportManager.GetChain(systemChannelID)
    59  	if !ok {
    60  		logger.Panicf("Supplied a SupportManager which did not contain a system channel")
    61  	}
    62  
    63  	return &Processor{
    64  		systemChannelID:      systemChannelID,
    65  		manager:              supportManager,
    66  		signer:               signer,
    67  		systemChannelSupport: support,
    68  	}
    69  }
    70  
    71  func channelID(env *cb.Envelope) (string, error) {
    72  	envPayload, err := utils.UnmarshalPayload(env.Payload)
    73  	if err != nil {
    74  		return "", fmt.Errorf("Failing to process config update because of payload unmarshaling error: %s", err)
    75  	}
    76  
    77  	if envPayload.Header == nil /* || envPayload.Header.ChannelHeader == nil */ {
    78  		return "", fmt.Errorf("Failing to process config update because no payload header was set")
    79  	}
    80  
    81  	chdr, err := utils.UnmarshalChannelHeader(envPayload.Header.ChannelHeader)
    82  	if err != nil {
    83  		return "", fmt.Errorf("Failing to process config update because of channel header unmarshaling error: %s", err)
    84  	}
    85  
    86  	if chdr.ChannelId == "" {
    87  		return "", fmt.Errorf("Failing to process config update because no channel ID was set")
    88  	}
    89  
    90  	return chdr.ChannelId, nil
    91  }
    92  
    93  // Process takes in an envelope of type CONFIG_UPDATE and proceses it
    94  // to transform it either into to a new channel creation request, or
    95  // into a channel CONFIG transaction (or errors on failure)
    96  func (p *Processor) Process(envConfigUpdate *cb.Envelope) (*cb.Envelope, error) {
    97  	channelID, err := channelID(envConfigUpdate)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  
   102  	support, ok := p.manager.GetChain(channelID)
   103  	if ok {
   104  		logger.Debugf("Processing channel reconfiguration request for channel %s", channelID)
   105  		return p.existingChannelConfig(envConfigUpdate, channelID, support)
   106  	}
   107  
   108  	logger.Debugf("Processing channel creation request for channel %s", channelID)
   109  	return p.newChannelConfig(channelID, envConfigUpdate)
   110  }
   111  
   112  func (p *Processor) existingChannelConfig(envConfigUpdate *cb.Envelope, channelID string, support Support) (*cb.Envelope, error) {
   113  	configEnvelope, err := support.ProposeConfigUpdate(envConfigUpdate)
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  
   118  	return utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID, p.signer, configEnvelope, msgVersion, epoch)
   119  }
   120  
   121  func (p *Processor) proposeNewChannelToSystemChannel(newChannelEnvConfig *cb.Envelope) (*cb.Envelope, error) {
   122  	return utils.CreateSignedEnvelope(cb.HeaderType_ORDERER_TRANSACTION, p.systemChannelID, p.signer, newChannelEnvConfig, msgVersion, epoch)
   123  }
   124  
   125  func (p *Processor) newChannelConfig(channelID string, envConfigUpdate *cb.Envelope) (*cb.Envelope, error) {
   126  	ctxm, err := p.manager.NewChannelConfig(envConfigUpdate)
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	newChannelConfigEnv, err := ctxm.ProposeConfigUpdate(envConfigUpdate)
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  
   136  	newChannelEnvConfig, err := utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, channelID, p.signer, newChannelConfigEnv, msgVersion, epoch)
   137  	if err != nil {
   138  		return nil, err
   139  	}
   140  
   141  	return p.proposeNewChannelToSystemChannel(newChannelEnvConfig)
   142  }