rewrite FindProvidersAsync

This PR implements a better `FindProvidersAsync` call that uses the query framework and actually takes advantage of closer peers.
?? confused. 

```Go
if ps.Contains(prov) {
  continue
}
select {
case peerOut <- prov:
case <-ctx.Done(): 
  ...
}
ps.Add(prov)
```

should be

```Go
if ps.Contains(prov) {
  continue
}
ps.Add(prov)
select {
case peerOut <- prov:
case <-ctx.Done(): 
  ...
}
```

actually, that's not even fully correct, because there's a TOCTOU bug (between Contains and Add).

maybe there should be a different goroutine checking + avoiding dupes in one place. and only call Add here:

```Go
ps := newPeerSet()
dedup := func(in <-chan peer.Peer)  <-chan peer.Peer {
  out := make(chan peer.Peer, 10) 
  for {
    p := <- in
    if ps.Contains(p) {
      continue
    }
    ps.Add(p)
    out<- p
  }
  return out
}
out := dedup(make(chan peer.Peer, 1))

```