github.com/xiaqingdoc/fabric@v2.1.1+incompatible/orderer/mocks/common/blockcutter/blockcutter.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package blockcutter
     8  
     9  import (
    10  	"sync"
    11  
    12  	cb "github.com/hyperledger/fabric-protos-go/common"
    13  	"github.com/hyperledger/fabric/common/flogging"
    14  )
    15  
    16  var logger = flogging.MustGetLogger("orderer.mocks.common.blockcutter")
    17  
    18  // Receiver mocks the blockcutter.Receiver interface
    19  type Receiver struct {
    20  	// IsolatedTx causes Ordered returns [][]{curBatch, []{newTx}}, false when set to true
    21  	IsolatedTx bool
    22  
    23  	// CutAncestors causes Ordered returns [][]{curBatch}, true when set to true
    24  	CutAncestors bool
    25  
    26  	// CutNext causes Ordered returns [][]{append(curBatch, newTx)}, false when set to true
    27  	CutNext bool
    28  
    29  	// SkipAppendCurBatch causes Ordered to skip appending to curBatch
    30  	SkipAppendCurBatch bool
    31  
    32  	// Lock to serialize writes access to curBatch
    33  	mutex sync.Mutex
    34  
    35  	// curBatch is the currently outstanding messages in the batch
    36  	curBatch []*cb.Envelope
    37  
    38  	// Block is a channel which is read from before returning from Ordered, it is useful for synchronization
    39  	// If you do not wish synchronization for whatever reason, simply close the channel
    40  	Block chan struct{}
    41  }
    42  
    43  // NewReceiver returns the mock blockcutter.Receiver implementation
    44  func NewReceiver() *Receiver {
    45  	return &Receiver{
    46  		IsolatedTx:   false,
    47  		CutAncestors: false,
    48  		CutNext:      false,
    49  		Block:        make(chan struct{}),
    50  	}
    51  }
    52  
    53  // Ordered will add or cut the batch according to the state of Receiver, it blocks reading from Block on return
    54  func (mbc *Receiver) Ordered(env *cb.Envelope) ([][]*cb.Envelope, bool) {
    55  	defer func() {
    56  		<-mbc.Block
    57  	}()
    58  
    59  	mbc.mutex.Lock()
    60  	defer mbc.mutex.Unlock()
    61  
    62  	if mbc.IsolatedTx {
    63  		logger.Debugf("Receiver: Returning dual batch")
    64  		res := [][]*cb.Envelope{mbc.curBatch, {env}}
    65  		mbc.curBatch = nil
    66  		return res, false
    67  	}
    68  
    69  	if mbc.CutAncestors {
    70  		logger.Debugf("Receiver: Returning current batch and appending newest env")
    71  		res := [][]*cb.Envelope{mbc.curBatch}
    72  		mbc.curBatch = []*cb.Envelope{env}
    73  		return res, true
    74  	}
    75  
    76  	if !mbc.SkipAppendCurBatch {
    77  		mbc.curBatch = append(mbc.curBatch, env)
    78  	}
    79  
    80  	if mbc.CutNext {
    81  		logger.Debugf("Receiver: Returning regular batch")
    82  		res := [][]*cb.Envelope{mbc.curBatch}
    83  		mbc.curBatch = nil
    84  		return res, false
    85  	}
    86  
    87  	logger.Debugf("Appending to batch")
    88  	return nil, true
    89  }
    90  
    91  // Cut terminates the current batch, returning it
    92  func (mbc *Receiver) Cut() []*cb.Envelope {
    93  	mbc.mutex.Lock()
    94  	defer mbc.mutex.Unlock()
    95  	logger.Debugf("Cutting batch")
    96  	res := mbc.curBatch
    97  	mbc.curBatch = nil
    98  	return res
    99  }
   100  
   101  func (mbc *Receiver) CurBatch() []*cb.Envelope {
   102  	mbc.mutex.Lock()
   103  	defer mbc.mutex.Unlock()
   104  	return mbc.curBatch
   105  }