@@ -24,8 +24,10 @@ import (
24
24
// ErrNoPeersQueried is returned when we failed to connect to any peers.
25
25
var ErrNoPeersQueried = errors .New ("failed to query any peers" )
26
26
27
- type queryFn func (context.Context , peer.ID ) ([]* peer.AddrInfo , error )
28
- type stopFn func (* qpeerset.QueryPeerset ) bool
27
+ type (
28
+ queryFn func (context.Context , peer.ID ) ([]* peer.AddrInfo , error )
29
+ stopFn func (* qpeerset.QueryPeerset ) bool
30
+ )
29
31
30
32
// query represents a single DHT query.
31
33
type query struct {
@@ -187,7 +189,7 @@ func (dht *IpfsDHT) runQuery(ctx context.Context, target string, queryFn queryFn
187
189
q .recordValuablePeers ()
188
190
}
189
191
190
- res := q .constructLookupResult (targetKadID )
192
+ res := q .constructLookupResult ()
191
193
return res , q .queryPeers , nil
192
194
}
193
195
@@ -218,45 +220,29 @@ func (q *query) recordValuablePeers() {
218
220
}
219
221
220
222
// constructLookupResult takes the query information and uses it to construct the lookup result
221
- func (q * query ) constructLookupResult (target kb.ID ) * lookupWithFollowupResult {
222
- // determine if the query terminated early
223
- completed := true
224
-
225
- // Lookup and starvation are both valid ways for a lookup to complete. (Starvation does not imply failure.)
226
- // Lookup termination (as defined in isLookupTermination) is not possible in small networks.
227
- // Starvation is a successful query termination in small networks.
228
- if ! (q .isLookupTermination () || q .isStarvationTermination ()) {
229
- completed = false
230
- }
223
+ func (q * query ) constructLookupResult () * lookupWithFollowupResult {
224
+ // Lookup and starvation are both valid ways for a lookup to complete.
225
+ // (Starvation does not imply failure.) Lookup termination (as defined in
226
+ // isLookupTermination) is not possible in small networks. Starvation is a
227
+ // successful query termination in small networks.
228
+ completed := q .isLookupTermination () || q .isStarvationTermination ()
231
229
232
230
// extract the top K not unreachable peers
233
- var peers []peer.ID
234
- peerState := make (map [peer.ID ]qpeerset.PeerState )
235
- qp := q .queryPeers .GetClosestNInStates (q .dht .bucketSize , qpeerset .PeerHeard , qpeerset .PeerWaiting , qpeerset .PeerQueried )
236
- for _ , p := range qp {
237
- state := q .queryPeers .GetState (p )
238
- peerState [p ] = state
239
- peers = append (peers , p )
240
- }
241
-
242
- // get the top K overall peers
243
- sortedPeers := kb .SortClosestPeers (peers , target )
244
- if len (sortedPeers ) > q .dht .bucketSize {
245
- sortedPeers = sortedPeers [:q .dht .bucketSize ]
246
- }
231
+ peers := q .queryPeers .GetClosestNInStates (q .dht .bucketSize , qpeerset .PeerHeard , qpeerset .PeerWaiting , qpeerset .PeerQueried )
247
232
233
+ // get the top K overall peers (including unreachable)
248
234
closest := q .queryPeers .GetClosestNInStates (q .dht .bucketSize , qpeerset .PeerHeard , qpeerset .PeerWaiting , qpeerset .PeerQueried , qpeerset .PeerUnreachable )
249
235
250
236
// return the top K not unreachable peers as well as their states at the end of the query
251
237
res := & lookupWithFollowupResult {
252
- peers : sortedPeers ,
253
- state : make ([]qpeerset.PeerState , len (sortedPeers )),
238
+ peers : peers ,
239
+ state : make ([]qpeerset.PeerState , len (peers )),
254
240
completed : completed ,
255
241
closest : closest ,
256
242
}
257
243
258
- for i , p := range sortedPeers {
259
- res .state [i ] = peerState [ p ]
244
+ for i , p := range peers {
245
+ res .state [i ] = q . queryPeers . GetState ( p )
260
246
}
261
247
262
248
return res
@@ -301,7 +287,7 @@ func (q *query) run() {
301
287
302
288
// termination is triggered on end-of-lookup conditions or starvation of unused peers
303
289
// it also returns the peers we should query next for a maximum of `maxNumQueriesToSpawn` peers.
304
- ready , reason , qPeers := q .isReadyToTerminate (pathCtx , maxNumQueriesToSpawn )
290
+ ready , reason , qPeers := q .isReadyToTerminate (maxNumQueriesToSpawn )
305
291
if ready {
306
292
q .terminate (pathCtx , cancelPath , reason )
307
293
}
@@ -347,7 +333,7 @@ func (q *query) spawnQuery(ctx context.Context, cause peer.ID, queryPeer peer.ID
347
333
go q .queryPeer (ctx , ch , queryPeer )
348
334
}
349
335
350
- func (q * query ) isReadyToTerminate (ctx context. Context , nPeersToQuery int ) (bool , LookupTerminationReason , []peer.ID ) {
336
+ func (q * query ) isReadyToTerminate (nPeersToQuery int ) (bool , LookupTerminationReason , []peer.ID ) {
351
337
// give the application logic a chance to terminate
352
338
if q .stopFn (q .queryPeers ) {
353
339
return true , LookupStopped , nil
@@ -360,16 +346,7 @@ func (q *query) isReadyToTerminate(ctx context.Context, nPeersToQuery int) (bool
360
346
}
361
347
362
348
// The peers we query next should be ones that we have only Heard about.
363
- var peersToQuery []peer.ID
364
- peers := q .queryPeers .GetClosestInStates (qpeerset .PeerHeard )
365
- count := 0
366
- for _ , p := range peers {
367
- peersToQuery = append (peersToQuery , p )
368
- count ++
369
- if count == nPeersToQuery {
370
- break
371
- }
372
- }
349
+ peersToQuery := q .queryPeers .GetClosestNInStates (nPeersToQuery , qpeerset .PeerHeard )
373
350
374
351
return false , - 1 , peersToQuery
375
352
}
@@ -415,12 +392,10 @@ func (q *query) terminate(ctx context.Context, cancel context.CancelFunc, reason
415
392
// queryPeer queries a single peer and reports its findings on the channel.
416
393
// queryPeer does not access the query state in queryPeers!
417
394
func (q * query ) queryPeer (ctx context.Context , ch chan <- * queryUpdate , p peer.ID ) {
418
- defer q .waitGroup .Done ()
419
-
420
395
ctx , span := internal .StartSpan (ctx , "IpfsDHT.QueryPeer" )
421
396
defer span .End ()
422
397
423
- dialCtx , queryCtx := ctx , ctx
398
+ dialCtx , queryCtx := ctx , q . ctx
424
399
425
400
// dial the peer
426
401
if err := q .dht .dialPeer (dialCtx , p ); err != nil {
0 commit comments