prysm-pulse/beacon-chain/operations/attestations/aggregate.go
terence tsao 6c4bf22723 Fix up attestation pool (#4493)
* Update aggregated methods

* Update aggregated methods

* Use improved HasAttestation to check caches

* Add back some validations

* There's no need to save unaggregated att

* Fixed all the tests

* remove TODO for now

* Raul feedback

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
2020-01-11 13:59:06 -08:00

73 lines
2.0 KiB
Go

package attestations
import (
"context"
"time"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/go-ssz"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
"github.com/prysmaticlabs/prysm/shared/params"
"go.opencensus.io/trace"
)
// Define time to aggregate the unaggregated attestations at 3 times per slot, this gives
// enough confidence all the unaggregated attestations will be aggregated as aggregator requests.
var timeToAggregate = time.Duration(params.BeaconConfig().SecondsPerSlot/3) * time.Second
// This kicks off a routine to aggregate the unaggregated attestations from pool.
func (s *Service) aggregateRoutine() {
ticker := time.NewTicker(timeToAggregate)
ctx := context.TODO()
for {
select {
case <-s.ctx.Done():
return
case <-ticker.C:
attsToBeAggregated := append(s.pool.UnaggregatedAttestations(), s.pool.AggregatedAttestations()...)
if err := s.aggregateAttestations(ctx, attsToBeAggregated); err != nil {
log.WithError(err).Error("Could not aggregate attestation")
}
}
}
}
// This aggregates the input attestations via AggregateAttestations helper
// function.
func (s *Service) aggregateAttestations(ctx context.Context, attsToBeAggregated []*ethpb.Attestation) error {
ctx, span := trace.StartSpan(ctx, "Operations.attestations.aggregateAttestations")
defer span.End()
attsByRoot := make(map[[32]byte][]*ethpb.Attestation)
for _, att := range attsToBeAggregated {
attDataRoot, err := ssz.HashTreeRoot(att.Data)
if err != nil {
return err
}
attsByRoot[attDataRoot] = append(attsByRoot[attDataRoot], att)
if !helpers.IsAggregated(att) {
if err := s.pool.DeleteUnaggregatedAttestation(att); err != nil {
return err
}
}
}
for _, atts := range attsByRoot {
aggregatedAtts, err := helpers.AggregateAttestations(atts)
if err != nil {
return err
}
for _, att := range aggregatedAtts {
if helpers.IsAggregated(att) {
if err := s.pool.SaveAggregatedAttestation(att); err != nil {
return err
}
}
}
}
return nil
}