Skip to content

Commit ac20335

Browse files
authored
feat: blog post v0.35.0 & roadmap update (#326)
* feat: blog post v0.35.0 & roadmap update * adjust examples to new `RouterBuilder::spawn` api * update "last updated" date in the roadmap
1 parent bf5b9e4 commit ac20335

File tree

8 files changed

+155
-57
lines changed

8 files changed

+155
-57
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import { BlogPostLayout } from '@/components/BlogPostLayout'
2+
import { MotionCanvas } from '@/components/MotionCanvas'
3+
4+
export const post = {
5+
draft: false,
6+
author: 'ramfox',
7+
date: '2025-05-13',
8+
title: 'iroh v0.35 - Prepping for 1.0',
9+
description: 'Iroh 0.35 release',
10+
}
11+
12+
export const metadata = {
13+
title: post.title,
14+
description: post.description,
15+
openGraph: {
16+
title: post.title,
17+
description: post.description,
18+
images: [{
19+
url: `/api/og?title=Blog&subtitle=${post.title}`,
20+
width: 1200,
21+
height: 630,
22+
alt: post.title,
23+
type: 'image/png',
24+
}],
25+
type: 'article'
26+
}
27+
}
28+
29+
export default (props) => <BlogPostLayout article={post} {...props} />
30+
31+
Welcome to a new release of `iroh`, a library for building on direct connections between devices, putting more control in the hands of your users.
32+
33+
The number0 team has been hard at work to get a 1.0 release of `iroh` out the door this year. As we’ve gotten closer to achieving our goal, we’ve also developed a clearer understanding of what that actually looks like. We’ve mentioned in previous blog posts that a wire-protocol and network-level breaking change is coming in the near future.
34+
35+
**This release, `0.35`, will be the last release before that protocol- and network-level breaking change.**
36+
37+
We will continue to maintain `0.35` and will release patches if any bugs are found and fixed. Our next release—unless a bug fix between now and then requires a breaking change—will be a release candidate, which we’ll refer to as `0.99`.
38+
39+
The `0.35` release contains minor API changes and a major update to our metrics collection.
40+
41+
## 🧚 v0.35 Changes
42+
43+
### **Metrics**
44+
45+
For those of you using the “metrics” feature in `iroh`: we’ve updated how metrics collection works. Previously, we had a global metrics collector, which meant we couldn’t separate metrics when multiple instances of `iroh` were running in the same process. This was most noticeable during testing, but it could also affect users running more than one endpoint in their code.
46+
47+
Now, metrics are collected by the `iroh::Endpoint`, so each instance can track its own metrics independently.
48+
49+
For many users, this change will go unnoticed, as it primarily involved internal refactoring.
50+
51+
### **Router**
52+
53+
One API change you’ll likely notice is that the `iroh::Router::spawn()` method is now synchronous and infallible. Say goodbye to that extra `.await?`.
54+
55+
## 🔧 Release Candidate Logistics
56+
57+
A few key changes are coming in the upcoming `0.99-rc-alpha` release:
58+
59+
1. **Removal of x.509 TLS certificates:** These will be removed in `0.99`.
60+
2. **Relay connection simplification:** Previously, connecting to the relay servers via Websockets was only available when using the "wasm" feature. Now, it is available regardless of what features you have enabled. This means we currently support two methods of connecting to relays: the old relay codec and WebSockets. The old relay codec will be removed in `0.99`. You can get ahead of the game and switch to using Websockets by using the `iroh::endpoint::Builder::relay_conn_protocol` method.
61+
3. **Error handling overhaul:** We currently use `anyhow` for errors. In `0.99`, we’ll move to concrete error types for our APIs.
62+
4. **QUIC multipath and NAT traversal:** The most significant change is our adoption of the [QUIC multipath extension](https://datatracker.ietf.org/doc/draft-ietf-quic-multipath/14/) and [QUIC NAT traversal](https://www.ietf.org/archive/id/draft-seemann-quic-nat-traversal-01.html). This is a substantial undertaking and will form the bulk of our work as we move from a release candidate to a well-tested and trusted `1.0`.
63+
64+
## How Does This Affect the `iroh`Maintained Protocols?
65+
66+
`iroh-gossip` and `iroh-blobs` will follow `iroh` in moving to the `0.99` release candidate pattern after `0.35`.
67+
68+
`iroh-gossip` will largely remain unchanged, apart from any necessary bug fixes.
69+
70+
We’ve been working on a major `iroh-blobs` API update that will make it easier to use in general, and more specifically, will dramatically simplify tracking progress updates. Although these changes are substantial, we’re confident the new API will be more intuitive and satisfying for users.
71+
72+
`iroh-docs` is not yet ready for a `1.0`, so we’ll continue releasing minor and patch updates as needed.
73+
74+
## Other Crates That Will No Longer Be Maintained
75+
76+
We will no longer update `quic-rpc` and `iroh-node-utils`.
77+
78+
None of the `0.99` crates will depend on `quic-rpc`. Instead, we’re developing `irpc`, a new crate with fewer bells and whistles than `quic-rpc` but a much simpler and more straightforward design.
79+
80+
To ensure the success of the `1.0` release, we’ve narrowed the scope of what `iroh` is responsible for and removed any CLI components from our roadmap. As a result, we won’t be updating `iroh-node-utils` after `0.35`, since its primary purpose was to support CLI development around `iroh` and its protocols.
81+
82+
## ⚠️ Breaking Changes
83+
84+
- `iroh`
85+
- remove
86+
- `pub fn default_from_node(url: RelayUrl, stun_port: u16) -> RelayMap`
87+
- change
88+
- `pub fn from_url(url: RelayUrl) -> RelayMap`, use `From<RelayUrl>` instead
89+
- `Router::spawn` is now a plain function instead of an `async fn`
90+
- `Router::spawn` is now infallible, instead of returning `anyhow::Result<()>`
91+
- All metrics structs (`iroh::metrics::{MagicsockMetrics, PortmapMetrics, NetReportMetrics}`) now implement `MetricsGroup` from the new version `0.34` of `iroh-metrics` and no longer implement traits from `[email protected]`.
92+
- Metrics are no longer registered onto the static superglobal `Core`. `iroh` does not use `static_core` feature of `iroh-metrics`. Metrics are now exposed from the subsystems that track them, see e.g. `Endpoint::metrics`.
93+
- Several methods now take a `Metrics` argument. You can always pass `Default::default` if you don't want to unify metrics tracking with other sections.
94+
- `pkarr::SignedPacket`, as used as a parameter in `iroh::dns::node_info::NodeInfo::to_pkarr_signed_packet` and `iroh::dns::node_info::NodeInfo::from_pkarr_signed_packet` is now expecting `pkarr` at major version `3` instead of `2`
95+
- `iroh-relay`
96+
- change
97+
- Minor change in the `From` impls for `ConnSendError` due to changing the underlying library
98+
99+
### But wait, there's more!
100+
101+
Many bugs were squashed, and smaller features were added. For all those details, check out the full changelog: [https://github.com/n0-computer/iroh/releases/tag/v0.35.0](https://github.com/n0-computer/iroh/releases/tag/v0.35.0).
102+
103+
If you want to know what is coming up, check out the [v0.99 milestone](https://github.com/n0-computer/iroh/milestone/34), and if you have any wishes, let us know about the [issues](https://github.com/n0-computer/iroh/issues)! If you need help using iroh or just want to chat, please join us on [discord](https://discord.com/invite/DpmJgtU7cW)! And to keep up with all things iroh, check out our [Twitter](https://x.com/iroh_n0).

src/app/docs/concepts/router/page.mdx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ async fn main() -> Result<()> {
2727
// identified by its ALPN. Spawn the router to start listening.
2828
let router = Router::builder(endpoint)
2929
.accept(iroh_blobs::ALPN, blobs)
30-
.spawn()
31-
.await?;
30+
.spawn();
3231

3332
// get our own address. At this point we have a running router
3433
// that's ready to accept connections.
@@ -46,4 +45,4 @@ async fn main() -> Result<()> {
4645
}
4746
```
4847

49-
You can add whatever protocols you need to the router, multiplexing them all over the same endpoint.
48+
You can add whatever protocols you need to the router, multiplexing them all over the same endpoint.

src/app/docs/examples/gossip-chat/page.mdx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,7 @@ async fn main() -> Result<()> {
118118
// protocol.
119119
let router = Router::builder(endpoint.clone())
120120
.accept(iroh_gossip::ALPN, gossip.clone())
121-
.spawn()
122-
.await?;
121+
.spawn();
123122

124123
// Cleanly shutdown the router.
125124
router.shutdown().await?;
@@ -147,8 +146,7 @@ async fn main() -> Result<()> {
147146

148147
let router = Router::builder(endpoint.clone())
149148
.accept(iroh_gossip::ALPN, gossip.clone())
150-
.spawn()
151-
.await?;
149+
.spawn();
152150

153151
// Create a new topic.
154152
let id = TopicId::from_bytes(rand::random());
@@ -342,8 +340,7 @@ async fn main() -> Result<()> {
342340

343341
let router = Router::builder(endpoint.clone())
344342
.accept(iroh_gossip::ALPN, gossip.clone())
345-
.spawn()
346-
.await?;
343+
.spawn();
347344

348345
let id = TopicId::from_bytes(rand::random());
349346
let node_ids = vec![];
@@ -599,8 +596,7 @@ async fn main() -> Result<()> {
599596

600597
let router = Router::builder(endpoint.clone())
601598
.accept(iroh_gossip::ALPN, gossip.clone())
602-
.spawn()
603-
.await?;
599+
.spawn();
604600

605601
// in our main file, after we create a topic `id`:
606602
// print a ticket that includes our own node id and endpoint addresses

src/app/docs/protocols/writing/page.mdx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ async fn start_accept_side() -> anyhow::Result<iroh::protocol::Router> {
3939
let endpoint = iroh::Endpoint::builder().discovery_n0().bind().await?;
4040

4141
let router = iroh::protocol::Router::builder(endpoint)
42-
.spawn()
43-
.await?;
42+
.spawn();
4443

4544
Ok(router)
4645
}
@@ -102,8 +101,7 @@ async fn start_accept_side() -> anyhow::Result<iroh::protocol::Router> {
102101

103102
let router = iroh::protocol::Router::builder(endpoint)
104103
.accept(ALPN, Echo) // This makes the router handle incoming connections with our ALPN via Echo::accept!
105-
.spawn()
106-
.await?;
104+
.spawn();
107105

108106
Ok(router)
109107
}

src/app/docs/quickstart/page.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ async fn main() -> anyhow::Result<()> {
123123
// to the blobs protocol.
124124
let router = Router::builder(endpoint)
125125
.accept(iroh_blobs::ALPN, blobs.clone())
126-
.spawn()
127-
.await?;
126+
.spawn();
128127

129128
// do *something*
130129

src/app/docs/tour/4-protocols/page.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ async fn main() -> anyhow::Result<()> {
2929
// build the router
3030
let router = Router::builder(endpoint)
3131
.accept(iroh_blobs::ALPN, blobs.clone())
32-
.spawn()
33-
.await?;
32+
.spawn();
3433

3534
router.shutdown().await?;
3635

src/app/docs/tour/5-routers/page.mdx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ async fn main() -> anyhow::Result<()> {
2929
let router = Router::builder(endpoint)
3030
.accept(iroh_blobs::ALPN, blobs.clone())
3131
.accept(iroh_gossip::ALPN, gossip.clone())
32-
.spawn()
33-
.await?;
32+
.spawn();
3433

3534
router.shutdown().await?;
3635
Ok(())

src/app/roadmap/roadmap.json

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"last_updated": "2025-02-25",
2+
"last_updated": "2025-05-13",
33
"milestones": [
44
{
55
"done": true,
@@ -152,21 +152,28 @@
152152
"description": "expand tags API",
153153
"tracking_issue": null
154154
},
155-
{ "version": "v0.34.0", "done": true, "released": "2025-03-18", "doc": null },
155+
{ "version": "v0.34.1", "done": true, "released": "2025-03-18", "doc": "https://www.iroh.computer/blog/iroh-0-34-0-raw-public-keys" },
156156
{
157-
"done": false,
158-
"title": "blobs 1.0 API",
159-
"description": "overhaul blobs API",
160-
"tracking_issue": null
161-
},
162-
{
163-
"done": false,
157+
"done": true,
164158
"title": "relay connections over websockets",
165159
"description": "Connections to the relay happen over websockets",
166160
"tracking_issue": null,
167161
"doc": null
168162
},
169-
{ "version": "v0.35.0", "done": false, "released": "2025-04-07", "doc": null },
163+
{
164+
"done": true,
165+
"title": "metrics are collected per-endpoint",
166+
"description": "Previously, metrics were collected globably. Now, each `iroh` endpoint collects metrics for itself.",
167+
"tracking_issue": null,
168+
"doc": null
169+
},
170+
{ "version": "v0.35.0", "done": true, "released": "2025-05-12", "doc": "https://www.iroh.computer/blog/iroh-0-35-prepping-for-1-0" },
171+
{
172+
"done": false,
173+
"title": "blobs 1.0 API",
174+
"description": "overhaul blobs API",
175+
"tracking_issue": null
176+
},
170177
{
171178
"done": false,
172179
"title": "iroh-blobs: multiprovider fan-in",
@@ -184,6 +191,27 @@
184191
"upstream to quinn": false
185192
}
186193
},
194+
{
195+
"done": false,
196+
"title": "QUIC NAT traversal",
197+
"description": "Using Quic to traverse NATs",
198+
"doc": "https://www.ietf.org/archive/id/draft-seemann-quic-nat-traversal-01.html"
199+
},
200+
{
201+
"done": false,
202+
"title": "Formalize Error Responses",
203+
"description": "transition from anyhow to thiserror in all critical code paths",
204+
"tracking_issue": "https://github.com/n0-computer/iroh/issues/2741"
205+
},
206+
{
207+
"done": false,
208+
"title": "release candidate",
209+
"description": "publish a release candidate, seeking feedback from the community",
210+
"tracking_issue": "",
211+
"doc": ""
212+
},
213+
{ "version": "v0.99-rc", "done": false, "released": "", "link": "", "expected": "H2 2025" },
214+
{ "ellipsis": true },
187215
{
188216
"done": false,
189217
"title": "draft specification",
@@ -201,50 +229,27 @@
201229
"iroh relay": false
202230
}
203231
},
204-
{
205-
"done": false,
206-
"title": "QUIC NAT traversal",
207-
"description": "Using Quic to traverse NATs",
208-
"doc": "https://www.ietf.org/archive/id/draft-seemann-quic-nat-traversal-01.html"
209-
},
210-
{
211-
"done": false,
212-
"title": "Finalize FFI integration",
213-
"description": "protocol developers have a clear path for integrating rust protocols into other languages",
214-
"tracking_issue": "",
215-
"doc": ""
216-
},
217-
{ "ellipsis": true },
218-
{ "version": "v0.36.0", "done": false, "released": "2025-04-21", "doc": null },
219-
{
220-
"done": false,
221-
"title": "Formalize Error Responses",
222-
"description": "transition from anyhow to thiserror in all critical code paths",
223-
"tracking_issue": "https://github.com/n0-computer/iroh/issues/2741"
224-
},
225232
{
226233
"done": false,
227234
"title": "finalize 1.0 spec",
228235
"description": "ratify the iroh 1.0 wire protocol",
229236
"tracking_issue": ""
230237
},
231-
{ "version": "v0.37.0", "done": false, "released": "2025-05-12", "doc": null },
232238
{
233239
"done": false,
234-
"title": "release candidate",
235-
"description": "publish a release candidate, seeking feedback from the community",
240+
"title": "Finalize FFI integration",
241+
"description": "protocol developers have a clear path for integrating rust protocols into other languages",
236242
"tracking_issue": "",
237243
"doc": ""
238244
},
239-
{ "version": "v0.38.0", "done": false, "released": "2025-06-02", "doc": null },
240245
{
241246
"done": false,
242247
"title": "documentation refinement",
243248
"description": "ensure documentation is accurate and robust",
244249
"tracking_issue": "",
245250
"doc": ""
246251
},
247-
{ "version": "v1.0", "done": false, "released": "", "link": "", "expected": "H2 2025" },
252+
{ "version": "v1.0", "done": false, "released": "", "link": "", "expected": "H3 2025" },
248253
{ "all_done": false, "title": "Party", "description": "That's it. All done. no more work left to do, ever. :)", "link": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }
249254
]
250255
}

0 commit comments

Comments
 (0)