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