code: func (tab *Table) doRevalidate(done chan<- struct{}) {
  	defer func() { done <- struct{}{} }()
  
  	last, bi := tab.nodeToRevalidate()
  	if last == nil {
  		// No non-empty bucket found.
  		return
  	}
  
  	// Ping the selected node and wait for a pong.
  	err := tab.net.ping(unwrapNode(last))
  
  	tab.mutex.Lock()
  	defer tab.mutex.Unlock()
  	b := tab.buckets[bi]
  	if err == nil {
  		// The node responded, move it to the front.
  		last.livenessChecks++
  		tab.log.Debug("Revalidated node", "b", bi, "id", last.ID(), "checks", last.livenessChecks)
  		tab.bumpInBucket(b, last)
  		return
  	}
  	// No reply received, pick a replacement or delete the node if there aren't
  	// any replacements.
  	if r := tab.replace(b, last); r != nil {
  		tab.log.Debug("Replaced dead node", "b", bi, "id", last.ID(), "ip", last.IP(), "checks", last.livenessChecks, "r", r.ID(), "rip", r.IP())
  	} else {
  		tab.log.Debug("Removed dead node", "b", bi, "id", last.ID(), "ip", last.IP(), "checks", last.livenessChecks)
  	}
  }
docs: // doRevalidate checks that the last node in a random bucket is still live
  // and replaces or deletes the node if it isn't.