Compare commits

...

5 Commits

Author SHA1 Message Date
Raul Jordan
c04a9436db merge 2024-08-19 09:46:32 -05:00
Raul Jordan
e2803bdd8c Merge branch 'slasher-defer-att' of github.com:prysmaticlabs/prysm into slasher-defer-att 2024-08-09 14:07:26 -05:00
Raul Jordan
94344b79f6 beacon blocks 2024-08-09 14:07:21 -05:00
Raul Jordan
d6df9b57c3 Merge branch 'develop' into slasher-defer-att 2024-08-09 13:46:23 -05:00
Raul Jordan
e65c82ef6e signature verification if not validated by pipeline before forwarding to slasher 2024-08-09 13:42:56 -05:00
2 changed files with 92 additions and 48 deletions

View File

@@ -101,19 +101,71 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p
return result, wrappedErr
}
if !features.Get().EnableSlasher {
// Verify this the first attestation received for the participating validator for the slot.
if s.hasSeenCommitteeIndicesSlot(data.Slot, committeeIndex, att.GetAggregationBits()) {
return pubsub.ValidationIgnore, nil
}
var signatureValidated bool
if features.Get().EnableSlasher {
// Feed the indexed attestation to slasher if enabled. This action
// is done in the background to avoid adding more load to this critical code path.
defer func() {
go func() {
// Using a different context to prevent timeouts as this operation can be expensive
// and we want to avoid affecting the critical code path.
ctx := context.TODO()
preState, err := s.cfg.chain.AttestationTargetState(ctx, data.Target)
if err != nil {
log.WithError(err).Error("Could not retrieve pre state")
tracing.AnnotateError(span, err)
return
}
if !signatureValidated {
set, err := blocks.AttestationSignatureBatch(ctx, preState, []eth.Att{att})
if err != nil {
log.WithError(err).Error("Could not prepare attestation signature batch")
tracing.AnnotateError(span, err)
attBadSignatureBatchCount.Inc()
return
}
validationResult, err := s.validateWithBatchVerifier(ctx, "attestation", set)
if err != nil {
log.WithError(err).Error("Could not validate attestation batch signature")
tracing.AnnotateError(span, err)
attBadSignatureBatchCount.Inc()
return
}
if validationResult != pubsub.ValidationAccept {
log.WithError(err).Error("Not forwarding attestation to slasher due to invalid signature")
tracing.AnnotateError(span, err)
attBadSignatureBatchCount.Inc()
return
}
}
committee, err := helpers.BeaconCommitteeFromState(ctx, preState, data.Slot, committeeIndex)
if err != nil {
log.WithError(err).Error("Could not get attestation committee")
tracing.AnnotateError(span, err)
return
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committee)
if err != nil {
log.WithError(err).Error("Could not convert to indexed attestation")
tracing.AnnotateError(span, err)
return
}
s.cfg.slasherAttestationsFeed.Send(&types.WrappedIndexedAtt{IndexedAtt: indexedAtt})
}()
}()
}
// Reject an attestation if it references an invalid block.
if s.hasBadBlock(bytesutil.ToBytes32(data.BeaconBlockRoot)) ||
s.hasBadBlock(bytesutil.ToBytes32(data.Target.Root)) ||
s.hasBadBlock(bytesutil.ToBytes32(data.Source.Root)) {
attBadBlockCount.Inc()
return pubsub.ValidationReject, errors.New("attestation data references bad block root")
}
// Verify this the first attestation received for the participating validator for the slot.
if s.hasSeenCommitteeIndicesSlot(data.Slot, data.CommitteeIndex, att.GetAggregationBits()) {
return pubsub.ValidationIgnore, nil
}
// Reject an attestation if it references an invalid block.
if s.hasBadBlock(bytesutil.ToBytes32(data.BeaconBlockRoot)) ||
s.hasBadBlock(bytesutil.ToBytes32(data.Target.Root)) ||
s.hasBadBlock(bytesutil.ToBytes32(data.Source.Root)) {
attBadBlockCount.Inc()
return pubsub.ValidationReject, errors.New("attestation data references bad block root")
}
// Verify the block being voted and the processed state is in beaconDB and the block has passed validation if it's in the beaconDB.
@@ -163,35 +215,7 @@ func (s *Service) validateCommitteeIndexBeaconAttestation(ctx context.Context, p
if validationRes != pubsub.ValidationAccept {
return validationRes, err
}
if features.Get().EnableSlasher {
// Feed the indexed attestation to slasher if enabled. This action
// is done in the background to avoid adding more load to this critical code path.
go func() {
// Using a different context to prevent timeouts as this operation can be expensive
// and we want to avoid affecting the critical code path.
ctx := context.TODO()
preState, err := s.cfg.chain.AttestationTargetState(ctx, data.Target)
if err != nil {
log.WithError(err).Error("Could not retrieve pre state")
tracing.AnnotateError(span, err)
return
}
committee, err := helpers.BeaconCommitteeFromState(ctx, preState, data.Slot, committeeIndex)
if err != nil {
log.WithError(err).Error("Could not get attestation committee")
tracing.AnnotateError(span, err)
return
}
indexedAtt, err := attestation.ConvertToIndexed(ctx, att, committee)
if err != nil {
log.WithError(err).Error("Could not convert to indexed attestation")
tracing.AnnotateError(span, err)
return
}
s.cfg.slasherAttestationsFeed.Send(&types.WrappedIndexedAtt{IndexedAtt: indexedAtt})
}()
}
signatureValidated = true
s.setSeenCommitteeIndicesSlot(data.Slot, committeeIndex, att.GetAggregationBits())

View File

@@ -81,16 +81,35 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
},
})
var signatureValidated bool
if features.Get().EnableSlasher {
// Feed the block header to slasher if enabled. This action
// is done in the background to avoid adding more load to this critical code path.
go func() {
blockHeader, err := interfaces.SignedBeaconBlockHeaderFromBlockInterface(blk)
if err != nil {
log.WithError(err).WithField("blockSlot", blk.Block().Slot()).Warn("Could not extract block header")
return
}
s.cfg.slasherBlockHeadersFeed.Send(blockHeader)
defer func() {
go func() {
if !signatureValidated {
blockRoot, err := blk.Block().HashTreeRoot()
if err != nil {
log.WithError(err).WithFields(getBlockFields(blk)).Debug("Ignored block")
return
}
parentState, err := s.cfg.stateGen.StateByRoot(ctx, blk.Block().ParentRoot())
if err != nil {
log.WithError(err).WithFields(getBlockFields(blk)).Debug("Could not get state for block by parent root")
return
}
if err := blocks.VerifyBlockSignatureUsingCurrentFork(parentState, blk, blockRoot); err != nil {
log.WithError(err).WithFields(getBlockFields(blk)).Debug("Signature failed to verify, not forwarding block to slasher")
return
}
}
blockHeader, err := interfaces.SignedBeaconBlockHeaderFromBlockInterface(blk)
if err != nil {
log.WithError(err).WithField("blockSlot", blk.Block().Slot()).Warn("Could not extract block header")
return
}
s.cfg.slasherBlockHeadersFeed.Send(blockHeader)
}()
}()
}
@@ -199,6 +218,7 @@ func (s *Service) validateBeaconBlockPubSub(ctx context.Context, pid peer.ID, ms
return pubsub.ValidationReject, err
}
}
signatureValidated = true
// Record attribute of valid block.
span.AddAttributes(trace.Int64Attribute("slotInEpoch", int64(blk.Block().Slot()%params.BeaconConfig().SlotsPerEpoch)))