code: func (d *Downloader) fetchHeight(p *peerConnection) (*types.Header, error) {
  	p.log.Debug("Retrieving remote chain height")
  
  	// Request the advertised remote head block and wait for the response
  	head, _ := p.peer.Head()
  	go p.peer.RequestHeadersByHash(head, 1, 0, false)
  
  	ttl := d.requestTTL()
  	timeout := time.After(ttl)
  	for {
  		select {
  		case <-d.cancelCh:
  			return nil, errCancelBlockFetch
  
  		case packet := <-d.headerCh:
  			// Discard anything not from the origin peer
  			if packet.PeerId() != p.id {
  				log.Debug("Received headers from incorrect peer", "peer", packet.PeerId())
  				break
  			}
  			// Make sure the peer actually gave something valid
  			headers := packet.(*headerPack).headers
  			if len(headers) != 1 {
  				p.log.Debug("Multiple headers for single request", "headers", len(headers))
  				return nil, errBadPeer
  			}
  			head := headers[0]
  			if (d.mode == FastSync || d.mode == LightSync) && head.Number.Uint64() < d.checkpoint {
  				p.log.Warn("Remote head below checkpoint", "number", head.Number, "hash", head.Hash())
  				return nil, errUnsyncedPeer
  			}
  			p.log.Debug("Remote head header identified", "number", head.Number, "hash", head.Hash())
  			return head, nil
  
  		case <-timeout:
  			p.log.Debug("Waiting for head header timed out", "elapsed", ttl)
  			return nil, errTimeout
  
  		case <-d.bodyCh:
  		case <-d.receiptCh:
  			// Out of bounds delivery, ignore
  		}
  	}
  }
docs: // fetchHeight retrieves the head header of the remote peer to aid in estimating
  // the total time a pending synchronisation would take.