]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Kick only the worst connection when a piece fails a check
authorMatt Joiner <anacrolix@gmail.com>
Wed, 23 Nov 2016 01:59:23 +0000 (12:59 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 23 Nov 2016 01:59:23 +0000 (12:59 +1100)
TODO
connection.go
misc.go
torrent.go

diff --git a/TODO b/TODO
index 9895f0449e0f27ff5e305366779a1692cee8ba87..16e9cbb5b3e872e54092baefd52cb792a41f6985 100644 (file)
--- a/TODO
+++ b/TODO
@@ -12,4 +12,3 @@
  * Implement BEP 40.
  * Rewrite tracker package to be announce-centric, rather than client. Currently the clients are private and adapted onto by the Announce() func.
  * Move tracker management code in the torrent package to its own file.
- * Kick only the poorest connection when a piece hash fails
index 94451c6de6d6939dda04e1f72aef6f30d116cb01..727f97f7846db605da1f43f487d3e8644e56ed77 100644 (file)
@@ -1068,3 +1068,7 @@ func (cn *connection) Drop() {
 func (cn *connection) sentHave(piece int) bool {
        return piece < len(cn.sentHaves) && cn.sentHaves[piece]
 }
+
+func (cn *connection) netGoodPiecesDirtied() int {
+       return cn.goodPiecesDirtied - cn.badPiecesDirtied
+}
diff --git a/misc.go b/misc.go
index a9b024ec4c7f9a2cccfb39dd25bf8f68d277e5e9..9d26738c765202f9bf0f1e6aad265e140fc2d6a1 100644 (file)
--- a/misc.go
+++ b/misc.go
@@ -81,3 +81,7 @@ func chunkIndexSpec(index int, pieceLength, chunkSize pp.Integer) chunkSpec {
        }
        return ret
 }
+
+func connLessTrusted(l, r *connection) bool {
+       return l.netGoodPiecesDirtied() < r.netGoodPiecesDirtied()
+}
index 89422917de494b24ecb03724c0b2c5214881db94..8610a5ec99ed7ff95d1c006fd54559efc62ef714 100644 (file)
@@ -1415,18 +1415,18 @@ func (t *Torrent) pieceHashed(piece int, correct bool) {
                return
        }
        p := &t.pieces[piece]
+       touchers := t.reapPieceTouchers(piece)
        if p.EverHashed {
                // Don't score the first time a piece is hashed, it could be an
                // initial check.
                if correct {
                        pieceHashedCorrect.Add(1)
                } else {
-                       log.Printf("%s: piece %d (%x) failed hash", t, piece, p.Hash)
+                       log.Printf("%s: piece %d (%x) failed hash: %d connections contributed", t, piece, p.Hash, len(touchers))
                        pieceHashedNotCorrect.Add(1)
                }
        }
        p.EverHashed = true
-       touchers := t.reapPieceTouchers(piece)
        if correct {
                for _, c := range touchers {
                        c.goodPiecesDirtied++
@@ -1437,12 +1437,20 @@ func (t *Torrent) pieceHashed(piece int, correct bool) {
                }
                t.updatePieceCompletion(piece)
        } else if len(touchers) != 0 {
-               log.Printf("dropping and banning %d conns that touched piece", len(touchers))
                for _, c := range touchers {
+                       // Y u do dis peer?!
                        c.badPiecesDirtied++
-                       t.cl.banPeerIP(missinggo.AddrIP(c.remoteAddr()))
-                       t.dropConnection(c)
                }
+               slices.Sort(touchers, connLessTrusted)
+               log.Printf("dropping first corresponding conn from trust: %s", func() (ret []int) {
+                       for _, c := range touchers {
+                               ret = append(ret, c.netGoodPiecesDirtied())
+                       }
+                       return
+               })
+               c := touchers[0]
+               t.cl.banPeerIP(missinggo.AddrIP(c.remoteAddr()))
+               c.Drop()
        }
 }