github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/orderer/mocks/blockcutter/blockcutter.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package mocks
    18  
    19  import (
    20  	"github.com/hyperledger/fabric/orderer/common/filter"
    21  	cb "github.com/hyperledger/fabric/protos/common"
    22  )
    23  
    24  import (
    25  	"github.com/op/go-logging"
    26  )
    27  
    28  var logger = logging.MustGetLogger("orderer/mocks/blockcutter")
    29  
    30  // Receiver mocks the blockcutter.Receiver interface
    31  type Receiver struct {
    32  	// QueueNext causes Ordered returns nil false when not set to true
    33  	QueueNext bool
    34  
    35  	// IsolatedTx causes Ordered returns [][]{curBatch, []{newTx}}, true when set to true
    36  	IsolatedTx bool
    37  
    38  	// CutNext causes Ordered returns [][]{append(curBatch, newTx)}, true when set to true
    39  	CutNext bool
    40  
    41  	// CurBatch is the currently outstanding messages in the batch
    42  	CurBatch []*cb.Envelope
    43  
    44  	// Block is a channel which is read from before returning from Ordered, it is useful for synchronization
    45  	// If you do not wish synchronization for whatever reason, simply close the channel
    46  	Block chan struct{}
    47  }
    48  
    49  // NewReceiver returns the mock blockcutter.Receiver implemenation
    50  func NewReceiver() *Receiver {
    51  	return &Receiver{
    52  		QueueNext:  true,
    53  		IsolatedTx: false,
    54  		CutNext:    false,
    55  		Block:      make(chan struct{}),
    56  	}
    57  }
    58  
    59  func noopCommitters(size int) []filter.Committer {
    60  	res := make([]filter.Committer, size)
    61  	for i := range res {
    62  		res[i] = filter.NoopCommitter
    63  	}
    64  	return res
    65  }
    66  
    67  // Ordered will add or cut the batch according to the state of Receiver, it blocks reading from Block on return
    68  func (mbc *Receiver) Ordered(env *cb.Envelope) ([][]*cb.Envelope, [][]filter.Committer, bool) {
    69  	defer func() {
    70  		<-mbc.Block
    71  	}()
    72  
    73  	if !mbc.QueueNext {
    74  		logger.Debugf("Not queueing message")
    75  		return nil, nil, false
    76  	}
    77  
    78  	if mbc.IsolatedTx {
    79  		logger.Debugf("Receiver: Returning dual batch")
    80  		res := [][]*cb.Envelope{mbc.CurBatch, []*cb.Envelope{env}}
    81  		mbc.CurBatch = nil
    82  		return res, [][]filter.Committer{noopCommitters(len(res[0])), noopCommitters(len(res[1]))}, true
    83  	}
    84  
    85  	mbc.CurBatch = append(mbc.CurBatch, env)
    86  
    87  	if mbc.CutNext {
    88  		logger.Debugf("Returning regular batch")
    89  		res := [][]*cb.Envelope{mbc.CurBatch}
    90  		mbc.CurBatch = nil
    91  		return res, [][]filter.Committer{noopCommitters(len(res))}, true
    92  	}
    93  
    94  	logger.Debugf("Appending to batch")
    95  	return nil, nil, true
    96  }
    97  
    98  // Cut terminates the current batch, returning it
    99  func (mbc *Receiver) Cut() ([]*cb.Envelope, []filter.Committer) {
   100  	logger.Debugf("Cutting batch")
   101  	res := mbc.CurBatch
   102  	mbc.CurBatch = nil
   103  	return res, noopCommitters(len(res))
   104  }