code: func (d *Downloader) fillHeaderSkeleton(from uint64, skeleton []*types.Header) ([]*types.Header, int, error) {
  	log.Debug("Filling up skeleton", "from", from)
  	d.queue.ScheduleSkeleton(from, skeleton)
  
  	var (
  		deliver = func(packet dataPack) (int, error) {
  			pack := packet.(*headerPack)
  			return d.queue.DeliverHeaders(pack.peerID, pack.headers, d.headerProcCh)
  		}
  		expire   = func() map[string]int { return d.queue.ExpireHeaders(d.requestTTL()) }
  		throttle = func() bool { return false }
  		reserve  = func(p *peerConnection, count int) (*fetchRequest, bool, error) {
  			return d.queue.ReserveHeaders(p, count), false, nil
  		}
  		fetch    = func(p *peerConnection, req *fetchRequest) error { return p.FetchHeaders(req.From, MaxHeaderFetch) }
  		capacity = func(p *peerConnection) int { return p.HeaderCapacity(d.requestRTT()) }
  		setIdle  = func(p *peerConnection, accepted int) { p.SetHeadersIdle(accepted) }
  	)
  	err := d.fetchParts(errCancelHeaderFetch, d.headerCh, deliver, d.queue.headerContCh, expire,
  		d.queue.PendingHeaders, d.queue.InFlightHeaders, throttle, reserve,
  		nil, fetch, d.queue.CancelHeaders, capacity, d.peers.HeaderIdlePeers, setIdle, "headers")
  
  	log.Debug("Skeleton fill terminated", "err", err)
  
  	filled, proced := d.queue.RetrieveHeaders()
  	return filled, proced, err
  }
docs: // fillHeaderSkeleton concurrently retrieves headers from all our available peers
  // and maps them to the provided skeleton header chain.
  //
  // Any partial results from the beginning of the skeleton is (if possible) forwarded
  // immediately to the header processor to keep the rest of the pipeline full even
  // in the case of header stalls.
  //
  // The method returns the entire filled skeleton and also the number of headers
  // already forwarded for processing.