github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/signature/block_signer_decoder.go (about)

     1  package signature
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/koko1123/flow-go-1/consensus/hotstuff"
     8  	"github.com/koko1123/flow-go-1/model/flow"
     9  	"github.com/koko1123/flow-go-1/module/signature"
    10  	"github.com/koko1123/flow-go-1/state"
    11  	"github.com/koko1123/flow-go-1/storage"
    12  )
    13  
    14  // BlockSignerDecoder is a wrapper around the `hotstuff.Committee`, which implements
    15  // the auxilluary logic for de-coding signer indices of a block (header) to full node IDs
    16  type BlockSignerDecoder struct {
    17  	// TODO: update to Replicas API once active PaceMaker is merged
    18  	hotstuff.Committee
    19  }
    20  
    21  func NewBlockSignerDecoder(committee hotstuff.Committee) *BlockSignerDecoder {
    22  	return &BlockSignerDecoder{committee}
    23  }
    24  
    25  var _ hotstuff.BlockSignerDecoder = (*BlockSignerDecoder)(nil)
    26  
    27  // DecodeSignerIDs decodes the signer indices from the given block header into full node IDs.
    28  // Expected Error returns during normal operations:
    29  //   - state.UnknownBlockError if block has not been ingested yet
    30  //   - signature.InvalidSignerIndicesError if signer indices included in the header do
    31  //     not encode a valid subset of the consensus committee
    32  func (b *BlockSignerDecoder) DecodeSignerIDs(header *flow.Header) (flow.IdentifierList, error) {
    33  	// root block does not have signer indices
    34  	if header.ParentVoterIndices == nil && header.View == 0 {
    35  		return []flow.Identifier{}, nil
    36  	}
    37  
    38  	// The block header contains the signatures for the parents. Hence, we need to get the
    39  	// identities that were authorized to sign the parent block, to decode the signer indices.
    40  	members, err := b.Identities(header.ParentID)
    41  	if err != nil {
    42  		// TODO: this potentially needs to be updated when we implement and document proper error handling for
    43  		//       `hotstuff.Committee` and underlying code (such as `protocol.Snapshot`)
    44  		if errors.Is(err, storage.ErrNotFound) {
    45  			return nil, state.WrapAsUnknownBlockError(header.ID(), err)
    46  		}
    47  		return nil, fmt.Errorf("fail to retrieve identities for block %v: %w", header.ID(), err)
    48  	}
    49  	signerIDs, err := signature.DecodeSignerIndicesToIdentifiers(members.NodeIDs(), header.ParentVoterIndices)
    50  	if err != nil {
    51  		return nil, fmt.Errorf("could not decode signer indices for block %v: %w", header.ID(), err)
    52  	}
    53  
    54  	return signerIDs, nil
    55  }
    56  
    57  // NoopBlockSignerDecoder does not decode any signer indices and consistently returns
    58  // nil for the signing node IDs (auxiliary data)
    59  type NoopBlockSignerDecoder struct{}
    60  
    61  func NewNoopBlockSignerDecoder() *NoopBlockSignerDecoder {
    62  	return &NoopBlockSignerDecoder{}
    63  }
    64  
    65  func (b *NoopBlockSignerDecoder) DecodeSignerIDs(_ *flow.Header) (flow.IdentifierList, error) {
    66  	return nil, nil
    67  }