github.com/prysmaticlabs/prysm@v1.4.4/beacon-chain/core/helpers/block.go (about)

     1  package helpers
     2  
     3  import (
     4  	"math"
     5  
     6  	"github.com/pkg/errors"
     7  	types "github.com/prysmaticlabs/eth2-types"
     8  	iface "github.com/prysmaticlabs/prysm/beacon-chain/state/interface"
     9  	"github.com/prysmaticlabs/prysm/proto/interfaces"
    10  	"github.com/prysmaticlabs/prysm/shared/params"
    11  )
    12  
    13  // VerifyNilBeaconBlock checks if any composite field of input signed beacon block is nil.
    14  // Access to these nil fields will result in run time panic,
    15  // it is recommended to run these checks as first line of defense.
    16  func VerifyNilBeaconBlock(b interfaces.SignedBeaconBlock) error {
    17  	if b == nil || b.IsNil() {
    18  		return errors.New("signed beacon block can't be nil")
    19  	}
    20  	if b.Block().IsNil() {
    21  		return errors.New("beacon block can't be nil")
    22  	}
    23  	if b.Block().Body().IsNil() {
    24  		return errors.New("beacon block body can't be nil")
    25  	}
    26  	return nil
    27  }
    28  
    29  // BlockRootAtSlot returns the block root stored in the BeaconState for a recent slot.
    30  // It returns an error if the requested block root is not within the slot range.
    31  //
    32  // Spec pseudocode definition:
    33  //  def get_block_root_at_slot(state: BeaconState, slot: Slot) -> Root:
    34  //    """
    35  //    Return the block root at a recent ``slot``.
    36  //    """
    37  //    assert slot < state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
    38  //    return state.block_roots[slot % SLOTS_PER_HISTORICAL_ROOT]
    39  func BlockRootAtSlot(state iface.ReadOnlyBeaconState, slot types.Slot) ([]byte, error) {
    40  	if math.MaxUint64-slot < params.BeaconConfig().SlotsPerHistoricalRoot {
    41  		return []byte{}, errors.New("slot overflows uint64")
    42  	}
    43  	if slot >= state.Slot() || state.Slot() > slot+params.BeaconConfig().SlotsPerHistoricalRoot {
    44  		return []byte{}, errors.Errorf("slot %d out of bounds", slot)
    45  	}
    46  	return state.BlockRootAtIndex(uint64(slot % params.BeaconConfig().SlotsPerHistoricalRoot))
    47  }
    48  
    49  // StateRootAtSlot returns the cached state root at that particular slot. If no state
    50  // root has been cached it will return a zero-hash.
    51  func StateRootAtSlot(state iface.ReadOnlyBeaconState, slot types.Slot) ([]byte, error) {
    52  	if slot >= state.Slot() || state.Slot() > slot+params.BeaconConfig().SlotsPerHistoricalRoot {
    53  		return []byte{}, errors.Errorf("slot %d out of bounds", slot)
    54  	}
    55  	return state.StateRootAtIndex(uint64(slot % params.BeaconConfig().SlotsPerHistoricalRoot))
    56  }
    57  
    58  // BlockRoot returns the block root stored in the BeaconState for epoch start slot.
    59  //
    60  // Spec pseudocode definition:
    61  //  def get_block_root(state: BeaconState, epoch: Epoch) -> Root:
    62  //    """
    63  //    Return the block root at the start of a recent ``epoch``.
    64  //    """
    65  //    return get_block_root_at_slot(state, compute_start_slot_at_epoch(epoch))
    66  func BlockRoot(state iface.ReadOnlyBeaconState, epoch types.Epoch) ([]byte, error) {
    67  	s, err := StartSlot(epoch)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	return BlockRootAtSlot(state, s)
    72  }