anacrolix / torrent

Full-featured BitTorrent client package and utilities
Mozilla Public License 2.0
5.51k stars 622 forks source link

How do I check for existing data when adding a torrent? #810

Closed colinmarc closed 1 year ago

colinmarc commented 1 year ago

Hi @anacrolix! (it's colin)

I'm playing around and trying to get a minimal torrent client set up. I'm using the default file storage, but pieces in boltdb (this is just copied from your boltdb implementation):

func newStorage(path string, db *bolt.DB) (storage.ClientImpl, error) {
    err := os.MkdirAll(path, 0755)
    if err != nil {
        return nil, err
    }

    return storage.NewFileOpts(storage.NewFileClientOpts{
        ClientBaseDir: path,
        TorrentDirMaker: func(base string, info *metainfo.Info, hash metainfo.Hash) string {
            return filepath.Join(base, hash.HexString())
        },
        FilePathMaker: func(opts storage.FilePathMakerOpts) string {
            return filepath.Join(opts.File.Path...)
        },
        PieceCompletion: &storageCompletion{db},
    }), nil
}

type storageCompletion struct {
    db *bolt.DB
}

func (c *storageCompletion) Get(pk metainfo.PieceKey) (cn storage.Completion, err error) {
// ... the rest is just copied from your boltdb implementation.

If I download a torrent, restart the client, and call AddTorrentSpec, everything works and it immediately starts seeding. However, if I blow away the database, restart the client, and then add the torrent again, it doesn't do anything to check if the files that are already there are actually correct. I would like to introduce that functionality somehow.

From the documentation and code, it seems like this is the job of the storage.ClientImpl. Is that wrong? If it is, does that mean I need to reimplement a storage that does that? If not, is there another way to tell the client to check?

Thanks in advance!

anacrolix commented 1 year ago

The Client should check for data if it hasn't done so before (the same behaviour as if you wiped the piece completion database), unless TorrentSpec.DisableInitialPieceCheck is set to true. You might try a call to Torrent.VerifyData to force it to try to hash data.

Unless there's a bug, I suspect that perhaps the piece completion database you think is being used is not being used? When you add the torrent the second time, do you know if it thinks it's already complete after you added it?

colinmarc commented 1 year ago

I think I was just getting confused - I just tested again and this time there was no network traffic the second time. Sorry for the incorrect report!