v0.90.0

n0-computer/irohv0.90.0Jun 30, 2025by github-actions[bot]

AI Summary

A major release introducing the n0-watcher crate, removing deprecated x509 TLS, and refactoring error handling and discovery APIs.

Key Highlights

  • iroh::watcher moved to a separate n0-watcher crate.
  • SecretKey display implementation removed.
  • ProtocolHandler methods now return impl Future instead of BoxFuture.
  • ProtocolHandler is no longer dyn-compatible.
  • Discovery constructors removed in favor of builder methods.
  • All public APIs now return concrete error types instead of anyhow::Error.

Breaking Changes

  • iroh::watcher moved to n0-watcher crate.
  • SecretKey Display impl removed.
  • ProtocolHandler methods return impl Future.
  • ProtocolHandler is no longer dyn-compatible.
  • Discovery constructors removed in favor of .builder().
  • Public APIs return concrete errors instead of anyhow::Error.
  • Endpoint::node_addr returns impl Watcher.
  • Endpoint::home_relay returns impl Watcher.
  • Endpoint::bound_sockets returns Vec<SocketAddr>.
  • iroh-quinn updated to 0.14.0.
  • RouterBuilder::accept signature changed.

New Features

  • n0-watcher crate and Watcher trait.
  • Transport abstraction.
  • Graceful shutdown.
  • Concrete error types.

Full Release Notes

## ⚠️  Breaking Changes

- iroh
    - removed
        - `iroh::endpoint::Builder:: tls_x509` removed, this is the tls mechanism that has been removed
        - `iroh::endpoint::Builder:: tls_raw_public_keys`  removed, this is the default mechanism now, so not needed anymore
        - `Display` implementation was removed for `SecretKey`, use `.to_bytes()` and encode as hex to get the previous bytes explicitly, for example:
        
        ```rust
        let encoded_key = data_encoding::HEXLOWER.encode(&secret_key.to_bytes())
        ```
        
        - removed `iroh_relay::protos::stun::StunError`
        - removed `iroh_relay::server::testing::stun_config`
        - removed `iroh_relay::protos::stun`
        - removed `iroh_relay::quic::QuicClient::get_addr_and_latency`
        - removed `DEFAULT_STUN_PORT`
        - Removed `iroh::discovery::dns::DnsDiscovery::new`, use `DnsDiscovery::builder` instead
        - Removed `iroh::discovery::pkarr::PkarrPublisher::new`, use `PkarrPublisher::builder` instead
        - Removed `iroh::discovery::pkarr::PkarrPublisher::with_options`, use `PkarrPublisher::builder` instead
        - Removed `iroh::discovery::pkarr::PkarrResolver::new`, use `PkarrResolver::builder` instead
    - changed
        - all public APIs return concrete error types, rather than `anyhow::Error`
        - `iroh::protocol::ProtocolHandler` methods now return `impl Future` instead of `BoxFuture`. You can simply remove the `Box::pin(async move {})` from the implementations and instead implement the methods as `async fn`. See the updated documentation for the `iroh::protocol` module for an example.
        - `iroh::protocol::ProtocolHandler` is no longer dyn-compatible. If you need a dyn-compatible version, you need to build your own dyn-compatible wrapper trait. See the (non-public) `DynProtocolHandler` in `iroh::protocol` as an example.
        - `iroh::watcher` is now its own crate `n0-watcher`, but the `Watcher` trait is still a top level export in `iroh`
        - `iroh::endpoint::Endpoint::node_addr` now returns `impl Watcher<Value = Option<NodeAddr>>`
        - `iroh::endpoint::Endpoint::home_relay` now returns `impl Watcher<Value = Vec<RelayUrl>>`
        - `iroh::endpoint::Endpoint::bound_sockets` now returns `Vec<SocketAddr>`
        - `iroh-quinn` is updated to `0.14.0`
        - `iroh::protocol::RouterBuilder::accept` now takes `impl Into<Box<dyn DynProtocolHandler>>` instead of `impl ProtocolHandler`. Because of a blanket `From` impl this change does not need any changes by users: you can still pass any `impl ProtocolHandler` to `accept`. Additionally, if you have your own builder struct upstream, you can now also pass a `Box<dyn DynProtocolHandler>` to `accept`, which wasn't possible previously.
        - `iroh::discovery::Lagged` changed from a tuple to a struct
        - `iroh::watcher::Disconnected` is changed from a tuple to a struct
        - `iroh::watcher::Disconnected` is no longer `UnwindSafe` or `RefUnwindSafe`
        - `iroh::watcher::InitializedFut` is no longer `RefUnwindSafeiroh-base`
        - `iroh::endpoint::Builder::add_discovery` now takes an `impl iroh::discovery::IntoDiscovery` argument instead of a closure that returns a `Discovery`. You can implement that on a builder struct, and any `T: Discovery` has an auto-impl of `IntoDiscovery`.
        - `iroh::discovery::Discovery::resolve` no longer gets a `&Endpoint` argument. If you need an endpoint in your discovery service, add a builder struct and implement `IntoDiscovery` for it, which gives you an endpoint that you can clone into your service
        - `iroh::discovery::pkarr::PkarrPublisher::n0_dns` now takes no arguments and returns a `PkarrPublisherBuilder`. The secret key is set on `PkarrPublisherBuilder::build` instead.
    
