github.com/prysmaticlabs/prysm@v1.4.4/slasher/detection/listeners.go (about)

     1  /*
     2  Package detection defines a service that reacts to incoming blocks/attestations
     3  by running slashing detection for double proposals, double votes, and surround votes
     4  according to the Ethereum Beacon Chain specification. As soon as slashing objects are found, they are
     5  sent over a feed for the beaconclient service to submit to a beacon node via gRPC.
     6  */
     7  package detection
     8  
     9  import (
    10  	"context"
    11  
    12  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    13  	"github.com/prysmaticlabs/prysm/shared/blockutil"
    14  	"go.opencensus.io/trace"
    15  )
    16  
    17  // detectIncomingBlocks subscribes to an event feed for
    18  // block objects from a notifier interface. Upon receiving
    19  // a signed beacon block from the feed, we run proposer slashing
    20  // detection on the block.
    21  func (s *Service) detectIncomingBlocks(ctx context.Context, ch chan *ethpb.SignedBeaconBlock) {
    22  	ctx, span := trace.StartSpan(ctx, "detection.detectIncomingBlocks")
    23  	defer span.End()
    24  	sub := s.cfg.Notifier.BlockFeed().Subscribe(ch)
    25  	defer sub.Unsubscribe()
    26  	for {
    27  		select {
    28  		case signedBlock := <-ch:
    29  			signedBlkHdr, err := blockutil.SignedBeaconBlockHeaderFromBlock(signedBlock)
    30  			if err != nil {
    31  				log.WithError(err).Error("Could not get block header from block")
    32  				continue
    33  			}
    34  			slashing, err := s.proposalsDetector.DetectDoublePropose(ctx, signedBlkHdr)
    35  			if err != nil {
    36  				log.WithError(err).Error("Could not perform detection on block header")
    37  				continue
    38  			}
    39  			s.submitProposerSlashing(ctx, slashing)
    40  		case <-sub.Err():
    41  			log.Error("Subscriber closed, exiting goroutine")
    42  			return
    43  		case <-ctx.Done():
    44  			log.Error("Context canceled")
    45  			return
    46  		}
    47  	}
    48  }
    49  
    50  // detectIncomingAttestations subscribes to an event feed for
    51  // attestation objects from a notifier interface. Upon receiving
    52  // an attestation from the feed, we run surround vote and double vote
    53  // detection on the attestation.
    54  func (s *Service) detectIncomingAttestations(ctx context.Context, ch chan *ethpb.IndexedAttestation) {
    55  	ctx, span := trace.StartSpan(ctx, "detection.detectIncomingAttestations")
    56  	defer span.End()
    57  	sub := s.cfg.Notifier.AttestationFeed().Subscribe(ch)
    58  	defer sub.Unsubscribe()
    59  	for {
    60  		select {
    61  		case indexedAtt := <-ch:
    62  			slashings, err := s.DetectAttesterSlashings(ctx, indexedAtt)
    63  			if err != nil {
    64  				log.WithError(err).Error("Could not detect attester slashings")
    65  				continue
    66  			}
    67  			if len(slashings) < 1 {
    68  				if err := s.minMaxSpanDetector.UpdateSpans(ctx, indexedAtt); err != nil {
    69  					log.WithError(err).Error("Could not update spans")
    70  				}
    71  			}
    72  			s.submitAttesterSlashings(ctx, slashings)
    73  
    74  			if err := s.UpdateHighestAttestation(ctx, indexedAtt); err != nil {
    75  				log.WithError(err).Error("Could not update highest attestation")
    76  			}
    77  		case <-sub.Err():
    78  			log.Error("Subscriber closed, exiting goroutine")
    79  			return
    80  		case <-ctx.Done():
    81  			log.Error("Context canceled")
    82  			return
    83  		}
    84  	}
    85  }