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  }