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  }