github.com/koko1123/flow-go-1@v0.29.6/model/flow/factory/cluster_list.go (about)

     1  package factory
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/koko1123/flow-go-1/model/flow"
     7  	"github.com/koko1123/flow-go-1/model/flow/order"
     8  )
     9  
    10  // NewClusterList creates a new cluster list based on the given cluster assignment
    11  // and the provided list of identities.
    12  // The caller must ensure each assignment contains identities ordered in canonical order, so that
    13  // each cluster in the returned cluster list is ordered in canonical order as well. If not,
    14  // an error will be returned.
    15  func NewClusterList(assignments flow.AssignmentList, collectors flow.IdentityList) (flow.ClusterList, error) {
    16  
    17  	// build a lookup for all the identities by node identifier
    18  	lookup := make(map[flow.Identifier]*flow.Identity)
    19  	for _, collector := range collectors {
    20  		lookup[collector.NodeID] = collector
    21  	}
    22  	if len(lookup) != len(collectors) {
    23  		return nil, fmt.Errorf("duplicate collector in list")
    24  	}
    25  
    26  	// replicate the identifier list but use identities instead
    27  	clusters := make(flow.ClusterList, 0, len(assignments))
    28  	for i, participants := range assignments {
    29  		cluster := make(flow.IdentityList, 0, len(participants))
    30  		if len(participants) == 0 {
    31  			return nil, fmt.Errorf("particpants in assignment list is empty, cluster index %v", i)
    32  		}
    33  
    34  		// Check assignments is sorted in canonical order
    35  		prev := participants[0]
    36  
    37  		for i, participantID := range participants {
    38  			participant, found := lookup[participantID]
    39  			if !found {
    40  				return nil, fmt.Errorf("could not find collector identity (%x)", participantID)
    41  			}
    42  			cluster = append(cluster, participant)
    43  			delete(lookup, participantID)
    44  
    45  			if i > 0 {
    46  				if !order.IdentifierCanonical(prev, participantID) {
    47  					return nil, fmt.Errorf("the assignments is not sorted in canonical order in cluster index %v, prev %v, next %v",
    48  						i, prev, participantID)
    49  				}
    50  			}
    51  			prev = participantID
    52  		}
    53  
    54  		clusters = append(clusters, cluster)
    55  	}
    56  
    57  	// check that every collector was assigned
    58  	if len(lookup) != 0 {
    59  		return nil, fmt.Errorf("missing collector assignments (%s)", lookup)
    60  	}
    61  
    62  	return clusters, nil
    63  }