github.com/true-sqn/fabric@v2.1.1+incompatible/orderer/consensus/consensus.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package consensus
     8  
     9  import (
    10  	cb "github.com/hyperledger/fabric-protos-go/common"
    11  	"github.com/hyperledger/fabric/common/channelconfig"
    12  	"github.com/hyperledger/fabric/internal/pkg/identity"
    13  	"github.com/hyperledger/fabric/orderer/common/blockcutter"
    14  	"github.com/hyperledger/fabric/orderer/common/msgprocessor"
    15  	"github.com/hyperledger/fabric/protoutil"
    16  )
    17  
    18  // Consenter defines the backing ordering mechanism.
    19  type Consenter interface {
    20  	// HandleChain should create and return a reference to a Chain for the given set of resources.
    21  	// It will only be invoked for a given chain once per process.  In general, errors will be treated
    22  	// as irrecoverable and cause system shutdown.  See the description of Chain for more details
    23  	// The second argument to HandleChain is a pointer to the metadata stored on the `ORDERER` slot of
    24  	// the last block committed to the ledger of this Chain. For a new chain, or one which is migrated,
    25  	// this metadata will be nil (or contain a zero-length Value), as there is no prior metadata to report.
    26  	HandleChain(support ConsenterSupport, metadata *cb.Metadata) (Chain, error)
    27  }
    28  
    29  // MetadataValidator performs the validation of updates to ConsensusMetadata during config updates to the channel.
    30  // NOTE: We expect the MetadataValidator interface to be optionally implemented by the Consenter implementation.
    31  //       If a Consenter does not implement MetadataValidator, we default to using a no-op MetadataValidator.
    32  type MetadataValidator interface {
    33  	// ValidateConsensusMetadata determines the validity of a ConsensusMetadata update during config
    34  	// updates on the channel.
    35  	// Since the ConsensusMetadata is specific to the consensus implementation (independent of the particular
    36  	// chain) this validation also needs to be implemented by the specific consensus implementation.
    37  	ValidateConsensusMetadata(oldMetadata, newMetadata []byte, newChannel bool) error
    38  }
    39  
    40  // Chain defines a way to inject messages for ordering.
    41  // Note, that in order to allow flexibility in the implementation, it is the responsibility of the implementer
    42  // to take the ordered messages, send them through the blockcutter.Receiver supplied via HandleChain to cut blocks,
    43  // and ultimately write the ledger also supplied via HandleChain.  This design allows for two primary flows
    44  // 1. Messages are ordered into a stream, the stream is cut into blocks, the blocks are committed (solo, kafka)
    45  // 2. Messages are cut into blocks, the blocks are ordered, then the blocks are committed (sbft)
    46  type Chain interface {
    47  	// Order accepts a message which has been processed at a given configSeq.
    48  	// If the configSeq advances, it is the responsibility of the consenter
    49  	// to revalidate and potentially discard the message
    50  	// The consenter may return an error, indicating the message was not accepted
    51  	Order(env *cb.Envelope, configSeq uint64) error
    52  
    53  	// Configure accepts a message which reconfigures the channel and will
    54  	// trigger an update to the configSeq if committed.  The configuration must have
    55  	// been triggered by a ConfigUpdate message. If the config sequence advances,
    56  	// it is the responsibility of the consenter to recompute the resulting config,
    57  	// discarding the message if the reconfiguration is no longer valid.
    58  	// The consenter may return an error, indicating the message was not accepted
    59  	Configure(config *cb.Envelope, configSeq uint64) error
    60  
    61  	// WaitReady blocks waiting for consenter to be ready for accepting new messages.
    62  	// This is useful when consenter needs to temporarily block ingress messages so
    63  	// that in-flight messages can be consumed. It could return error if consenter is
    64  	// in erroneous states. If this blocking behavior is not desired, consenter could
    65  	// simply return nil.
    66  	WaitReady() error
    67  
    68  	// Errored returns a channel which will close when an error has occurred.
    69  	// This is especially useful for the Deliver client, who must terminate waiting
    70  	// clients when the consenter is not up to date.
    71  	Errored() <-chan struct{}
    72  
    73  	// Start should allocate whatever resources are needed for staying up to date with the chain.
    74  	// Typically, this involves creating a thread which reads from the ordering source, passes those
    75  	// messages to a block cutter, and writes the resulting blocks to the ledger.
    76  	Start()
    77  
    78  	// Halt frees the resources which were allocated for this Chain.
    79  	Halt()
    80  }
    81  
    82  //go:generate counterfeiter -o mocks/mock_consenter_support.go . ConsenterSupport
    83  
    84  // ConsenterSupport provides the resources available to a Consenter implementation.
    85  type ConsenterSupport interface {
    86  	identity.SignerSerializer
    87  	msgprocessor.Processor
    88  
    89  	// VerifyBlockSignature verifies a signature of a block with a given optional
    90  	// configuration (can be nil).
    91  	VerifyBlockSignature([]*protoutil.SignedData, *cb.ConfigEnvelope) error
    92  
    93  	// BlockCutter returns the block cutting helper for this channel.
    94  	BlockCutter() blockcutter.Receiver
    95  
    96  	// SharedConfig provides the shared config from the channel's current config block.
    97  	SharedConfig() channelconfig.Orderer
    98  
    99  	// ChannelConfig provides the channel config from the channel's current config block.
   100  	ChannelConfig() channelconfig.Channel
   101  
   102  	// CreateNextBlock takes a list of messages and creates the next block based on the block with highest block number committed to the ledger
   103  	// Note that either WriteBlock or WriteConfigBlock must be called before invoking this method a second time.
   104  	CreateNextBlock(messages []*cb.Envelope) *cb.Block
   105  
   106  	// Block returns a block with the given number,
   107  	// or nil if such a block doesn't exist.
   108  	Block(number uint64) *cb.Block
   109  
   110  	// WriteBlock commits a block to the ledger.
   111  	WriteBlock(block *cb.Block, encodedMetadataValue []byte)
   112  
   113  	// WriteConfigBlock commits a block to the ledger, and applies the config update inside.
   114  	WriteConfigBlock(block *cb.Block, encodedMetadataValue []byte)
   115  
   116  	// Sequence returns the current config sequence.
   117  	Sequence() uint64
   118  
   119  	// ChannelID returns the channel ID this support is associated with.
   120  	ChannelID() string
   121  
   122  	// Height returns the number of blocks in the chain this channel is associated with.
   123  	Height() uint64
   124  
   125  	// Append appends a new block to the ledger in its raw form,
   126  	// unlike WriteBlock that also mutates its metadata.
   127  	Append(block *cb.Block) error
   128  }
   129  
   130  // NoOpMetadataValidator implements a MetadataValidator that always returns nil error irrespecttive of the inputs.
   131  type NoOpMetadataValidator struct {
   132  }
   133  
   134  // ValidateConsensusMetadata determines the validity of a ConsensusMetadata update during config updates
   135  // on the channel, and it always returns nil error for the NoOpMetadataValidator implementation.
   136  func (n NoOpMetadataValidator) ValidateConsensusMetadata(oldMetadataBytes, newMetadataBytes []byte, newChannel bool) error {
   137  	return nil
   138  }