mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 23:18:15 -05:00
157 lines
5.8 KiB
Go
157 lines
5.8 KiB
Go
package sync
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/OffchainLabs/prysm/v7/config/params"
|
|
"github.com/OffchainLabs/prysm/v7/consensus-types/interfaces"
|
|
"github.com/OffchainLabs/prysm/v7/monitoring/tracing"
|
|
"github.com/OffchainLabs/prysm/v7/monitoring/tracing/trace"
|
|
"github.com/OffchainLabs/prysm/v7/time/slots"
|
|
pubsub "github.com/libp2p/go-libp2p-pubsub"
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
"github.com/sirupsen/logrus"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
func (s *Service) validateLightClientOptimisticUpdate(ctx context.Context, pid peer.ID, msg *pubsub.Message) (pubsub.ValidationResult, error) {
|
|
// Validation runs on publish (not just subscriptions), so we should approve any message from
|
|
// ourselves.
|
|
if pid == s.cfg.p2p.PeerID() {
|
|
return pubsub.ValidationAccept, nil
|
|
}
|
|
|
|
// Ignore updates while syncing
|
|
if s.cfg.initialSync.Syncing() {
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
_, span := trace.StartSpan(ctx, "sync.validateLightClientOptimisticUpdate")
|
|
defer span.End()
|
|
|
|
currentUpdate := s.lcStore.LastOptimisticUpdate()
|
|
if currentUpdate == nil {
|
|
log.Debug("No existing optimistic update to compare against. Ignoring.")
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
m, err := s.decodePubsubMessage(msg)
|
|
if err != nil {
|
|
tracing.AnnotateError(span, err)
|
|
return pubsub.ValidationReject, err
|
|
}
|
|
|
|
newUpdate, ok := m.(interfaces.LightClientOptimisticUpdate)
|
|
if !ok {
|
|
return pubsub.ValidationReject, errWrongMessage
|
|
}
|
|
|
|
attestedHeaderRoot, err := newUpdate.AttestedHeader().Beacon().HashTreeRoot()
|
|
if err != nil {
|
|
return pubsub.ValidationIgnore, err
|
|
}
|
|
|
|
// validate that enough time has passed since the start of the slot so the block has had enough time to propagate
|
|
slotStart, err := slots.StartTime(s.cfg.clock.GenesisTime(), newUpdate.SignatureSlot())
|
|
if err != nil {
|
|
log.WithError(err).Debug("Peer sent a slot that would overflow slot start time")
|
|
return pubsub.ValidationReject, nil
|
|
}
|
|
earliestValidTime := slotStart.
|
|
Add(params.BeaconConfig().SlotComponentDuration(params.BeaconConfig().SyncMessageDueBPS)).
|
|
Add(-params.BeaconConfig().MaximumGossipClockDisparityDuration())
|
|
if s.cfg.clock.Now().Before(earliestValidTime) {
|
|
log.Debug("Newly received light client optimistic update ignored. not enough time passed for block to propagate")
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
if !proto.Equal(newUpdate.Proto(), currentUpdate.Proto()) {
|
|
log.WithFields(logrus.Fields{
|
|
"attestedSlot": fmt.Sprintf("%d", newUpdate.AttestedHeader().Beacon().Slot),
|
|
"signatureSlot": fmt.Sprintf("%d", newUpdate.SignatureSlot()),
|
|
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
|
|
}).Debug("Received light client optimistic update is different from the local one. Ignoring.")
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
log.WithFields(logrus.Fields{
|
|
"attestedSlot": fmt.Sprintf("%d", newUpdate.AttestedHeader().Beacon().Slot),
|
|
"signatureSlot": fmt.Sprintf("%d", newUpdate.SignatureSlot()),
|
|
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
|
|
}).Debug("New gossiped light client optimistic update validated.")
|
|
|
|
msg.ValidatorData = newUpdate.Proto()
|
|
return pubsub.ValidationAccept, nil
|
|
}
|
|
|
|
func (s *Service) validateLightClientFinalityUpdate(ctx context.Context, pid peer.ID, msg *pubsub.Message) (pubsub.ValidationResult, error) {
|
|
// Validation runs on publish (not just subscriptions), so we should approve any message from
|
|
// ourselves.
|
|
if pid == s.cfg.p2p.PeerID() {
|
|
return pubsub.ValidationAccept, nil
|
|
}
|
|
|
|
// Ignore updates while syncing
|
|
if s.cfg.initialSync.Syncing() {
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
_, span := trace.StartSpan(ctx, "sync.validateLightClientFinalityUpdate")
|
|
defer span.End()
|
|
|
|
currentUpdate := s.lcStore.LastFinalityUpdate()
|
|
if currentUpdate == nil {
|
|
log.Debug("No existing finality update to compare against. Ignoring.")
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
m, err := s.decodePubsubMessage(msg)
|
|
if err != nil {
|
|
tracing.AnnotateError(span, err)
|
|
return pubsub.ValidationReject, err
|
|
}
|
|
|
|
newUpdate, ok := m.(interfaces.LightClientFinalityUpdate)
|
|
if !ok {
|
|
return pubsub.ValidationReject, errWrongMessage
|
|
}
|
|
|
|
attestedHeaderRoot, err := newUpdate.AttestedHeader().Beacon().HashTreeRoot()
|
|
if err != nil {
|
|
return pubsub.ValidationIgnore, err
|
|
}
|
|
|
|
// validate that enough time has passed since the start of the slot so the block has had enough time to propagate
|
|
slotStart, err := slots.StartTime(s.cfg.clock.GenesisTime(), newUpdate.SignatureSlot())
|
|
if err != nil {
|
|
log.WithError(err).Debug("Peer sent a slot that would overflow slot start time")
|
|
return pubsub.ValidationReject, nil
|
|
}
|
|
earliestValidTime := slotStart.
|
|
Add(params.BeaconConfig().SlotComponentDuration(params.BeaconConfig().SyncMessageDueBPS)).
|
|
Add(-params.BeaconConfig().MaximumGossipClockDisparityDuration())
|
|
if s.cfg.clock.Now().Before(earliestValidTime) {
|
|
log.Debug("Newly received light client finality update ignored. not enough time passed for block to propagate")
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
if !proto.Equal(newUpdate.Proto(), currentUpdate.Proto()) {
|
|
log.WithFields(logrus.Fields{
|
|
"attestedSlot": fmt.Sprintf("%d", newUpdate.AttestedHeader().Beacon().Slot),
|
|
"signatureSlot": fmt.Sprintf("%d", newUpdate.SignatureSlot()),
|
|
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
|
|
}).Debug("Received light client finality update is different from the local one. ignoring.")
|
|
return pubsub.ValidationIgnore, nil
|
|
}
|
|
|
|
log.WithFields(logrus.Fields{
|
|
"attestedSlot": fmt.Sprintf("%d", newUpdate.AttestedHeader().Beacon().Slot),
|
|
"signatureSlot": fmt.Sprintf("%d", newUpdate.SignatureSlot()),
|
|
"attestedHeaderRoot": fmt.Sprintf("%x", attestedHeaderRoot),
|
|
}).Debug("New gossiped light client finality update validated.")
|
|
|
|
msg.ValidatorData = newUpdate.Proto()
|
|
return pubsub.ValidationAccept, nil
|
|
}
|