github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/mempool/consensus/incorporated_result_seals.go (about) 1 package consensus 2 3 import ( 4 "github.com/rs/zerolog/log" 5 6 "github.com/onflow/flow-go/model/flow" 7 "github.com/onflow/flow-go/module/mempool" 8 "github.com/onflow/flow-go/storage" 9 "github.com/onflow/flow-go/utils/logging" 10 ) 11 12 // IncorporatedResultSeals implements the incorporated result seals memory pool 13 // of the consensus nodes. 14 // ATTENTION: this is a temporary wrapper for `mempool.IncorporatedResultSeals` 15 // to enforce that there are at least 2 receipts from _different_ ENs 16 // committing to the same incorporated result. 17 // This wrapper should only be used with `Core`. 18 type IncorporatedResultSeals struct { 19 seals mempool.IncorporatedResultSeals // seals mempool that wrapped 20 receiptsDB storage.ExecutionReceipts // receipts DB to decide if we have multiple receipts for same result 21 } 22 23 // NewIncorporatedResultSeals creates a mempool for the incorporated result seals 24 func NewIncorporatedResultSeals(mempool mempool.IncorporatedResultSeals, receiptsDB storage.ExecutionReceipts) *IncorporatedResultSeals { 25 return &IncorporatedResultSeals{ 26 seals: mempool, 27 receiptsDB: receiptsDB, 28 } 29 } 30 31 // Add adds an IncorporatedResultSeal to the mempool 32 func (ir *IncorporatedResultSeals) Add(seal *flow.IncorporatedResultSeal) (bool, error) { 33 return ir.seals.Add(seal) 34 } 35 36 // All returns all the items in the mempool 37 func (ir *IncorporatedResultSeals) All() []*flow.IncorporatedResultSeal { 38 unfiltered := ir.seals.All() 39 seals := make([]*flow.IncorporatedResultSeal, 0, len(unfiltered)) 40 for _, s := range unfiltered { 41 if ir.resultHasMultipleReceipts(s.IncorporatedResult) { 42 seals = append(seals, s) 43 } 44 } 45 return seals 46 } 47 48 // resultHasMultipleReceipts implements an additional _temporary_ safety measure: 49 // only consider incorporatedResult sealable if there are at AT LEAST 2 RECEIPTS 50 // from _different_ ENs committing to the result. 51 func (ir *IncorporatedResultSeals) resultHasMultipleReceipts(incorporatedResult *flow.IncorporatedResult) bool { 52 blockID := incorporatedResult.Result.BlockID // block that was computed 53 resultID := incorporatedResult.Result.ID() 54 55 // get all receipts that are known for the block 56 receipts, err := ir.receiptsDB.ByBlockID(blockID) 57 if err != nil { 58 log.Error().Err(err). 59 Hex("block_id", logging.ID(blockID)). 60 Msg("could not get receipts by block ID") 61 return false 62 } 63 64 // Index receipts for given incorporatedResult by their executor. In case 65 // there are multiple receipts from the same executor, we keep the last one. 66 receiptsForIncorporatedResults := receipts.GroupByResultID().GetGroup(resultID) 67 return receiptsForIncorporatedResults.GroupByExecutorID().NumberGroups() >= 2 68 } 69 70 // ByID gets an IncorporatedResultSeal by IncorporatedResult ID 71 func (ir *IncorporatedResultSeals) ByID(id flow.Identifier) (*flow.IncorporatedResultSeal, bool) { 72 seal, ok := ir.seals.ByID(id) 73 if !ok { 74 return nil, false 75 } 76 77 // _temporary_ measure, return only receipts that have multiple commitments from different ENs. 78 if !ir.resultHasMultipleReceipts(seal.IncorporatedResult) { 79 return nil, false 80 } 81 82 return seal, true 83 } 84 85 // Limit returns the size limit of the mempool 86 func (ir *IncorporatedResultSeals) Limit() uint { 87 return ir.seals.Limit() 88 } 89 90 // Remove removes an IncorporatedResultSeal from the mempool 91 func (ir *IncorporatedResultSeals) Remove(id flow.Identifier) bool { 92 return ir.seals.Remove(id) 93 } 94 95 // Size returns the number of items in the mempool 96 func (ir *IncorporatedResultSeals) Size() uint { 97 return ir.seals.Size() 98 } 99 100 // Clear removes all entities from the pool. 101 func (ir *IncorporatedResultSeals) Clear() { 102 ir.seals.Clear() 103 } 104 105 // PruneUpToHeight remove all seals for blocks whose height is strictly 106 // smaller that height. Note: seals for blocks at height are retained. 107 func (ir *IncorporatedResultSeals) PruneUpToHeight(height uint64) error { 108 return ir.seals.PruneUpToHeight(height) 109 }