func (et *epochTarget) constructNewEpoch(newLeaders []uint64, nc *msgs.NetworkState_Config) *msgs.NewEpoch {
	assertGreaterThanOrEqualf(uint64(len(et.strongChanges)), uint64(intersectionQuorum(nc)),
		"received %d acked epoch change messages, only received %d",
		uint64(len(et.strongChanges)), uint64(intersectionQuorum(nc)))
	newConfig := constructNewEpochConfig(nc, newLeaders, et.strongChanges)
	if newConfig == nil {
		return nil
	}
	remoteChanges := make([]*msgs.NewEpoch_RemoteEpochChange, 0, len(et.changes))
	for _, id := range et.networkConfig.Nodes {
		_, ok := et.strongChanges[nodeID(id)]
		if !ok {
			continue
		}
		remoteChanges = append(remoteChanges, &msgs.NewEpoch_RemoteEpochChange{
			NodeId: uint64(id),
			Digest: et.changes[nodeID(id)].strongCert,
		})
	}
	return &msgs.NewEpoch{
		NewConfig:    newConfig,
		EpochChanges: remoteChanges,
	}
}
Constructs and returns a NewEpoch message.
This message consists of the configuration for the new epoch
and a set of digests of acked EpochChange messages.
Note specifically that this NewEpoch message does not contain the payload of the EpochChange messages.
The recipient receives those directly from other nodes.
package legacy_statemachine
import (
	"bytes"
	"fmt"
	"github.com/hyperledger-labs/mirbft/pkg/logger"
	"sort"
	"github.com/hyperledger-labs/mirbft/pkg/pb/msgs"
	"github.com/hyperledger-labs/mirbft/pkg/pb/state"
	"github.com/hyperledger-labs/mirbft/pkg/status"
	"google.golang.org/protobuf/proto"
)
type epochTargetState int
const (
	etPrepending = iota  
	etPending            
	etVerifying          
	etFetching           
	etEchoing            
	etReadying           
	etResuming           
	etReady              
	etInProgress         
	etEnding             
	etDone               
)
type epochTarget struct {
	state           epochTargetState
	commitState     *commitState
	stateTicks      uint64
	number          uint64
	startingSeqNo   uint64
	changes         map[nodeID]*epochChange
	strongChanges   map[nodeID]*parsedEpochChange  
	echos           map[*msgs.NewEpochConfig]map[nodeID]struct{}
	readies         map[*msgs.NewEpochConfig]map[nodeID]struct{}
	activeEpoch     *activeEpoch
	suspicions      map[nodeID]struct{}
	myNewEpoch      *msgs.NewEpoch  
	myEpochChange   *parsedEpochChange
	myLeaderChoice  []uint64              
	leaderNewEpoch  *msgs.NewEpoch        
	networkNewEpoch *msgs.NewEpochConfig  
	isPrimary       bool
	prestartBuffers map[nodeID]*msgBuffer
	persisted              *persisted
	nodeBuffers            *nodeBuffers
	clientTracker          *clientTracker
	clientHashDisseminator *clientHashDisseminator
	batchTracker           *batchTracker
	networkConfig          *msgs.NetworkState_Config
	myConfig               *state.EventInitialParameters
	logger                 logging.Logger
}
func newEpochTarget(
	number uint64,
	persisted *persisted,
	nodeBuffers *nodeBuffers,
	commitState *commitState,
	clientTracker *clientTracker,
	clientHashDisseminator *clientHashDisseminator,
	batchTracker *batchTracker,
	networkConfig *msgs.NetworkState_Config,
	myConfig *state.EventInitialParameters,
	logger logging.Logger,
) *epochTarget {
	prestartBuffers := map[nodeID]*msgBuffer{}
	for _, id := range networkConfig.Nodes {
		prestartBuffers[nodeID(id)] = newMsgBuffer(
			fmt.Sprintf("epoch-%d-prestart", number),
			nodeBuffers.nodeBuffer(nodeID(id)),
		)
	}
	return &epochTarget{
		state:                  etPrepending,
		number:                 number,
		commitState:            commitState,
		suspicions:             map[nodeID]struct{}{},
		changes:                map[nodeID]*epochChange{},
		strongChanges:          map[nodeID]*parsedEpochChange{},
		echos:                  map[*msgs.NewEpochConfig]map[nodeID]struct{}{},
		readies:                map[*msgs.NewEpochConfig]map[nodeID]struct{}{},
		isPrimary:              number%uint64(len(networkConfig.Nodes)) == myConfig.Id,
		prestartBuffers:        prestartBuffers,
		persisted:              persisted,
		nodeBuffers:            nodeBuffers,
		clientTracker:          clientTracker,
		clientHashDisseminator: clientHashDisseminator,
		batchTracker:           batchTracker,
		networkConfig:          networkConfig,
		myConfig:               myConfig,
		logger:                 logger,
	}
}
func (et *epochTarget) step(source nodeID, msg *msgs.Msg) *ActionList {
	if et.state < etInProgress {
		et.prestartBuffers[source].store(msg)
		return &ActionList{}
	}
	if et.state == etDone {
		return &ActionList{}
	}
	return et.activeEpoch.step(source, msg)
}