Skip to content

Commit 3e3798f

Browse files
authored
refactor!: streamline discovery and node info types (#3175)
## Description Adds a `NodeData` struct that contains the information about a node that can be published in discovery services. This struct is both used in `iroh_relay::dns::NodeInfo` and in `iroh::discovery::Discovery`. Also, `iroh::discovery::DiscoveryItem` has no public fields anymore and uses `NodeInfo` internally to again reduce duplication. With these changes, the fields published about a node in discovery now are only defined in a single place. This PR also serves these prupsoes: * We want to add some "user defined data" to discovery (see #3176). This would add a third argument to `Discovery::publish`; with this PR instead we can just add it as an optional field to `NodeData`. * It makes it possible to potentially add data to discovery after 1.0. The fields of `NodeData` are private, so we can add fields, and setter/getter methods, without this being a semver-breaking change. A few other places are changed for consistency: `StaticProvider` now works with `NodeInfo` instead of `NodeAddr` (`NodeInfo` can be easily converted into `NodeAddr`). `DnsProvider::lookup_node_by_id` etc. now return `NodeInfo` instead of `NodeAddr`. A few method names are adjusted for consistency. `NodeInfo` is constructed in a builder-style fashion instead of passing all fields to `new`. ## Breaking Changes * `iroh::discovery::Discovery::publish` now takes `data: &NodeData` as its single argument. `iroh::discovery::NodeData` is a re-export of `iroh_relay::dns::node_info::NodeData`, and contains relay URL and direct addresses. See docs for `NodeData` for details. * `iroh::discovery::DiscoveryItem` no longer has any public fields. There are now getters for the contained data, and constructors for createing a `DiscoveryItem` from a `NodeInfo`. * `iroh_relay::dns::node_info::NodeInfo` is changed. * `NodeInfo::new` now has a single `NodeId` argument. Use `NodeInfo::with_direct_addresses` and `NodeInfo::with_relay_url` to set addresses and relay URL. Alternatively, use `NodeInfo::from_parts` and pass a `NodeData` struct. * `NodeInfo` now has two public fields `node_id: NodeId` and `data: NodeData`, and setter and getter methods for the relay URL and direct addresses. * ` iroh::discovery::pkarr::PkarrPublisher::update_addr_info` now takes a `NodeData` argument ## Notes & open questions <!-- Any notes, remarks or open questions you have to make about the PR. --> ## Change checklist - [x] Self-review. - [x] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [x] Tests if relevant. - [x] All breaking changes documented.
1 parent d9a5b8e commit 3e3798f

File tree

13 files changed

+445
-327
lines changed

13 files changed

+445
-327
lines changed

iroh-dns-server/benches/write.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ fn benchmark_dns_server(c: &mut Criterion) {
2929
let node_id = secret_key.public();
3030

3131
let pkarr_relay = LOCALHOST_PKARR.parse().expect("valid url");
32-
let relay_url = Some("http://localhost:8080".parse().unwrap());
3332
let pkarr = PkarrRelayClient::new(pkarr_relay);
34-
let node_info = NodeInfo::new(node_id, relay_url, Default::default());
33+
let relay_url = "http://localhost:8080".parse().unwrap();
34+
let node_info = NodeInfo::new(node_id).with_relay_url(Some(relay_url));
3535
let signed_packet = node_info.to_pkarr_signed_packet(&secret_key, 30).unwrap();
3636

3737
let start = std::time::Instant::now();

iroh-dns-server/examples/publish.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ async fn main() -> Result<()> {
7777
println!("publish to {pkarr_relay} ...");
7878

7979
let pkarr = PkarrRelayClient::new(pkarr_relay);
80-
let node_info = NodeInfo::new(node_id, Some(args.relay_url), Default::default());
80+
let node_info = NodeInfo::new(node_id).with_relay_url(Some(args.relay_url.into()));
8181
let signed_packet = node_info.to_pkarr_signed_packet(&secret_key, 30)?;
8282
pkarr.publish(&signed_packet).await?;
8383

iroh-dns-server/examples/resolve.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ async fn main() -> anyhow::Result<()> {
5151
Command::Domain { domain } => resolver.lookup_node_by_domain_name(&domain).await?,
5252
};
5353
println!("resolved node {}", resolved.node_id);
54-
if let Some(url) = resolved.relay_url {
54+
if let Some(url) = resolved.relay_url() {
5555
println!(" relay={url}")
5656
}
57-
for addr in resolved.direct_addresses {
57+
for addr in resolved.direct_addresses() {
5858
println!(" addr={addr}")
5959
}
6060
Ok(())

iroh-dns-server/src/lib.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@ mod tests {
2525
use iroh::{
2626
discovery::pkarr::PkarrRelayClient,
2727
dns::{node_info::NodeInfo, DnsResolver},
28-
SecretKey,
28+
RelayUrl, SecretKey,
2929
};
3030
use pkarr::{PkarrClient, SignedPacket};
3131
use testresult::TestResult;
3232
use tracing_test::traced_test;
33-
use url::Url;
3433

3534
use crate::{
3635
config::BootstrapOption,
@@ -170,9 +169,9 @@ mod tests {
170169

171170
let secret_key = SecretKey::generate(rand::thread_rng());
172171
let node_id = secret_key.public();
173-
let relay_url: Url = "https://relay.example.".parse()?;
174172
let pkarr = PkarrRelayClient::new(pkarr_relay);
175-
let node_info = NodeInfo::new(node_id, Some(relay_url.clone()), Default::default());
173+
let relay_url: RelayUrl = "https://relay.example.".parse()?;
174+
let node_info = NodeInfo::new(node_id).with_relay_url(Some(relay_url.clone()));
176175
let signed_packet = node_info.to_pkarr_signed_packet(&secret_key, 30)?;
177176

178177
pkarr.publish(&signed_packet).await?;
@@ -181,7 +180,7 @@ mod tests {
181180
let res = resolver.lookup_node_by_id(&node_id, origin).await?;
182181

183182
assert_eq!(res.node_id, node_id);
184-
assert_eq!(res.relay_url.map(Url::from), Some(relay_url));
183+
assert_eq!(res.relay_url(), Some(&relay_url));
185184

186185
server.shutdown().await?;
187186
Ok(())
@@ -234,8 +233,8 @@ mod tests {
234233
// create a signed packet
235234
let secret_key = SecretKey::generate(rand::thread_rng());
236235
let node_id = secret_key.public();
237-
let relay_url: Url = "https://relay.example.".parse()?;
238-
let node_info = NodeInfo::new(node_id, Some(relay_url.clone()), Default::default());
236+
let relay_url: RelayUrl = "https://relay.example.".parse()?;
237+
let node_info = NodeInfo::new(node_id).with_relay_url(Some(relay_url.clone()));
239238
let signed_packet = node_info.to_pkarr_signed_packet(&secret_key, 30)?;
240239

241240
// publish the signed packet to our DHT
@@ -252,7 +251,7 @@ mod tests {
252251
let res = resolver.lookup_node_by_id(&node_id, origin).await?;
253252

254253
assert_eq!(res.node_id, node_id);
255-
assert_eq!(res.relay_url.map(Url::from), Some(relay_url));
254+
assert_eq!(res.relay_url(), Some(&relay_url));
256255

257256
server.shutdown().await?;
258257
for mut node in testnet.nodes {
@@ -268,8 +267,8 @@ mod tests {
268267
fn random_signed_packet() -> Result<SignedPacket> {
269268
let secret_key = SecretKey::generate(rand::thread_rng());
270269
let node_id = secret_key.public();
271-
let relay_url: Url = "https://relay.example.".parse()?;
272-
let node_info = NodeInfo::new(node_id, Some(relay_url.clone()), Default::default());
270+
let relay_url: RelayUrl = "https://relay.example.".parse()?;
271+
let node_info = NodeInfo::new(node_id).with_relay_url(Some(relay_url.clone()));
273272
node_info.to_pkarr_signed_packet(&secret_key, 30)
274273
}
275274
}

iroh-relay/src/dns.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ use std::{
88

99
use anyhow::{bail, Context, Result};
1010
use hickory_resolver::{Resolver, TokioResolver};
11-
use iroh_base::{NodeAddr, NodeId};
11+
use iroh_base::NodeId;
1212
use n0_future::{
1313
time::{self, Duration},
1414
StreamExt,
1515
};
16+
use node_info::NodeInfo;
1617
use url::Url;
1718

1819
pub mod node_info;
@@ -215,18 +216,18 @@ impl DnsResolver {
215216
///
216217
/// To lookup nodes that published their node info to the DNS servers run by n0,
217218
/// pass [`N0_DNS_NODE_ORIGIN_PROD`] as `origin`.
218-
pub async fn lookup_node_by_id(&self, node_id: &NodeId, origin: &str) -> Result<NodeAddr> {
219+
pub async fn lookup_node_by_id(&self, node_id: &NodeId, origin: &str) -> Result<NodeInfo> {
219220
let attrs =
220221
node_info::TxtAttrs::<node_info::IrohAttr>::lookup_by_id(self, node_id, origin).await?;
221-
let info: node_info::NodeInfo = attrs.into();
222-
Ok(info.into())
222+
let info = attrs.into();
223+
Ok(info)
223224
}
224225

225226
/// Looks up node info by DNS name.
226-
pub async fn lookup_node_by_domain_name(&self, name: &str) -> Result<NodeAddr> {
227+
pub async fn lookup_node_by_domain_name(&self, name: &str) -> Result<NodeInfo> {
227228
let attrs = node_info::TxtAttrs::<node_info::IrohAttr>::lookup_by_name(self, name).await?;
228-
let info: node_info::NodeInfo = attrs.into();
229-
Ok(info.into())
229+
let info = attrs.into();
230+
Ok(info)
230231
}
231232

232233
/// Looks up node info by DNS name in a staggered fashion.
@@ -239,7 +240,7 @@ impl DnsResolver {
239240
&self,
240241
name: &str,
241242
delays_ms: &[u64],
242-
) -> Result<NodeAddr> {
243+
) -> Result<NodeInfo> {
243244
let f = || self.lookup_node_by_domain_name(name);
244245
stagger_call(f, delays_ms).await
245246
}
@@ -255,7 +256,7 @@ impl DnsResolver {
255256
node_id: &NodeId,
256257
origin: &str,
257258
delays_ms: &[u64],
258-
) -> Result<NodeAddr> {
259+
) -> Result<NodeInfo> {
259260
let f = || self.lookup_node_by_id(node_id, origin);
260261
stagger_call(f, delays_ms).await
261262
}

0 commit comments

Comments
 (0)