github.com/anjalikarhana/fabric@v2.1.1+incompatible/orderer/common/msgprocessor/standardchannel.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package msgprocessor
     8  
     9  import (
    10  	cb "github.com/hyperledger/fabric-protos-go/common"
    11  	"github.com/hyperledger/fabric-protos-go/orderer"
    12  	"github.com/hyperledger/fabric/bccsp"
    13  	"github.com/hyperledger/fabric/common/channelconfig"
    14  	"github.com/hyperledger/fabric/common/policies"
    15  	"github.com/hyperledger/fabric/internal/pkg/identity"
    16  	"github.com/hyperledger/fabric/protoutil"
    17  
    18  	"github.com/hyperledger/fabric/orderer/common/localconfig"
    19  	"github.com/pkg/errors"
    20  )
    21  
    22  //go:generate counterfeiter -o mocks/signer_serializer.go --fake-name SignerSerializer . signerSerializer
    23  
    24  type signerSerializer interface {
    25  	identity.SignerSerializer
    26  }
    27  
    28  // StandardChannelSupport includes the resources needed for the StandardChannel processor.
    29  type StandardChannelSupport interface {
    30  	// Sequence should return the current configSeq
    31  	Sequence() uint64
    32  
    33  	// ChannelID returns the ChannelID
    34  	ChannelID() string
    35  
    36  	// Signer returns the signer for this orderer
    37  	Signer() identity.SignerSerializer
    38  
    39  	// ProposeConfigUpdate takes in an Envelope of type CONFIG_UPDATE and produces a
    40  	// ConfigEnvelope to be used as the Envelope Payload Data of a CONFIG message
    41  	ProposeConfigUpdate(configtx *cb.Envelope) (*cb.ConfigEnvelope, error)
    42  
    43  	OrdererConfig() (channelconfig.Orderer, bool)
    44  }
    45  
    46  // StandardChannel implements the Processor interface for standard extant channels
    47  type StandardChannel struct {
    48  	support           StandardChannelSupport
    49  	filters           *RuleSet // Rules applicable to both normal and config messages
    50  	maintenanceFilter Rule     // Rule applicable only to config messages
    51  }
    52  
    53  // NewStandardChannel creates a new standard message processor
    54  func NewStandardChannel(support StandardChannelSupport, filters *RuleSet, bccsp bccsp.BCCSP) *StandardChannel {
    55  	return &StandardChannel{
    56  		filters:           filters,
    57  		support:           support,
    58  		maintenanceFilter: NewMaintenanceFilter(support, bccsp),
    59  	}
    60  }
    61  
    62  // CreateStandardChannelFilters creates the set of filters for a normal (non-system) chain.
    63  //
    64  // In maintenance mode, require the signature of /Channel/Orderer/Writer. This will filter out configuration
    65  // changes that are not related to consensus-type migration (e.g on /Channel/Application).
    66  func CreateStandardChannelFilters(filterSupport channelconfig.Resources, config localconfig.TopLevel) *RuleSet {
    67  	rules := []Rule{
    68  		EmptyRejectRule,
    69  		NewSizeFilter(filterSupport),
    70  		NewSigFilter(policies.ChannelWriters, policies.ChannelOrdererWriters, filterSupport),
    71  	}
    72  
    73  	if !config.General.Authentication.NoExpirationChecks {
    74  		expirationRule := NewExpirationRejectRule(filterSupport)
    75  		// In case of DoS, expiration is inserted before SigFilter, so it is evaluated first
    76  		rules = append(rules[:2], append([]Rule{expirationRule}, rules[2:]...)...)
    77  	}
    78  
    79  	return NewRuleSet(rules)
    80  }
    81  
    82  // ClassifyMsg inspects the message to determine which type of processing is necessary
    83  func (s *StandardChannel) ClassifyMsg(chdr *cb.ChannelHeader) Classification {
    84  	switch chdr.Type {
    85  	case int32(cb.HeaderType_CONFIG_UPDATE):
    86  		return ConfigUpdateMsg
    87  	case int32(cb.HeaderType_ORDERER_TRANSACTION):
    88  		// In order to maintain backwards compatibility, we must classify these messages
    89  		return ConfigMsg
    90  	case int32(cb.HeaderType_CONFIG):
    91  		// In order to maintain backwards compatibility, we must classify these messages
    92  		return ConfigMsg
    93  	default:
    94  		return NormalMsg
    95  	}
    96  }
    97  
    98  // ProcessNormalMsg will check the validity of a message based on the current configuration.  It returns the current
    99  // configuration sequence number and nil on success, or an error if the message is not valid
   100  func (s *StandardChannel) ProcessNormalMsg(env *cb.Envelope) (configSeq uint64, err error) {
   101  	oc, ok := s.support.OrdererConfig()
   102  	if !ok {
   103  		logger.Panicf("Missing orderer config")
   104  	}
   105  	if oc.Capabilities().ConsensusTypeMigration() {
   106  		if oc.ConsensusState() != orderer.ConsensusType_STATE_NORMAL {
   107  			return 0, errors.WithMessage(
   108  				ErrMaintenanceMode, "normal transactions are rejected")
   109  		}
   110  	}
   111  
   112  	configSeq = s.support.Sequence()
   113  	err = s.filters.Apply(env)
   114  	return
   115  }
   116  
   117  // ProcessConfigUpdateMsg will attempt to apply the config impetus msg to the current configuration, and if successful
   118  // return the resulting config message and the configSeq the config was computed from.  If the config impetus message
   119  // is invalid, an error is returned.
   120  func (s *StandardChannel) ProcessConfigUpdateMsg(env *cb.Envelope) (config *cb.Envelope, configSeq uint64, err error) {
   121  	logger.Debugf("Processing config update message for exisitng channel %s", s.support.ChannelID())
   122  
   123  	// Call Sequence first.  If seq advances between proposal and acceptance, this is okay, and will cause reprocessing
   124  	// however, if Sequence is called last, then a success could be falsely attributed to a newer configSeq
   125  	seq := s.support.Sequence()
   126  	err = s.filters.Apply(env)
   127  	if err != nil {
   128  		return nil, 0, errors.WithMessage(err, "config update for existing channel did not pass initial checks")
   129  	}
   130  
   131  	configEnvelope, err := s.support.ProposeConfigUpdate(env)
   132  	if err != nil {
   133  		return nil, 0, errors.WithMessagef(err, "error applying config update to existing channel '%s'", s.support.ChannelID())
   134  	}
   135  
   136  	config, err = protoutil.CreateSignedEnvelope(cb.HeaderType_CONFIG, s.support.ChannelID(), s.support.Signer(), configEnvelope, msgVersion, epoch)
   137  	if err != nil {
   138  		return nil, 0, err
   139  	}
   140  
   141  	// We re-apply the filters here, especially for the size filter, to ensure that the transaction we
   142  	// just constructed is not too large for our consenter.  It additionally reapplies the signature
   143  	// check, which although not strictly necessary, is a good sanity check, in case the orderer
   144  	// has not been configured with the right cert material.  The additional overhead of the signature
   145  	// check is negligible, as this is the reconfig path and not the normal path.
   146  	err = s.filters.Apply(config)
   147  	if err != nil {
   148  		return nil, 0, errors.WithMessage(err, "config update for existing channel did not pass final checks")
   149  	}
   150  
   151  	err = s.maintenanceFilter.Apply(config)
   152  	if err != nil {
   153  		return nil, 0, errors.WithMessage(err, "config update for existing channel did not pass maintenance checks")
   154  	}
   155  
   156  	return config, seq, nil
   157  }
   158  
   159  // ProcessConfigMsg takes an envelope of type `HeaderType_CONFIG`, unpacks the `ConfigEnvelope` from it
   160  // extracts the `ConfigUpdate` from `LastUpdate` field, and calls `ProcessConfigUpdateMsg` on it.
   161  func (s *StandardChannel) ProcessConfigMsg(env *cb.Envelope) (config *cb.Envelope, configSeq uint64, err error) {
   162  	logger.Debugf("Processing config message for channel %s", s.support.ChannelID())
   163  
   164  	configEnvelope := &cb.ConfigEnvelope{}
   165  	_, err = protoutil.UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, configEnvelope)
   166  	if err != nil {
   167  		return
   168  	}
   169  
   170  	return s.ProcessConfigUpdateMsg(configEnvelope.LastUpdate)
   171  }