mirror of
https://github.com/transmission/transmission
synced 2024-12-23 00:04:06 +00:00
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:
parent
f78727a4c1
commit
f87d737e0f
3 changed files with 60 additions and 0 deletions
|
@ -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);
|
||||
|
|
|
@ -118,6 +118,8 @@ struct tr_completion
|
|||
}
|
||||
}
|
||||
|
||||
void setHasAll();
|
||||
|
||||
void setBlocks(tr_bitfield blocks);
|
||||
|
||||
void invalidateSizeWhenDone()
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue