---
tags: workflow
---
# Определение ParentRoot при создании блока
Для Altair & Phase0
````go
// Build data required for creating a new beacon block, so this method can be shared across forks.
func (vs *Server) buildPhase0BlockData(ctx context.Context, req *ethpb.BlockRequest) (*blockData, error) {
...
// Retrieve the parent block as the current head of the canonical chain.
parentRoot, err := vs.HeadFetcher.HeadRoot(ctx)
...
return &blockData{
ParentRoot: parentRoot,
...
}, nil
}
````
````go
// HeadRoot returns the root of the head of the chain.
func (s *Service) HeadRoot(ctx context.Context) ([]byte, error) {
if s.headRoot() != params.BeaconConfig().ZeroHash {
r := s.headRoot()
return r[:], nil
}
b, err := s.cfg.BeaconDB.HeadBlock(ctx)
r, err := b.Block().HashTreeRoot()
return r[:], nil
}
````
````go
// This returns the head root.
func (s *Service) headRoot() [32]byte {
if s.head == nil {
return params.BeaconConfig().ZeroHash
}
return s.head.root
}
````
````go
// HeadBlock returns the head block of the chain.
// If the head is nil from service struct,
// it will attempt to get the head block from DB.
func (s *Service) HeadBlock(ctx context.Context) (block.SignedBeaconBlock, error) {
s.headLock.RLock()
defer s.headLock.RUnlock()
if s.hasHeadState() {
return s.headBlock(), nil
}
return s.cfg.BeaconDB.HeadBlock(ctx)
}
````
````go
// HeadBlock returns the latest canonical block in the Ethereum Beacon Chain.
func (s *Store) HeadBlock(ctx context.Context) (block.SignedBeaconBlock, error) {
var headBlock block.SignedBeaconBlock
err := s.db.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket(blocksBucket)
headRoot := bkt.Get(headBlockRootKey)
if headRoot == nil {
return nil
}
enc := bkt.Get(headRoot)
if enc == nil {
return nil
}
var err error
headBlock, err = unmarshalBlock(ctx, enc)
return err
})
return headBlock, err
}
````