Struct Dht

Source
pub struct Dht(/* private fields */);
Expand description

Mainline Dht node.

Implementations§

Source§

impl Dht

Source

pub fn new(config: Config) -> Result<Self, Error>

Create a new Dht node.

Could return an error if it failed to bind to the specified port or other io errors while binding the udp socket.

Source

pub fn builder() -> DhtBuilder

Returns a builder to edit settings before creating a Dht node.

Source

pub fn client() -> Result<Self, Error>

Create a new DHT client with default bootstrap nodes.

Source

pub fn server() -> Result<Self, Error>

Create a new DHT node that is running in Server mode as soon as possible.

You shouldn’t use this option unless you are sure your DHT node is publicly accessible (not firewalled) AND will be long running, and/or you are running your own local network for testing.

If you are not sure, use Self::client and it will switch to server mode when/if these two conditions are met.

Source

pub fn info(&self) -> Info

Information and statistics about this Dht node.

Source

pub fn to_bootstrap(&self) -> Vec<String>

Turn this node’s routing table to a list of bootstrapping nodes.

Source

pub fn bootstrapped(&self) -> bool

Block until the bootstrapping query is done.

Returns true if the bootstrapping was successful.

Source

pub fn find_node(&self, target: Id) -> Box<[Node]>

Returns the closest 20 secure nodes to a target Id.

Mostly useful to crawl the DHT.

The returned nodes are claims by other nodes, they may be lies, or may have churned since they were last seen, but haven’t been pinged yet.

You might need to ping them to confirm they exist, and responsive, or if you want to learn more about them like the client they are using, or if they support a given BEP.

If you are trying to find the closest nodes to a target with intent to Self::put, a request directly to these nodes (using extra_nodes parameter), then you should use Self::get_closest_nodes instead.

Source

pub fn get_peers(&self, info_hash: Id) -> GetIterator<Vec<SocketAddrV4>>

Get peers for a given infohash.

Note: each node of the network will only return a random subset (usually 20) of the total peers it has for a given infohash, so if you are getting responses from 20 nodes, you can expect up to 400 peers in total, but if there are more announced peers on that infohash, you are likely to miss some, the logic here for Bittorrent is that any peer will introduce you to more peers through “peer exchange” so if you are implementing something different from Bittorrent, you might want to implement your own logic for gossipping more peers after you discover the first ones.

Source

pub fn announce_peer( &self, info_hash: Id, port: Option<u16>, ) -> Result<Id, PutQueryError>

Announce a peer for a given infohash.

The peer will be announced on this process IP. If explicit port is passed, it will be used, otherwise the port will be implicitly assumed by remote nodes to be the same ase port they received the request from.

Source

pub fn get_immutable(&self, target: Id) -> Option<Box<[u8]>>

Get an Immutable data by its sha1 hash.

Source

pub fn put_immutable(&self, value: &[u8]) -> Result<Id, PutQueryError>

Put an immutable data to the DHT.

Source

pub fn get_mutable( &self, public_key: &[u8; 32], salt: Option<&[u8]>, more_recent_than: Option<i64>, ) -> GetIterator<MutableItem>

Get a mutable data by its public_key and optional salt.

You can ask for items more_recent_than than a certain seq, usually one that you already have seen before, similar to If-Modified-Since header in HTTP.

§Order

The order of MutableItems returned by this iterator is not guaranteed to reflect their seq value. You should not assume that the later items are more recent than earlier ones.

Consider using Self::get_mutable_most_recent if that is what you need.

Source

pub fn get_mutable_most_recent( &self, public_key: &[u8; 32], salt: Option<&[u8]>, ) -> Option<MutableItem>

Get the most recent MutableItem from the network.

Source

pub fn put_mutable( &self, item: MutableItem, cas: Option<i64>, ) -> Result<Id, PutMutableError>

Put a mutable data to the DHT.

§Lost Update Problem

As mainline DHT is a distributed system, it is vulnerable to Write–write conflict.

§Read first

To mitigate the risk of lost updates, you should call the Self::get_mutable_most_recent method then start authoring the new MutableItem based on the most recent as in the following example:

 use mainline::{Dht, MutableItem, SigningKey, Testnet};

 let testnet = Testnet::new(3).unwrap();
 let dht = Dht::builder().bootstrap(&testnet.bootstrap).build().unwrap();

 let signing_key = SigningKey::from_bytes(&[0; 32]);
 let key = signing_key.verifying_key().to_bytes();
 let salt = Some(b"salt".as_ref());

 let (item, cas) = if let Some(most_recent) = dht .get_mutable_most_recent(&key, salt) {
     // 1. Optionally Create a new value to take the most recent's value in consideration.
     let mut new_value = most_recent.value().to_vec();
     new_value.extend_from_slice(b" more data");

     // 2. Increment the sequence number to be higher than the most recent's.
     let most_recent_seq = most_recent.seq();
     let new_seq = most_recent_seq + 1;

     (
         MutableItem::new(signing_key, &new_value, new_seq, salt),
         // 3. Use the most recent [MutableItem::seq] as a `CAS`.
         Some(most_recent_seq)
     )
 } else {
     (MutableItem::new(signing_key, b"first value", 1, salt), None)
 };

 dht.put_mutable(item, cas).unwrap();
§Errors

In addition to the PutQueryError common with all PUT queries, PUT mutable item query has other Concurrency errors, that try to detect write conflict risks or obvious conflicts.

If you are lucky to get one of these errors (which is not guaranteed), then you should read the most recent item again, and repeat the steps in the previous example.

Source

pub fn get_closest_nodes(&self, target: Id) -> Box<[Node]>

Get closet nodes to a specific target, that support BEP_0044.

Useful to Self::put a request to nodes further from the 20 closest nodes to the PutRequestSpecific::target. Which itself is useful to circumvent extreme vertical sybil attacks.

Source

pub fn put( &self, request: PutRequestSpecific, extra_nodes: Option<Box<[Node]>>, ) -> Result<Id, PutError>

Send a PUT request to the closest nodes, and optionally some extra nodes.

This is useful to put data to regions of the DHT other than the closest nodes to this request’s target.

You can find nodes close to other regions of the network by calling Self::get_closest_nodes with the target that you want to find the closest nodes to.

Note: extra nodes need to have Node::valid_token.

Source§

impl Dht

Source

pub fn as_async(self) -> AsyncDht

Return an async version of the Dht client.

Trait Implementations§

Source§

impl Clone for Dht

Source§

fn clone(&self) -> Dht

Returns a copy of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for Dht

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Dht

§

impl RefUnwindSafe for Dht

§

impl Send for Dht

§

impl Sync for Dht

§

impl Unpin for Dht

§

impl UnwindSafe for Dht

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> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

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> Same for T

Source§

type Output = T

Should always be Self
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