[ipfs/go-bitswap] Question about sendWants and send blocks in peermanager
- 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.