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 }