Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
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
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
57 changes: 56 additions & 1 deletion iroh-base/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,62 @@ 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 PartialEq<PublicKey> for EndpointId {
fn eq(&self, other: &PublicKey) -> bool {
match self {
EndpointId::Ed25519(key) => key == other,
EndpointId::Other(_) => false,
}
}
}

impl Display for EndpointId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EndpointId::Ed25519(key) => write!(f, "Ed25519({})", key),
EndpointId::Other(bytes) => write!(f, "Other({})", data_encoding::HEXLOWER.encode(bytes)),
}
}
}

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")
}

/// Format a short representation of this endpoint id.
pub fn fmt_short(&self) -> String {
match self {
EndpointId::Ed25519(key) => key.fmt_short().to_string(),
EndpointId::Other(_) => "Other".to_string(),
}
}
}

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 +117,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
10 changes: 5 additions & 5 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 @@ -382,13 +382,13 @@ impl DnsResolver {
stagger_call(f, delays_ms).await
}

/// Looks up endpoint info by [`EndpointId`] and origin domain name.
/// Looks up endpoint info by [`PublicKey`] and origin domain name.
///
/// To lookup endpoints that published their endpoint info to the DNS servers run by n0,
/// 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 @@ -424,15 +424,15 @@ impl DnsResolver {
stagger_call(f, delays_ms).await
}

/// Looks up endpoint info by [`EndpointId`] and origin domain name.
/// Looks up endpoint info by [`PublicKey`] and origin domain name.
///
/// From the moment this function is called, each lookup is scheduled after the delays in
/// `delays_ms` with the first call being done immediately. `[200ms, 300ms]` results in calls
/// at T+0ms, T+200ms and T+300ms. The result of the first successful call is returned, or a
/// 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
Loading
Loading