ipfs / ipfs/boxo

[ipfs/go-bitswap] Question about sendWants and send blocks in peermanager

Open
#70 2 comments 0 reactions 0 assignees View on GitHub
need/triage
Dominant language
Go
Stars
316
Forks
163
Avg merge
4d 12h
Merged PRs (30d)
8

Description

I've run many rounds of ipfs cluster test with 1 bootstrap node (node1) and 2 nodes (node2 and node3).

And I've discovered **SOMETIMES** (not always) when I put a data (using `ipfs dag put`) on bootstrap node (node1), node2 (sometimes node3) can't get the CID's data (using `ipfs dag get `).

From the debug log I can see the node2 CAN find who has the CID's data block by using DHT network, but bitswap can't get the block and waiting indefinitely.

After some debugging, I found the source code may have some logic in package peermanager:
`https://github.com/ipfs/go-bitswap/blob/master/client/internal/peermanager/peermanager.go`
from line 144 to line 153:
```
// SendWants sends the given want-blocks and want-haves to the given peer.
// It filters out wants that have previously been sent to the peer.
func (pm *PeerManager) SendWants(ctx context.Context, p peer.ID, wantBlocks []cid.Cid, wantHaves []cid.Cid) {
pm.pqLk.Lock()
defer pm.pqLk.Unlock()

if _, ok := pm.peerQueues[p]; ok {
pm.pwm.sendWants(p, wantBlocks, wantHaves)
}
}
```

**SOMETIMES** node2's pm.peerQueues[p] is empty (p is node1 / bootstrap node), node2 CAN'T get the CID's data block from node1 forever.

I don't quite understand why sometimes pm.peerQueues[p] is empty.

Then I tried to add some code in `else` branch like:
```
func (pm *PeerManager) SendWants(ctx context.Context, p peer.ID, wantBlocks []cid.Cid, wantHaves []cid.Cid) {
pm.pqLk.Lock()
defer pm.pqLk.Unlock()

if _, ok := pm.peerQueues[p]; ok {
pm.pwm.sendWants(p, wantBlocks, wantHaves)
} else {
pq := pm.getOrCreate(p)
pm.pwm.addPeer(pq, p) // Inform the peer want manager that there's a new peer
pm.signalAvailability(p, true) // Inform the sessions that the peer has connected
pm.pwm.sendWants(p, wantBlocks, wantHaves)
}
}
```
The logic is: when pm.peerQueues[p] is empty, call "addPeer" to add the peer in the peerQueue explicitly.
After peer added, then node2 can get CID's data block from node1 successfully.

I'm wondering if the code I added is neccessary?
And why the original code does not handle the case when pm.peerQueues[p] is empty ?

Thanks!

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.