Skip to content

feat: add BEP-0005 DHT bootstrap nodes support in .torrent files#583

Draft
chantra wants to merge 1 commit into
ikatson:mainfrom
chantra:bep005_nodes_torrent
Draft

feat: add BEP-0005 DHT bootstrap nodes support in .torrent files#583
chantra wants to merge 1 commit into
ikatson:mainfrom
chantra:bep005_nodes_torrent

Conversation

@chantra
Copy link
Copy Markdown
Contributor

@chantra chantra commented May 6, 2026

Add DhtNode type with custom serde that serializes as a 2-element bencode list ["", ] per the BEP-5 spec. The Deserialize impl drains the sequence after reading host/port to properly consume the list end-marker, preventing a BytesRemaining(1) error when nodes appear before other fields in the outer torrent dict.

  • New dht_node module in librqbit_core with DhtNode struct
  • Add nodes: Vec<DhtNode> field to TorrentMetaV1
  • Wire nodes through CreateTorrentOptions and create_torrent()
  • Inject torrent-embedded nodes as initial peers in session.rs
  • Add bencode roundtrip tests (single, vec, nested struct, empty vec)

Test Plan:

  • cargo test -p librqbit test_create_torrent_with_bootstrap_nodes passes
  • cargo test -p librqbit-core dht_node::tests passes (5 tests: roundtrip single, vec, in-struct, empty vec, JSON)
  • cargo clippy -p librqbit-core clean

Also tested with an internal seeder/client

Note: Generated with Cursor

@chantra
Copy link
Copy Markdown
Contributor Author

chantra commented May 6, 2026

@ikatson I am not super psyche about the current DhtNode serde, but did not find a good way to have it working using the existing bencode crate. Mostly due to serialize_tuple . Let me know if there is ways you would prefer this written.

};

// BEP-0005: inject nodes from .torrent as initial peers.
if !torrent.meta.nodes.is_empty() {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm reading the spec correctly, these nodes aren't peers necessarily, but the closest DHT nodes.
Means they need to be queried through DHT to find peers, but not (just) added to initial parts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, those are nodes that can be queried over DHT. Are you asking because then they should be added to a separate variable?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose in some ways, it is similar to #485 . Would you prefer that the initial torrent nodes are added to the Session.dht? I have not found a way to insert a node in the DhtState struct. Anything I am missing?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ikatson I have been spending a bit more time on this and I believe my test worked initially because it probably leaked to the DHT_BOOTSTRAP.
As much as I can see, in its current state, there is no way tell the Session to add those nodes to the dht table, right?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and I think you need to add support for this to make this PR useful.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me put this into draft mode for now. Thanks for the feedback.

Comment thread crates/librqbit/src/session.rs Outdated
@ikatson
Copy link
Copy Markdown
Owner

ikatson commented May 6, 2026

As to custom deserialize/serialize that's totally fine and how it's usually done anyway

@chantra chantra requested a review from ikatson May 6, 2026 22:21
@chantra
Copy link
Copy Markdown
Contributor Author

chantra commented May 6, 2026

Re-requesting review in case this is needed to get it back on your radar.
I just realized tests are failing, will address in parallel.

Add DhtNode type with custom serde that serializes as a 2-element
bencode list ["<host>", <port>] per the BEP-5 spec. The Deserialize
impl drains the sequence after reading host/port to properly consume
the list end-marker, preventing a BytesRemaining(1) error when nodes
appear before other fields in the outer torrent dict.
- New `dht_node` module in librqbit_core with DhtNode struct
- Add `nodes: Vec<DhtNode>` field to TorrentMetaV1
- Wire nodes through CreateTorrentOptions and create_torrent()
- Inject torrent-embedded nodes as initial peers in session.rs
- Add bencode roundtrip tests (single, vec, nested struct, empty vec)

Test Plan:
- `cargo test -p librqbit test_create_torrent_with_bootstrap_nodes` passes
- `cargo test -p librqbit-core dht_node::tests` passes (5 tests:
  roundtrip single, vec, in-struct, empty vec, JSON)
- `cargo clippy -p librqbit-core` clean
@chantra chantra force-pushed the bep005_nodes_torrent branch from bfc4040 to 2baf72d Compare May 6, 2026 22:43
@chantra chantra marked this pull request as draft May 11, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants