Skip to main content

PeerDiagnosticsResult

Struct PeerDiagnosticsResult 

Source
pub struct PeerDiagnosticsResult {
    pub nickname: String,
    pub principal: String,
    pub user_id: Option<String>,
    pub paired_at: Option<String>,
    pub last_addr: Option<String>,
    pub hint_addrs: Vec<String>,
    pub hint_usable: bool,
    pub reachability: Option<PeerReachability>,
}
Expand description

Result of Request::PeerDiagnostics (#140): the DURABLE per-peer state this node carries, for diagnosing why a specific long-lived pairing behaves differently from a fresh one.

This surface carries a PEER’s transport coordinates on purpose. The rendered porcelain is address-free everywhere — nicknames and path KINDS — because that discipline keeps a peer’s coordinates out of screenshots. (SelfNetwork.direct_addrs already returns this node’s OWN addresses on status; what is new here is another endpoint’s.) The question this answers is “what address is this node about to dial, and where did it come from”, which has no answer without the address. It is your own store’s record of your own paired peers. Do not render it in ordinary porcelain, and read it before pasting it anywhere public.

The intended use is a paired capture: run it on BOTH ends of a stuck pairing and compare the stored hint against the live path each side reports.

Fields§

§nickname: String

The peer’s nickname as this node stores it.

§principal: String

The peer’s stable eid: device principal.

§user_id: Option<String>

The peer’s b64u: user_id if it proved a device→user binding at pairing.

§paired_at: Option<String>

When the pairing was written (epoch seconds as a string), if recorded. A LONG-LIVED pairing is exactly what #140 is about, so the age is part of the evidence.

§last_addr: Option<String>

The persisted dial HINT, verbatim as stored — the durable state a freshly paired identity does not have. None for a peer added without one.

It is MERGED with discovery rather than replacing it — iroh inserts it as one more candidate path (Source::App) and then triggers address lookup.

But that lookup is skipped when a path is already selected. iroh’s trigger_address_lookup returns early if selected_path.is_some(), and a selected path is cleared only when the last connection to that peer closes. So on a pair that already holds an open RELAYED connection — live sessions, dial-backs, a working relay — discovery does NOT re-run, and this hint is the only addressing the dial contributes. Do not read “merged, so a stale hint is harmless” as unconditional; it is least true in exactly the state a stuck pairing is in.

It is the only durable per-peer state ON THIS NODE’S DISK that the dial path reads, which is what makes it the first thing to compare between two ends. It is not the only durable state a long-lived identity carries — a published discovery record under the same key, and SelfNetwork::identity_conflict_epoch, live elsewhere.

§hint_addrs: Vec<String>

The addresses parsed out of last_addr, for reading without a JSON round trip: IP addresses verbatim, relay URLs as relay <url> and SANITIZED to scheme+host+port (an operator’s relay URL can carry a userinfo token, and this output is meant to be pasted into an issue). Empty when the hint is absent, unparseable, or for a different endpoint — all of which degrade to an id-only dial.

A relay … entry with no IP alongside it is worth noticing: that hint can never punch.

§hint_usable: bool

Whether last_addr parses AND its embedded id matches this peer. A false here with a present last_addr means the hint is being silently discarded at every dial.

§reachability: Option<PeerReachability>

This node’s LIVE view of the peer, read straight from the reachability cache — the same values status reports, repeated here so one capture holds both the durable and the live side. None when this peer has never been probed, which is the honest answer on a freshly restarted daemon; it is not the same as unreachable.

Read from the cache rather than through status’s projection deliberately: that projection spawns a background probe for every stale peer, which would make this diagnostic a participant in the reproduction it is meant to observe.

Trait Implementations§

Source§

impl Clone for PeerDiagnosticsResult

Source§

fn clone(&self) -> PeerDiagnosticsResult

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PeerDiagnosticsResult

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for PeerDiagnosticsResult

Source§

fn default() -> PeerDiagnosticsResult

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for PeerDiagnosticsResult

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Eq for PeerDiagnosticsResult

Source§

impl PartialEq for PeerDiagnosticsResult

Source§

fn eq(&self, other: &PeerDiagnosticsResult) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for PeerDiagnosticsResult

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for PeerDiagnosticsResult

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more