--- 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 } ````