func (a *ACS) inputValue(data []byte) error {
	rbc, ok := a.rbcInstances[a.ID]
	if !ok {
		return fmt.Errorf("could not find rbc instance (%d)", a.ID)
	}
	reqs, err := rbc.InputValue(data)
	if err != nil {
		return err
	}
	if len(reqs) != a.N-1 {
		return fmt.Errorf("expecting (%d) proof messages got (%d)", a.N, len(reqs))
	}
	for i, id := range uint64sWithout(a.Nodes, a.ID) {
		a.messageQue.addMessage(&ACSMessage{a.ID, reqs[i]}, id)
	}
	for _, msg := range rbc.Messages() {
		a.addMessage(a.ID, msg)
	}
	if output := rbc.Output(); output != nil {
		a.rbcResults[a.ID] = output
		a.processAgreement(a.ID, func(bba *BBA) error {
			if bba.AcceptInput() {
				return bba.InputValue(true)
			}
			return nil
		})
	}
	return nil
}
inputValue sets the input value for broadcast and returns an initial set of
Broadcast and ACS Messages to be broadcasted in the network.
package hbbft
import (
	"fmt"
)
type ACSMessage struct {
	ProposerID uint64
	Payload interface{}
}
type ACS struct {
	Config
	rbcInstances map[uint64]*RBC
	bbaInstances map[uint64]*BBA
	rbcResults map[uint64][]byte
	bbaResults map[uint64]bool
	output map[uint64][]byte
	messageQue *messageQue
	decided bool
	closeCh   chan struct{}
	inputCh   chan acsInputTuple
	messageCh chan acsMessageTuple
}
type (
	acsMessageTuple struct {
		senderID uint64
		msg      *ACSMessage
		err      chan error
	}
	acsInputResponse struct {
		rbcMessages []*BroadcastMessage
		acsMessages []*ACSMessage
		err         error
	}
	acsInputTuple struct {
		value    []byte
		response chan acsInputResponse
	}
)
func NewACS(cfg Config) *ACS {
	if cfg.F == 0 {
		cfg.F = (cfg.N - 1) / 3
	}
	acs := &ACS{
		Config:       cfg,
		rbcInstances: make(map[uint64]*RBC),
		bbaInstances: make(map[uint64]*BBA),
		rbcResults:   make(map[uint64][]byte),
		bbaResults:   make(map[uint64]bool),
		messageQue:   newMessageQue(),
		closeCh:      make(chan struct{}),
		inputCh:      make(chan acsInputTuple),
		messageCh:    make(chan acsMessageTuple),
	}
	for _, id := range cfg.Nodes {
		acs.rbcInstances[id] = NewRBC(cfg, id)
		acs.bbaInstances[id] = NewBBA(cfg)
	}
	go acs.run()
	return acs
}
func (a *ACS) InputValue(val []byte) error {
	t := acsInputTuple{
		value:    val,
		response: make(chan acsInputResponse),
	}
	a.inputCh <- t
	resp := <-t.response
	return resp.err
}
func (a *ACS) HandleMessage(senderID uint64, msg *ACSMessage) error {
	t := acsMessageTuple{
		senderID: senderID,
		msg:      msg,
		err:      make(chan error),
	}
	a.messageCh <- t
	return <-t.err
}
func (a *ACS) handleMessage(senderID uint64, msg *ACSMessage) error {
	switch t := msg.Payload.(type) {
	case *AgreementMessage:
		return a.handleAgreement(senderID, msg.ProposerID, t)
	case *BroadcastMessage:
		return a.handleBroadcast(senderID, msg.ProposerID, t)
	default:
		return fmt.Errorf("received unknown message (%v)", t)
	}
}
func (a *ACS) Output() map[uint64][]byte {
	if a.output != nil {
		out := a.output
		a.output = nil
		return out
	}
	return nil
}
func (a *ACS) Done() bool {
	agreementsDone := true
	for _, bba := range a.bbaInstances {
		if !bba.done {
			agreementsDone = false
		}
	}
	return agreementsDone && a.messageQue.len() == 0
}