Skip to content

Commit

Permalink
fix v2 hashing
Browse files Browse the repository at this point in the history
  • Loading branch information
arvidn committed Jan 15, 2024
1 parent 7e671ee commit cd5388a
Showing 1 changed file with 17 additions and 7 deletions.
24 changes: 17 additions & 7 deletions include/libtorrent/aux_/disk_cache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,9 @@ struct cached_block_entry

struct cached_piece_entry
{
cached_piece_entry(piece_location const& loc, int const num_blocks)
cached_piece_entry(piece_location const& loc, int const num_blocks, int const piece_size_v2)
: piece(loc)
, piece_size2(piece_size_v2)
, blocks_in_piece(num_blocks)
, blocks(std::make_unique<cached_block_entry[]>(std::size_t(num_blocks)))
, ph(hasher())
Expand Down Expand Up @@ -144,6 +145,10 @@ struct cached_piece_entry
bool v1_hashes = false;
bool v2_hashes = false;

// if this is a v2 torrent, this is the exact size of this piece. The
// end-piece of each file may be truncated for v2 torrents
int piece_size2;

int blocks_in_piece = 0;

// the number of blocks that have been hashed so far. Specifically for the
Expand Down Expand Up @@ -404,11 +409,11 @@ struct disk_cache
auto i = view.find(loc);
if (i == view.end())
{
//#error this computation is not right for v2 torrents. it will make v2 hashes computed incorrectly
//#error we don't know what the block size actually is here. If the piece size is less than 16 kiB, this computation is incorrect
pread_storage* storage = write_job->storage.get();
file_storage const& fs = storage->files();
int const blocks_in_piece = (storage->files().piece_size(loc.piece) + default_block_size - 1) / default_block_size;
cached_piece_entry pe(loc, blocks_in_piece);
int const piece_size2 = fs.piece_size2(loc.piece);
cached_piece_entry pe(loc, blocks_in_piece, piece_size2);
pe.v1_hashes = storage->v1();
pe.v2_hashes = storage->v2();
i = m_pieces.insert(std::move(pe)).first;
Expand Down Expand Up @@ -526,7 +531,7 @@ struct disk_cache
++block_idx;
++end;
}
auto blocks = blocks_storage.first(block_idx);
auto const blocks = blocks_storage.first(block_idx);

hasher& ctx = const_cast<hasher&>(piece_iter->ph);

Expand All @@ -537,15 +542,20 @@ struct disk_cache

l.unlock();

int bytes_left = piece_iter->piece_size2 - (cursor * default_block_size);
for (auto& buf: blocks)
{
cached_block_entry& cbe = piece_iter->blocks[cursor];

if (need_v1)
ctx.update(buf);

if (need_v2)
cbe.block_hash = hasher256(buf).final();
if (need_v2 && bytes_left > 0)
{
int const this_block_size = std::min(bytes_left, default_block_size);
cbe.block_hash = hasher256(buf.first(this_block_size)).final();
bytes_left -= default_block_size;
}

++cursor;
}
Expand Down

0 comments on commit cd5388a

Please sign in to comment.