2022-10-09 16:50:40 +02:00
|
|
|
|
//! Waku [peer handling and connection](https://rfc.vac.dev/spec/36/#connecting-to-peers) methods
|
|
|
|
|
|
|
2022-10-06 15:28:25 +02:00
|
|
|
|
// std
|
2023-02-16 11:55:09 +01:00
|
|
|
|
use std::ffi::CString;
|
2022-10-06 15:28:25 +02:00
|
|
|
|
use std::time::Duration;
|
|
|
|
|
|
// crates
|
|
|
|
|
|
use multiaddr::Multiaddr;
|
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
// internal
|
2023-02-16 11:55:09 +01:00
|
|
|
|
use crate::general::{PeerId, ProtocolId, Result};
|
2023-02-14 18:30:08 +01:00
|
|
|
|
use crate::utils::decode_and_free_response;
|
2022-10-06 15:28:25 +02:00
|
|
|
|
|
|
|
|
|
|
/// Add a node multiaddress and protocol to the waku node’s peerstore.
|
|
|
|
|
|
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_add_peerchar-address-char-protocolid)
|
2022-10-17 19:30:07 +02:00
|
|
|
|
pub fn waku_add_peers(address: &Multiaddr, protocol_id: ProtocolId) -> Result<PeerId> {
|
2023-02-14 18:30:08 +01:00
|
|
|
|
let address_ptr = CString::new(address.to_string())
|
|
|
|
|
|
.expect("CString should build properly from the address")
|
|
|
|
|
|
.into_raw();
|
|
|
|
|
|
let protocol_id_ptr = CString::new(protocol_id.to_string())
|
|
|
|
|
|
.expect("CString should build properly from the protocol id")
|
|
|
|
|
|
.into_raw();
|
|
|
|
|
|
|
|
|
|
|
|
let response_ptr = unsafe {
|
|
|
|
|
|
let res = waku_sys::waku_add_peer(address_ptr, protocol_id_ptr);
|
|
|
|
|
|
drop(CString::from_raw(address_ptr));
|
|
|
|
|
|
drop(CString::from_raw(protocol_id_ptr));
|
|
|
|
|
|
res
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-02-16 11:55:09 +01:00
|
|
|
|
decode_and_free_response(response_ptr)
|
2022-10-06 15:28:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Dial peer using a multiaddress
|
|
|
|
|
|
/// If `timeout` as milliseconds doesn't fit into a `i32` it is clamped to [`i32::MAX`]
|
|
|
|
|
|
/// If the function execution takes longer than `timeout` value, the execution will be canceled and an error returned.
|
|
|
|
|
|
/// Use 0 for no timeout
|
|
|
|
|
|
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_connect_peerchar-address-int-timeoutms)
|
2022-10-17 19:30:07 +02:00
|
|
|
|
pub fn waku_connect_peer_with_address(
|
|
|
|
|
|
address: &Multiaddr,
|
|
|
|
|
|
timeout: Option<Duration>,
|
|
|
|
|
|
) -> Result<()> {
|
2023-02-14 18:30:08 +01:00
|
|
|
|
let address_ptr = CString::new(address.to_string())
|
|
|
|
|
|
.expect("CString should build properly from multiaddress")
|
|
|
|
|
|
.into_raw();
|
|
|
|
|
|
let response_ptr = unsafe {
|
|
|
|
|
|
let res = waku_sys::waku_connect(
|
|
|
|
|
|
address_ptr,
|
2022-10-06 15:28:25 +02:00
|
|
|
|
timeout
|
|
|
|
|
|
.map(|duration| duration.as_millis().try_into().unwrap_or(i32::MAX))
|
|
|
|
|
|
.unwrap_or(0),
|
2023-02-14 18:30:08 +01:00
|
|
|
|
);
|
|
|
|
|
|
drop(CString::from_raw(address_ptr));
|
|
|
|
|
|
res
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-02-16 11:55:09 +01:00
|
|
|
|
decode_and_free_response::<bool>(response_ptr).map(|_| ())
|
2022-10-06 15:28:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Dial peer using a peer id
|
|
|
|
|
|
/// If `timeout` as milliseconds doesn't fit into a `i32` it is clamped to [`i32::MAX`]
|
|
|
|
|
|
/// The peer must be already known.
|
2022-10-06 15:51:00 +02:00
|
|
|
|
/// It must have been added before with [`waku_add_peers`] or previously dialed with [`waku_connect_peer_with_address`]
|
2022-10-06 15:28:25 +02:00
|
|
|
|
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_connect_peeridchar-peerid-int-timeoutms)
|
2023-02-14 18:30:08 +01:00
|
|
|
|
pub fn waku_connect_peer_with_id(peer_id: &PeerId, timeout: Option<Duration>) -> Result<()> {
|
|
|
|
|
|
let peer_id_ptr = CString::new(peer_id.as_bytes())
|
|
|
|
|
|
.expect("CString should build properly from peer id")
|
|
|
|
|
|
.into_raw();
|
2023-02-16 11:55:09 +01:00
|
|
|
|
let result_ptr = unsafe {
|
2023-02-14 18:30:08 +01:00
|
|
|
|
let res = waku_sys::waku_connect_peerid(
|
|
|
|
|
|
peer_id_ptr,
|
2022-10-06 15:28:25 +02:00
|
|
|
|
timeout
|
|
|
|
|
|
.map(|duration| duration.as_millis().try_into().unwrap_or(i32::MAX))
|
|
|
|
|
|
.unwrap_or(0),
|
2023-02-14 18:30:08 +01:00
|
|
|
|
);
|
|
|
|
|
|
drop(CString::from_raw(peer_id_ptr));
|
|
|
|
|
|
res
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-02-16 11:55:09 +01:00
|
|
|
|
decode_and_free_response::<bool>(result_ptr).map(|_| ())
|
2022-10-06 15:28:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Disconnect a peer using its peer id
|
|
|
|
|
|
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_disconnect_peerchar-peerid)
|
2022-10-17 19:30:07 +02:00
|
|
|
|
pub fn waku_disconnect_peer_with_id(peer_id: &PeerId) -> Result<()> {
|
2023-02-14 18:30:08 +01:00
|
|
|
|
let peer_id_ptr = CString::new(peer_id.as_bytes())
|
|
|
|
|
|
.expect("CString should build properly from peer id")
|
|
|
|
|
|
.into_raw();
|
|
|
|
|
|
|
|
|
|
|
|
let response_ptr = unsafe {
|
|
|
|
|
|
let res = waku_sys::waku_disconnect(peer_id_ptr);
|
|
|
|
|
|
drop(CString::from_raw(peer_id_ptr));
|
|
|
|
|
|
res
|
|
|
|
|
|
};
|
2023-02-16 11:55:09 +01:00
|
|
|
|
decode_and_free_response::<bool>(response_ptr).map(|_| ())
|
2022-10-06 15:28:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Get number of connected peers
|
|
|
|
|
|
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_peer_count)
|
|
|
|
|
|
pub fn waku_peer_count() -> Result<usize> {
|
2023-02-14 18:30:08 +01:00
|
|
|
|
let response_ptr = unsafe { waku_sys::waku_peer_cnt() };
|
2023-02-16 11:55:09 +01:00
|
|
|
|
decode_and_free_response(response_ptr)
|
2022-10-06 15:28:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-09 16:50:40 +02:00
|
|
|
|
/// Waku peer supported protocol
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Examples:
|
|
|
|
|
|
/// `"/ipfs/id/1.0.0"`
|
|
|
|
|
|
/// `"/vac/waku/relay/2.0.0"`
|
|
|
|
|
|
/// `"/ipfs/ping/1.0.0"`
|
2022-10-06 15:28:25 +02:00
|
|
|
|
pub type Protocol = String;
|
|
|
|
|
|
|
|
|
|
|
|
/// Peer data from known/connected waku nodes
|
2023-01-03 12:30:14 +02:00
|
|
|
|
#[derive(Deserialize, Clone, Debug)]
|
2022-10-06 15:28:25 +02:00
|
|
|
|
#[serde(rename_all = "camelCase")]
|
|
|
|
|
|
pub struct WakuPeerData {
|
|
|
|
|
|
/// Waku peer id
|
|
|
|
|
|
#[serde(alias = "peerID")]
|
|
|
|
|
|
peer_id: PeerId,
|
|
|
|
|
|
/// Supported node protocols
|
|
|
|
|
|
protocols: Vec<Protocol>,
|
|
|
|
|
|
/// Node available addresses
|
|
|
|
|
|
#[serde(alias = "addrs")]
|
|
|
|
|
|
addresses: Vec<Multiaddr>,
|
|
|
|
|
|
/// Already connected flag
|
|
|
|
|
|
connected: bool,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-10-09 16:50:40 +02:00
|
|
|
|
impl WakuPeerData {
|
|
|
|
|
|
pub fn peer_id(&self) -> &PeerId {
|
|
|
|
|
|
&self.peer_id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn protocols(&self) -> &[Protocol] {
|
|
|
|
|
|
&self.protocols
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn addresses(&self) -> &[Multiaddr] {
|
|
|
|
|
|
&self.addresses
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn connected(&self) -> bool {
|
|
|
|
|
|
self.connected
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-11-02 16:21:15 +01:00
|
|
|
|
/// List of [`WakuPeerData`]
|
2022-10-06 15:28:25 +02:00
|
|
|
|
pub type WakuPeers = Vec<WakuPeerData>;
|
|
|
|
|
|
|
|
|
|
|
|
/// Retrieve the list of peers known by the Waku node
|
|
|
|
|
|
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_peers)
|
|
|
|
|
|
pub fn waku_peers() -> Result<WakuPeers> {
|
2023-02-14 18:30:08 +01:00
|
|
|
|
let response_ptr = unsafe { waku_sys::waku_peers() };
|
|
|
|
|
|
decode_and_free_response(response_ptr)
|
2022-10-06 15:28:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
|
mod tests {
|
|
|
|
|
|
use crate::node::peers::WakuPeerData;
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn deserialize_waku_peer_data() {
|
|
|
|
|
|
let json_str = r#"{
|
|
|
|
|
|
"peerID": "16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47RedcBafeDCBA",
|
|
|
|
|
|
"protocols": [
|
|
|
|
|
|
"/ipfs/id/1.0.0",
|
|
|
|
|
|
"/vac/waku/relay/2.0.0",
|
|
|
|
|
|
"/ipfs/ping/1.0.0"
|
|
|
|
|
|
],
|
|
|
|
|
|
"addrs": [
|
|
|
|
|
|
"/ip4/1.2.3.4/tcp/30303"
|
|
|
|
|
|
],
|
|
|
|
|
|
"connected": true
|
|
|
|
|
|
}"#;
|
2022-10-17 19:30:07 +02:00
|
|
|
|
let _: WakuPeerData = serde_json::from_str(json_str).unwrap();
|
2022-10-06 15:28:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|