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 }