github.com/koko1123/flow-go-1@v0.29.6/engine/consensus/approvals/signature_collector.go (about)

     1  package approvals
     2  
     3  import (
     4  	"github.com/onflow/flow-go/crypto"
     5  	"github.com/koko1123/flow-go-1/model/flow"
     6  )
     7  
     8  // SignatureCollector contains a set of of signatures from verifiers attesting
     9  // to the validity of an execution result chunk.
    10  // NOT concurrency safe.
    11  // TODO: this will be replaced with stateful BLS aggregation
    12  type SignatureCollector struct {
    13  	// List of signatures
    14  	verifierSignatures []crypto.Signature
    15  	// List of signer identifiers
    16  	signerIDs []flow.Identifier
    17  
    18  	// set of all signerIDs for de-duplicating signatures; the mapped value
    19  	// is the storage index in the verifierSignatures and signerIDs
    20  	signerIDSet map[flow.Identifier]int
    21  }
    22  
    23  // NewSignatureCollector instantiates a new SignatureCollector
    24  func NewSignatureCollector() SignatureCollector {
    25  	return SignatureCollector{
    26  		verifierSignatures: nil,
    27  		signerIDs:          nil,
    28  		signerIDSet:        make(map[flow.Identifier]int),
    29  	}
    30  }
    31  
    32  // ToAggregatedSignature generates an aggregated signature from all signatures
    33  // in the SignatureCollector
    34  func (c *SignatureCollector) ToAggregatedSignature() flow.AggregatedSignature {
    35  	signatures := make([]crypto.Signature, len(c.verifierSignatures))
    36  	copy(signatures, c.verifierSignatures)
    37  
    38  	signers := make([]flow.Identifier, len(c.signerIDs))
    39  	copy(signers, c.signerIDs)
    40  
    41  	return flow.AggregatedSignature{
    42  		VerifierSignatures: signatures,
    43  		SignerIDs:          signers,
    44  	}
    45  }
    46  
    47  // BySigner returns a signer's signature if it exists
    48  func (c *SignatureCollector) BySigner(signerID flow.Identifier) (*crypto.Signature, bool) {
    49  	idx, found := c.signerIDSet[signerID]
    50  	if !found {
    51  		return nil, false
    52  	}
    53  	return &c.verifierSignatures[idx], true
    54  }
    55  
    56  // HasSigned checks if signer has already provided a signature
    57  func (c *SignatureCollector) HasSigned(signerID flow.Identifier) bool {
    58  	_, found := c.signerIDSet[signerID]
    59  	return found
    60  }
    61  
    62  // Add appends a signature. Only the _first_ signature is retained for each signerID.
    63  func (c *SignatureCollector) Add(signerID flow.Identifier, signature crypto.Signature) {
    64  	if _, found := c.signerIDSet[signerID]; found {
    65  		return
    66  	}
    67  	c.signerIDSet[signerID] = len(c.signerIDs)
    68  	c.signerIDs = append(c.signerIDs, signerID)
    69  	c.verifierSignatures = append(c.verifierSignatures, signature)
    70  }
    71  
    72  // NumberSignatures returns the number of stored (distinct) signatures
    73  func (c *SignatureCollector) NumberSignatures() uint {
    74  	return uint(len(c.signerIDs))
    75  }