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 }