package state_native import ( "fmt" ethpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1" ) // LatestBlockHeader stored within the beacon state. func (b *BeaconState) LatestBlockHeader() *ethpb.BeaconBlockHeader { if b.latestBlockHeader == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() return b.latestBlockHeaderVal() } // latestBlockHeaderVal stored within the beacon state. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) latestBlockHeaderVal() *ethpb.BeaconBlockHeader { if b.latestBlockHeader == nil { return nil } hdr := ðpb.BeaconBlockHeader{ Slot: b.latestBlockHeader.Slot, ProposerIndex: b.latestBlockHeader.ProposerIndex, } parentRoot := make([]byte, len(b.latestBlockHeader.ParentRoot)) bodyRoot := make([]byte, len(b.latestBlockHeader.BodyRoot)) stateRoot := make([]byte, len(b.latestBlockHeader.StateRoot)) copy(parentRoot, b.latestBlockHeader.ParentRoot) copy(bodyRoot, b.latestBlockHeader.BodyRoot) copy(stateRoot, b.latestBlockHeader.StateRoot) hdr.ParentRoot = parentRoot hdr.BodyRoot = bodyRoot hdr.StateRoot = stateRoot return hdr } // BlockRoots kept track of in the beacon state. func (b *BeaconState) BlockRoots() [][]byte { if b.blockRoots == nil { return nil } b.lock.RLock() defer b.lock.RUnlock() return b.blockRoots.Slice() } // BlockRootAtIndex retrieves a specific block root based on an // input index value. func (b *BeaconState) BlockRootAtIndex(idx uint64) ([]byte, error) { if b.blockRoots == nil { return []byte{}, nil } b.lock.RLock() defer b.lock.RUnlock() r, err := b.blockRootAtIndex(idx) if err != nil { return nil, err } return r[:], nil } // blockRootAtIndex retrieves a specific block root based on an // input index value. // This assumes that a lock is already held on BeaconState. func (b *BeaconState) blockRootAtIndex(idx uint64) ([32]byte, error) { if uint64(len(b.blockRoots)) <= idx { return [32]byte{}, fmt.Errorf("index %d out of range", idx) } return b.blockRoots[idx], nil }