github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/prysm/v1alpha1/validator/proposer_sync_aggregate.go (about) 1 package validator 2 3 import ( 4 "bytes" 5 6 eth "github.com/prysmaticlabs/prysm/proto/prysm/v2" 7 ) 8 9 type proposerSyncContributions []*eth.SyncCommitteeContribution 10 11 // filterByBlockRoot separates sync aggregate list into a valid group. 12 // The valid group contains the input block root. 13 func (cs proposerSyncContributions) filterByBlockRoot(r [32]byte) proposerSyncContributions { 14 matchedSyncContributions := make([]*eth.SyncCommitteeContribution, 0, len(cs)) 15 for _, c := range cs { 16 if bytes.Equal(c.BlockRoot, r[:]) { 17 matchedSyncContributions = append(matchedSyncContributions, c) 18 } 19 } 20 return matchedSyncContributions 21 } 22 23 // filterBySubIndex separates sync aggregate list into a valid group. 24 // The valid group contains the matching sub committee index. 25 func (cs proposerSyncContributions) filterBySubIndex(i uint64) proposerSyncContributions { 26 matchedSyncContributions := make([]*eth.SyncCommitteeContribution, 0, len(cs)) 27 for _, c := range cs { 28 if c.SubcommitteeIndex == i { 29 matchedSyncContributions = append(matchedSyncContributions, c) 30 } 31 } 32 return matchedSyncContributions 33 } 34 35 // dedup removes duplicate sync contributions (ones with the same bits set on). 36 // Important: not only exact duplicates are removed, but proper subsets are removed too 37 // (their known bits are redundant and are already contained in their supersets). 38 func (cs proposerSyncContributions) dedup() (proposerSyncContributions, error) { 39 if len(cs) < 2 { 40 return cs, nil 41 } 42 contributionsBySubIdx := make(map[uint64][]*eth.SyncCommitteeContribution, len(cs)) 43 for _, c := range cs { 44 contributionsBySubIdx[c.SubcommitteeIndex] = append(contributionsBySubIdx[c.SubcommitteeIndex], c) 45 } 46 47 uniqContributions := make([]*eth.SyncCommitteeContribution, 0, len(cs)) 48 for _, cs := range contributionsBySubIdx { 49 for i := 0; i < len(cs); i++ { 50 a := cs[i] 51 for j := i + 1; j < len(cs); j++ { 52 b := cs[j] 53 if c, err := a.AggregationBits.Contains(b.AggregationBits); err != nil { 54 return nil, err 55 } else if c { 56 // a contains b, b is redundant. 57 cs[j] = cs[len(cs)-1] 58 cs[len(cs)-1] = nil 59 cs = cs[:len(cs)-1] 60 j-- 61 } else if c, err := b.AggregationBits.Contains(a.GetAggregationBits()); err != nil { 62 return nil, err 63 } else if c { 64 // b contains a, a is redundant. 65 cs[i] = cs[len(cs)-1] 66 cs[len(cs)-1] = nil 67 cs = cs[:len(cs)-1] 68 i-- 69 break 70 } 71 } 72 } 73 uniqContributions = append(uniqContributions, cs...) 74 } 75 return uniqContributions, nil 76 } 77 78 // mostProfitable returns the most profitable sync contribution, the one with the most 79 // votes (ie. aggregation bits count) 80 func (cs proposerSyncContributions) mostProfitable() *eth.SyncCommitteeContribution { 81 if len(cs) == 0 { 82 return nil 83 } 84 mostProfitable := cs[0] 85 for _, c := range cs[1:] { 86 if c.AggregationBits.Count() > mostProfitable.AggregationBits.Count() { 87 mostProfitable = c 88 } 89 } 90 return mostProfitable 91 }