From 8eef3178b2393cbf13de94bcfcaf8bbac9807c3a Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Sat, 1 Nov 2025 12:14:22 +0100 Subject: [PATCH 1/2] refactor: use ensure more --- iroh-base/src/key.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/iroh-base/src/key.rs b/iroh-base/src/key.rs index 69e61f3e9a..9cb7b01bdd 100644 --- a/iroh-base/src/key.rs +++ b/iroh-base/src/key.rs @@ -11,7 +11,7 @@ use std::{ use curve25519_dalek::edwards::CompressedEdwardsY; use ed25519_dalek::{SigningKey, VerifyingKey}; -use n0_error::{e, stack_error}; +use n0_error::{ensure, stack_error}; use rand_core::CryptoRng; use serde::{Deserialize, Serialize, de, ser}; @@ -424,16 +424,18 @@ fn decode_base32_hex(s: &str) -> Result<[u8; 32], KeyParsingError> { } else { let input = s.to_ascii_uppercase(); let input = input.as_bytes(); - if data_encoding::BASE32_NOPAD.decode_len(input.len())? != bytes.len() { - return Err(e!(KeyParsingError::DecodeInvalidLength)); - } + ensure!( + data_encoding::BASE32_NOPAD.decode_len(input.len())? == bytes.len(), + KeyParsingError::DecodeInvalidLength + ); data_encoding::BASE32_NOPAD.decode_mut(input, &mut bytes) }; match res { Ok(len) => { - if len != PublicKey::LENGTH { - return Err(e!(KeyParsingError::DecodeInvalidLength)); - } + ensure!( + len == PublicKey::LENGTH, + KeyParsingError::DecodeInvalidLength + ); } Err(partial) => return Err(partial.error.into()), } From 0f78cc8907e45565ab9759f6de04f486b7f67ffb Mon Sep 17 00:00:00 2001 From: dignifiedquire Date: Sat, 1 Nov 2025 16:58:22 +0100 Subject: [PATCH 2/2] refactor(iroh-dns-server): use concrete erros in utils --- iroh-dns-server/src/store.rs | 17 +++++++++------ iroh-dns-server/src/util.rs | 42 +++++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/iroh-dns-server/src/store.rs b/iroh-dns-server/src/store.rs index 08d492fdef..537075598d 100644 --- a/iroh-dns-server/src/store.rs +++ b/iroh-dns-server/src/store.rs @@ -2,9 +2,12 @@ use std::{collections::BTreeMap, num::NonZeroUsize, path::Path, sync::Arc, time::Duration}; -use hickory_server::proto::rr::{Name, RecordSet, RecordType, RrKey}; +use hickory_server::proto::{ + ProtoError, + rr::{Name, RecordSet, RecordType, RrKey}, +}; use lru::LruCache; -use n0_error::Result; +use n0_error::{Result, StdResultExt}; use pkarr::{Client as PkarrClient, SignedPacket}; use tokio::sync::Mutex; use tracing::{debug, trace, warn}; @@ -234,7 +237,7 @@ impl ZoneCache { record_type: RecordType, ) -> Result>> { let pubkey = PublicKeyBytes::from_signed_packet(signed_packet); - let zone = CachedZone::from_signed_packet(signed_packet)?; + let zone = CachedZone::from_signed_packet(signed_packet).anyerr()?; let res = zone.resolve(name, record_type); self.dht_cache.insert(pubkey, zone, DHT_CACHE_TTL); Ok(res) @@ -251,8 +254,10 @@ impl ZoneCache { trace!("insert skip: cached is newer"); Ok(()) } else { - self.cache - .put(pubkey, CachedZone::from_signed_packet(signed_packet)?); + self.cache.put( + pubkey, + CachedZone::from_signed_packet(signed_packet).anyerr()?, + ); trace!("inserted into cache"); Ok(()) } @@ -271,7 +276,7 @@ struct CachedZone { } impl CachedZone { - fn from_signed_packet(signed_packet: &SignedPacket) -> Result { + fn from_signed_packet(signed_packet: &SignedPacket) -> Result { let (_label, records) = signed_packet_to_hickory_records_without_origin(signed_packet, |_| true)?; Ok(Self { diff --git a/iroh-dns-server/src/util.rs b/iroh-dns-server/src/util.rs index 060498527c..6419b6adc5 100644 --- a/iroh-dns-server/src/util.rs +++ b/iroh-dns-server/src/util.rs @@ -6,6 +6,7 @@ use std::{ }; use hickory_server::proto::{ + ProtoError, op::Message, rr::{ Name, Record, RecordSet, RecordType, RrKey, @@ -13,7 +14,7 @@ use hickory_server::proto::{ }, serialize::binary::BinDecodable, }; -use n0_error::{AnyError, Result, StdResultExt}; +use n0_error::{AnyError, StdResultExt, e, stack_error}; use pkarr::SignedPacket; #[derive( @@ -21,14 +22,26 @@ use pkarr::SignedPacket; )] pub struct PublicKeyBytes([u8; 32]); +#[stack_error(derive, add_meta, from_sources)] +pub enum InvalidPublicKeyBytes { + #[error(transparent)] + Encoding { + #[error(std_err)] + source: z32::Z32Error, + }, + #[error("invalid length, must be 32 bytes")] + InvalidLength, +} + impl PublicKeyBytes { pub fn new(bytes: [u8; 32]) -> Self { Self(bytes) } - pub fn from_z32(s: &str) -> Result { - let bytes = z32::decode(s.as_bytes()).anyerr()?; - let bytes = TryInto::<[u8; 32]>::try_into(&bytes[..]).std_context("invalid length")?; + pub fn from_z32(s: &str) -> Result { + let bytes = z32::decode(s.as_bytes())?; + let bytes = TryInto::<[u8; 32]>::try_into(&bytes[..]) + .map_err(|_| e!(InvalidPublicKeyBytes::InvalidLength))?; Ok(Self(bytes)) } @@ -75,7 +88,8 @@ impl TryFrom for pkarr::PublicKey { } impl FromStr for PublicKeyBytes { - type Err = AnyError; + type Err = InvalidPublicKeyBytes; + fn from_str(s: &str) -> Result { Self::from_z32(s) } @@ -87,17 +101,19 @@ impl AsRef<[u8; 32]> for PublicKeyBytes { } } -pub fn signed_packet_to_hickory_message(signed_packet: &SignedPacket) -> Result { +pub fn signed_packet_to_hickory_message( + signed_packet: &SignedPacket, +) -> Result { let encoded = signed_packet.encoded_packet(); - let message = Message::from_bytes(&encoded).anyerr()?; + let message = Message::from_bytes(&encoded)?; Ok(message) } pub fn signed_packet_to_hickory_records_without_origin( signed_packet: &SignedPacket, filter: impl Fn(&Record) -> bool, -) -> Result<(Label, BTreeMap>)> { - let common_zone = Label::from_utf8(&signed_packet.public_key().to_z32()).anyerr()?; +) -> Result<(Label, BTreeMap>), ProtoError> { + let common_zone = Label::from_utf8(&signed_packet.public_key().to_z32())?; let mut message = signed_packet_to_hickory_message(signed_packet)?; let answers = message.take_answers(); let mut output: BTreeMap> = BTreeMap::new(); @@ -111,7 +127,7 @@ pub fn signed_packet_to_hickory_records_without_origin( if name.num_labels() < 1 { continue; } - let zone = name.iter().next_back().unwrap().into_label().anyerr()?; + let zone = name.iter().next_back().unwrap().into_label()?; if zone != common_zone { continue; } @@ -120,7 +136,7 @@ pub fn signed_packet_to_hickory_records_without_origin( } let name_without_zone = - Name::from_labels(name.iter().take(name.num_labels() as usize - 1)).anyerr()?; + Name::from_labels(name.iter().take(name.num_labels() as usize - 1))?; record.set_name(name_without_zone); let rrkey = RrKey::new(record.name().into(), record.record_type()); @@ -144,8 +160,8 @@ pub fn record_set_append_origin( input: &RecordSet, origin: &Name, serial: u32, -) -> Result { - let new_name = input.name().clone().append_name(origin).anyerr()?; +) -> Result { + let new_name = input.name().clone().append_name(origin)?; let mut output = RecordSet::new(new_name.clone(), input.record_type(), serial); // TODO: less clones for record in input.records_without_rrsigs() {