func (r *RBC) Output() []byte {
	if r.output != nil {
		out := r.output
		r.output = nil
		return out
	}
	return nil
}
Output will return the output of the rbc instance. If the output was not nil
then it will return the output else nil. Note that after consuming the output
its will be set to nil forever.
package hbbft
import (
	"bytes"
	"crypto/sha256"
	"fmt"
	"sort"
	"github.com/NebulousLabs/merkletree"
	"github.com/klauspost/reedsolomon"
)
type BroadcastMessage struct {
	Payload interface{}
}
type ProofRequest struct {
	RootHash []byte
	Proof         [][]byte
	Index, Leaves int
}
type EchoRequest struct {
	ProofRequest
}
type ReadyRequest struct {
	RootHash []byte
}
type proofs []ProofRequest
func (p proofs) Len() int           { return len(p) }
func (p proofs) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
func (p proofs) Less(i, j int) bool { return p[i].Index < p[j].Index }
type RBC struct {
	Config
	proposerID uint64
	enc reedsolomon.Encoder
	recvReadys map[uint64][]byte
	recvEchos map[uint64]*EchoRequest
	numParityShards, numDataShards int
	messages []*BroadcastMessage
	echoSent, readySent, outputDecoded bool
	output []byte
	closeCh   chan struct{}
	inputCh   chan rbcInputTuple
	messageCh chan rbcMessageTuple
}
type (
	rbcMessageTuple struct {
		senderID uint64
		msg      *BroadcastMessage
		err      chan error
	}
	rbcInputResponse struct {
		messages []*BroadcastMessage
		err      error
	}
	rbcInputTuple struct {
		value    []byte
		response chan rbcInputResponse
	}
)
func NewRBC(cfg Config, proposerID uint64) *RBC {
	if cfg.F == 0 {
		cfg.F = (cfg.N - 1) / 3
	}
	var (
		parityShards = 2 * cfg.F
		dataShards   = cfg.N - parityShards
	)
	enc, err := reedsolomon.New(dataShards, parityShards)
	if err != nil {
		panic(err)
	}
	rbc := &RBC{
		Config:          cfg,
		recvEchos:       make(map[uint64]*EchoRequest),
		recvReadys:      make(map[uint64][]byte),
		enc:             enc,
		numParityShards: parityShards,
		numDataShards:   dataShards,
		messages:        []*BroadcastMessage{},
		proposerID:      proposerID,
		closeCh:         make(chan struct{}),
		inputCh:         make(chan rbcInputTuple),
		messageCh:       make(chan rbcMessageTuple),
	}
	go rbc.run()
	return rbc
}
func (r *RBC) InputValue(data []byte) ([]*BroadcastMessage, error) {
	t := rbcInputTuple{
		value:    data,
		response: make(chan rbcInputResponse),
	}
	r.inputCh <- t
	resp := <-t.response
	return resp.messages, resp.err
}
func (r *RBC) HandleMessage(senderID uint64, msg *BroadcastMessage) error {
	t := rbcMessageTuple{
		senderID: senderID,
		msg:      msg,
		err:      make(chan error),
	}
	r.messageCh <- t
	return <-t.err
}
func (r *RBC) stop() {
	close(r.closeCh)
}
func (r *RBC) run() {
	for {
		select {
		case <-r.closeCh:
			return
		case t := <-r.inputCh:
			msgs, err := r.inputValue(t.value)
			t.response <- rbcInputResponse{
				messages: msgs,
				err:      err,
			}
		case t := <-r.messageCh:
			t.err <- r.handleMessage(t.senderID, t.msg)
		}
	}
}
func (r *RBC) inputValue(data []byte) ([]*BroadcastMessage, error) {
	shards, err := makeShards(r.enc, data)
	if err != nil {
		return nil, err
	}
	reqs, err := makeBroadcastMessages(shards)
	if err != nil {
		return nil, err
	}
	proof := reqs[0].Payload.(*ProofRequest)
	if err := r.handleProofRequest(r.ID, proof); err != nil {
		return nil, err
	}
	return reqs[1:], nil
}
func (r *RBC) handleMessage(senderID uint64, msg *BroadcastMessage) error {
	switch t := msg.Payload.(type) {
	case *ProofRequest:
		return r.handleProofRequest(senderID, t)
	case *EchoRequest:
		return r.handleEchoRequest(senderID, t)
	case *ReadyRequest:
		return r.handleReadyRequest(senderID, t)
	default:
		return fmt.Errorf("invalid RBC protocol message: %+v", msg)
	}
}
func (r *RBC) Messages() []*BroadcastMessage {
	msgs := r.messages
	r.messages = []*BroadcastMessage{}
	return msgs
}