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 }