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

     1  package v1
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/prysmaticlabs/prysm/shared/copyutil"
     7  
     8  	"github.com/pkg/errors"
     9  	pbp2p "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
    10  	ethpb "github.com/prysmaticlabs/prysm/proto/eth/v1alpha1"
    11  )
    12  
    13  // InnerStateUnsafe returns the pointer value of the underlying
    14  // beacon state proto object, bypassing immutability. Use with care.
    15  func (b *BeaconState) InnerStateUnsafe() interface{} {
    16  	if b == nil {
    17  		return nil
    18  	}
    19  	return b.state
    20  }
    21  
    22  // CloneInnerState the beacon state into a protobuf for usage.
    23  func (b *BeaconState) CloneInnerState() interface{} {
    24  	if b == nil || b.state == nil {
    25  		return nil
    26  	}
    27  
    28  	b.lock.RLock()
    29  	defer b.lock.RUnlock()
    30  	return &pbp2p.BeaconState{
    31  		GenesisTime:                 b.genesisTime(),
    32  		GenesisValidatorsRoot:       b.genesisValidatorRoot(),
    33  		Slot:                        b.slot(),
    34  		Fork:                        b.fork(),
    35  		LatestBlockHeader:           b.latestBlockHeader(),
    36  		BlockRoots:                  b.blockRoots(),
    37  		StateRoots:                  b.stateRoots(),
    38  		HistoricalRoots:             b.historicalRoots(),
    39  		Eth1Data:                    b.eth1Data(),
    40  		Eth1DataVotes:               b.eth1DataVotes(),
    41  		Eth1DepositIndex:            b.eth1DepositIndex(),
    42  		Validators:                  b.validators(),
    43  		Balances:                    b.balances(),
    44  		RandaoMixes:                 b.randaoMixes(),
    45  		Slashings:                   b.slashings(),
    46  		PreviousEpochAttestations:   b.previousEpochAttestations(),
    47  		CurrentEpochAttestations:    b.currentEpochAttestations(),
    48  		JustificationBits:           b.justificationBits(),
    49  		PreviousJustifiedCheckpoint: b.previousJustifiedCheckpoint(),
    50  		CurrentJustifiedCheckpoint:  b.currentJustifiedCheckpoint(),
    51  		FinalizedCheckpoint:         b.finalizedCheckpoint(),
    52  	}
    53  }
    54  
    55  // hasInnerState detects if the internal reference to the state data structure
    56  // is populated correctly. Returns false if nil.
    57  func (b *BeaconState) hasInnerState() bool {
    58  	return b != nil && b.state != nil
    59  }
    60  
    61  // StateRoots kept track of in the beacon state.
    62  func (b *BeaconState) StateRoots() [][]byte {
    63  	if !b.hasInnerState() {
    64  		return nil
    65  	}
    66  	if b.state.StateRoots == nil {
    67  		return nil
    68  	}
    69  
    70  	b.lock.RLock()
    71  	defer b.lock.RUnlock()
    72  
    73  	return b.stateRoots()
    74  }
    75  
    76  // StateRoots kept track of in the beacon state.
    77  // This assumes that a lock is already held on BeaconState.
    78  func (b *BeaconState) stateRoots() [][]byte {
    79  	if !b.hasInnerState() {
    80  		return nil
    81  	}
    82  	return b.safeCopy2DByteSlice(b.state.StateRoots)
    83  }
    84  
    85  // StateRootAtIndex retrieves a specific state root based on an
    86  // input index value.
    87  func (b *BeaconState) StateRootAtIndex(idx uint64) ([]byte, error) {
    88  	if !b.hasInnerState() {
    89  		return nil, ErrNilInnerState
    90  	}
    91  	if b.state.StateRoots == nil {
    92  		return nil, nil
    93  	}
    94  
    95  	b.lock.RLock()
    96  	defer b.lock.RUnlock()
    97  
    98  	return b.stateRootAtIndex(idx)
    99  }
   100  
   101  // stateRootAtIndex retrieves a specific state root based on an
   102  // input index value.
   103  // This assumes that a lock is already held on BeaconState.
   104  func (b *BeaconState) stateRootAtIndex(idx uint64) ([]byte, error) {
   105  	if !b.hasInnerState() {
   106  		return nil, ErrNilInnerState
   107  	}
   108  	return b.safeCopyBytesAtIndex(b.state.StateRoots, idx)
   109  }
   110  
   111  // MarshalSSZ marshals the underlying beacon state to bytes.
   112  func (b *BeaconState) MarshalSSZ() ([]byte, error) {
   113  	if !b.hasInnerState() {
   114  		return nil, errors.New("nil beacon state")
   115  	}
   116  	return b.state.MarshalSSZ()
   117  }
   118  
   119  // ProtobufBeaconState transforms an input into beacon state in the form of protobuf.
   120  // Error is returned if the input is not type protobuf beacon state.
   121  func ProtobufBeaconState(s interface{}) (*pbp2p.BeaconState, error) {
   122  	pbState, ok := s.(*pbp2p.BeaconState)
   123  	if !ok {
   124  		return nil, errors.New("input is not type pb.BeaconState")
   125  	}
   126  	return pbState, nil
   127  }
   128  
   129  func (b *BeaconState) safeCopy2DByteSlice(input [][]byte) [][]byte {
   130  	if input == nil {
   131  		return nil
   132  	}
   133  
   134  	dst := make([][]byte, len(input))
   135  	for i, r := range input {
   136  		tmp := make([]byte, len(r))
   137  		copy(tmp, r)
   138  		dst[i] = tmp
   139  	}
   140  	return dst
   141  }
   142  
   143  func (b *BeaconState) safeCopyBytesAtIndex(input [][]byte, idx uint64) ([]byte, error) {
   144  	if input == nil {
   145  		return nil, nil
   146  	}
   147  
   148  	if uint64(len(input)) <= idx {
   149  		return nil, fmt.Errorf("index %d out of range", idx)
   150  	}
   151  	root := make([]byte, 32)
   152  	copy(root, input[idx])
   153  	return root, nil
   154  }
   155  
   156  func (b *BeaconState) safeCopyPendingAttestationSlice(input []*pbp2p.PendingAttestation) []*pbp2p.PendingAttestation {
   157  	if input == nil {
   158  		return nil
   159  	}
   160  
   161  	res := make([]*pbp2p.PendingAttestation, len(input))
   162  	for i := 0; i < len(res); i++ {
   163  		res[i] = copyutil.CopyPendingAttestation(input[i])
   164  	}
   165  	return res
   166  }
   167  
   168  func (b *BeaconState) safeCopyCheckpoint(input *ethpb.Checkpoint) *ethpb.Checkpoint {
   169  	if input == nil {
   170  		return nil
   171  	}
   172  
   173  	return copyutil.CopyCheckpoint(input)
   174  }