// are okay.
type messageWriter func(pp.Message) bool
+// This function seems to only used by Peer.request. It's all logic checks, so maybe we can no-op it
+// when we want to go fast.
func (cn *Peer) shouldRequest(r RequestIndex) error {
pi := pieceIndex(r / cn.t.chunksPerRegularPiece())
if !cn.peerHasPiece(pi) {
panic("piece is queued for hash")
}
if cn.peerChoking && !cn.peerAllowedFast.Contains(bitmap.BitIndex(pi)) {
- panic("peer choking and piece not allowed fast")
+ // This could occur if we made a request with the fast extension, and then got choked and
+ // haven't had the request rejected yet.
+ if !cn.actualRequestState.Requests.Contains(r) {
+ panic("peer choking and piece not allowed fast")
+ }
}
return nil
}
allowedFast := p.peerAllowedFast.ContainsInt(pieceIndex)
rsp.IterPendingChunks.Iter(func(ci request_strategy.ChunkIndex) {
if !allowedFast {
- // We must signal interest to request this..
+ // We must signal interest to request this
desired.Interested = true
+ // We can make or will allow sustaining a request here if we're not choked, or
+ // have made the request previously (presumably while unchoked), and haven't had
+ // the peer respond yet (and the request was retained because we are using the
+ // fast extension).
if p.peerChoking && !p.actualRequestState.Requests.Contains(ci) {
// We can't request this right now.
return