github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/sync/validate_proposer_slashing.go (about) 1 package sync 2 3 import ( 4 "context" 5 6 "github.com/libp2p/go-libp2p-core/peer" 7 pubsub "github.com/libp2p/go-libp2p-pubsub" 8 types "github.com/prysmaticlabs/eth2-types" 9 "github.com/prysmaticlabs/prysm/beacon-chain/core/blocks" 10 ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1" 11 "github.com/prysmaticlabs/prysm/shared/traceutil" 12 "go.opencensus.io/trace" 13 ) 14 15 // Clients who receive a proposer slashing on this topic MUST validate the conditions within VerifyProposerSlashing before 16 // forwarding it across the network. 17 func (s *Service) validateProposerSlashing(ctx context.Context, pid peer.ID, msg *pubsub.Message) pubsub.ValidationResult { 18 // Validation runs on publish (not just subscriptions), so we should approve any message from 19 // ourselves. 20 if pid == s.cfg.P2P.PeerID() { 21 return pubsub.ValidationAccept 22 } 23 24 // The head state will be too far away to validate any slashing. 25 if s.cfg.InitialSync.Syncing() { 26 return pubsub.ValidationIgnore 27 } 28 29 ctx, span := trace.StartSpan(ctx, "sync.validateProposerSlashing") 30 defer span.End() 31 32 m, err := s.decodePubsubMessage(msg) 33 if err != nil { 34 log.WithError(err).Debug("Could not decode message") 35 traceutil.AnnotateError(span, err) 36 return pubsub.ValidationReject 37 } 38 39 slashing, ok := m.(*ethpb.ProposerSlashing) 40 if !ok { 41 return pubsub.ValidationReject 42 } 43 44 if slashing.Header_1 == nil || slashing.Header_1.Header == nil { 45 return pubsub.ValidationReject 46 } 47 if s.hasSeenProposerSlashingIndex(slashing.Header_1.Header.ProposerIndex) { 48 return pubsub.ValidationIgnore 49 } 50 51 headState, err := s.cfg.Chain.HeadState(ctx) 52 if err != nil { 53 return pubsub.ValidationIgnore 54 } 55 if err := blocks.VerifyProposerSlashing(headState, slashing); err != nil { 56 return pubsub.ValidationReject 57 } 58 59 msg.ValidatorData = slashing // Used in downstream subscriber 60 return pubsub.ValidationAccept 61 } 62 63 // Returns true if the node has already received a valid proposer slashing received for the proposer with index 64 func (s *Service) hasSeenProposerSlashingIndex(i types.ValidatorIndex) bool { 65 s.seenProposerSlashingLock.RLock() 66 defer s.seenProposerSlashingLock.RUnlock() 67 _, seen := s.seenProposerSlashingCache.Get(i) 68 return seen 69 } 70 71 // Set proposer slashing index in proposer slashing cache. 72 func (s *Service) setProposerSlashingIndexSeen(i types.ValidatorIndex) { 73 s.seenProposerSlashingLock.Lock() 74 defer s.seenProposerSlashingLock.Unlock() 75 s.seenProposerSlashingCache.Add(i, true) 76 }