feat(bitswap) find providers for all keys on wantlist
@jbenet @whyrusleeping this addresses a failure case where 1) bitswap wants blocks A and B 2) partner 1 has A and partner 2 has B 3) We choose a key at random, drawing A. 4) Then, we request A, neglecting to find a provider for B. Sending the full wantlist is meant to be used as a helpful additional piece of data, but... unless our hunch is support by statistical inference at runtime, it's not safe to assume that a peer will have blocks for related keys. Routing must be the source of truth. License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com>
Brian Tiger Chow committed
Nov 20, 2014 at 18:19 UTC
ecf62dbf3a52f3742bd62cf2394fc77513e3c85b
1 file changed
+6
-11
exchange/bitswap/bitswap.go
+6
-11
@@ -3,7 +3,6 @@
3
package bitswap
4
5
import (
6
- "math/rand"
6
"time"
7
8
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
@@ -175,16 +174,12 @@ func (bs *bitswap) run(ctx context.Context) {
174
for {
175
select {
176
case <-broadcastSignal.C:
178
- wantlist := bs.wantlist.Keys()
179
- if len(wantlist) == 0 {
180
- continue
181
- }
182
- n := rand.Intn(len(wantlist))
183
- providers := bs.routing.FindProvidersAsync(ctx, wantlist[n], maxProvidersPerRequest)
184
-
185
- err := bs.sendWantListTo(ctx, providers)
186
- if err != nil {
187
- log.Errorf("error sending wantlist: %s", err)
177
+ for _, k := range bs.wantlist.Keys() {
178
+ providers := bs.routing.FindProvidersAsync(ctx, k, maxProvidersPerRequest)
179
+ err := bs.sendWantListTo(ctx, providers)
180
+ if err != nil {
181
+ log.Errorf("error sending wantlist: %s", err)
182
+ }
183
}
184
case ks := <-bs.batchRequests:
185
// TODO: implement batching on len(ks) > X for some X