pub struct DhtService { /* private fields */ }Expand description
The DHT service for one node. Cloneable-by-Arc internally; wrap in Arc to share between the
serving task (inbound RPC) and querying callers.
Implementations§
Source§impl DhtService
impl DhtService
Sourcepub fn new(
local_id: PeerId,
local_addresses: Vec<CandidateAddr>,
config: DhtConfig,
transport: Arc<dyn DhtTransport>,
) -> Self
pub fn new( local_id: PeerId, local_addresses: Vec<CandidateAddr>, config: DhtConfig, transport: Arc<dyn DhtTransport>, ) -> Self
Create a service for the node identified by local_id, advertising local_addresses in the
provider records it announces, driving RPC over transport.
Sourcepub async fn bootstrap(
&self,
peers: &[BootstrapPeer],
) -> Result<usize, DhtError>
pub async fn bootstrap( &self, peers: &[BootstrapPeer], ) -> Result<usize, DhtError>
Seed the routing table from peers and populate it by looking up this node’s own id (the
canonical Kademlia bootstrap: a self-lookup fills the buckets around us). Returns the number
of distinct peers now known.
Safe to call repeatedly (on reconnect / when new bootstrap peers arrive) — it merges, never resets.
Sourcepub async fn find_node(
&self,
peer_id: &PeerId,
) -> Result<Vec<Contact>, DhtError>
pub async fn find_node( &self, peer_id: &PeerId, ) -> Result<Vec<Contact>, DhtError>
Find the k peers closest to peer_id (the routing primitive). Runs an iterative
find_node lookup and returns the converged closest contacts.
Sourcepub async fn find_providers(
&self,
content: &ContentId,
) -> Result<Vec<ProviderRecord>, DhtError>
pub async fn find_providers( &self, content: &ContentId, ) -> Result<Vec<ProviderRecord>, DhtError>
Find the providers of content — the peers holding it. Runs an iterative find_providers
lookup toward the content key, returning every live provider record collected (deduped by
provider). The node then connects to those providers over dig-nat and fetches via the L7 peer
RPC.
Returns an empty vec (not an error) when the content simply has no known providers; returns
DhtError::NoPeers only when there is no one to ask (empty routing table + no bootstrap).
Sourcepub async fn announce_provider(
&self,
content: &ContentId,
) -> Result<usize, DhtError>
pub async fn announce_provider( &self, content: &ContentId, ) -> Result<usize, DhtError>
Announce that THIS node holds content: build a provider record (this node’s peer_id +
addresses, expiring at now + provider_ttl), store it locally, remember to republish it, and
PUT it at the k nodes closest to the content key. Returns how many peers accepted the PUT.
Called when the node’s inventory gains content (a new capsule/root/resource it now serves).
Sourcepub async fn withdraw_provider(&self, content: &ContentId) -> bool
pub async fn withdraw_provider(&self, content: &ContentId) -> bool
Stop announcing content (the node no longer holds it). The record ages out of the DHT via
TTL; we just stop republishing it. Returns whether it was being announced.
Sourcepub async fn republish(&self) -> usize
pub async fn republish(&self) -> usize
Republish every content key this node still announces — re-runs the announce PUT so provider
records never expire while the node is online. Call on the DhtConfig::republish_interval.
Returns the number of content keys republished.
Sourcepub async fn refresh_buckets(&self) -> usize
pub async fn refresh_buckets(&self) -> usize
Refresh populated buckets by looking up a random key in each — keeps the routing table fresh
as peers churn. Call on the DhtConfig::refresh_interval. Returns the number of buckets
refreshed.
Sourcepub async fn gc(&self) -> usize
pub async fn gc(&self) -> usize
Drop expired provider records. Call periodically (piggy-backs on republish/refresh). Returns the number of records removed.
Sourcepub async fn ping(&self, peer: &Contact) -> bool
pub async fn ping(&self, peer: &Contact) -> bool
Ping a peer for liveness; on failure, evict it from the routing table. Used by the ping-and-replace maintenance when a bucket is full. Returns whether the peer is alive.
Sourcepub async fn handle_request(&self, request: DhtRequest) -> DhtResponse
pub async fn handle_request(&self, request: DhtRequest) -> DhtResponse
Answer an inbound DHT request from another node, without a known caller identity. Prefer
handle_request_from on an authenticated transport (it lets the
responder learn the caller and populate its routing table bidirectionally, the way Kademlia
tables fill).
Sourcepub async fn handle_request_from(
&self,
caller: Option<Contact>,
request: DhtRequest,
) -> DhtResponse
pub async fn handle_request_from( &self, caller: Option<Contact>, request: DhtRequest, ) -> DhtResponse
Answer an inbound DHT request, folding the authenticated caller into the routing table.
This is the server half — a dig-node wires it to inbound DHT streams, passing the caller’s
mTLS-verified Contact as caller. Learning the caller from every inbound RPC is how a
Kademlia node discovers peers without an explicit announce: a node that talks to you becomes
a candidate in your table. The caller MUST come from the authenticated transport (the mTLS
peer_id), never from the request body — identity is not self-asserted.
It reads/writes only local state (routing table + provider store) and never makes outbound RPCs, so it cannot recurse or block on the network.
Sourcepub async fn known_closest(&self, target: &Key) -> Vec<Contact>
pub async fn known_closest(&self, target: &Key) -> Vec<Contact>
The contacts currently in this node’s routing table closest to target (diagnostic /
introspection — the peers this node knows without any network round-trip).
Sourcepub async fn routing_len(&self) -> usize
pub async fn routing_len(&self) -> usize
The number of peers currently in this node’s routing table (diagnostic / metrics).
Auto Trait Implementations§
impl !RefUnwindSafe for DhtService
impl !UnwindSafe for DhtService
impl Freeze for DhtService
impl Send for DhtService
impl Sync for DhtService
impl Unpin for DhtService
impl UnsafeUnpin for DhtService
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.