github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/committee.go (about) 1 package hotstuff 2 3 import ( 4 "github.com/onflow/flow-go/model/flow" 5 "github.com/onflow/flow-go/state/protocol" 6 ) 7 8 // A committee provides a subset of the protocol.State, which is restricted to exactly those 9 // nodes that participate in the current HotStuff instance: the state of all legitimate HotStuff 10 // participants for the specified view. Legitimate HotStuff participants have NON-ZERO WEIGHT. 11 // 12 // For the purposes of validating votes, timeouts, quorum certificates, and timeout certificates 13 // we consider a committee which is static over the course of an epoch. Although committee 14 // members may be ejected, or have their weight change during an epoch, we ignore these changes. 15 // For these purposes we use the Replicas and *ByEpoch methods. 16 // 17 // When validating proposals, we take into account changes to the committee during the course of 18 // an epoch. In particular, if a node is ejected, we will immediately reject all future proposals 19 // from that node. For these purposes we use the DynamicCommittee and *ByBlock methods. 20 21 // Replicas defines the consensus committee for the purposes of validating votes, timeouts, 22 // quorum certificates, and timeout certificates. Any consensus committee member who was 23 // authorized to contribute to consensus AT THE BEGINNING of the epoch may produce valid 24 // votes and timeouts for the entire epoch, even if they are later ejected. 25 // So for validating votes/timeouts we use *ByEpoch methods. 26 // 27 // Since the voter committee is considered static over an epoch: 28 // - we can query identities by view 29 // - we don't need the full block ancestry prior to validating messages 30 type Replicas interface { 31 32 // LeaderForView returns the identity of the leader for a given view. 33 // CAUTION: per liveness requirement of HotStuff, the leader must be fork-independent. 34 // Therefore, a node retains its proposer view slots even if it is slashed. 35 // Its proposal is simply considered invalid, as it is not from a legitimate participant. 36 // Returns the following expected errors for invalid inputs: 37 // - model.ErrViewForUnknownEpoch if no epoch containing the given view is known 38 LeaderForView(view uint64) (flow.Identifier, error) 39 40 // QuorumThresholdForView returns the minimum total weight for a supermajority 41 // at the given view. This weight threshold is computed using the total weight 42 // of the initial committee and is static over the course of an epoch. 43 // Returns the following expected errors for invalid inputs: 44 // - model.ErrViewForUnknownEpoch if no epoch containing the given view is known 45 QuorumThresholdForView(view uint64) (uint64, error) 46 47 // TimeoutThresholdForView returns the minimum total weight of observed timeout objects 48 // required to safely timeout for the given view. This weight threshold is computed 49 // using the total weight of the initial committee and is static over the course of 50 // an epoch. 51 // Returns the following expected errors for invalid inputs: 52 // - model.ErrViewForUnknownEpoch if no epoch containing the given view is known 53 TimeoutThresholdForView(view uint64) (uint64, error) 54 55 // Self returns our own node identifier. 56 // TODO: ultimately, the own identity of the node is necessary for signing. 57 // Ideally, we would move the method for checking whether an Identifier refers to this node to the signer. 58 // This would require some refactoring of EventHandler (postponed to later) 59 Self() flow.Identifier 60 61 // DKG returns the DKG info for epoch given by the input view. 62 // Returns the following expected errors for invalid inputs: 63 // - model.ErrViewForUnknownEpoch if no epoch containing the given view is known 64 DKG(view uint64) (DKG, error) 65 66 // IdentitiesByEpoch returns a list of the legitimate HotStuff participants for the epoch 67 // given by the input view. 68 // The returned list of HotStuff participants: 69 // - contains nodes that are allowed to submit votes or timeouts within the given epoch 70 // (un-ejected, non-zero weight at the beginning of the epoch) 71 // - is ordered in the canonical order 72 // - contains no duplicates. 73 // 74 // CAUTION: DO NOT use this method for validating block proposals. 75 // CAUTION: This method considers epochs outside of Previous, Current, Next, w.r.t. the 76 // finalized block, to be unknown. https://github.com/onflow/flow-go/issues/4085 77 // 78 // Returns the following expected errors for invalid inputs: 79 // - model.ErrViewForUnknownEpoch if no epoch containing the given view is known 80 // 81 IdentitiesByEpoch(view uint64) (flow.IdentitySkeletonList, error) 82 83 // IdentityByEpoch returns the full Identity for specified HotStuff participant. 84 // The node must be a legitimate HotStuff participant with NON-ZERO WEIGHT at the specified block. 85 // CAUTION: This method considers epochs outside of Previous, Current, Next, w.r.t. the 86 // finalized block, to be unknown. https://github.com/onflow/flow-go/issues/4085 87 // 88 // ERROR conditions: 89 // - model.InvalidSignerError if participantID does NOT correspond to an authorized HotStuff participant at the specified block. 90 // 91 // Returns the following expected errors for invalid inputs: 92 // - model.ErrViewForUnknownEpoch if no epoch containing the given view is known 93 // 94 IdentityByEpoch(view uint64, participantID flow.Identifier) (*flow.IdentitySkeleton, error) 95 } 96 97 // DynamicCommittee extends Replicas to provide the consensus committee for the purposes 98 // of validating proposals. The proposer committee reflects block-to-block changes in the 99 // identity table to support immediately rejecting proposals from nodes after they are ejected. 100 // For validating proposals, we use *ByBlock methods. 101 // 102 // Since the proposer committee can change at any block: 103 // - we query by block ID 104 // - we must have incorporated the full block ancestry prior to validating messages 105 type DynamicCommittee interface { 106 Replicas 107 108 // IdentitiesByBlock returns a list of the legitimate HotStuff participants for the given block. 109 // The returned list of HotStuff participants: 110 // - contains nodes that are allowed to submit proposals, votes, and timeouts 111 // (un-ejected, non-zero weight at current block) 112 // - is ordered in the canonical order 113 // - contains no duplicates. 114 // 115 // ERROR conditions: 116 // - state.ErrUnknownSnapshotReference if the blockID is for an unknown block 117 IdentitiesByBlock(blockID flow.Identifier) (flow.IdentityList, error) 118 119 // IdentityByBlock returns the full Identity for specified HotStuff participant. 120 // The node must be a legitimate HotStuff participant with NON-ZERO WEIGHT at the specified block. 121 // ERROR conditions: 122 // - model.InvalidSignerError if participantID does NOT correspond to an authorized HotStuff participant at the specified block. 123 // - state.ErrUnknownSnapshotReference if the blockID is for an unknown block 124 IdentityByBlock(blockID flow.Identifier, participantID flow.Identifier) (*flow.Identity, error) 125 } 126 127 // BlockSignerDecoder defines how to convert the ParentSignerIndices field within a 128 // particular block header to the identifiers of the nodes which signed the block. 129 type BlockSignerDecoder interface { 130 // DecodeSignerIDs decodes the signer indices from the given block header into full node IDs. 131 // Note: A block header contains a quorum certificate for its parent, which proves that the 132 // consensus committee has reached agreement on validity of parent block. Consequently, the 133 // returned IdentifierList contains the consensus participants that signed the parent block. 134 // Expected Error returns during normal operations: 135 // - signature.InvalidSignerIndicesError if signer indices included in the header do 136 // not encode a valid subset of the consensus committee 137 DecodeSignerIDs(header *flow.Header) (flow.IdentifierList, error) 138 } 139 140 type DKG interface { 141 protocol.DKG 142 }