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