code: func (b *blockManager) handleNewPeerMsg(peers *list.List, sp *ServerPeer) {
  	// Ignore if in the process of shutting down.
  	if atomic.LoadInt32(&b.shutdown) != 0 {
  		return
  	}
  
  	log.Infof("New valid peer %s (%s)", sp, sp.UserAgent())
  
  	// Ignore the peer if it's not a sync candidate.
  	if !b.isSyncCandidate(sp) {
  		return
  	}
  
  	// Add the peer as a candidate to sync from.
  	peers.PushBack(sp)
  
  	// If we're current with our sync peer and the new peer is advertising
  	// a higher block than the newest one we know of, request headers from
  	// the new peer.
  	_, height, err := b.server.BlockHeaders.ChainTip()
  	if err != nil {
  		log.Criticalf("Couldn't retrieve block header chain tip: %s",
  			err)
  		return
  	}
  	if height < uint32(sp.StartingHeight()) && b.BlockHeadersSynced() {
  		locator, err := b.server.BlockHeaders.LatestBlockLocator()
  		if err != nil {
  			log.Criticalf("Couldn't retrieve latest block "+
  				"locator: %s", err)
  			return
  		}
  		stopHash := &zeroHash
  		sp.PushGetHeadersMsg(locator, stopHash)
  	}
  
  	// Start syncing by choosing the best candidate if needed.
  	b.startSync(peers)
  }
docs: // handleNewPeerMsg deals with new peers that have signalled they may be
  // considered as a sync peer (they have already successfully negotiated).  It
  // also starts syncing if needed.  It is invoked from the syncHandler
  // goroutine.