github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/engine/consensus/approvals/chunk_collector.go (about) 1 package approvals 2 3 import ( 4 "sync" 5 6 "github.com/onflow/flow-go/model/flow" 7 ) 8 9 // ChunkApprovalCollector implements logic for checking chunks against assignments as 10 // well as accumulating signatures of already checked approvals. 11 type ChunkApprovalCollector struct { 12 assignment map[flow.Identifier]struct{} // set of verifiers that were assigned to current chunk 13 chunkApprovals SignatureCollector // accumulator of signatures for current collector 14 lock sync.Mutex // lock to protect `chunkApprovals` 15 requiredApprovalsForSealConstruction uint // number of approvals that are required for each chunk to be sealed 16 } 17 18 func NewChunkApprovalCollector(assignment map[flow.Identifier]struct{}, requiredApprovalsForSealConstruction uint) *ChunkApprovalCollector { 19 return &ChunkApprovalCollector{ 20 assignment: assignment, 21 chunkApprovals: NewSignatureCollector(), 22 lock: sync.Mutex{}, 23 requiredApprovalsForSealConstruction: requiredApprovalsForSealConstruction, 24 } 25 } 26 27 // ProcessApproval performs processing and bookkeeping of single approval 28 func (c *ChunkApprovalCollector) ProcessApproval(approval *flow.ResultApproval) (flow.AggregatedSignature, bool) { 29 approverID := approval.Body.ApproverID 30 if _, ok := c.assignment[approverID]; ok { 31 c.lock.Lock() 32 defer c.lock.Unlock() 33 c.chunkApprovals.Add(approverID, approval.Body.AttestationSignature) 34 if c.chunkApprovals.NumberSignatures() >= c.requiredApprovalsForSealConstruction { 35 return c.chunkApprovals.ToAggregatedSignature(), true 36 } 37 } 38 39 return flow.AggregatedSignature{}, false 40 } 41 42 // GetMissingSigners returns ids of approvers that are present in assignment but didn't provide approvals 43 func (c *ChunkApprovalCollector) GetMissingSigners() flow.IdentifierList { 44 // provide capacity for worst-case 45 result := make(flow.IdentifierList, 0, len(c.assignment)) 46 c.lock.Lock() 47 for id := range c.assignment { 48 if hasSigned := c.chunkApprovals.HasSigned(id); !hasSigned { 49 result = append(result, id) 50 } 51 } 52 c.lock.Unlock() 53 54 return result 55 }