github.com/onflow/flow-go@v0.33.17/consensus/hotstuff/committees/static.go (about)

     1  package committees
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/onflow/flow-go/consensus/hotstuff"
     7  	"github.com/onflow/flow-go/consensus/hotstuff/model"
     8  	"github.com/onflow/flow-go/crypto"
     9  	"github.com/onflow/flow-go/model/flow"
    10  	"github.com/onflow/flow-go/state/protocol"
    11  )
    12  
    13  // NewStaticCommittee returns a new committee with a static participant set.
    14  func NewStaticCommittee(participants flow.IdentityList, myID flow.Identifier, dkgParticipants map[flow.Identifier]flow.DKGParticipant, dkgGroupKey crypto.PublicKey) (*Static, error) {
    15  
    16  	return NewStaticCommitteeWithDKG(participants, myID, staticDKG{
    17  		dkgParticipants: dkgParticipants,
    18  		dkgGroupKey:     dkgGroupKey,
    19  	})
    20  }
    21  
    22  // NewStaticCommitteeWithDKG returns a new committee with a static participant set.
    23  func NewStaticCommitteeWithDKG(participants flow.IdentityList, myID flow.Identifier, dkg protocol.DKG) (*Static, error) {
    24  	valid := flow.IsIdentityListCanonical(participants)
    25  	if !valid {
    26  		return nil, fmt.Errorf("participants %v is not in Canonical order", participants)
    27  	}
    28  
    29  	static := &Static{
    30  		participants: participants,
    31  		myID:         myID,
    32  		dkg:          dkg,
    33  	}
    34  	return static, nil
    35  }
    36  
    37  // Static represents a committee with a static participant set. It is used for
    38  // bootstrapping purposes.
    39  type Static struct {
    40  	participants flow.IdentityList
    41  	myID         flow.Identifier
    42  	dkg          protocol.DKG
    43  }
    44  
    45  func (s Static) IdentitiesByBlock(_ flow.Identifier) (flow.IdentityList, error) {
    46  	return s.participants, nil
    47  }
    48  
    49  func (s Static) IdentityByBlock(_ flow.Identifier, participantID flow.Identifier) (*flow.Identity, error) {
    50  	identity, ok := s.participants.ByNodeID(participantID)
    51  	if !ok {
    52  		return nil, model.NewInvalidSignerErrorf("unknown participant %x", participantID)
    53  	}
    54  	return identity, nil
    55  }
    56  
    57  func (s Static) IdentitiesByEpoch(_ uint64) (flow.IdentityList, error) {
    58  	return s.participants, nil
    59  }
    60  
    61  func (s Static) IdentityByEpoch(_ uint64, participantID flow.Identifier) (*flow.Identity, error) {
    62  	identity, ok := s.participants.ByNodeID(participantID)
    63  	if !ok {
    64  		return nil, model.NewInvalidSignerErrorf("unknown participant %x", participantID)
    65  	}
    66  	return identity, nil
    67  }
    68  
    69  func (s Static) LeaderForView(_ uint64) (flow.Identifier, error) {
    70  	return flow.ZeroID, fmt.Errorf("invalid for static committee")
    71  }
    72  
    73  func (s Static) QuorumThresholdForView(_ uint64) (uint64, error) {
    74  	return WeightThresholdToBuildQC(s.participants.TotalWeight()), nil
    75  }
    76  
    77  func (s Static) TimeoutThresholdForView(_ uint64) (uint64, error) {
    78  	return WeightThresholdToTimeout(s.participants.TotalWeight()), nil
    79  }
    80  
    81  func (s Static) Self() flow.Identifier {
    82  	return s.myID
    83  }
    84  
    85  func (s Static) DKG(_ uint64) (hotstuff.DKG, error) {
    86  	return s.dkg, nil
    87  }
    88  
    89  type staticDKG struct {
    90  	dkgParticipants map[flow.Identifier]flow.DKGParticipant
    91  	dkgGroupKey     crypto.PublicKey
    92  }
    93  
    94  func (s staticDKG) Size() uint {
    95  	return uint(len(s.dkgParticipants))
    96  }
    97  
    98  func (s staticDKG) GroupKey() crypto.PublicKey {
    99  	return s.dkgGroupKey
   100  }
   101  
   102  // Index returns the index for the given node. Error Returns:
   103  // protocol.IdentityNotFoundError if nodeID is not a valid DKG participant.
   104  func (s staticDKG) Index(nodeID flow.Identifier) (uint, error) {
   105  	participant, ok := s.dkgParticipants[nodeID]
   106  	if !ok {
   107  		return 0, protocol.IdentityNotFoundError{NodeID: nodeID}
   108  	}
   109  	return participant.Index, nil
   110  }
   111  
   112  // KeyShare returns the public key share for the given node. Error Returns:
   113  // protocol.IdentityNotFoundError if nodeID is not a valid DKG participant.
   114  func (s staticDKG) KeyShare(nodeID flow.Identifier) (crypto.PublicKey, error) {
   115  	participant, ok := s.dkgParticipants[nodeID]
   116  	if !ok {
   117  		return nil, protocol.IdentityNotFoundError{NodeID: nodeID}
   118  	}
   119  	return participant.KeyShare, nil
   120  }