Compare commits

...

2 Commits

Author SHA1 Message Date
terence tsao
da8eda99f9 Comments 2021-09-27 14:06:52 -07:00
terence tsao
a515ac56ed Filter attestations by canonical blocks 2021-09-27 14:02:23 -07:00
5 changed files with 96 additions and 3 deletions

View File

@@ -34,6 +34,7 @@ go_library(
"//beacon-chain/core/signing:go_default_library",
"//beacon-chain/core/transition:go_default_library",
"//beacon-chain/core/transition/interop:go_default_library",
"//beacon-chain/db:go_default_library",
"//beacon-chain/operations/attestations:go_default_library",
"//beacon-chain/operations/slashings:go_default_library",
"//beacon-chain/operations/synccommittee:go_default_library",

View File

@@ -711,7 +711,29 @@ func (vs *Server) filterAttestationsForBlockInclusion(ctx context.Context, st st
ctx, span := trace.StartSpan(ctx, "ProposerServer.filterAttestationsForBlockInclusion")
defer span.End()
validAtts, invalidAtts := proposerAtts(atts).filter(ctx, st)
// Retrieve parent blocks up to one epoch old.
parentBlock, err := vs.HeadFetcher.HeadBlock(ctx)
if err != nil {
return nil, err
}
blks := make([]block.SignedBeaconBlock, 0, params.BeaconConfig().SlotsPerEpoch)
for {
if parentBlock.Block().Slot()+params.BeaconConfig().SlotsPerEpoch < vs.TimeFetcher.CurrentSlot() {
break
}
blks = append(blks, parentBlock)
parentBlock, err = vs.BeaconDB.Block(ctx, bytesutil.ToBytes32(parentBlock.Block().ParentRoot()))
if err != nil {
return nil, err
}
}
validAtts, err := proposerAtts(atts).filterByBlocks(ctx, blks)
if err != nil {
return nil, err
}
validAtts, invalidAtts := validAtts.filterByValidation(ctx, st)
if err := vs.deleteAttsInPool(ctx, invalidAtts); err != nil {
return nil, err
}

View File

@@ -12,17 +12,21 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/state"
"github.com/prysmaticlabs/prysm/config/features"
"github.com/prysmaticlabs/prysm/config/params"
"github.com/prysmaticlabs/prysm/crypto/hash"
ethpb "github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/attestation/aggregation"
"github.com/prysmaticlabs/prysm/proto/prysm/v1alpha1/block"
"github.com/prysmaticlabs/prysm/runtime/version"
)
var hashFn = hash.HashProto
type proposerAtts []*ethpb.Attestation
// filter separates attestation list into two groups: valid and invalid attestations.
// filterByValidation separates attestation list into two groups: valid and invalid attestations.
// The first group passes the all the required checks for attestation to be considered for proposing.
// And attestations from the second group should be deleted.
func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (proposerAtts, proposerAtts) {
func (a proposerAtts) filterByValidation(ctx context.Context, st state.BeaconState) (proposerAtts, proposerAtts) {
validAtts := make([]*ethpb.Attestation, 0, len(a))
invalidAtts := make([]*ethpb.Attestation, 0, len(a))
var attestationProcessor func(context.Context, state.BeaconState, *ethpb.Attestation) (state.BeaconState, error)
@@ -53,6 +57,69 @@ func (a proposerAtts) filter(ctx context.Context, st state.BeaconState) (propose
return validAtts, invalidAtts
}
// filterByBlocks filters the attestation list that's not covered by the attestations contained in input `blks`.
func (a proposerAtts) filterByBlocks(ctx context.Context, blks []block.SignedBeaconBlock) (proposerAtts, error) {
// Construct a map of seen attestation bits given the input block's attestations.
seenBits := make(map[[32]byte][]bitfield.Bitlist)
for _, blk := range blks {
for _, att := range blk.Block().Body().Attestations() {
r, err := hashFn(att.Data)
if err != nil {
return nil, err
}
bits, ok := seenBits[r]
if ok {
exists := false
for _, b := range bits {
c, err := b.Contains(att.AggregationBits)
if err != nil {
return nil, err
}
if c {
exists = true
break
}
}
if !exists {
seenBits[r] = append(seenBits[r], att.AggregationBits)
}
} else {
seenBits[r] = []bitfield.Bitlist{att.AggregationBits}
}
}
}
// Filter out attestations that are covered by the constructed map.
filteredAtts := make(proposerAtts, 0, len(a))
for _, att := range a {
r, err := hashFn(att.Data)
if err != nil {
return nil, err
}
bits, ok := seenBits[r]
hasSeen := false
if ok {
for _, b := range bits {
c, err := b.Contains(att.AggregationBits)
if err != nil {
return nil, err
}
if c {
hasSeen = true
break
}
}
} else {
filteredAtts = append(filteredAtts, att)
}
if !hasSeen {
filteredAtts = append(filteredAtts, att)
}
}
return filteredAtts, nil
}
// sortByProfitability orders attestations by highest slot and by highest aggregation bit count.
func (a proposerAtts) sortByProfitability() (proposerAtts, error) {
if len(a) < 2 {

View File

@@ -16,6 +16,7 @@ import (
opfeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/operation"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/core/signing"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/attestations"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/slashings"
"github.com/prysmaticlabs/prysm/beacon-chain/operations/synccommittee"
@@ -63,6 +64,7 @@ type Server struct {
PendingDepositsFetcher depositcache.PendingDepositsFetcher
OperationNotifier opfeed.Notifier
StateGen stategen.StateManager
BeaconDB db.ReadOnlyDatabase
}
// WaitForActivation checks if a validator public key exists in the active validator registry of the current

View File

@@ -192,6 +192,7 @@ func (s *Service) Start() {
SlashingsPool: s.cfg.SlashingsPool,
StateGen: s.cfg.StateGen,
SyncCommitteePool: s.cfg.SyncCommitteeObjectPool,
BeaconDB: s.cfg.BeaconDB,
}
validatorServerV1 := &validator.Server{
HeadFetcher: s.cfg.HeadFetcher,