Currently, torrent files are loaded by the
torrent_info constructor. The
torrent_info object essentially holds all state from the .torrent file.
This post is arguing in favor of moving towards torrent_info only representing the immutable portion of torrent files. i.e. what’s in the info-section.
This is primarily motivated by the v2 piece-layers that are currently part of torrent_info. The piece layers, when parsed into merkle trees, have a non-trivial size. So once a torrent is added to a session, they need to be removed from the torrent_info object and stored in their internal representation in the session. Because of this, a
torrent_info object you get by calling
torrent_handle::torrent_file() is now a “crippled” version of what you get when loading the same torrent file from disk. i.e. the piece layers are stripped when added to the session. For v2 torrents, it’s no longer possible to save a copy of the .torrent file from a
torrent_handle by just asking for the torrent_info object, you have to call
torrent_file_with_hashes(). This new function is more expensive because it needs to make a copy of the
torrent_info object and also copy the piece layers into it.
I believe a cleaner and clearer future API to move towards would be to make torrent_info represent the immutable info-section, and
add_torrent_params represent the whole torrent (as well as resume data). It already holds most necessary states. A few new fields would have to be added:
It would mean
torrent_info would not hold trackers or web seeds, since those are mutable.
Similar torrent lists and collections lists can be found both inside the info-dictionary, and outside of it. So these need to live in both
The benefits I anticipate with this design are:
add_torrent_params duplicate some fields like trackers and web seeds. There are flags to indicate whether they should be merged or whether the resume data should take precedence. (see
load_torrent_file() function can load the torrent into an
add_torrent_params object. Thus, trackers, web seeds and piece layers (or any other mutable metadata) can be loaded just into the (mutable)
torrent_info won’t overlap with any of those fields.
Saving a torrent file from a
torrent_handle would just be a matter of asking to save resume data (which posts an
add_torrent_params object in an alert. This can then be passed to
write_torrent_file()to write it to disk. Since the resume data already contains trackers, web seeds and the piece layer hashes, it has all it needs to write a complete .torrent file.
This also has the added benefit of being able to request the resume data asynchronously, without blocking the calling thread.
Just like writing a torrent file, making a magnet URI is a matter of first requesting the resume data (
add_torrent_params) and pass that to
This new API would be made up by the following functions (some of which are new and have already landed in RC_2_0):
void torrent_handle::save_resume_data();// post add_torrent_params
add_torrent_params load_torrent_file(std::string file);
add_torrent_params parse_magnet_uri(string_view uri);
std::string make_magnet_uri(add_torrent_params const&);
entry write_torrent_file(add_torrent_params const&);
Along with the new API, the following functions would be deprecated at some point in the future: