Skip to content

Commit 3dc87d2

Browse files
committed
fix: Correct byte counting in total_bytes_downloaded for partial blocks
1 parent 49ccc38 commit 3dc87d2

File tree

1 file changed

+45
-6
lines changed

1 file changed

+45
-6
lines changed

crates/libtortillas/src/torrent/actor.rs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,18 +322,57 @@ impl TorrentActor {
322322
/// Calculates the total number of bytes downloaded by the torrent. Returns
323323
/// None if the info dict is not present.
324324
pub fn total_bytes_downloaded(&self) -> Option<usize> {
325-
let completed_pieces = self.bitfield.count_ones();
326-
let piece_size = self.info_dict().map(|info| info.piece_length)? as usize;
325+
let info = self.info_dict()?;
326+
let total_length = info.total_length();
327+
let piece_length = info.piece_length as usize;
327328

328-
let mut total_bytes = completed_pieces * piece_size;
329+
let num_pieces = self.bitfield.len();
330+
let mut total_bytes = 0usize;
329331

330-
for block in self.block_map.iter() {
331-
total_bytes += BLOCK_SIZE * block.count_ones();
332+
// Calculate the size of the last piece
333+
let last_piece_len = if total_length % piece_length == 0 {
334+
piece_length
335+
} else {
336+
total_length % piece_length
337+
};
338+
339+
// Sum bytes from completed pieces
340+
for piece_idx in 0..num_pieces {
341+
if self.bitfield[piece_idx] {
342+
let piece_size = if piece_idx == num_pieces - 1 {
343+
last_piece_len
344+
} else {
345+
piece_length
346+
};
347+
total_bytes = total_bytes.saturating_add(piece_size);
348+
}
349+
}
350+
351+
// Sum bytes from incomplete pieces via block_map
352+
for (piece_idx, block) in self.block_map.iter().enumerate() {
353+
if piece_idx < num_pieces && !self.bitfield[piece_idx] {
354+
let piece_size = if piece_idx == num_pieces - 1 {
355+
last_piece_len
356+
} else {
357+
piece_length
358+
};
359+
360+
let mut piece_offset = 0usize;
361+
for block_idx in 0..block.len() {
362+
if block[block_idx] {
363+
let block_size = (piece_size - piece_offset).min(BLOCK_SIZE);
364+
total_bytes = total_bytes.saturating_add(block_size);
365+
piece_offset = piece_offset.saturating_add(block_size);
366+
} else {
367+
piece_offset =
368+
piece_offset.saturating_add(BLOCK_SIZE.min(piece_size - piece_offset));
369+
}
370+
}
371+
}
332372
}
333373

334374
Some(total_bytes)
335375
}
336-
337376
pub fn export(&self) -> TorrentExport {
338377
TorrentExport {
339378
info_hash: self.info_hash(),

0 commit comments

Comments
 (0)