github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/rpc/prysm/v1alpha1/debug/block.go (about)

     1  package debug
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	types "github.com/prysmaticlabs/eth2-types"
     8  	"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
     9  	"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
    10  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
    11  	pbrpc "github.com/prysmaticlabs/prysm/proto/beacon/rpc/v1"
    12  	"github.com/prysmaticlabs/prysm/shared/attestationutil"
    13  	"github.com/prysmaticlabs/prysm/shared/bytesutil"
    14  	"github.com/prysmaticlabs/prysm/shared/params"
    15  	"google.golang.org/grpc/codes"
    16  	"google.golang.org/grpc/status"
    17  )
    18  
    19  // GetBlock in an ssz-encoded format by block root.
    20  func (ds *Server) GetBlock(
    21  	ctx context.Context,
    22  	req *pbrpc.BlockRequest,
    23  ) (*pbrpc.SSZResponse, error) {
    24  	root := bytesutil.ToBytes32(req.BlockRoot)
    25  	signedBlock, err := ds.BeaconDB.Block(ctx, root)
    26  	if err != nil {
    27  		return nil, status.Errorf(codes.Internal, "Could not retrieve block by root: %v", err)
    28  	}
    29  	if signedBlock == nil || signedBlock.IsNil() {
    30  		return &pbrpc.SSZResponse{Encoded: make([]byte, 0)}, nil
    31  	}
    32  	encoded, err := signedBlock.MarshalSSZ()
    33  	if err != nil {
    34  		return nil, status.Errorf(codes.Internal, "Could not marshal block: %v", err)
    35  	}
    36  	return &pbrpc.SSZResponse{
    37  		Encoded: encoded,
    38  	}, nil
    39  }
    40  
    41  // GetInclusionSlot of an attestation in block.
    42  func (ds *Server) GetInclusionSlot(ctx context.Context, req *pbrpc.InclusionSlotRequest) (*pbrpc.InclusionSlotResponse, error) {
    43  	ds.GenesisTimeFetcher.CurrentSlot()
    44  
    45  	// Attestation has one epoch to get included in the chain. This blocks users from requesting too soon.
    46  	epochBack := types.Slot(0)
    47  	if ds.GenesisTimeFetcher.CurrentSlot() > params.BeaconConfig().SlotsPerEpoch {
    48  		epochBack = ds.GenesisTimeFetcher.CurrentSlot() - params.BeaconConfig().SlotsPerEpoch
    49  	}
    50  	if epochBack < req.Slot {
    51  		return nil, fmt.Errorf("attestation has one epoch window, please request slot older than %d", epochBack)
    52  	}
    53  
    54  	// Attestation could be in blocks between slot + 1 to slot + epoch_duration.
    55  	startSlot := req.Slot + params.BeaconConfig().MinAttestationInclusionDelay
    56  	endSlot := req.Slot + params.BeaconConfig().SlotsPerEpoch
    57  
    58  	filter := filters.NewFilter().SetStartSlot(startSlot).SetEndSlot(endSlot)
    59  	blks, _, err := ds.BeaconDB.Blocks(ctx, filter)
    60  	if err != nil {
    61  		return nil, status.Errorf(codes.Internal, "Could not retrieve blocks: %v", err)
    62  	}
    63  
    64  	inclusionSlot := types.Slot(1<<64 - 1)
    65  	targetStates := make(map[[32]byte]iface.ReadOnlyBeaconState)
    66  	for _, blk := range blks {
    67  		for _, a := range blk.Block().Body().Attestations() {
    68  			tr := bytesutil.ToBytes32(a.Data.Target.Root)
    69  			s, ok := targetStates[tr]
    70  			if !ok {
    71  				s, err = ds.StateGen.StateByRoot(ctx, tr)
    72  				if err != nil {
    73  					return nil, status.Errorf(codes.Internal, "Could not retrieve state: %v", err)
    74  				}
    75  				targetStates[tr] = s
    76  			}
    77  			c, err := helpers.BeaconCommitteeFromState(s, a.Data.Slot, a.Data.CommitteeIndex)
    78  			if err != nil {
    79  				return nil, status.Errorf(codes.Internal, "Could not get committee: %v", err)
    80  			}
    81  			indices, err := attestationutil.AttestingIndices(a.AggregationBits, c)
    82  			if err != nil {
    83  				return nil, err
    84  			}
    85  			for _, i := range indices {
    86  				if req.Id == i && req.Slot == a.Data.Slot {
    87  					inclusionSlot = blk.Block().Slot()
    88  					break
    89  				}
    90  			}
    91  		}
    92  	}
    93  
    94  	return &pbrpc.InclusionSlotResponse{Slot: inclusionSlot}, nil
    95  }