feat: newly-added seeds skip the full verify step (#2626)

* feat: newly-added seeds skip the full verify step

This has been a much-requested feature but has also been contentious
because I want to ensure that Transmission never transmits unverified
data. See the GH pull request for context on how this works.
This commit is contained in:
Charles Kerr 2022-02-14 13:17:51 -06:00 committed by GitHub
parent f78727a4c1
commit f87d737e0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 0 deletions

View File

@ -167,6 +167,16 @@ void tr_completion::setBlocks(tr_bitfield blocks)
has_valid_.reset();
}
void tr_completion::setHasAll()
{
auto const total_size = block_info_->totalSize();
blocks_.setHasAll();
size_now_ = total_size;
size_when_done_ = total_size;
has_valid_ = total_size;
}
void tr_completion::addPiece(tr_piece_index_t piece)
{
auto const [begin, end] = block_info_->blockSpanForPiece(piece);

View File

@ -118,6 +118,8 @@ struct tr_completion
}
}
void setHasAll();
void setBlocks(tr_bitfield blocks);
void invalidateSizeWhenDone()

View File

@ -628,6 +628,49 @@ static bool setLocalErrorIfFilesDisappeared(tr_torrent* tor)
return disappeared;
}
/**
* Sniff out newly-added seeds so that they can skip the verify step
*/
static bool isNewTorrentASeed(tr_torrent* tor)
{
if (!tor->hasMetadata())
{
return false;
}
auto filename_buf = std::string{};
for (tr_file_index_t i = 0, n = tor->fileCount(); i < n; ++i)
{
// it's not a new seed if a file is missing
auto const found = tor->findFile(filename_buf, i);
if (!found)
{
return false;
}
// it's not a new seed if a file is partial
if (tr_strvEndsWith(found->filename, ".part"sv))
{
return false;
}
// it's not a new seed if a file size is wrong
if (found->size != tor->fileSize(i))
{
return false;
}
// it's not a new seed if it was modified after it was added
if (found->last_modified_at >= tor->addedDate)
{
return false;
}
}
// check the first piece
return tor->ensurePieceIsChecked(0);
}
static void refreshCurrentDir(tr_torrent* tor);
static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
@ -752,6 +795,11 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
tor->prefetchMagnetMetadata = true;
tr_torrentStartNow(tor);
}
else if (isNewTorrentASeed(tor))
{
tor->completion.setHasAll();
tor->recheckCompleteness();
}
else
{
tor->startAfterVerify = doStart;