github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/blockchain/weak_subjectivity_checks.go (about)

     1  package blockchain
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
     8  	"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
     9  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    10  	"github.com/prysmaticlabs/prysm/shared/params"
    11  )
    12  
    13  // VerifyWeakSubjectivityRoot verifies the weak subjectivity root in the service struct.
    14  // Reference design: https://github.com/ethereum/eth2.0-specs/blob/master/specs/phase0/weak-subjectivity.md#weak-subjectivity-sync-procedure
    15  func (s *Service) VerifyWeakSubjectivityRoot(ctx context.Context) error {
    16  	// TODO(7342): Remove the following to fully use weak subjectivity in production.
    17  	if s.cfg.WeakSubjectivityCheckpt == nil || len(s.cfg.WeakSubjectivityCheckpt.Root) == 0 || s.cfg.WeakSubjectivityCheckpt.Epoch == 0 {
    18  		return nil
    19  	}
    20  
    21  	// Do nothing if the weak subjectivity has previously been verified,
    22  	// or weak subjectivity epoch is higher than last finalized epoch.
    23  	if s.wsVerified {
    24  		return nil
    25  	}
    26  	if s.cfg.WeakSubjectivityCheckpt.Epoch > s.finalizedCheckpt.Epoch {
    27  		return nil
    28  	}
    29  
    30  	r := bytesutil.ToBytes32(s.cfg.WeakSubjectivityCheckpt.Root)
    31  	log.Infof("Performing weak subjectivity check for root %#x in epoch %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
    32  	// Save initial sync cached blocks to DB.
    33  	if err := s.cfg.BeaconDB.SaveBlocks(ctx, s.getInitSyncBlocks()); err != nil {
    34  		return err
    35  	}
    36  	// A node should have the weak subjectivity block in the DB.
    37  	if !s.cfg.BeaconDB.HasBlock(ctx, r) {
    38  		return fmt.Errorf("node does not have root in DB: %#x", r)
    39  	}
    40  
    41  	startSlot, err := helpers.StartSlot(s.cfg.WeakSubjectivityCheckpt.Epoch)
    42  	if err != nil {
    43  		return err
    44  	}
    45  	// A node should have the weak subjectivity block corresponds to the correct epoch in the DB.
    46  	filter := filters.NewFilter().SetStartSlot(startSlot).SetEndSlot(startSlot + params.BeaconConfig().SlotsPerEpoch)
    47  	roots, err := s.cfg.BeaconDB.BlockRoots(ctx, filter)
    48  	if err != nil {
    49  		return err
    50  	}
    51  	for _, root := range roots {
    52  		if r == root {
    53  			log.Info("Weak subjectivity check has passed")
    54  			s.wsVerified = true
    55  			return nil
    56  		}
    57  	}
    58  
    59  	return fmt.Errorf("node does not have root in db corresponding to epoch: %#x %d", r, s.cfg.WeakSubjectivityCheckpt.Epoch)
    60  }