github.com/onflow/flow-go@v0.33.17/consensus/hotstuff/model/signature_data.go (about)

     1  package model
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  
     7  	"github.com/onflow/flow-go/crypto"
     8  	"github.com/onflow/flow-go/model/encoding/rlp"
     9  	"github.com/onflow/flow-go/model/flow"
    10  )
    11  
    12  // SigDataPacker implements logic for encoding/decoding SignatureData using RLP encoding.
    13  type SigDataPacker struct {
    14  	codec rlp.Codec // rlp encoder is used in order to ensure deterministic encoding
    15  }
    16  
    17  // SignatureData is a compact data type for encoding the block signature data
    18  type SignatureData struct {
    19  	// bit-vector indicating type of signature for each signer.
    20  	// the order of each sig type matches the order of corresponding signer IDs
    21  	SigType []byte
    22  
    23  	AggregatedStakingSig         []byte
    24  	AggregatedRandomBeaconSig    []byte
    25  	ReconstructedRandomBeaconSig crypto.Signature
    26  }
    27  
    28  // Encode performs encoding of SignatureData
    29  func (p *SigDataPacker) Encode(sigData *SignatureData) ([]byte, error) {
    30  	var buf bytes.Buffer
    31  	encoder := p.codec.NewEncoder(&buf)
    32  	err := encoder.Encode(sigData)
    33  	return buf.Bytes(), err
    34  }
    35  
    36  // Decode performs decoding of SignatureData
    37  // This function is side-effect free. It only ever returns
    38  // a model.InvalidFormatError, which indicates an invalid encoding.
    39  func (p *SigDataPacker) Decode(data []byte) (*SignatureData, error) {
    40  	bs := bytes.NewReader(data)
    41  	decoder := p.codec.NewDecoder(bs)
    42  	var sigData SignatureData
    43  	err := decoder.Decode(&sigData)
    44  	if err != nil {
    45  		return nil, NewInvalidFormatErrorf("given data is not a valid encoding of SignatureData: %w", err)
    46  	}
    47  	return &sigData, nil
    48  }
    49  
    50  // BeaconSignature extracts the source of randomness from the QC sigData.
    51  //
    52  // The sigData is an RLP encoded structure that is part of QuorumCertificate.
    53  // The function only ever returns a model.InvalidFormatError, which indicates an
    54  // invalid encoding.
    55  func BeaconSignature(qc *flow.QuorumCertificate) ([]byte, error) {
    56  	// unpack sig data to extract random beacon signature
    57  	packer := SigDataPacker{}
    58  	sigData, err := packer.Decode(qc.SigData)
    59  	if err != nil {
    60  		return nil, fmt.Errorf("could not unpack block signature: %w", err)
    61  	}
    62  	return sigData.ReconstructedRandomBeaconSig, nil
    63  }