Skip to content

Conversation

rklaehn
Copy link
Collaborator

@rklaehn rklaehn commented Sep 11, 2025

Description

This PR introduces abstract versions of iroh::endpoint::{SendStream, RecvStream} and modifies the provide side and get side implementation to use these abstract streams instead of directly using iroh::endpoint streams.

This is necessary for wrapping the streams into a transformation such as compression, see the discussion in n0-computer/sendme#93 .

The compression example shows how streams can be wrapped into compression/decompression to create a derived protocol with a different ALPN that is identical to the blobs protocol except for compression.

Breaking Changes

iroh::endpoint::SendStream and iroh::endpoint::RecvStream are replaced with the traits iroh_blobs::util::SendStream and iroh_blobs::util::RecvStream in the get FSM and in the provider side API.

Notes & open questions

Change checklist

  • Self-review.
  • Documentation updates following the style guide, if relevant.
  • Tests if relevant.
  • All breaking changes documented.

rklaehn and others added 30 commits August 28, 2025 14:54
… notifications/requests for each event type.
This shows how to limit serving content in various ways

- by node id
- by content hash
- throttling
- limiting max number of connections
so the other side can know if reconnecting is OK
Also make the whole get fsm generic so it can be used with an arbitrary stream, not just a quinn/iroh RecvStream.
@n0bot n0bot bot added this to iroh Sep 11, 2025
@github-project-automation github-project-automation bot moved this to 🏗 In progress in iroh Sep 11, 2025
Base automatically changed from provider-events-refactor to main September 11, 2025 15:01
@rklaehn rklaehn mentioned this pull request Sep 16, 2025
4 tasks
@rklaehn rklaehn changed the title Newtype it feat: abstract over stream types on provide and get side Sep 16, 2025
@rklaehn rklaehn marked this pull request as ready for review September 16, 2025 11:39
We only need async-compression as a dev dep for the compression example!
/// Send bytes to the stream. This takes a `Bytes` because iroh can directly use them.
fn send_bytes(&mut self, bytes: Bytes) -> impl Future<Output = io::Result<()>> + Send;
/// Send that sends a fixed sized buffer.
fn send<const L: usize>(
Copy link
Member

Choose a reason for hiding this comment

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

Why the const L instead of taking &[u8]?

Copy link
Collaborator Author

@rklaehn rklaehn Sep 17, 2025

Choose a reason for hiding this comment

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

Since these traits are hopeless, they will never be dynable, I thought I might as well use a const generic since it is convenient. But sure, could change this.

In case of the recv version the code just reads nicer if you return a fixed size slice instead of taking a &mut [u8], and for returning a fixed size slice you don't have to allocate.

/// Note that this is different from `recv_bytes`, which will return fewer bytes if the stream ends.
fn recv_bytes_exact(&mut self, len: usize) -> impl Future<Output = io::Result<Bytes>> + Send;
/// Receive exactly `L` bytes from the stream, directly into a `[u8; L]`.
fn recv<const L: usize>(&mut self) -> impl Future<Output = io::Result<[u8; L]>> + Send;
Copy link
Member

Choose a reason for hiding this comment

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

Maybe call this recv_exact?

Ok((value, data.len()))
}

async fn read_length_prefixed<T: DeserializeOwned>(
Copy link
Member

Choose a reason for hiding this comment

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

Yeah these are great. We should move all this with some cleanup and better docs to an iroh-util crate I think. It will be useful for many people working with iroh send/recv streams even independently of the trait abstraction.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am somewhat hesitant to have yet another crate, but I guess maybe we have to do it even before iroh 1.0?

Also remove const generics and make the read and write fns a bit more "traditional".

Makes usage a bit more inconvenient, but 🤷
@rklaehn
Copy link
Collaborator Author

rklaehn commented Oct 6, 2025

cargo deny is just because we are pointing to iroh-* main.
semver changes are documented.

@rklaehn rklaehn merged commit f890c79 into main Oct 6, 2025
22 of 24 checks passed
@github-project-automation github-project-automation bot moved this from 🏗 In progress to ✅ Done in iroh Oct 6, 2025
@rklaehn rklaehn deleted the newtype-it branch October 6, 2025 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants