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

     1  package sync
     2  
     3  import (
     4  	"context"
     5  
     6  	libp2pcore "github.com/libp2p/go-libp2p-core"
     7  	"github.com/libp2p/go-libp2p-core/peer"
     8  	"github.com/pkg/errors"
     9  	"github.com/prysmaticlabs/prysm/beacon-chain/p2p/types"
    10  	"github.com/prysmaticlabs/prysm/proto/interfaces"
    11  	"github.com/prysmaticlabs/prysm/shared/params"
    12  )
    13  
    14  // sendRecentBeaconBlocksRequest sends a recent beacon blocks request to a peer to get
    15  // those corresponding blocks from that peer.
    16  func (s *Service) sendRecentBeaconBlocksRequest(ctx context.Context, blockRoots *types.BeaconBlockByRootsReq, id peer.ID) error {
    17  	ctx, cancel := context.WithTimeout(ctx, respTimeout)
    18  	defer cancel()
    19  
    20  	_, err := SendBeaconBlocksByRootRequest(ctx, s.cfg.Chain, s.cfg.P2P, id, blockRoots, func(blk interfaces.SignedBeaconBlock) error {
    21  		blkRoot, err := blk.Block().HashTreeRoot()
    22  		if err != nil {
    23  			return err
    24  		}
    25  		s.pendingQueueLock.Lock()
    26  		if err := s.insertBlockToPendingQueue(blk.Block().Slot(), blk, blkRoot); err != nil {
    27  			return err
    28  		}
    29  		s.pendingQueueLock.Unlock()
    30  		return nil
    31  	})
    32  	return err
    33  }
    34  
    35  // beaconBlocksRootRPCHandler looks up the request blocks from the database from the given block roots.
    36  func (s *Service) beaconBlocksRootRPCHandler(ctx context.Context, msg interface{}, stream libp2pcore.Stream) error {
    37  	ctx, cancel := context.WithTimeout(ctx, ttfbTimeout)
    38  	defer cancel()
    39  	SetRPCStreamDeadlines(stream)
    40  	log := log.WithField("handler", "beacon_blocks_by_root")
    41  
    42  	rawMsg, ok := msg.(*types.BeaconBlockByRootsReq)
    43  	if !ok {
    44  		return errors.New("message is not type BeaconBlockByRootsReq")
    45  	}
    46  	blockRoots := *rawMsg
    47  	if err := s.rateLimiter.validateRequest(stream, uint64(len(blockRoots))); err != nil {
    48  		return err
    49  	}
    50  	if len(blockRoots) == 0 {
    51  		// Add to rate limiter in the event no
    52  		// roots are requested.
    53  		s.rateLimiter.add(stream, 1)
    54  		s.writeErrorResponseToStream(responseCodeInvalidRequest, "no block roots provided in request", stream)
    55  		return errors.New("no block roots provided")
    56  	}
    57  
    58  	if uint64(len(blockRoots)) > params.BeaconNetworkConfig().MaxRequestBlocks {
    59  		s.writeErrorResponseToStream(responseCodeInvalidRequest, "requested more than the max block limit", stream)
    60  		return errors.New("requested more than the max block limit")
    61  	}
    62  	s.rateLimiter.add(stream, int64(len(blockRoots)))
    63  
    64  	for _, root := range blockRoots {
    65  		blk, err := s.cfg.DB.Block(ctx, root)
    66  		if err != nil {
    67  			log.WithError(err).Debug("Could not fetch block")
    68  			s.writeErrorResponseToStream(responseCodeServerError, types.ErrGeneric.Error(), stream)
    69  			return err
    70  		}
    71  		if blk == nil || blk.IsNil() {
    72  			continue
    73  		}
    74  		if err := s.chunkWriter(stream, blk.Proto()); err != nil {
    75  			return err
    76  		}
    77  	}
    78  	closeStream(stream, log)
    79  	return nil
    80  }