- `iroh-base`
    - `changed`
        - `iroh_base::ticket::Error` is renamed to `iroh_base::ticket::ParseError`
        - `iroh_base::key::KeyParsingError` has changed from a `thiserror` error to a `snafu` error`iroh-relay`
- `iroh-relay`
    - `changed`
        - `iroh_relay::node_info::MaxLengthExceededError` is no longer `UnwindSafe` or `RefUnwindSafe`
        - `iroh_relay::node_info::MaxLengthExceededError` was changed from a `thiserror` to a `snafu` error
        - `iroh_relay::client::ConnSendError` is now `iroh_relay::client::SendError`
        - `iroh_relay::protos::stun::Error` is now `iroh_relay::protos::stun::StunError`

## ⛰️  Features

- *(iroh)* Allow protocols to gracefully shutdown connections ([#3319](https://github.com/n0-computer/iroh/issues/3319)) - ([da571c1](https://github.com/n0-computer/iroh/commit/da571c19591fee13504e5a226b5cc0dc4dc1435e))
- *(iroh)* [**breaking**] Make ProtocolHandler use async functions ([#3320](https://github.com/n0-computer/iroh/issues/3320)) - ([e36ac77](https://github.com/n0-computer/iroh/commit/e36ac776fec2d5aabec8300e13b30b6f81ed4721))
- *(iroh)* [**breaking**] Remove deprecated x509 libp2p TLS authentication ([#3330](https://github.com/n0-computer/iroh/issues/3330)) - ([136b855](https://github.com/n0-computer/iroh/commit/136b855087900fd65638833aae1513267955fcf6))
- *(iroh)* [**breaking**] Introduce transport abstraction ([#3279](https://github.com/n0-computer/iroh/issues/3279)) - ([d915bfd](https://github.com/n0-computer/iroh/commit/d915bfdff45235f90e06e7a8502bebebd6621857))
- *(iroh)* Re-export `n0_watcher::Watcher` trait ([#3356](https://github.com/n0-computer/iroh/issues/3356)) - ([bc6e9e3](https://github.com/n0-computer/iroh/commit/bc6e9e3077a62f61f25efcd0bc93540006222e18))
- *(iroh)* [**breaking**] Expose `DynProtocolHandler` ([#3366](https://github.com/n0-computer/iroh/issues/3366)) - ([056df1d](https://github.com/n0-computer/iroh/commit/056df1de3ccd01b918d95c0140a36c13b42758dd))
- Make `Endpoint::node_addr` watchable and add `trait Watcher` & combinators ([#3045](https://github.com/n0-computer/iroh/issues/3045)) - ([7911255](https://github.com/n0-computer/iroh/commit/79112552b71301db4e17795862b5e06865644a93))
- [**breaking**] Concrete errors ([#3161](https://github.com/n0-computer/iroh/issues/3161)) - ([75eae87](https://github.com/n0-computer/iroh/commit/75eae87c5b14b7f919f1d3e3a083e97547e11a6e))
- Add methods to create variants of the `iroh-base::ticket::ParseError` enum. ([#3362](https://github.com/n0-computer/iroh/issues/3362)) - ([1859de3](https://github.com/n0-computer/iroh/commit/1859de331e9df01eecea2ede1143edb19005c9a6))

## 🐛 Bug Fixes

- *(iroh)* Correctly hook up ipv6 addr lookups ([#3342](https://github.com/n0-computer/iroh/issues/3342)) - ([b8b5bc3](https://github.com/n0-computer/iroh/commit/b8b5bc36b63e43d06ba494135b1ad549c619f202))
- *(iroh-base)* [**breaking**] Remove display impl for SecretKey ([#3364](https://github.com/n0-computer/iroh/issues/3364)) - ([19323e6](https://github.com/n0-computer/iroh/commit/19323e6f5a892f7c9648b934be0e993b6e9c574c))
- Remove unneeded lifetime bound for watcher in wasm ([#3354](https://github.com/n0-computer/iroh/issues/3354)) - ([84dd511](https://github.com/n0-computer/iroh/commit/84dd511c1057d5e68ee8c35cf5ca77df4fee86f6))

## 🚜 Refactor

- *(iroh)* [**breaking**] Simplify discovery errors ([#3340](https://github.com/n0-computer/iroh/issues/3340)) - ([fad99ab](https://github.com/n0-computer/iroh/commit/fad99ab551117ebea2f391605243ee864128ee1e))
- *(iroh)* [**breaking**] Rename ProtocolError to AcceptError ([#3339](https://github.com/n0-computer/iroh/issues/3339)) - ([d4de591](https://github.com/n0-computer/iroh/commit/d4de591cb54be888e587320e6fb705648036ab38))
- *(iroh)* [**breaking**] Rework net_report ([#3314](https://github.com/n0-computer/iroh/issues/3314)) - ([dcbebe9](https://github.com/n0-computer/iroh/commit/dcbebe93f90b2b6408496869fc61503297ba9b86))
- *(iroh)* [**breaking**] Add `IntoDiscovery` trait ([#3327](https://github.com/n0-computer/iroh/issues/3327)) - ([7f2cdd1](https://github.com/n0-computer/iroh/commit/7f2cdd17fd8a01ab4a7d1b48c6e82e5d7520233e))
- *(iroh-relay,iroh)* Slightly clean up staggered DNS errors ([#3337](https://github.com/n0-computer/iroh/issues/3337)) - ([444c76b](https://github.com/n0-computer/iroh/commit/444c76b54680b748684242a34f5a880212509ab0))

## 🧪 Testing

- *(iroh-relay)* Add 300ms timeout to the `test_qad_client_closes_unresponsive_fast` test ([#3332](https://github.com/n0-computer/iroh/issues/3332)) - ([b647af9](https://github.com/n0-computer/iroh/commit/b647af998c8705abaf3183fd7682291350c47225))

## ⚙️ Miscellaneous Tasks

- *(*)* Upgrade to the latest `iroh-metrics`, `portmapper`, and `swarm-discovery` ([#3369](https://github.com/n0-computer/iroh/issues/3369)) - ([79bc05b](https://github.com/n0-computer/iroh/commit/79bc05bdfcb8829adbc8c9ea55c72861556ff846))
- *(iroh)* [**breaking**] Change default relays to new "canary" relays ([#3368](https://github.com/n0-computer/iroh/issues/3368)) - ([6e72f20](https://github.com/n0-computer/iroh/commit/6e72f201db1a6b5c03818a2c193d5dda4d9d03cc))
- *(iroh-relay)* Make QAD test non-flaky by using tokio's paused time ([#3341](https://github.com/n0-computer/iroh/issues/3341)) - ([2b6c258](https://github.com/n0-computer/iroh/commit/2b6c2589b08a516086d4e9aa807d98983085b719))
- *(iroh-relay)* Fix cargo check warning ([#3346](https://github.com/n0-computer/iroh/issues/3346)) - ([c7cf08d](https://github.com/n0-computer/iroh/commit/c7cf08da74ce547c87601a05b309d5e3110d8161))
- Make clippy 1.87 happy ([#3318](https://github.com/n0-computer/iroh/issues/3318)) - ([02acba9](https://github.com/n0-computer/iroh/commit/02acba96985808d6243036965a37021180bf1515))
- Update project_sync workflow ([#3325](https://github.com/n0-computer/iroh/issues/3325)) - ([518400b](https://github.com/n0-computer/iroh/commit/518400b0d7fa1851b49da3598995ff9f0aeece3b))

## Bugfix

- Use staging relay in n0_dns_pkarr_relay ([#3335](https://github.com/n0-computer/iroh/issues/3335)) - ([aebbc72](https://github.com/n0-computer/iroh/commit/aebbc727ffbb72d738f8c76b489e034fdd6a5cc8))

## Example

- Example for 0rtt that can also serve as a benchmark ([#3323](https://github.com/n0-computer/iroh/issues/3323)) - ([b0b11f0](https://github.com/n0-computer/iroh/commit/b0b11f0a52951215bb4e39404a79d3ddabfa60c3))