Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
WIP
- remove EndpointId type alias
- add EndpointId enum
- gradually reintroduce EndpointId to the public API
  • Loading branch information
rklaehn committed Nov 12, 2025
commit eec477828f62c1a7b71a4d8043895d9dcc40d9e5
14 changes: 10 additions & 4 deletions iroh-base/src/endpoint_addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,17 @@ impl EndpointAddr {
///
/// This still is usable with e.g. a discovery service to establish a connection,
/// depending on the situation.
pub fn new(id: PublicKey) -> Self {
pub fn new(id: impl Into<EndpointId>) -> Self {
EndpointAddr {
id,
id: id.into(),
addrs: Default::default(),
}
}

/// Creates a new [`EndpointAddr`] from its parts.
pub fn from_parts(id: PublicKey, addrs: impl IntoIterator<Item = TransportAddr>) -> Self {
pub fn from_parts(id: impl Into<EndpointId>, addrs: impl IntoIterator<Item = TransportAddr>) -> Self {
Self {
id,
id: id.into(),
addrs: addrs.into_iter().collect(),
}
}
Expand Down Expand Up @@ -118,6 +118,12 @@ impl EndpointAddr {
}
}

impl From<PublicKey> for EndpointAddr {
fn from(endpoint_id: PublicKey) -> Self {
EndpointAddr::new(endpoint_id)
}
}

impl From<EndpointId> for EndpointAddr {
fn from(endpoint_id: EndpointId) -> Self {
EndpointAddr::new(endpoint_id)
Expand Down
31 changes: 30 additions & 1 deletion iroh-base/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,36 @@ use serde::{Deserialize, Serialize, de, ser};
#[repr(transparent)]
pub struct PublicKey(CompressedEdwardsY);

/// The identifier for an endpoint in the (iroh) network.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub enum EndpointId {
/// An Ed25519 public key.
Ed25519(PublicKey),
/// Other types of endpoint identifiers.
Other([u8; 8]),
}

impl EndpointId {
/// If this is an Ed25519 endpoint id, return the public key.
pub fn as_ed(self) -> Option<PublicKey> {
match self {
EndpointId::Ed25519(key) => Some(key),
EndpointId::Other(_) => None,
}
}

/// Expect this to be an Ed25519 endpoint id, panic if not.
pub fn expect_ed(self) -> PublicKey {
self.as_ed().expect("not an ed25519 endpoint id")
}
}

impl From<PublicKey> for EndpointId {
fn from(key: PublicKey) -> Self {
EndpointId::Ed25519(key)
}
}

impl Borrow<[u8; 32]> for PublicKey {
fn borrow(&self) -> &[u8; 32] {
self.as_bytes()
Expand Down Expand Up @@ -61,7 +91,6 @@ impl Ord for PublicKey {
///
/// - `encrypt(key: PublicKey)`
/// - `send_to(endpoint: EndpointId)`
pub type EndpointId = PublicKey;

impl Hash for PublicKey {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
Expand Down
2 changes: 1 addition & 1 deletion iroh-base/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ mod relay_url;
#[cfg(feature = "key")]
pub use self::endpoint_addr::{EndpointAddr, TransportAddr};
#[cfg(feature = "key")]
pub use self::key::{EndpointId, KeyParsingError, PublicKey, SecretKey, Signature, SignatureError};
pub use self::key::{EndpointId, PublicKey, KeyParsingError, SecretKey, Signature, SignatureError};
#[cfg(feature = "relay")]
pub use self::relay_url::{RelayUrl, RelayUrlParseError};
6 changes: 3 additions & 3 deletions iroh-dns-server/examples/convert.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::str::FromStr;

use clap::Parser;
use iroh::EndpointId;
use iroh::PublicKey;
use n0_error::{Result, StdResultExt};

#[derive(Debug, Parser)]
Expand All @@ -20,13 +20,13 @@ fn main() -> Result<()> {
let args = Cli::parse();
match args.command {
Command::EndpointToPkarr { endpoint_id } => {
let endpoint_id = EndpointId::from_str(&endpoint_id)?;
let endpoint_id = PublicKey::from_str(&endpoint_id)?;
let public_key = pkarr::PublicKey::try_from(endpoint_id.as_bytes()).anyerr()?;
println!("{}", public_key.to_z32())
}
Command::PkarrToEndpoint { z32_pubkey } => {
let public_key = pkarr::PublicKey::try_from(z32_pubkey.as_str()).anyerr()?;
let endpoint_id = EndpointId::from_bytes(public_key.as_bytes())?;
let endpoint_id = PublicKey::from_bytes(public_key.as_bytes())?;
println!("{endpoint_id}")
}
}
Expand Down
4 changes: 2 additions & 2 deletions iroh-dns-server/examples/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{net::SocketAddr, str::FromStr};

use clap::{Parser, ValueEnum};
use iroh::{
EndpointId, SecretKey,
PublicKey, SecretKey,
discovery::{
UserData,
dns::{N0_DNS_ENDPOINT_ORIGIN_PROD, N0_DNS_ENDPOINT_ORIGIN_STAGING},
Expand Down Expand Up @@ -140,6 +140,6 @@ async fn main() -> Result<()> {
Ok(())
}

fn fmt_domain(endpoint_id: &EndpointId, origin: &str) -> String {
fn fmt_domain(endpoint_id: &PublicKey, origin: &str) -> String {
format!("{IROH_TXT_NAME}.{}.{origin}", endpoint_id.to_z32())
}
4 changes: 2 additions & 2 deletions iroh-dns-server/examples/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::{Parser, ValueEnum};
use iroh::{
EndpointId,
PublicKey,
discovery::dns::{N0_DNS_ENDPOINT_ORIGIN_PROD, N0_DNS_ENDPOINT_ORIGIN_STAGING},
dns::DnsResolver,
};
Expand Down Expand Up @@ -34,7 +34,7 @@ enum Command {
/// Resolve endpoint info by endpoint id.
Endpoint {
/// The endpoint id to resolve.
endpoint_id: EndpointId,
endpoint_id: PublicKey,
/// Use a custom domain when resolving endpoint info via DNS.
#[clap(long)]
dns_origin_domain: Option<String>,
Expand Down
6 changes: 3 additions & 3 deletions iroh-relay/src/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use hickory_resolver::{
config::{ResolverConfig, ResolverOpts},
name_server::TokioConnectionProvider,
};
use iroh_base::EndpointId;
use iroh_base::PublicKey;
use n0_error::{StackError, e, stack_error};
use n0_future::{
StreamExt,
Expand Down Expand Up @@ -388,7 +388,7 @@ impl DnsResolver {
/// pass [`N0_DNS_ENDPOINT_ORIGIN_PROD`] as `origin`.
pub async fn lookup_endpoint_by_id(
&self,
endpoint_id: &EndpointId,
endpoint_id: &PublicKey,
origin: &str,
) -> Result<EndpointInfo, LookupError> {
let name = endpoint_info::endpoint_domain(endpoint_id, origin);
Expand Down Expand Up @@ -432,7 +432,7 @@ impl DnsResolver {
/// summary of all errors otherwise.
pub async fn lookup_endpoint_by_id_staggered(
&self,
endpoint_id: &EndpointId,
endpoint_id: &PublicKey,
origin: &str,
delays_ms: &[u64],
) -> Result<EndpointInfo, StaggeredError<LookupError>> {
Expand Down
48 changes: 24 additions & 24 deletions iroh-relay/src/endpoint_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use std::{
str::{FromStr, Utf8Error},
};

use iroh_base::{EndpointAddr, EndpointId, KeyParsingError, RelayUrl, SecretKey, TransportAddr};
use iroh_base::{EndpointAddr, EndpointId, KeyParsingError, PublicKey, RelayUrl, SecretKey, TransportAddr};
use n0_error::{e, ensure, stack_error};
use url::Url;

Expand Down Expand Up @@ -89,22 +89,22 @@ pub trait EndpointIdExt {
/// Parses a [`EndpointId`] from [`z-base-32`] encoding.
///
/// [`z-base-32`]: https://philzimmermann.com/docs/human-oriented-base-32-encoding.txt
fn from_z32(s: &str) -> Result<EndpointId, DecodingError>;
fn from_z32(s: &str) -> Result<PublicKey, DecodingError>;
}

impl EndpointIdExt for EndpointId {
impl EndpointIdExt for PublicKey {
fn to_z32(&self) -> String {
z32::encode(self.as_bytes())
}

fn from_z32(s: &str) -> Result<EndpointId, DecodingError> {
fn from_z32(s: &str) -> Result<PublicKey, DecodingError> {
let bytes =
z32::decode(s.as_bytes()).map_err(|err| e!(DecodingError::InvalidEncodingZ32, err))?;
let bytes: &[u8; 32] = &bytes
.try_into()
.map_err(|_| e!(DecodingError::InvalidLength { len: s.len() }))?;
let endpoint_id =
EndpointId::from_bytes(bytes).map_err(|err| e!(DecodingError::InvalidKey, err))?;
PublicKey::from_bytes(bytes).map_err(|err| e!(DecodingError::InvalidKey, err))?;
Ok(endpoint_id)
}
}
Expand Down Expand Up @@ -321,7 +321,7 @@ impl From<&TxtAttrs<IrohAttr>> for EndpointInfo {
data.set_user_data(user_data);
data.add_addrs(relay_urls.chain(ip_addrs));

Self { endpoint_id, data }
Self { endpoint_id: endpoint_id.into(), data }
}
}

Expand All @@ -338,16 +338,16 @@ impl From<EndpointAddr> for EndpointInfo {
info
}
}

impl EndpointInfo {
/// Creates a new [`EndpointInfo`] with an empty [`EndpointData`].
pub fn new(endpoint_id: EndpointId) -> Self {
pub fn new(endpoint_id: impl Into<EndpointId>) -> Self {
Self::from_parts(endpoint_id, Default::default())
}

/// Creates a new [`EndpointInfo`] from its parts.
pub fn from_parts(endpoint_id: EndpointId, data: EndpointData) -> Self {
Self { endpoint_id, data }
pub fn from_parts(endpoint_id: impl Into<EndpointId>, data: EndpointData) -> Self {
Self { endpoint_id: endpoint_id.into(), data }
}

/// Sets the relay URL and returns the updated endpoint info.
Expand Down Expand Up @@ -462,7 +462,7 @@ impl std::ops::DerefMut for EndpointInfo {
/// [`IROH_TXT_NAME`] and the second label to be a z32 encoded [`EndpointId`]. Ignores
/// subsequent labels.
#[cfg(not(wasm_browser))]
fn endpoint_id_from_txt_name(name: &str) -> Result<EndpointId, ParseError> {
fn endpoint_id_from_txt_name(name: &str) -> Result<PublicKey, ParseError> {
let num_labels = name.split(".").count();
if num_labels < 2 {
return Err(e!(ParseError::NumLabels { num_labels }));
Expand All @@ -475,7 +475,7 @@ fn endpoint_id_from_txt_name(name: &str) -> Result<EndpointId, ParseError> {
}));
}
let label = labels.next().expect("checked above");
let endpoint_id = EndpointId::from_z32(label)?;
let endpoint_id = PublicKey::from_z32(label)?;
Ok(endpoint_id)
}

Expand All @@ -502,7 +502,7 @@ pub(crate) enum IrohAttr {
/// [`Display`].
#[derive(Debug)]
pub(crate) struct TxtAttrs<T> {
endpoint_id: EndpointId,
endpoint_id: PublicKey,
attrs: BTreeMap<T, Vec<String>>,
}

Expand All @@ -522,14 +522,14 @@ impl From<&EndpointInfo> for TxtAttrs<IrohAttr> {
if let Some(user_data) = &info.data.user_data {
attrs.push((IrohAttr::UserData, user_data.to_string()));
}
Self::from_parts(info.endpoint_id, attrs.into_iter())
Self::from_parts(info.endpoint_id.expect_ed(), attrs.into_iter())
}
}

impl<T: FromStr + Display + Hash + Ord> TxtAttrs<T> {
/// Creates [`TxtAttrs`] from an endpoint id and an iterator of key-value pairs.
pub(crate) fn from_parts(
endpoint_id: EndpointId,
endpoint_id: PublicKey,
pairs: impl Iterator<Item = (T, String)>,
) -> Self {
let mut attrs: BTreeMap<T, Vec<String>> = BTreeMap::new();
Expand All @@ -541,7 +541,7 @@ impl<T: FromStr + Display + Hash + Ord> TxtAttrs<T> {

/// Creates [`TxtAttrs`] from an endpoint id and an iterator of "{key}={value}" strings.
pub(crate) fn from_strings(
endpoint_id: EndpointId,
endpoint_id: PublicKey,
strings: impl Iterator<Item = String>,
) -> Result<Self, ParseError> {
let mut attrs: BTreeMap<T, Vec<String>> = BTreeMap::new();
Expand All @@ -566,7 +566,7 @@ impl<T: FromStr + Display + Hash + Ord> TxtAttrs<T> {
}

/// Returns the endpoint id.
pub(crate) fn endpoint_id(&self) -> EndpointId {
pub(crate) fn endpoint_id(&self) -> PublicKey {
self.endpoint_id
}

Expand All @@ -581,7 +581,7 @@ impl<T: FromStr + Display + Hash + Ord> TxtAttrs<T> {
let pubkey = packet.public_key();
let pubkey_z32 = pubkey.to_z32();
let endpoint_id =
EndpointId::from_bytes(&pubkey.verifying_key().to_bytes()).expect("valid key");
PublicKey::from_bytes(&pubkey.verifying_key().to_bytes()).expect("valid key");
let zone = dns::Name::new(&pubkey_z32).expect("z32 encoding is valid");
let txt_data = packet
.all_resource_records()
Expand Down Expand Up @@ -652,8 +652,8 @@ pub(crate) fn ensure_iroh_txt_label(name: String) -> String {
}

#[cfg(not(wasm_browser))]
pub(crate) fn endpoint_domain(endpoint_id: &EndpointId, origin: &str) -> String {
format!("{}.{}", EndpointId::to_z32(endpoint_id), origin)
pub(crate) fn endpoint_domain(endpoint_id: &PublicKey, origin: &str) -> String {
format!("{}.{}", PublicKey::to_z32(endpoint_id), origin)
}

#[cfg(test)]
Expand All @@ -671,7 +671,7 @@ mod tests {
},
},
};
use iroh_base::{EndpointId, SecretKey, TransportAddr};
use iroh_base::{PublicKey, SecretKey, TransportAddr};
use n0_error::{Result, StdResultExt};

use super::{EndpointData, EndpointIdExt, EndpointInfo};
Expand All @@ -684,7 +684,7 @@ mod tests {
TransportAddr::Ip("127.0.0.1:1234".parse().unwrap()),
])
.with_user_data(Some("foobar".parse().unwrap()));
let endpoint_id = "vpnk377obfvzlipnsfbqba7ywkkenc4xlpmovt5tsfujoa75zqia"
let endpoint_id: PublicKey = "vpnk377obfvzlipnsfbqba7ywkkenc4xlpmovt5tsfujoa75zqia"
.parse()
.unwrap();
let expected = EndpointInfo::from_parts(endpoint_id, endpoint_data);
Expand Down Expand Up @@ -738,7 +738,7 @@ mod tests {
Record::from_rdata(
Name::from_utf8(format!(
"_iroh.{}.dns.iroh.link.",
EndpointId::from_str(
PublicKey::from_str(
// Another EndpointId
"a55f26132e5e43de834d534332f66a20d480c3e50a13a312a071adea6569981e"
)?
Expand Down Expand Up @@ -774,7 +774,7 @@ mod tests {

let endpoint_info = EndpointInfo::from_txt_lookup(name.to_string(), lookup)?;

let expected_endpoint_info = EndpointInfo::new(EndpointId::from_str(
let expected_endpoint_info = EndpointInfo::new(PublicKey::from_str(
"1992d53c02cdc04566e5c0edb1ce83305cd550297953a047a445ea3264b54b18",
)?)
.with_relay_url(Some("https://euw1-1.relay.iroh.network./".parse()?))
Expand Down
10 changes: 5 additions & 5 deletions iroh-relay/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::{

use clap::Parser;
use http::StatusCode;
use iroh_base::EndpointId;
use iroh_base::PublicKey;
use iroh_relay::{
defaults::{
DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT, DEFAULT_METRICS_PORT, DEFAULT_RELAY_QUIC_PORT,
Expand Down Expand Up @@ -179,9 +179,9 @@ enum AccessConfig {
#[default]
Everyone,
/// Allows only these endpoints.
Allowlist(Vec<EndpointId>),
Allowlist(Vec<PublicKey>),
/// Allows everyone, except these endpoints.
Denylist(Vec<EndpointId>),
Denylist(Vec<PublicKey>),
/// Performs a HTTP POST request to determine access for each endpoint that connects to the relay.
///
/// The request will have a header `X-Iroh-Endpoint-Id` set to the hex-encoded endpoint id attempting
Expand Down Expand Up @@ -261,7 +261,7 @@ impl From<AccessConfig> for iroh_relay::server::AccessConfig {
async fn http_access_check(
client: &reqwest::Client,
config: &HttpAccessConfig,
endpoint_id: EndpointId,
endpoint_id: PublicKey,
) -> iroh_relay::server::Access {
use iroh_relay::server::Access;
debug!(url=%config.url, "Check relay access via HTTP POST");
Expand All @@ -281,7 +281,7 @@ async fn http_access_check(
async fn http_access_check_inner(
client: &reqwest::Client,
config: &HttpAccessConfig,
endpoint_id: EndpointId,
endpoint_id: PublicKey,
) -> Result<()> {
let mut request = client
.post(config.url.clone())
Expand Down
Loading