doc work
This commit is contained in:
parent
c377a59278
commit
246056913e
@ -86,18 +86,18 @@ impl AttachmentManager {
|
|||||||
self.unlocked_inner.network_manager.clone()
|
self.unlocked_inner.network_manager.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_attached(&self) -> bool {
|
// pub fn is_attached(&self) -> bool {
|
||||||
let s = self.inner.lock().last_attachment_state;
|
// let s = self.inner.lock().last_attachment_state;
|
||||||
!matches!(s, AttachmentState::Detached | AttachmentState::Detaching)
|
// !matches!(s, AttachmentState::Detached | AttachmentState::Detaching)
|
||||||
}
|
// }
|
||||||
pub fn is_detached(&self) -> bool {
|
// pub fn is_detached(&self) -> bool {
|
||||||
let s = self.inner.lock().last_attachment_state;
|
// let s = self.inner.lock().last_attachment_state;
|
||||||
matches!(s, AttachmentState::Detached)
|
// matches!(s, AttachmentState::Detached)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn get_attach_timestamp(&self) -> Option<Timestamp> {
|
// pub fn get_attach_timestamp(&self) -> Option<Timestamp> {
|
||||||
self.inner.lock().attach_ts
|
// self.inner.lock().attach_ts
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn translate_routing_table_health(
|
fn translate_routing_table_health(
|
||||||
health: &RoutingTableHealth,
|
health: &RoutingTableHealth,
|
||||||
@ -321,9 +321,9 @@ impl AttachmentManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_attachment_state(&self) -> AttachmentState {
|
// pub fn get_attachment_state(&self) -> AttachmentState {
|
||||||
self.inner.lock().last_attachment_state
|
// self.inner.lock().last_attachment_state
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn get_veilid_state_inner(inner: &AttachmentManagerInner) -> VeilidStateAttachment {
|
fn get_veilid_state_inner(inner: &AttachmentManagerInner) -> VeilidStateAttachment {
|
||||||
VeilidStateAttachment {
|
VeilidStateAttachment {
|
||||||
|
@ -290,6 +290,14 @@ lazy_static::lazy_static! {
|
|||||||
static ref INITIALIZED: AsyncMutex<bool> = AsyncMutex::new(false);
|
static ref INITIALIZED: AsyncMutex<bool> = AsyncMutex::new(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize a Veilid node.
|
||||||
|
///
|
||||||
|
/// Must be called only once at the start of an application
|
||||||
|
///
|
||||||
|
/// * `update_callback` - called when internal state of the Veilid node changes, for example, when app-level messages are received, when private routes die and need to be reallocated, or when routing table states change
|
||||||
|
/// * `config_callback` - called at startup to supply a configuration object directly to Veilid
|
||||||
|
///
|
||||||
|
/// Returns a [VeilidAPI] object that can be used to operate the node
|
||||||
#[instrument(err, skip_all)]
|
#[instrument(err, skip_all)]
|
||||||
pub async fn api_startup(
|
pub async fn api_startup(
|
||||||
update_callback: UpdateCallback,
|
update_callback: UpdateCallback,
|
||||||
@ -313,6 +321,14 @@ pub async fn api_startup(
|
|||||||
Ok(veilid_api)
|
Ok(veilid_api)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize a Veilid node, with the configuration in JSON format
|
||||||
|
///
|
||||||
|
/// Must be called only once at the start of an application
|
||||||
|
///
|
||||||
|
/// * `update_callback` - called when internal state of the Veilid node changes, for example, when app-level messages are received, when private routes die and need to be reallocated, or when routing table states change
|
||||||
|
/// * `config_json` - called at startup to supply a JSON configuration object
|
||||||
|
///
|
||||||
|
/// Returns a [VeilidAPI] object that can be used to operate the node
|
||||||
#[instrument(err, skip_all)]
|
#[instrument(err, skip_all)]
|
||||||
pub async fn api_startup_json(
|
pub async fn api_startup_json(
|
||||||
update_callback: UpdateCallback,
|
update_callback: UpdateCallback,
|
||||||
|
@ -3,20 +3,20 @@ use crate::*;
|
|||||||
|
|
||||||
// Diffie-Hellman key exchange cache
|
// Diffie-Hellman key exchange cache
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Eq, Hash)]
|
#[derive(Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||||
pub struct DHCacheKey {
|
pub(crate) struct DHCacheKey {
|
||||||
pub key: PublicKey,
|
pub key: PublicKey,
|
||||||
pub secret: SecretKey,
|
pub secret: SecretKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct DHCacheValue {
|
pub(crate) struct DHCacheValue {
|
||||||
pub shared_secret: SharedSecret,
|
pub shared_secret: SharedSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type DHCache = LruCache<DHCacheKey, DHCacheValue>;
|
pub(crate) type DHCache = LruCache<DHCacheKey, DHCacheValue>;
|
||||||
pub const DH_CACHE_SIZE: usize = 4096;
|
pub(crate) const DH_CACHE_SIZE: usize = 4096;
|
||||||
|
|
||||||
pub fn cache_to_bytes(cache: &DHCache) -> Vec<u8> {
|
pub(crate) fn cache_to_bytes(cache: &DHCache) -> Vec<u8> {
|
||||||
let cnt: usize = cache.len();
|
let cnt: usize = cache.len();
|
||||||
let mut out: Vec<u8> = Vec::with_capacity(cnt * (32 + 32 + 32));
|
let mut out: Vec<u8> = Vec::with_capacity(cnt * (32 + 32 + 32));
|
||||||
for e in cache.iter() {
|
for e in cache.iter() {
|
||||||
@ -31,7 +31,7 @@ pub fn cache_to_bytes(cache: &DHCache) -> Vec<u8> {
|
|||||||
rev
|
rev
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytes_to_cache(bytes: &[u8], cache: &mut DHCache) {
|
pub(crate) fn bytes_to_cache(bytes: &[u8], cache: &mut DHCache) {
|
||||||
for d in bytes.chunks(32 + 32 + 32) {
|
for d in bytes.chunks(32 + 32 + 32) {
|
||||||
let k = DHCacheKey {
|
let k = DHCacheKey {
|
||||||
key: PublicKey::new(d[0..32].try_into().expect("asdf")),
|
key: PublicKey::new(d[0..32].try_into().expect("asdf")),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! The Veilid Framework
|
//! # The Veilid Framework
|
||||||
//!
|
//!
|
||||||
//! Core library used to create a Veilid node and operate veilid services as part of an application.
|
//! Core library used to create a Veilid node and operate veilid services as part of an application.
|
||||||
//!
|
//!
|
||||||
@ -9,6 +9,18 @@
|
|||||||
//!
|
//!
|
||||||
//! From there, a [RoutingContext] object can get you access to public and private routed operations.
|
//! From there, a [RoutingContext] object can get you access to public and private routed operations.
|
||||||
//!
|
//!
|
||||||
|
//! ## Features
|
||||||
|
//!
|
||||||
|
//! The default `veilid-core` configurations are:
|
||||||
|
//!
|
||||||
|
//! * `default` - Uses `tokio` as the async runtime
|
||||||
|
//!
|
||||||
|
//! If you use `--no-default-features`, you can switch to other runtimes:
|
||||||
|
//!
|
||||||
|
//! * `default-async-std` - Uses `async-std` as the async runtime
|
||||||
|
//! * `default-wasm` - When building for the `wasm32` architecture, use this to enable `wasm-bindgen-futures` as the async runtime
|
||||||
|
//!
|
||||||
|
|
||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
@ -489,14 +489,12 @@ impl DiscoveryContext {
|
|||||||
#[instrument(level = "trace", skip(self), ret, err)]
|
#[instrument(level = "trace", skip(self), ret, err)]
|
||||||
pub async fn protocol_process_nat(&self) -> EyreResult<bool> {
|
pub async fn protocol_process_nat(&self) -> EyreResult<bool> {
|
||||||
// Get the external dial info for our use here
|
// Get the external dial info for our use here
|
||||||
let (node_1, external_1_dial_info, external_1_address, protocol_type, address_type) = {
|
let (node_1, external_1_dial_info, protocol_type) = {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
(
|
(
|
||||||
inner.node_1.as_ref().unwrap().clone(),
|
inner.node_1.as_ref().unwrap().clone(),
|
||||||
inner.external_1_dial_info.as_ref().unwrap().clone(),
|
inner.external_1_dial_info.as_ref().unwrap().clone(),
|
||||||
inner.external_1_address.unwrap(),
|
|
||||||
inner.protocol_type.unwrap(),
|
inner.protocol_type.unwrap(),
|
||||||
inner.address_type.unwrap(),
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -595,13 +593,10 @@ impl DiscoveryContext {
|
|||||||
|
|
||||||
// We are restricted, determine what kind of restriction
|
// We are restricted, determine what kind of restriction
|
||||||
// Get the external dial info for our use here
|
// Get the external dial info for our use here
|
||||||
let (node_1, external_1_dial_info, external_1_address, protocol_type, address_type) = {
|
let (external_1_address, address_type) = {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
(
|
(
|
||||||
inner.node_1.as_ref().unwrap().clone(),
|
|
||||||
inner.external_1_dial_info.as_ref().unwrap().clone(),
|
|
||||||
inner.external_1_address.unwrap(),
|
inner.external_1_address.unwrap(),
|
||||||
inner.protocol_type.unwrap(),
|
|
||||||
inner.address_type.unwrap(),
|
inner.address_type.unwrap(),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -50,9 +50,9 @@ impl RoutedOperation {
|
|||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn destructure(self) -> (Sequencing, Vec<Signature>, Nonce, Vec<u8>) {
|
// pub fn destructure(self) -> (Sequencing, Vec<Signature>, Nonce, Vec<u8>) {
|
||||||
(self.sequencing, self.signatures, self.nonce, self.data)
|
// (self.sequencing, self.signatures, self.nonce, self.data)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn decode(reader: &veilid_capnp::routed_operation::Reader) -> Result<Self, RPCError> {
|
pub fn decode(reader: &veilid_capnp::routed_operation::Reader) -> Result<Self, RPCError> {
|
||||||
let sigs_reader = reader.get_signatures().map_err(RPCError::protocol)?;
|
let sigs_reader = reader.get_signatures().map_err(RPCError::protocol)?;
|
||||||
@ -125,9 +125,9 @@ impl RPCOperationRoute {
|
|||||||
pub fn safety_route(&self) -> &SafetyRoute {
|
pub fn safety_route(&self) -> &SafetyRoute {
|
||||||
&self.safety_route
|
&self.safety_route
|
||||||
}
|
}
|
||||||
pub fn operation(&self) -> &RoutedOperation {
|
// pub fn operation(&self) -> &RoutedOperation {
|
||||||
&self.operation
|
// &self.operation
|
||||||
}
|
// }
|
||||||
pub fn destructure(self) -> (SafetyRoute, RoutedOperation) {
|
pub fn destructure(self) -> (SafetyRoute, RoutedOperation) {
|
||||||
(self.safety_route, self.operation)
|
(self.safety_route, self.operation)
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Shut down Veilid and terminate the API
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub async fn shutdown(self) {
|
pub async fn shutdown(self) {
|
||||||
let context = { self.inner.lock().context.take() };
|
let context = { self.inner.lock().context.take() };
|
||||||
@ -56,6 +57,7 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check to see if Veilid is already shut down
|
||||||
pub fn is_shutdown(&self) -> bool {
|
pub fn is_shutdown(&self) -> bool {
|
||||||
self.inner.lock().context.is_none()
|
self.inner.lock().context.is_none()
|
||||||
}
|
}
|
||||||
@ -63,6 +65,7 @@ impl VeilidAPI {
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Public Accessors
|
// Public Accessors
|
||||||
|
|
||||||
|
/// Access the configuration that Veilid was initialized with
|
||||||
pub fn config(&self) -> VeilidAPIResult<VeilidConfig> {
|
pub fn config(&self) -> VeilidAPIResult<VeilidConfig> {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
if let Some(context) = &inner.context {
|
if let Some(context) = &inner.context {
|
||||||
@ -70,6 +73,8 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
Err(VeilidAPIError::NotInitialized)
|
Err(VeilidAPIError::NotInitialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the cryptosystem manager
|
||||||
pub fn crypto(&self) -> VeilidAPIResult<Crypto> {
|
pub fn crypto(&self) -> VeilidAPIResult<Crypto> {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
if let Some(context) = &inner.context {
|
if let Some(context) = &inner.context {
|
||||||
@ -77,6 +82,8 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
Err(VeilidAPIError::NotInitialized)
|
Err(VeilidAPIError::NotInitialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the TableStore manager
|
||||||
pub fn table_store(&self) -> VeilidAPIResult<TableStore> {
|
pub fn table_store(&self) -> VeilidAPIResult<TableStore> {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
if let Some(context) = &inner.context {
|
if let Some(context) = &inner.context {
|
||||||
@ -84,6 +91,8 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
Err(VeilidAPIError::not_initialized())
|
Err(VeilidAPIError::not_initialized())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the ProtectedStore manager
|
||||||
pub fn protected_store(&self) -> VeilidAPIResult<ProtectedStore> {
|
pub fn protected_store(&self) -> VeilidAPIResult<ProtectedStore> {
|
||||||
let inner = self.inner.lock();
|
let inner = self.inner.lock();
|
||||||
if let Some(context) = &inner.context {
|
if let Some(context) = &inner.context {
|
||||||
@ -141,7 +150,7 @@ impl VeilidAPI {
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// Attach/Detach
|
// Attach/Detach
|
||||||
|
|
||||||
/// Get a full copy of the current state
|
/// Get a full copy of the current state of Veilid
|
||||||
pub async fn get_state(&self) -> VeilidAPIResult<VeilidState> {
|
pub async fn get_state(&self) -> VeilidAPIResult<VeilidState> {
|
||||||
let attachment_manager = self.attachment_manager()?;
|
let attachment_manager = self.attachment_manager()?;
|
||||||
let network_manager = attachment_manager.network_manager();
|
let network_manager = attachment_manager.network_manager();
|
||||||
@ -217,6 +226,9 @@ impl VeilidAPI {
|
|||||||
/// Allocate a new private route set with default cryptography and network options
|
/// Allocate a new private route set with default cryptography and network options
|
||||||
/// Returns a route id and a publishable 'blob' with the route encrypted with each crypto kind
|
/// Returns a route id and a publishable 'blob' with the route encrypted with each crypto kind
|
||||||
/// Those nodes importing the blob will have their choice of which crypto kind to use
|
/// Those nodes importing the blob will have their choice of which crypto kind to use
|
||||||
|
///
|
||||||
|
/// Returns a route id and 'blob' that can be published over some means (DHT or otherwise) to be
|
||||||
|
/// imported by another Veilid node.
|
||||||
pub async fn new_private_route(&self) -> VeilidAPIResult<(RouteId, Vec<u8>)> {
|
pub async fn new_private_route(&self) -> VeilidAPIResult<(RouteId, Vec<u8>)> {
|
||||||
self.new_custom_private_route(
|
self.new_custom_private_route(
|
||||||
&VALID_CRYPTO_KINDS,
|
&VALID_CRYPTO_KINDS,
|
||||||
@ -226,7 +238,12 @@ impl VeilidAPI {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate a new private route and specify a specific cryptosystem, stability and sequencing preference
|
||||||
|
/// Returns a route id and a publishable 'blob' with the route encrypted with each crypto kind
|
||||||
|
/// Those nodes importing the blob will have their choice of which crypto kind to use
|
||||||
///
|
///
|
||||||
|
/// Returns a route id and 'blob' that can be published over some means (DHT or otherwise) to be
|
||||||
|
/// imported by another Veilid node.
|
||||||
pub async fn new_custom_private_route(
|
pub async fn new_custom_private_route(
|
||||||
&self,
|
&self,
|
||||||
crypto_kinds: &[CryptoKind],
|
crypto_kinds: &[CryptoKind],
|
||||||
@ -282,12 +299,19 @@ impl VeilidAPI {
|
|||||||
Ok((route_id, blob))
|
Ok((route_id, blob))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Import a private route blob as a remote private route.
|
||||||
|
///
|
||||||
|
/// Returns a route id that can be used to send private messages to the node creating this route.
|
||||||
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> VeilidAPIResult<RouteId> {
|
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> VeilidAPIResult<RouteId> {
|
||||||
let rss = self.routing_table()?.route_spec_store();
|
let rss = self.routing_table()?.route_spec_store();
|
||||||
rss.import_remote_private_route(blob)
|
rss.import_remote_private_route(blob)
|
||||||
.map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob"))
|
.map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Release either a locally allocated or remotely imported private route
|
||||||
|
///
|
||||||
|
/// This will deactivate the route and free its resources and it can no longer be sent to
|
||||||
|
/// or received from.
|
||||||
pub fn release_private_route(&self, route_id: RouteId) -> VeilidAPIResult<()> {
|
pub fn release_private_route(&self, route_id: RouteId) -> VeilidAPIResult<()> {
|
||||||
let rss = self.routing_table()?.route_spec_store();
|
let rss = self.routing_table()?.route_spec_store();
|
||||||
if !rss.release_route(route_id) {
|
if !rss.release_route(route_id) {
|
||||||
@ -299,6 +323,10 @@ impl VeilidAPI {
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// App Calls
|
// App Calls
|
||||||
|
|
||||||
|
/// Respond to an AppCall received over a [VeilidUpdate::AppCall].
|
||||||
|
///
|
||||||
|
/// * `call_id` - specifies which call to reply to, and it comes from a [VeilidUpdate::AppCall], specifically the [VeilidAppCall::id()] value.
|
||||||
|
/// * `message` - is an answer blob to be returned by the remote node's [RoutingContext::app_call()] function, and may be up to 32768 bytes
|
||||||
pub async fn app_call_reply(
|
pub async fn app_call_reply(
|
||||||
&self,
|
&self,
|
||||||
call_id: OperationId,
|
call_id: OperationId,
|
||||||
|
@ -1363,6 +1363,7 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the help text for 'internal debug' commands
|
||||||
pub async fn debug_help(&self, _args: String) -> VeilidAPIResult<String> {
|
pub async fn debug_help(&self, _args: String) -> VeilidAPIResult<String> {
|
||||||
Ok(r#"buckets [dead|reliable]
|
Ok(r#"buckets [dead|reliable]
|
||||||
dialinfo
|
dialinfo
|
||||||
@ -1425,6 +1426,7 @@ record list <local|remote>
|
|||||||
.to_owned())
|
.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Execute an 'internal debug command'
|
||||||
pub async fn debug(&self, args: String) -> VeilidAPIResult<String> {
|
pub async fn debug(&self, args: String) -> VeilidAPIResult<String> {
|
||||||
let res = {
|
let res = {
|
||||||
let args = args.trim_start();
|
let args = args.trim_start();
|
||||||
|
@ -2,10 +2,13 @@ use super::*;
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/// Valid destinations for a message sent over a routing context
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Target {
|
pub enum Target {
|
||||||
NodeId(TypedKey), // Node by its public key
|
/// Node by its public key
|
||||||
PrivateRoute(RouteId), // Remote private route by its id
|
NodeId(TypedKey),
|
||||||
|
/// Remote private route by its id
|
||||||
|
PrivateRoute(RouteId),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RoutingContextInner {}
|
pub struct RoutingContextInner {}
|
||||||
@ -24,6 +27,12 @@ impl Drop for RoutingContextInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Routing contexts are the way you specify the communication preferences for Veilid.
|
||||||
|
///
|
||||||
|
/// By default routing contexts are 'direct' from node to node, offering no privacy. To enable sender
|
||||||
|
/// privacy, use [RoutingContext::with_privacy()]. To enable receiver privacy, you should send to a private route RouteId that you have
|
||||||
|
/// imported, rather than directly to a NodeId.
|
||||||
|
///
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RoutingContext {
|
pub struct RoutingContext {
|
||||||
/// Veilid API handle
|
/// Veilid API handle
|
||||||
@ -45,6 +54,15 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Turn on sender privacy, enabling the use of safety routes.
|
||||||
|
///
|
||||||
|
/// Default values for hop count, stability and sequencing preferences are used.
|
||||||
|
///
|
||||||
|
/// * Hop count default is dependent on config, but is set to 1 extra hop.
|
||||||
|
/// * Stability default is to choose 'low latency' routes, preferring them over long-term reliability.
|
||||||
|
/// * Sequencing default is to have no preference for ordered vs unordered message delivery
|
||||||
|
///
|
||||||
|
/// To modify these defaults, use [RoutingContext::with_custom_privacy()].
|
||||||
pub fn with_privacy(self) -> VeilidAPIResult<Self> {
|
pub fn with_privacy(self) -> VeilidAPIResult<Self> {
|
||||||
let config = self.api.config()?;
|
let config = self.api.config()?;
|
||||||
let c = config.get();
|
let c = config.get();
|
||||||
@ -57,6 +75,7 @@ impl RoutingContext {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Turn on privacy using a custom [SafetySelection]
|
||||||
pub fn with_custom_privacy(self, safety_selection: SafetySelection) -> VeilidAPIResult<Self> {
|
pub fn with_custom_privacy(self, safety_selection: SafetySelection) -> VeilidAPIResult<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
api: self.api.clone(),
|
api: self.api.clone(),
|
||||||
@ -65,6 +84,7 @@ impl RoutingContext {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Use a specified [Sequencing] preference, with or without privacy
|
||||||
pub fn with_sequencing(self, sequencing: Sequencing) -> Self {
|
pub fn with_sequencing(self, sequencing: Sequencing) -> Self {
|
||||||
Self {
|
Self {
|
||||||
api: self.api.clone(),
|
api: self.api.clone(),
|
||||||
@ -90,6 +110,7 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the [VeilidAPI] object that created this [RoutingContext]
|
||||||
pub fn api(&self) -> VeilidAPI {
|
pub fn api(&self) -> VeilidAPI {
|
||||||
self.api.clone()
|
self.api.clone()
|
||||||
}
|
}
|
||||||
@ -135,6 +156,14 @@ impl RoutingContext {
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// App-level Messaging
|
// App-level Messaging
|
||||||
|
|
||||||
|
/// App-level bidirectional call that expects a response to be returned.
|
||||||
|
///
|
||||||
|
/// Veilid apps may use this for arbitrary message passing.
|
||||||
|
///
|
||||||
|
/// * `target` - can be either a direct node id or a private route
|
||||||
|
/// * `message` - an arbitrary message blob of up to 32768 bytes
|
||||||
|
///
|
||||||
|
/// Returns an answer blob of up to 32768 bytes
|
||||||
pub async fn app_call(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<Vec<u8>> {
|
pub async fn app_call(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<Vec<u8>> {
|
||||||
let rpc_processor = self.api.rpc_processor()?;
|
let rpc_processor = self.api.rpc_processor()?;
|
||||||
|
|
||||||
@ -162,6 +191,12 @@ impl RoutingContext {
|
|||||||
Ok(answer.answer)
|
Ok(answer.answer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// App-level unidirectional message that does not expect any value to be returned.
|
||||||
|
///
|
||||||
|
/// Veilid apps may use this for arbitrary message passing.
|
||||||
|
///
|
||||||
|
/// * `target` - can be either a direct node id or a private route
|
||||||
|
/// * `message` - an arbitrary message blob of up to 32768 bytes
|
||||||
pub async fn app_message(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<()> {
|
pub async fn app_message(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<()> {
|
||||||
let rpc_processor = self.api.rpc_processor()?;
|
let rpc_processor = self.api.rpc_processor()?;
|
||||||
|
|
||||||
@ -192,7 +227,10 @@ impl RoutingContext {
|
|||||||
/// DHT Records
|
/// DHT Records
|
||||||
|
|
||||||
/// Creates a new DHT record a specified crypto kind and schema
|
/// Creates a new DHT record a specified crypto kind and schema
|
||||||
/// Returns the newly allocated DHT record's key if successful. The records is considered 'open' after the create operation succeeds.
|
///
|
||||||
|
/// The record is considered 'open' after the create operation succeeds.
|
||||||
|
///
|
||||||
|
/// Returns the newly allocated DHT record's key if successful.
|
||||||
pub async fn create_dht_record(
|
pub async fn create_dht_record(
|
||||||
&self,
|
&self,
|
||||||
schema: DHTSchema,
|
schema: DHTSchema,
|
||||||
@ -206,9 +244,12 @@ impl RoutingContext {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Opens a DHT record at a specific key. Associates a secret if one is provided to provide writer capability.
|
/// Opens a DHT record at a specific key
|
||||||
|
///
|
||||||
|
/// Associates a secret if one is provided to provide writer capability.
|
||||||
|
/// Records may only be opened or created. To re-open with a different routing context, first close the value.
|
||||||
|
///
|
||||||
/// Returns the DHT record descriptor for the opened record if successful
|
/// Returns the DHT record descriptor for the opened record if successful
|
||||||
/// Records may only be opened or created . To re-open with a different routing context, first close the value.
|
|
||||||
pub async fn open_dht_record(
|
pub async fn open_dht_record(
|
||||||
&self,
|
&self,
|
||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
@ -222,6 +263,7 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Closes a DHT record at a specific key that was opened with create_dht_record or open_dht_record.
|
/// Closes a DHT record at a specific key that was opened with create_dht_record or open_dht_record.
|
||||||
|
///
|
||||||
/// Closing a record allows you to re-open it with a different routing context
|
/// Closing a record allows you to re-open it with a different routing context
|
||||||
pub async fn close_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
|
pub async fn close_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
|
||||||
Crypto::validate_crypto_kind(key.kind)?;
|
Crypto::validate_crypto_kind(key.kind)?;
|
||||||
@ -229,7 +271,9 @@ impl RoutingContext {
|
|||||||
storage_manager.close_record(key).await
|
storage_manager.close_record(key).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes a DHT record at a specific key. If the record is opened, it must be closed before it is deleted.
|
/// Deletes a DHT record at a specific key
|
||||||
|
///
|
||||||
|
/// If the record is opened, it must be closed before it is deleted.
|
||||||
/// Deleting a record does not delete it from the network, but will remove the storage of the record
|
/// Deleting a record does not delete it from the network, but will remove the storage of the record
|
||||||
/// locally, and will prevent its value from being refreshed on the network by this node.
|
/// locally, and will prevent its value from being refreshed on the network by this node.
|
||||||
pub async fn delete_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
|
pub async fn delete_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
|
||||||
@ -239,9 +283,11 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the latest value of a subkey
|
/// Gets the latest value of a subkey
|
||||||
|
///
|
||||||
/// May pull the latest value from the network, but by settings 'force_refresh' you can force a network data refresh
|
/// May pull the latest value from the network, but by settings 'force_refresh' you can force a network data refresh
|
||||||
/// Returns None if the value subkey has not yet been set
|
///
|
||||||
/// Returns Some(data) if the value subkey has valid data
|
/// Returns `None` if the value subkey has not yet been set
|
||||||
|
/// Returns `Some(data)` if the value subkey has valid data
|
||||||
pub async fn get_dht_value(
|
pub async fn get_dht_value(
|
||||||
&self,
|
&self,
|
||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
@ -254,8 +300,9 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pushes a changed subkey value to the network
|
/// Pushes a changed subkey value to the network
|
||||||
/// Returns None if the value was successfully put
|
///
|
||||||
/// Returns Some(data) if the value put was older than the one available on the network
|
/// Returns `None` if the value was successfully put
|
||||||
|
/// Returns `Some(data)` if the value put was older than the one available on the network
|
||||||
pub async fn set_dht_value(
|
pub async fn set_dht_value(
|
||||||
&self,
|
&self,
|
||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
@ -268,9 +315,11 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Watches changes to an opened or created value
|
/// Watches changes to an opened or created value
|
||||||
|
///
|
||||||
/// Changes to subkeys within the subkey range are returned via a ValueChanged callback
|
/// Changes to subkeys within the subkey range are returned via a ValueChanged callback
|
||||||
/// If the subkey range is empty, all subkey changes are considered
|
/// If the subkey range is empty, all subkey changes are considered
|
||||||
/// Expiration can be infinite to keep the watch for the maximum amount of time
|
/// Expiration can be infinite to keep the watch for the maximum amount of time
|
||||||
|
///
|
||||||
/// Return value upon success is the amount of time allowed for the watch
|
/// Return value upon success is the amount of time allowed for the watch
|
||||||
pub async fn watch_dht_values(
|
pub async fn watch_dht_values(
|
||||||
&self,
|
&self,
|
||||||
@ -287,6 +336,7 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Cancels a watch early
|
/// Cancels a watch early
|
||||||
|
///
|
||||||
/// This is a convenience function that cancels watching all subkeys in a range
|
/// This is a convenience function that cancels watching all subkeys in a range
|
||||||
pub async fn cancel_dht_watch(
|
pub async fn cancel_dht_watch(
|
||||||
&self,
|
&self,
|
||||||
|
@ -3,15 +3,13 @@ use super::*;
|
|||||||
/// Direct statement blob passed to hosting application for processing
|
/// Direct statement blob passed to hosting application for processing
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct VeilidAppMessage {
|
pub struct VeilidAppMessage {
|
||||||
/// Some(sender) if the message was sent directly, None if received via a private/safety route
|
|
||||||
#[serde(with = "as_human_opt_string")]
|
#[serde(with = "as_human_opt_string")]
|
||||||
#[schemars(with = "Option<String>")]
|
#[schemars(with = "Option<String>")]
|
||||||
pub sender: Option<TypedKey>,
|
sender: Option<TypedKey>,
|
||||||
|
|
||||||
/// The content of the message to deliver to the application
|
|
||||||
#[serde(with = "as_human_base64")]
|
#[serde(with = "as_human_base64")]
|
||||||
#[schemars(with = "String")]
|
#[schemars(with = "String")]
|
||||||
pub message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VeilidAppMessage {
|
impl VeilidAppMessage {
|
||||||
@ -19,9 +17,12 @@ impl VeilidAppMessage {
|
|||||||
Self { sender, message }
|
Self { sender, message }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Some(sender) if the message was sent directly, None if received via a private/safety route
|
||||||
pub fn sender(&self) -> Option<&TypedKey> {
|
pub fn sender(&self) -> Option<&TypedKey> {
|
||||||
self.sender.as_ref()
|
self.sender.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The content of the message to deliver to the application
|
||||||
pub fn message(&self) -> &[u8] {
|
pub fn message(&self) -> &[u8] {
|
||||||
&self.message
|
&self.message
|
||||||
}
|
}
|
||||||
@ -30,17 +31,14 @@ impl VeilidAppMessage {
|
|||||||
/// Direct question blob passed to hosting application for processing to send an eventual AppReply
|
/// Direct question blob passed to hosting application for processing to send an eventual AppReply
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct VeilidAppCall {
|
pub struct VeilidAppCall {
|
||||||
/// Some(sender) if the request was sent directly, None if received via a private/safety route
|
|
||||||
#[serde(with = "as_human_opt_string")]
|
#[serde(with = "as_human_opt_string")]
|
||||||
#[schemars(with = "Option<String>")]
|
#[schemars(with = "Option<String>")]
|
||||||
sender: Option<TypedKey>,
|
sender: Option<TypedKey>,
|
||||||
|
|
||||||
/// The content of the request to deliver to the application
|
|
||||||
#[serde(with = "as_human_base64")]
|
#[serde(with = "as_human_base64")]
|
||||||
#[schemars(with = "String")]
|
#[schemars(with = "String")]
|
||||||
message: Vec<u8>,
|
message: Vec<u8>,
|
||||||
|
|
||||||
/// The id to reply to
|
|
||||||
#[serde(with = "as_human_string")]
|
#[serde(with = "as_human_string")]
|
||||||
#[schemars(with = "String")]
|
#[schemars(with = "String")]
|
||||||
call_id: OperationId,
|
call_id: OperationId,
|
||||||
@ -55,12 +53,16 @@ impl VeilidAppCall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Some(sender) if the request was sent directly, None if received via a private/safety route
|
||||||
pub fn sender(&self) -> Option<&TypedKey> {
|
pub fn sender(&self) -> Option<&TypedKey> {
|
||||||
self.sender.as_ref()
|
self.sender.as_ref()
|
||||||
}
|
}
|
||||||
|
/// The content of the request to deliver to the application
|
||||||
pub fn message(&self) -> &[u8] {
|
pub fn message(&self) -> &[u8] {
|
||||||
&self.message
|
&self.message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The id to specify as `call_id` in the [VeilidAPI::app_call_reply] function
|
||||||
pub fn id(&self) -> OperationId {
|
pub fn id(&self) -> OperationId {
|
||||||
self.call_id
|
self.call_id
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ wasm-bindgen = "0.2.87"
|
|||||||
js-sys = "0.3.64"
|
js-sys = "0.3.64"
|
||||||
wasm-bindgen-futures = "0.4.37"
|
wasm-bindgen-futures = "0.4.37"
|
||||||
async_executors = { version = "0.7.0", default-features = false }
|
async_executors = { version = "0.7.0", default-features = false }
|
||||||
|
|
||||||
async-lock = "2.8.0"
|
async-lock = "2.8.0"
|
||||||
send_wrapper = { version = "0.6.0", features = ["futures"] }
|
send_wrapper = { version = "0.6.0", features = ["futures"] }
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//! # Veilid Tools
|
||||||
|
//!
|
||||||
//! A collection of baseline tools for Rust development use by Veilid and Veilid-enabled Rust applications
|
//! A collection of baseline tools for Rust development use by Veilid and Veilid-enabled Rust applications
|
||||||
//!
|
//!
|
||||||
//! These are used by `veilid-core`, `veilid-server`, `veilid-cli` and may be used by any other applications
|
//! These are used by `veilid-core`, `veilid-server`, `veilid-cli` and may be used by any other applications
|
||||||
@ -6,6 +8,18 @@
|
|||||||
//! remain free of boilerplate and utility classes that could be reused elsewhere.
|
//! remain free of boilerplate and utility classes that could be reused elsewhere.
|
||||||
//!
|
//!
|
||||||
//! Everything added to this crate must be extensively unit-tested.
|
//! Everything added to this crate must be extensively unit-tested.
|
||||||
|
//!
|
||||||
|
//! ## Features
|
||||||
|
//!
|
||||||
|
//! The default `veilid-tools` configurations are:
|
||||||
|
//!
|
||||||
|
//! * `default` - Uses `tokio` as the async runtime
|
||||||
|
//!
|
||||||
|
//! If you use `--no-default-features`, you can switch to other runtimes:
|
||||||
|
//!
|
||||||
|
//! * `rt-async-std` - Uses `async-std` as the async runtime
|
||||||
|
//! * `rt-wasm-bindgen` - When building for the `wasm32` architecture, use this to enable `wasm-bindgen-futures` as the async runtime
|
||||||
|
//!
|
||||||
|
|
||||||
// pub mod bump_port;
|
// pub mod bump_port;
|
||||||
pub mod assembly_buffer;
|
pub mod assembly_buffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user