issue97_test.go | 2 ++ torrent.go | 27 ++++++++++++++------------- diff --git a/issue97_test.go b/issue97_test.go index 5ccfa62e6a9d00f4a99d3f6a6d2c693115866e12..2091b758df633dd373665c8088456c715090a810 100644 --- a/issue97_test.go +++ b/issue97_test.go @@ -5,6 +5,7 @@ "io/ioutil" "os" "testing" + "github.com/anacrolix/log" "github.com/stretchr/testify/require" "github.com/anacrolix/torrent/internal/testutil" @@ -17,6 +18,7 @@ require.NoError(t, err) defer os.RemoveAll(td) tt := &Torrent{ storageOpener: storage.NewClient(storage.NewFile(td)), + logger: log.Default, } mi := testutil.GreetingMetaInfo() info, err := mi.UnmarshalInfo() diff --git a/torrent.go b/torrent.go index 2937b94ca3b96e194e344851a33a9a6e05f212d3..9b353b44988c6389944eb6fd546abdd55677bc64 100644 --- a/torrent.go +++ b/torrent.go @@ -8,7 +8,6 @@ "fmt" "io" "math/rand" "net/url" - "os" "sync" "text/tabwriter" "time" @@ -744,20 +743,14 @@ } return pp.Integer(t.info.PieceLength) } -func (t *Torrent) hashPiece(piece pieceIndex) (ret metainfo.Hash) { +func (t *Torrent) hashPiece(piece pieceIndex) (ret metainfo.Hash, copyErr error) { hash := pieceHash.New() p := t.piece(piece) p.waitNoPendingWrites() ip := t.info.Piece(int(piece)) pl := ip.Length() - n, err := io.Copy(hash, io.NewSectionReader(t.pieces[piece].Storage(), 0, pl)) - if n == pl { - missinggo.CopyExact(&ret, hash.Sum(nil)) - return - } - if err != io.ErrUnexpectedEOF && !os.IsNotExist(err) { - t.logger.Printf("unexpected error hashing piece %d through %T: %s", piece, t.storage.TorrentImpl, err) - } + _, copyErr = io.CopyN(hash, io.NewSectionReader(t.pieces[piece].Storage(), 0, pl), pl) + missinggo.CopyExact(&ret, hash.Sum(nil)) return } @@ -1073,8 +1066,12 @@ p := t.piece(piece) uncached := t.pieceCompleteUncached(piece) cached := p.completion() changed := cached != uncached + complete := uncached.Complete p.storageCompletionOk = uncached.Ok - t.completedPieces.Set(bitmap.BitIndex(piece), uncached.Complete) + t.completedPieces.Set(bitmap.BitIndex(piece), complete) + if complete && len(p.dirtiers) != 0 { + t.logger.Printf("marked piece %v complete but still has dirtiers", piece) + } if changed { log.Fstr("piece %d completion changed: %+v -> %+v", piece, cached, uncached).WithValues(debugLogValue).Log(t.logger) t.pieceCompletionChanged(piece) @@ -1658,13 +1655,17 @@ } func (t *Torrent) pieceHasher(index pieceIndex) { p := t.piece(index) - sum := t.hashPiece(index) + sum, copyErr := t.hashPiece(index) + correct := sum == *p.hash + if !correct { + log.Fmsg("piece %v hash failure copy error: %v", index, copyErr).Log(t.logger) + } t.storageLock.RUnlock() t.cl.lock() defer t.cl.unlock() p.hashing = false t.updatePiecePriority(index) - t.pieceHashed(index, sum == *p.hash) + t.pieceHashed(index, correct) t.publishPieceChange(index) t.activePieceHashes-- t.tryCreateMorePieceHashers()