github.com/onflow/flow-go@v0.33.17/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  	// TODO: should return identity skeleton https://github.com/dapperlabs/flow-go/issues/6232
    82  	IdentitiesByEpoch(view uint64) (flow.IdentityList, error)
    83  
    84  	// IdentityByEpoch returns the full Identity for specified HotStuff participant.
    85  	// The node must be a legitimate HotStuff participant with NON-ZERO WEIGHT at the specified block.
    86  	// CAUTION: This method considers epochs outside of Previous, Current, Next, w.r.t. the
    87  	// finalized block, to be unknown. https://github.com/onflow/flow-go/issues/4085
    88  	//
    89  	// ERROR conditions:
    90  	//  - model.InvalidSignerError if participantID does NOT correspond to an authorized HotStuff participant at the specified block.
    91  	//
    92  	// Returns the following expected errors for invalid inputs:
    93  	//   - model.ErrViewForUnknownEpoch if no epoch containing the given view is known
    94  	//
    95  	// TODO: should return identity skeleton https://github.com/dapperlabs/flow-go/issues/6232
    96  	IdentityByEpoch(view uint64, participantID flow.Identifier) (*flow.Identity, error)
    97  }
    98  
    99  // DynamicCommittee extends Replicas to provide the consensus committee for the purposes
   100  // of validating proposals. The proposer committee reflects block-to-block changes in the
   101  // identity table to support immediately rejecting proposals from nodes after they are ejected.
   102  // For validating proposals, we use *ByBlock methods.
   103  //
   104  // Since the proposer committee can change at any block:
   105  //   - we query by block ID
   106  //   - we must have incorporated the full block ancestry prior to validating messages
   107  type DynamicCommittee interface {
   108  	Replicas
   109  
   110  	// IdentitiesByBlock returns a list of the legitimate HotStuff participants for the given block.
   111  	// The returned list of HotStuff participants:
   112  	//   - contains nodes that are allowed to submit proposals, votes, and timeouts
   113  	//     (un-ejected, non-zero weight at current block)
   114  	//   - is ordered in the canonical order
   115  	//   - contains no duplicates.
   116  	//
   117  	// ERROR conditions:
   118  	//  - state.ErrUnknownSnapshotReference if the blockID is for an unknown block
   119  	IdentitiesByBlock(blockID flow.Identifier) (flow.IdentityList, error)
   120  
   121  	// IdentityByBlock returns the full Identity for specified HotStuff participant.
   122  	// The node must be a legitimate HotStuff participant with NON-ZERO WEIGHT at the specified block.
   123  	// ERROR conditions:
   124  	//  - model.InvalidSignerError if participantID does NOT correspond to an authorized HotStuff participant at the specified block.
   125  	//  - state.ErrUnknownSnapshotReference if the blockID is for an unknown block
   126  	IdentityByBlock(blockID flow.Identifier, participantID flow.Identifier) (*flow.Identity, error)
   127  }
   128  
   129  // BlockSignerDecoder defines how to convert the ParentSignerIndices field within a
   130  // particular block header to the identifiers of the nodes which signed the block.
   131  type BlockSignerDecoder interface {
   132  	// DecodeSignerIDs decodes the signer indices from the given block header into full node IDs.
   133  	// Note: A block header contains a quorum certificate for its parent, which proves that the
   134  	// consensus committee has reached agreement on validity of parent block. Consequently, the
   135  	// returned IdentifierList contains the consensus participants that signed the parent block.
   136  	// Expected Error returns during normal operations:
   137  	//  - signature.InvalidSignerIndicesError if signer indices included in the header do
   138  	//    not encode a valid subset of the consensus committee
   139  	DecodeSignerIDs(header *flow.Header) (flow.IdentifierList, error)
   140  }
   141  
   142  type DKG interface {
   143  	protocol.DKG
   144  }