NAME

Net::BitTorrent::Storage - Modular BitTorrent Storage Layer (v2.0.0)

SYNOPSIS

use Net::BitTorrent::Storage;

my $storage = Net::BitTorrent::Storage->new(
    base_path  => "./downloads",
    file_tree  => $metadata->{info}{'file tree'}, # From BEP 52
    piece_size => 262144
);

# Write a block (16KiB) to the async cache
# $pieces_root is the SHA-256 Merkle root from the metadata
$storage->write_block($pieces_root, $offset, $data);

# Periodically flush the cache to disk
$storage->tick(0.1);

# Force all pending data to disk (e.g. before shutdown)
$storage->explicit_flush();

DESCRIPTION

Net::BitTorrent::Storage is the central I/O manager for BitTorrent swarms. It abstracts the complexity of mapping BitTorrent "pieces" and "blocks" to actual files on disk.

In a multi-file torrent, the protocol treats all files as a single contiguous stream of bytes. This class manages the translation between this "virtual file" and the physical files on the filesystem. It is particularly important for BitTorrent v2 (BEP 52) and hybrid torrents, where file alignment and padding are strictly defined.

Key Features:

  • BitTorrent v2 (BEP 52): Uses pieces root (SHA-256 Merkle roots) to identify and verify files. Each file is verified independently.

  • Merkle Trees: Maintains internal Merkle trees for each file, allowing per-block (16KiB) verification as data arrives from the network.

  • Hybrid Mapping: Automatically handles the padding required to align v1 pieces with v2 file boundaries. This ensures that a single v1 piece never spans multiple v2 files, which simplifies verification.

  • Async Disk Cache: Buffers writes in memory and flushes them in small batches during the tick() cycle, preventing synchronous I/O from blocking the network logic.

  • Sub-range Reads: The cache is intelligent enough to serve partial reads from larger cached blocks.

METHODS

verify_block( $root, $index, $data )

Verifies a 16KiB block against the Merkle tree for the file identified by $root. $index is the block index within the file. Returns boolean. Part of BEP 52.

verify_block_audit( $root, $index, $data, $audit_path )

Verifies a block using an audit path (branch nodes of the Merkle tree). Useful when the full piece layer hasn't been downloaded yet.

verify_piece_v2( $root, $index, $data )

Verifies an entire v2 piece against the cached piece layers.

write_block( $root, $offset, $data )

Writes a block to the asynchronous cache. The data will be flushed to the file $root at $offset during a subsequent tick().

read_block( $root, $offset, $length )

Reads data from the cache (if available) or falls back to disk.

read_global( $offset, $length ) / write_global( $offset, $data )

Legacy methods for accessing the swarm as a single contiguous virtual file. Essential for BEP 03 compatibility.

map_v1_piece( $index )

Calculates which files and segments are contained within a v1 piece index. In hybrid torrents, this accounts for the padding files/space defined in BEP 52. Returns an arrayref of segment hashes.

map_v2_piece( $index )

Returns a list containing the pieces_root and relative index for a v2 piece. Since v2 pieces are aligned to files, a piece always belongs to exactly one file (or padding).

get_hashes( $root, $base_layer, $index, $count )

Retrieves a string of concatenated hashes from the Merkle tree for file $root. Used to respond to BEP 52 HASH_REQUEST messages.

explicit_flush()

Guarantees that all data currently in the memory cache is written to the physical disk immediately.

dump_state() / load_state( $state )

Persistence API. Saves the Merkle tree nodes and verification state so that swarms can be resumed instantly without a full file re-hash.

SEE ALSO

Net::BitTorrent::Storage::File, Digest::Merkle::SHA256

AUTHOR

Sanko Robinson <sanko@cpan.org>

COPYRIGHT

Copyright (C) 2008-2026 by Sanko Robinson.

This library is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0.