github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/model/signature_data.go (about)

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