removing dev branch, many changes

This commit is contained in:
John Smith
2023-05-29 19:24:57 +00:00
parent 1430f3f656
commit 0a890c8707
250 changed files with 18084 additions and 8040 deletions
+27 -24
View File
@@ -49,75 +49,82 @@ impl VeilidAPI {
////////////////////////////////////////////////////////////////
// Accessors
pub fn config(&self) -> Result<VeilidConfig, VeilidAPIError> {
pub fn config(&self) -> VeilidAPIResult<VeilidConfig> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.config.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn crypto(&self) -> Result<Crypto, VeilidAPIError> {
pub fn crypto(&self) -> VeilidAPIResult<Crypto> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.crypto.clone());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn table_store(&self) -> Result<TableStore, VeilidAPIError> {
pub fn table_store(&self) -> VeilidAPIResult<TableStore> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.table_store.clone());
}
Err(VeilidAPIError::not_initialized())
}
pub fn block_store(&self) -> Result<BlockStore, VeilidAPIError> {
pub fn block_store(&self) -> VeilidAPIResult<BlockStore> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.block_store.clone());
}
Err(VeilidAPIError::not_initialized())
}
pub fn protected_store(&self) -> Result<ProtectedStore, VeilidAPIError> {
pub fn protected_store(&self) -> VeilidAPIResult<ProtectedStore> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.protected_store.clone());
}
Err(VeilidAPIError::not_initialized())
}
pub fn attachment_manager(&self) -> Result<AttachmentManager, VeilidAPIError> {
pub fn attachment_manager(&self) -> VeilidAPIResult<AttachmentManager> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.clone());
}
Err(VeilidAPIError::not_initialized())
}
pub fn network_manager(&self) -> Result<NetworkManager, VeilidAPIError> {
pub fn network_manager(&self) -> VeilidAPIResult<NetworkManager> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager());
}
Err(VeilidAPIError::not_initialized())
}
pub fn rpc_processor(&self) -> Result<RPCProcessor, VeilidAPIError> {
pub fn rpc_processor(&self) -> VeilidAPIResult<RPCProcessor> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager().rpc_processor());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn routing_table(&self) -> Result<RoutingTable, VeilidAPIError> {
pub fn routing_table(&self) -> VeilidAPIResult<RoutingTable> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.attachment_manager.network_manager().routing_table());
}
Err(VeilidAPIError::NotInitialized)
}
pub fn storage_manager(&self) -> VeilidAPIResult<StorageManager> {
let inner = self.inner.lock();
if let Some(context) = &inner.context {
return Ok(context.storage_manager.clone());
}
Err(VeilidAPIError::NotInitialized)
}
////////////////////////////////////////////////////////////////
// Attach/Detach
/// Get a full copy of the current state
pub async fn get_state(&self) -> Result<VeilidState, VeilidAPIError> {
pub async fn get_state(&self) -> VeilidAPIResult<VeilidState> {
let attachment_manager = self.attachment_manager()?;
let network_manager = attachment_manager.network_manager();
let config = self.config()?;
@@ -135,7 +142,7 @@ impl VeilidAPI {
/// Connect to the network
#[instrument(level = "debug", err, skip_all)]
pub async fn attach(&self) -> Result<(), VeilidAPIError> {
pub async fn attach(&self) -> VeilidAPIResult<()> {
let attachment_manager = self.attachment_manager()?;
if !attachment_manager.attach().await {
apibail_generic!("Already attached");
@@ -145,7 +152,7 @@ impl VeilidAPI {
/// Disconnect from the network
#[instrument(level = "debug", err, skip_all)]
pub async fn detach(&self) -> Result<(), VeilidAPIError> {
pub async fn detach(&self) -> VeilidAPIResult<()> {
let attachment_manager = self.attachment_manager()?;
if !attachment_manager.detach().await {
apibail_generic!("Already detached");
@@ -168,7 +175,7 @@ impl VeilidAPI {
/// 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
#[instrument(level = "debug", skip(self))]
pub async fn new_private_route(&self) -> Result<(RouteId, Vec<u8>), VeilidAPIError> {
pub async fn new_private_route(&self) -> VeilidAPIResult<(RouteId, Vec<u8>)> {
self.new_custom_private_route(
&VALID_CRYPTO_KINDS,
Stability::default(),
@@ -184,7 +191,7 @@ impl VeilidAPI {
crypto_kinds: &[CryptoKind],
stability: Stability,
sequencing: Sequencing,
) -> Result<(RouteId, Vec<u8>), VeilidAPIError> {
) -> VeilidAPIResult<(RouteId, Vec<u8>)> {
let default_route_hop_count: usize = {
let config = self.config()?;
let c = config.get();
@@ -231,14 +238,14 @@ impl VeilidAPI {
}
#[instrument(level = "debug", skip(self))]
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> Result<RouteId, VeilidAPIError> {
pub fn import_remote_private_route(&self, blob: Vec<u8>) -> VeilidAPIResult<RouteId> {
let rss = self.routing_table()?.route_spec_store();
rss.import_remote_private_route(blob)
.map_err(|e| VeilidAPIError::invalid_argument(e, "blob", "private route blob"))
}
#[instrument(level = "debug", skip(self))]
pub fn release_private_route(&self, route_id: RouteId) -> Result<(), VeilidAPIError> {
pub fn release_private_route(&self, route_id: RouteId) -> VeilidAPIResult<()> {
let rss = self.routing_table()?.route_spec_store();
if !rss.release_route(route_id) {
apibail_invalid_argument!("release_private_route", "key", route_id);
@@ -250,11 +257,7 @@ impl VeilidAPI {
// App Calls
#[instrument(level = "debug", skip(self))]
pub async fn app_call_reply(
&self,
id: OperationId,
message: Vec<u8>,
) -> Result<(), VeilidAPIError> {
pub async fn app_call_reply(&self, id: OperationId, message: Vec<u8>) -> VeilidAPIResult<()> {
let rpc_processor = self.rpc_processor()?;
rpc_processor
.app_call_reply(id, message)
@@ -270,7 +273,7 @@ impl VeilidAPI {
&self,
_endpoint_mode: TunnelMode,
_depth: u8,
) -> Result<PartialTunnel, VeilidAPIError> {
) -> VeilidAPIResult<PartialTunnel> {
panic!("unimplemented");
}
@@ -280,12 +283,12 @@ impl VeilidAPI {
_endpoint_mode: TunnelMode,
_depth: u8,
_partial_tunnel: PartialTunnel,
) -> Result<FullTunnel, VeilidAPIError> {
) -> VeilidAPIResult<FullTunnel> {
panic!("unimplemented");
}
#[instrument(level = "debug", err, skip(self))]
pub async fn cancel_tunnel(&self, _tunnel_id: TunnelId) -> Result<bool, VeilidAPIError> {
pub async fn cancel_tunnel(&self, _tunnel_id: TunnelId) -> VeilidAPIResult<bool> {
panic!("unimplemented");
}
}
+63 -26
View File
@@ -3,6 +3,7 @@
use super::*;
use data_encoding::BASE64URL_NOPAD;
use network_manager::*;
use routing_table::*;
#[derive(Default, Debug)]
@@ -304,7 +305,7 @@ fn get_debug_argument<T, G: FnOnce(&str) -> Option<T>>(
context: &str,
argument: &str,
getter: G,
) -> Result<T, VeilidAPIError> {
) -> VeilidAPIResult<T> {
let Some(val) = getter(value) else {
apibail_invalid_argument!(context, argument, value);
};
@@ -316,7 +317,7 @@ fn get_debug_argument_at<T, G: FnOnce(&str) -> Option<T>>(
context: &str,
argument: &str,
getter: G,
) -> Result<T, VeilidAPIError> {
) -> VeilidAPIResult<T> {
if pos >= debug_args.len() {
apibail_missing_argument!(context, argument);
}
@@ -328,7 +329,7 @@ fn get_debug_argument_at<T, G: FnOnce(&str) -> Option<T>>(
}
impl VeilidAPI {
async fn debug_buckets(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_buckets(&self, args: String) -> VeilidAPIResult<String> {
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
let mut min_state = BucketEntryState::Unreliable;
if args.len() == 1 {
@@ -344,19 +345,19 @@ impl VeilidAPI {
Ok(routing_table.debug_info_buckets(min_state))
}
async fn debug_dialinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
async fn debug_dialinfo(&self, _args: String) -> VeilidAPIResult<String> {
// Dump routing table dialinfo
let routing_table = self.network_manager()?.routing_table();
Ok(routing_table.debug_info_dialinfo())
}
async fn debug_txtrecord(&self, _args: String) -> Result<String, VeilidAPIError> {
async fn debug_txtrecord(&self, _args: String) -> VeilidAPIResult<String> {
// Dump routing table txt record
let routing_table = self.network_manager()?.routing_table();
Ok(routing_table.debug_info_txtrecord().await)
}
async fn debug_entries(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_entries(&self, args: String) -> VeilidAPIResult<String> {
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
let mut min_state = BucketEntryState::Unreliable;
@@ -373,7 +374,7 @@ impl VeilidAPI {
Ok(routing_table.debug_info_entries(min_state))
}
async fn debug_entry(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_entry(&self, args: String) -> VeilidAPIResult<String> {
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
let routing_table = self.network_manager()?.routing_table();
@@ -390,13 +391,13 @@ impl VeilidAPI {
Ok(routing_table.debug_info_entry(node_ref))
}
async fn debug_nodeinfo(&self, _args: String) -> Result<String, VeilidAPIError> {
async fn debug_nodeinfo(&self, _args: String) -> VeilidAPIResult<String> {
// Dump routing table entry
let routing_table = self.network_manager()?.routing_table();
Ok(routing_table.debug_info_nodeinfo())
}
async fn debug_config(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_config(&self, args: String) -> VeilidAPIResult<String> {
let config = self.config()?;
let args = args.trim_start();
if args.is_empty() {
@@ -425,7 +426,7 @@ impl VeilidAPI {
Ok("Config value set".to_owned())
}
async fn debug_restart(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_restart(&self, args: String) -> VeilidAPIResult<String> {
let args = args.trim_start();
if args.is_empty() {
apibail_missing_argument!("debug_restart", "arg_0");
@@ -451,7 +452,7 @@ impl VeilidAPI {
}
}
async fn debug_purge(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_purge(&self, args: String) -> VeilidAPIResult<String> {
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
if !args.is_empty() {
if args[0] == "buckets" {
@@ -503,7 +504,7 @@ impl VeilidAPI {
}
}
async fn debug_attach(&self, _args: String) -> Result<String, VeilidAPIError> {
async fn debug_attach(&self, _args: String) -> VeilidAPIResult<String> {
if !matches!(
self.get_state().await?.attachment.state,
AttachmentState::Detached
@@ -516,7 +517,7 @@ impl VeilidAPI {
Ok("Attached".to_owned())
}
async fn debug_detach(&self, _args: String) -> Result<String, VeilidAPIError> {
async fn debug_detach(&self, _args: String) -> VeilidAPIResult<String> {
if matches!(
self.get_state().await?.attachment.state,
AttachmentState::Detaching
@@ -529,7 +530,7 @@ impl VeilidAPI {
Ok("Detached".to_owned())
}
async fn debug_contact(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_contact(&self, args: String) -> VeilidAPIResult<String> {
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
let network_manager = self.network_manager()?;
@@ -550,7 +551,7 @@ impl VeilidAPI {
Ok(format!("{:#?}", cm))
}
async fn debug_ping(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_ping(&self, args: String) -> VeilidAPIResult<String> {
let netman = self.network_manager()?;
let routing_table = netman.routing_table();
let rpc = netman.rpc_processor();
@@ -592,7 +593,7 @@ impl VeilidAPI {
Ok(format!("{:#?}", out))
}
async fn debug_route_allocate(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_allocate(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// [ord|*ord] [rel] [<count>] [in|out] [avoid_node_id]
let netman = self.network_manager()?;
@@ -651,7 +652,7 @@ impl VeilidAPI {
Ok(out)
}
async fn debug_route_release(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_release(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// <route id>
let netman = self.network_manager()?;
let routing_table = netman.routing_table();
@@ -683,7 +684,7 @@ impl VeilidAPI {
Ok(out)
}
async fn debug_route_publish(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_publish(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// <route id> [full]
let netman = self.network_manager()?;
let routing_table = netman.routing_table();
@@ -735,7 +736,7 @@ impl VeilidAPI {
Ok(out)
}
async fn debug_route_unpublish(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_unpublish(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// <route id>
let netman = self.network_manager()?;
let routing_table = netman.routing_table();
@@ -757,7 +758,7 @@ impl VeilidAPI {
};
Ok(out)
}
async fn debug_route_print(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_print(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// <route id>
let netman = self.network_manager()?;
let routing_table = netman.routing_table();
@@ -776,7 +777,7 @@ impl VeilidAPI {
None => Ok("Route does not exist".to_owned()),
}
}
async fn debug_route_list(&self, _args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_list(&self, _args: Vec<String>) -> VeilidAPIResult<String> {
//
let netman = self.network_manager()?;
let routing_table = netman.routing_table();
@@ -799,7 +800,7 @@ impl VeilidAPI {
Ok(out)
}
async fn debug_route_import(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_import(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// <blob>
let blob = get_debug_argument_at(&args, 1, "debug_route", "blob", get_string)?;
@@ -819,7 +820,7 @@ impl VeilidAPI {
return Ok(out);
}
async fn debug_route_test(&self, args: Vec<String>) -> Result<String, VeilidAPIError> {
async fn debug_route_test(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// <route id>
let netman = self.network_manager()?;
let routing_table = netman.routing_table();
@@ -847,7 +848,7 @@ impl VeilidAPI {
return Ok(out);
}
async fn debug_route(&self, args: String) -> Result<String, VeilidAPIError> {
async fn debug_route(&self, args: String) -> VeilidAPIResult<String> {
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
let command = get_debug_argument_at(&args, 0, "debug_route", "command", get_string)?;
@@ -873,7 +874,40 @@ impl VeilidAPI {
}
}
pub async fn debug_help(&self, _args: String) -> Result<String, VeilidAPIError> {
async fn debug_record_list(&self, args: Vec<String>) -> VeilidAPIResult<String> {
// <local|remote>
let storage_manager = self.storage_manager()?;
let scope = get_debug_argument_at(&args, 1, "debug_record_list", "scope", get_string)?;
let out = match scope.as_str() {
"local" => {
let mut out = format!("Local Records:\n");
out += &storage_manager.debug_local_records().await;
out
}
"remote" => {
let mut out = format!("Remote Records:\n");
out += &storage_manager.debug_remote_records().await;
out
}
_ => "Invalid scope\n".to_owned(),
};
return Ok(out);
}
async fn debug_record(&self, args: String) -> VeilidAPIResult<String> {
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
let command = get_debug_argument_at(&args, 0, "debug_record", "command", get_string)?;
if command == "list" {
self.debug_record_list(args).await
} else {
Ok(">>> Unknown command\n".to_owned())
}
}
pub async fn debug_help(&self, _args: String) -> VeilidAPIResult<String> {
Ok(r#">>> Debug commands:
help
buckets [dead|reliable]
@@ -896,6 +930,7 @@ impl VeilidAPI {
list
import <blob>
test <route>
record list <local|remote>
<destination> is:
* direct: <node>[+<safety>][<modifiers>]
@@ -912,7 +947,7 @@ impl VeilidAPI {
.to_owned())
}
pub async fn debug(&self, args: String) -> Result<String, VeilidAPIError> {
pub async fn debug(&self, args: String) -> VeilidAPIResult<String> {
let res = {
let args = args.trim_start();
if args.is_empty() {
@@ -952,6 +987,8 @@ impl VeilidAPI {
self.debug_restart(rest).await
} else if arg == "route" {
self.debug_route(rest).await
} else if arg == "record" {
self.debug_record(rest).await
} else {
Err(VeilidAPIError::generic("Unknown debug command"))
}
+53 -4
View File
@@ -1,5 +1,13 @@
use super::*;
#[allow(unused_macros)]
#[macro_export]
macro_rules! apibail_not_initialized {
() => {
return Err(VeilidAPIError::not_initialized())
};
}
#[allow(unused_macros)]
#[macro_export]
macro_rules! apibail_timeout {
@@ -64,6 +72,14 @@ macro_rules! apibail_no_connection {
};
}
#[allow(unused_macros)]
#[macro_export]
macro_rules! apibail_key_not_found {
($x:expr) => {
return Err(VeilidAPIError::key_not_found($x))
};
}
#[allow(unused_macros)]
#[macro_export]
macro_rules! apibail_invalid_target {
@@ -119,8 +135,8 @@ pub enum VeilidAPIError {
InvalidTarget,
#[error("No connection: {message}")]
NoConnection { message: String },
#[error("No peer info: {node_id}")]
NoPeerInfo { node_id: TypedKey },
#[error("Key not found: {key}")]
KeyNotFound { key: TypedKey },
#[error("Internal: {message}")]
Internal { message: String },
#[error("Unimplemented: {message}")]
@@ -163,8 +179,8 @@ impl VeilidAPIError {
message: msg.to_string(),
}
}
pub fn no_peer_info(node_id: TypedKey) -> Self {
Self::NoPeerInfo { node_id }
pub fn key_not_found(key: TypedKey) -> Self {
Self::KeyNotFound { key }
}
pub fn internal<T: ToString>(msg: T) -> Self {
Self::Internal {
@@ -205,3 +221,36 @@ impl VeilidAPIError {
}
}
}
pub type VeilidAPIResult<T> = Result<T, VeilidAPIError>;
impl From<std::io::Error> for VeilidAPIError {
fn from(e: std::io::Error) -> Self {
match e.kind() {
std::io::ErrorKind::TimedOut => VeilidAPIError::timeout(),
std::io::ErrorKind::ConnectionRefused => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::ConnectionReset => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::HostUnreachable => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::NetworkUnreachable => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::ConnectionAborted => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::NotConnected => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::AddrInUse => VeilidAPIError::no_connection(e.to_string()),
std::io::ErrorKind::AddrNotAvailable => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::NetworkDown => VeilidAPIError::no_connection(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::ReadOnlyFilesystem => VeilidAPIError::internal(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::NotSeekable => VeilidAPIError::internal(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::FilesystemQuotaExceeded => VeilidAPIError::internal(e.to_string()),
#[cfg(feature = "io_error_more")]
std::io::ErrorKind::Deadlock => VeilidAPIError::internal(e.to_string()),
std::io::ErrorKind::Unsupported => VeilidAPIError::internal(e.to_string()),
std::io::ErrorKind::OutOfMemory => VeilidAPIError::internal(e.to_string()),
_ => VeilidAPIError::generic(e.to_string()),
}
}
}
+5 -7
View File
@@ -1,6 +1,5 @@
#![allow(dead_code)]
mod aligned_u64;
mod api;
mod debug;
mod error;
@@ -8,7 +7,8 @@ mod routing_context;
mod serialize_helpers;
mod types;
pub use aligned_u64::*;
pub mod tests;
pub use api::*;
pub use debug::*;
pub use error::*;
@@ -22,17 +22,15 @@ pub use core::str::FromStr;
pub use crypto::*;
pub use intf::BlockStore;
pub use intf::ProtectedStore;
pub use intf::{TableDB, TableDBTransaction, TableStore};
pub use network_manager::NetworkManager;
pub use routing_table::{NodeRef, NodeRefBase};
pub use table_store::{TableDB, TableDBTransaction, TableStore};
use crate::*;
use core::fmt;
use core_context::{api_shutdown, VeilidCoreContext};
use enumset::*;
use rkyv::{Archive as RkyvArchive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
use routing_table::{RouteSpecStore, RoutingTable};
use routing_table::{Direction, RouteSpecStore, RoutingTable};
use rpc_processor::*;
use serde::*;
use storage_manager::StorageManager;
/////////////////////////////////////////////////////////////////////////////////////////////////////
+100 -45
View File
@@ -4,7 +4,7 @@ use super::*;
#[derive(Clone, Debug)]
pub enum Target {
NodeId(PublicKey), // Node by any of its public keys
NodeId(TypedKey), // Node by its public key
PrivateRoute(RouteId), // Remote private route by its id
}
@@ -45,11 +45,11 @@ impl RoutingContext {
}
}
pub fn with_privacy(self) -> Result<Self, VeilidAPIError> {
pub fn with_privacy(self) -> VeilidAPIResult<Self> {
self.with_custom_privacy(Stability::default())
}
pub fn with_custom_privacy(self, stability: Stability) -> Result<Self, VeilidAPIError> {
pub fn with_custom_privacy(self, stability: Stability) -> VeilidAPIResult<Self> {
let config = self.api.config()?;
let c = config.get();
@@ -96,16 +96,16 @@ impl RoutingContext {
self.api.clone()
}
async fn get_destination(
&self,
target: Target,
) -> Result<rpc_processor::Destination, VeilidAPIError> {
async fn get_destination(&self, target: Target) -> VeilidAPIResult<rpc_processor::Destination> {
let rpc_processor = self.api.rpc_processor()?;
match target {
Target::NodeId(node_id) => {
// Resolve node
let mut nr = match rpc_processor.resolve_node(node_id).await {
let mut nr = match rpc_processor
.resolve_node(node_id, self.unlocked_inner.safety_selection)
.await
{
Ok(Some(nr)) => nr,
Ok(None) => apibail_invalid_target!(),
Err(e) => return Err(e.into()),
@@ -138,11 +138,7 @@ impl RoutingContext {
// App-level Messaging
#[instrument(level = "debug", err, skip(self))]
pub async fn app_call(
&self,
target: Target,
request: Vec<u8>,
) -> Result<Vec<u8>, VeilidAPIError> {
pub async fn app_call(&self, target: Target, request: Vec<u8>) -> VeilidAPIResult<Vec<u8>> {
let rpc_processor = self.api.rpc_processor()?;
// Get destination
@@ -167,11 +163,7 @@ impl RoutingContext {
}
#[instrument(level = "debug", err, skip(self))]
pub async fn app_message(
&self,
target: Target,
message: Vec<u8>,
) -> Result<(), VeilidAPIError> {
pub async fn app_message(&self, target: Target, message: Vec<u8>) -> VeilidAPIResult<()> {
let rpc_processor = self.api.rpc_processor()?;
// Get destination
@@ -195,51 +187,114 @@ impl RoutingContext {
}
///////////////////////////////////
/// DHT Values
/// DHT Records
pub async fn get_value(
/// 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.
pub async fn create_dht_record(
&self,
_key: TypedKey,
_subkey: ValueSubkey,
) -> Result<ValueData, VeilidAPIError> {
panic!("unimplemented");
kind: CryptoKind,
schema: DHTSchema,
) -> VeilidAPIResult<DHTRecordDescriptor> {
let storage_manager = self.api.storage_manager()?;
storage_manager
.create_record(kind, schema, self.unlocked_inner.safety_selection)
.await
}
pub async fn set_value(
/// Opens a DHT record at a specific key. Associates a secret if one is provided to provide writer capability.
/// 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(
&self,
_key: TypedKey,
_subkey: ValueSubkey,
_value: ValueData,
) -> Result<bool, VeilidAPIError> {
panic!("unimplemented");
key: TypedKey,
writer: Option<KeyPair>,
) -> VeilidAPIResult<DHTRecordDescriptor> {
let storage_manager = self.api.storage_manager()?;
storage_manager
.open_record(key, writer, self.unlocked_inner.safety_selection)
.await
}
pub async fn watch_value(
&self,
_key: TypedKey,
_subkeys: &[ValueSubkeyRange],
_expiration: Timestamp,
_count: u32,
) -> Result<bool, VeilidAPIError> {
panic!("unimplemented");
/// 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
pub async fn close_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
let storage_manager = self.api.storage_manager()?;
storage_manager.close_record(key).await
}
pub async fn cancel_watch_value(
/// 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
/// 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<()> {
let storage_manager = self.api.storage_manager()?;
storage_manager.delete_record(key).await
}
/// 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
/// 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(
&self,
_key: TypedKey,
_subkeys: &[ValueSubkeyRange],
) -> Result<bool, VeilidAPIError> {
panic!("unimplemented");
key: TypedKey,
subkey: ValueSubkey,
force_refresh: bool,
) -> VeilidAPIResult<Option<ValueData>> {
let storage_manager = self.api.storage_manager()?;
storage_manager.get_value(key, subkey, force_refresh).await
}
/// 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
pub async fn set_dht_value(
&self,
key: TypedKey,
subkey: ValueSubkey,
data: Vec<u8>,
) -> VeilidAPIResult<Option<ValueData>> {
let storage_manager = self.api.storage_manager()?;
storage_manager.set_value(key, subkey, data).await
}
/// Watches changes to an opened or created value
/// Changes to subkeys within the subkey range are returned via a ValueChanged callback
/// 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
/// Return value upon success is the amount of time allowed for the watch
pub async fn watch_dht_values(
&self,
key: TypedKey,
subkeys: ValueSubkeyRangeSet,
expiration: Timestamp,
count: u32,
) -> VeilidAPIResult<Timestamp> {
let storage_manager = self.api.storage_manager()?;
storage_manager
.watch_values(key, subkeys, expiration, count)
.await
}
/// Cancels a watch early
/// This is a convenience function that cancels watching all subkeys in a range
pub async fn cancel_dht_watch(
&self,
key: TypedKey,
subkeys: ValueSubkeyRangeSet,
) -> VeilidAPIResult<bool> {
let storage_manager = self.api.storage_manager()?;
storage_manager.cancel_watch_values(key, subkeys).await
}
///////////////////////////////////
/// Block Store
pub async fn find_block(&self, _block_id: PublicKey) -> Result<Vec<u8>, VeilidAPIError> {
pub async fn find_block(&self, _block_id: PublicKey) -> VeilidAPIResult<Vec<u8>> {
panic!("unimplemented");
}
pub async fn supply_block(&self, _block_id: PublicKey) -> Result<bool, VeilidAPIError> {
pub async fn supply_block(&self, _block_id: PublicKey) -> VeilidAPIResult<bool> {
panic!("unimplemented");
}
}
@@ -0,0 +1,14 @@
mod rkyv_enum_set;
mod rkyv_range_set_blaze;
pub mod serialize_arc;
mod serialize_json;
pub mod serialize_range_set_blaze;
mod veilid_rkyv;
use super::*;
use core::fmt::Debug;
pub use rkyv_enum_set::*;
pub use rkyv_range_set_blaze::*;
pub use serialize_json::*;
pub use veilid_rkyv::*;
@@ -0,0 +1,53 @@
use super::*;
pub struct RkyvEnumSet;
impl<T> rkyv::with::ArchiveWith<EnumSet<T>> for RkyvEnumSet
where
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
{
type Archived = rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>;
type Resolver = rkyv::Resolver<<T as EnumSetTypeWithRepr>::Repr>;
#[inline]
unsafe fn resolve_with(
field: &EnumSet<T>,
pos: usize,
resolver: Self::Resolver,
out: *mut Self::Archived,
) {
let r = field.as_repr();
r.resolve(pos, resolver, out);
}
}
impl<T, S> rkyv::with::SerializeWith<EnumSet<T>, S> for RkyvEnumSet
where
S: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Serialize<S>,
{
fn serialize_with(field: &EnumSet<T>, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
let r = field.as_repr();
r.serialize(serializer)
}
}
impl<T, D>
rkyv::with::DeserializeWith<rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>, EnumSet<T>, D>
for RkyvEnumSet
where
D: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>:
rkyv::Deserialize<<T as EnumSetTypeWithRepr>::Repr, D>,
{
fn deserialize_with(
field: &rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>,
deserializer: &mut D,
) -> Result<EnumSet<T>, D::Error> {
Ok(EnumSet::<T>::from_repr(field.deserialize(deserializer)?))
}
}
@@ -0,0 +1,73 @@
use super::*;
use range_set_blaze::*;
pub struct RkyvRangeSetBlaze;
impl<T> rkyv::with::ArchiveWith<RangeSetBlaze<T>> for RkyvRangeSetBlaze
where
T: rkyv::Archive + Integer,
{
type Archived = rkyv::Archived<Vec<T>>;
type Resolver = rkyv::Resolver<Vec<T>>;
#[inline]
unsafe fn resolve_with(
field: &RangeSetBlaze<T>,
pos: usize,
resolver: Self::Resolver,
out: *mut Self::Archived,
) {
let mut r = Vec::<T>::with_capacity(field.ranges_len() * 2);
for range in field.ranges() {
r.push(*range.start());
r.push(*range.end());
}
r.resolve(pos, resolver, out);
}
}
impl<T, S> rkyv::with::SerializeWith<RangeSetBlaze<T>, S> for RkyvRangeSetBlaze
where
S: rkyv::Fallible + ?Sized,
Vec<T>: rkyv::Serialize<S>,
T: rkyv::Archive + Integer,
{
fn serialize_with(
field: &RangeSetBlaze<T>,
serializer: &mut S,
) -> Result<Self::Resolver, S::Error> {
let mut r = Vec::<T>::with_capacity(field.ranges_len() * 2);
for range in field.ranges() {
r.push(*range.start());
r.push(*range.end());
}
r.serialize(serializer)
}
}
impl<T, D> rkyv::with::DeserializeWith<rkyv::Archived<Vec<T>>, RangeSetBlaze<T>, D>
for RkyvRangeSetBlaze
where
D: rkyv::Fallible + ?Sized,
T: rkyv::Archive + Integer,
rkyv::Archived<T>: rkyv::Deserialize<T, D>,
D::Error: From<String>,
{
fn deserialize_with(
field: &rkyv::Archived<Vec<T>>,
deserializer: &mut D,
) -> Result<RangeSetBlaze<T>, D::Error> {
let mut out = RangeSetBlaze::<T>::new();
if field.len() % 2 == 1 {
return Err("invalid range set length".to_owned().into());
}
let f = field.as_slice();
for i in 0..field.len() / 2 {
let l: T = f[i * 2].deserialize(deserializer)?;
let u: T = f[i * 2 + 1].deserialize(deserializer)?;
out.ranges_insert(l..=u);
}
Ok(out)
}
}
@@ -0,0 +1,12 @@
use alloc::sync::Arc;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn serialize<T: Serialize, S: Serializer>(v: &Arc<T>, s: S) -> Result<S::Ok, S::Error> {
T::serialize(v.as_ref(), s)
}
pub fn deserialize<'de, T: Deserialize<'de>, D: Deserializer<'de>>(
d: D,
) -> Result<Arc<T>, D::Error> {
Ok(Arc::new(T::deserialize(d)?))
}
@@ -1,16 +1,9 @@
use super::*;
pub use bytecheck::CheckBytes;
use core::fmt::Debug;
use rkyv::Archive as RkyvArchive;
use rkyv::Deserialize as RkyvDeserialize;
use rkyv::Serialize as RkyvSerialize;
// Don't trace these functions as they are used in the transfer of API logs, which will recurse!
// #[instrument(level = "trace", ret, err)]
pub fn deserialize_json<'a, T: de::Deserialize<'a> + Debug>(
arg: &'a str,
) -> Result<T, VeilidAPIError> {
pub fn deserialize_json<'a, T: de::Deserialize<'a> + Debug>(arg: &'a str) -> VeilidAPIResult<T> {
serde_json::from_str(arg).map_err(|e| VeilidAPIError::ParseError {
message: e.to_string(),
value: format!(
@@ -24,7 +17,7 @@ pub fn deserialize_json<'a, T: de::Deserialize<'a> + Debug>(
// #[instrument(level = "trace", ret, err)]
pub fn deserialize_opt_json<T: de::DeserializeOwned + Debug>(
arg: Option<String>,
) -> Result<T, VeilidAPIError> {
) -> VeilidAPIResult<T> {
let arg = arg.as_ref().ok_or_else(|| VeilidAPIError::ParseError {
message: "invalid null string".to_owned(),
value: format!(
@@ -117,95 +110,3 @@ pub mod opt_json_as_string {
}
}
}
pub mod arc_serialize {
use alloc::sync::Arc;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub fn serialize<T: Serialize, S: Serializer>(v: &Arc<T>, s: S) -> Result<S::Ok, S::Error> {
T::serialize(v.as_ref(), s)
}
pub fn deserialize<'de, T: Deserialize<'de>, D: Deserializer<'de>>(
d: D,
) -> Result<Arc<T>, D::Error> {
Ok(Arc::new(T::deserialize(d)?))
}
}
pub fn to_rkyv<T>(v: &T) -> EyreResult<Vec<u8>>
where
T: RkyvSerialize<rkyv::ser::serializers::AllocSerializer<1024>>,
{
Ok(rkyv::to_bytes::<T, 1024>(v)
.wrap_err("failed to freeze object")?
.to_vec())
}
pub fn from_rkyv<T>(v: Vec<u8>) -> EyreResult<T>
where
T: RkyvArchive,
<T as RkyvArchive>::Archived:
for<'t> bytecheck::CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>,
<T as RkyvArchive>::Archived:
rkyv::Deserialize<T, rkyv::de::deserializers::SharedDeserializeMap>,
{
match rkyv::from_bytes::<T>(&v) {
Ok(v) => Ok(v),
Err(e) => {
bail!("failed to deserialize frozen object: {}", e);
}
}
}
pub struct RkyvEnumSet;
impl<T> rkyv::with::ArchiveWith<EnumSet<T>> for RkyvEnumSet
where
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
{
type Archived = rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>;
type Resolver = rkyv::Resolver<<T as EnumSetTypeWithRepr>::Repr>;
#[inline]
unsafe fn resolve_with(
field: &EnumSet<T>,
pos: usize,
resolver: Self::Resolver,
out: *mut Self::Archived,
) {
let r = field.as_repr();
r.resolve(pos, resolver, out);
}
}
impl<T, S> rkyv::with::SerializeWith<EnumSet<T>, S> for RkyvEnumSet
where
S: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Serialize<S>,
{
fn serialize_with(field: &EnumSet<T>, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
let r = field.as_repr();
r.serialize(serializer)
}
}
impl<T, D>
rkyv::with::DeserializeWith<rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>, EnumSet<T>, D>
for RkyvEnumSet
where
D: rkyv::Fallible + ?Sized,
T: EnumSetType + EnumSetTypeWithRepr,
<T as EnumSetTypeWithRepr>::Repr: rkyv::Archive,
rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>:
rkyv::Deserialize<<T as EnumSetTypeWithRepr>::Repr, D>,
{
fn deserialize_with(
field: &rkyv::Archived<<T as EnumSetTypeWithRepr>::Repr>,
deserializer: &mut D,
) -> Result<EnumSet<T>, D::Error> {
Ok(EnumSet::<T>::from_repr(field.deserialize(deserializer)?))
}
}
@@ -0,0 +1,60 @@
use core::fmt;
use core::marker::PhantomData;
use range_set_blaze::*;
use serde::{
de::SeqAccess, de::Visitor, ser::SerializeSeq, Deserialize, Deserializer, Serialize, Serializer,
};
pub fn serialize<T: Integer + Serialize, S: Serializer>(
v: &RangeSetBlaze<T>,
s: S,
) -> Result<S::Ok, S::Error> {
let cnt = v.ranges_len() * 2;
let mut seq = s.serialize_seq(Some(cnt))?;
for range in v.ranges() {
seq.serialize_element(range.start())?;
seq.serialize_element(range.end())?;
}
seq.end()
}
pub fn deserialize<'de, T: Integer + Deserialize<'de>, D: Deserializer<'de>>(
d: D,
) -> Result<RangeSetBlaze<T>, D::Error> {
struct RangeSetBlazeVisitor<T> {
marker: PhantomData<T>,
}
impl<'de, T> Visitor<'de> for RangeSetBlazeVisitor<T>
where
T: Deserialize<'de> + Integer,
{
type Value = RangeSetBlaze<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a RangeSetBlaze")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = RangeSetBlaze::<T>::new();
while let Some(start) = seq.next_element()? {
let Some(end) = seq.next_element()? else {
break;
};
values.ranges_insert(start..=end);
}
Ok(values)
}
}
let visitor = RangeSetBlazeVisitor {
marker: PhantomData,
};
d.deserialize_seq(visitor)
}
@@ -0,0 +1,151 @@
use super::*;
use rkyv::ser::Serializer;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub struct VeilidRkyvSerializer<S> {
inner: S,
}
impl<S> VeilidRkyvSerializer<S> {
pub fn into_inner(self) -> S {
self.inner
}
}
impl<S: rkyv::Fallible> rkyv::Fallible for VeilidRkyvSerializer<S> {
type Error = VeilidRkyvError<S::Error>;
}
impl<S: rkyv::ser::ScratchSpace> rkyv::ser::ScratchSpace for VeilidRkyvSerializer<S> {
unsafe fn push_scratch(
&mut self,
layout: core::alloc::Layout,
) -> Result<core::ptr::NonNull<[u8]>, Self::Error> {
self.inner
.push_scratch(layout)
.map_err(VeilidRkyvError::Inner)
}
unsafe fn pop_scratch(
&mut self,
ptr: core::ptr::NonNull<u8>,
layout: core::alloc::Layout,
) -> Result<(), Self::Error> {
self.inner
.pop_scratch(ptr, layout)
.map_err(VeilidRkyvError::Inner)
}
}
impl<S: rkyv::ser::Serializer> rkyv::ser::Serializer for VeilidRkyvSerializer<S> {
#[inline]
fn pos(&self) -> usize {
self.inner.pos()
}
#[inline]
fn write(&mut self, bytes: &[u8]) -> Result<(), Self::Error> {
self.inner.write(bytes).map_err(VeilidRkyvError::Inner)
}
}
impl<S: Default> Default for VeilidRkyvSerializer<S> {
fn default() -> Self {
Self {
inner: S::default(),
}
}
}
pub type DefaultVeilidRkyvSerializer =
VeilidRkyvSerializer<rkyv::ser::serializers::AllocSerializer<1024>>;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Debug, Default)]
pub struct VeilidSharedDeserializeMap {
inner: SharedDeserializeMap,
}
impl VeilidSharedDeserializeMap {
#[inline]
pub fn new() -> Self {
Self {
inner: SharedDeserializeMap::new(),
}
}
}
impl rkyv::Fallible for VeilidSharedDeserializeMap {
type Error = VeilidRkyvError<rkyv::de::deserializers::SharedDeserializeMapError>;
}
impl rkyv::de::SharedDeserializeRegistry for VeilidSharedDeserializeMap {
fn get_shared_ptr(&mut self, ptr: *const u8) -> Option<&dyn rkyv::de::SharedPointer> {
self.inner.get_shared_ptr(ptr)
}
fn add_shared_ptr(
&mut self,
ptr: *const u8,
shared: Box<dyn rkyv::de::SharedPointer>,
) -> Result<(), Self::Error> {
self.inner
.add_shared_ptr(ptr, shared)
.map_err(VeilidRkyvError::Inner)
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[derive(Debug)]
pub enum VeilidRkyvError<E> {
Inner(E),
StringError(String),
}
impl<E: Debug> From<String> for VeilidRkyvError<E> {
fn from(s: String) -> Self {
Self::StringError(s)
}
}
impl<E: Debug + fmt::Display> fmt::Display for VeilidRkyvError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VeilidRkyvError::Inner(e) => write!(f, "Inner: {}", e),
VeilidRkyvError::StringError(s) => write!(f, "StringError: {}", s),
}
}
}
impl<E: Debug + fmt::Display> std::error::Error for VeilidRkyvError<E> {}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub fn to_rkyv<T>(value: &T) -> VeilidAPIResult<Vec<u8>>
where
T: RkyvSerialize<DefaultVeilidRkyvSerializer>,
{
let mut serializer = DefaultVeilidRkyvSerializer::default();
serializer
.serialize_value(value)
.map_err(|e| VeilidAPIError::generic(format!("failed to serialize object: {}", e)))?;
Ok(serializer
.into_inner()
.into_serializer()
.into_inner()
.to_vec())
}
pub fn from_rkyv<T>(bytes: Vec<u8>) -> VeilidAPIResult<T>
where
T: RkyvArchive,
<T as RkyvArchive>::Archived:
for<'t> CheckBytes<rkyv::validation::validators::DefaultValidator<'t>>,
<T as RkyvArchive>::Archived: RkyvDeserialize<T, VeilidSharedDeserializeMap>,
{
rkyv::check_archived_root::<T>(&bytes)
.map_err(|e| VeilidAPIError::generic(format!("checkbytes failed: {}", e)))?
.deserialize(&mut VeilidSharedDeserializeMap::default())
.map_err(|e| VeilidAPIError::generic(format!("failed to deserialize: {}", e)))
}
+1
View File
@@ -0,0 +1 @@
pub mod test_serialize_rkyv;
@@ -0,0 +1,16 @@
use crate::*;
pub async fn test_simple_string() {
let plain = "basic string".to_string();
let serialized = b"basic string\x0c\x00\x00\x00\xf4\xff\xff\xff".to_vec();
let a = to_rkyv(&plain);
assert_eq!(a.unwrap(), serialized);
let b = from_rkyv::<String>(serialized);
assert_eq!(b.unwrap(), plain);
}
pub async fn test_all() {
test_simple_string().await;
}
File diff suppressed because it is too large Load Diff
@@ -120,3 +120,17 @@ impl AlignedU64 {
Self(self.0.saturating_sub(rhs.0))
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/// Microseconds since epoch
pub type Timestamp = AlignedU64;
pub fn get_aligned_timestamp() -> Timestamp {
get_timestamp().into()
}
/// Microseconds duration
pub type TimestampDuration = AlignedU64;
/// Request/Response matching id
pub type OperationId = AlignedU64;
/// Number of bytes
pub type ByteCount = AlignedU64;
@@ -0,0 +1,65 @@
use super::*;
/// Direct statement blob passed to hosting application for processing
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidAppMessage {
/// Some(sender) if the message was sent directly, None if received via a private/safety route
#[serde(with = "opt_json_as_string")]
sender: Option<TypedKey>,
/// The content of the message to deliver to the application
#[serde(with = "json_as_base64")]
message: Vec<u8>,
}
impl VeilidAppMessage {
pub fn new(sender: Option<TypedKey>, message: Vec<u8>) -> Self {
Self { sender, message }
}
pub fn sender(&self) -> Option<&TypedKey> {
self.sender.as_ref()
}
pub fn message(&self) -> &[u8] {
&self.message
}
}
/// Direct question blob passed to hosting application for processing to send an eventual AppReply
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidAppCall {
/// Some(sender) if the request was sent directly, None if received via a private/safety route
#[serde(with = "opt_json_as_string")]
sender: Option<TypedKey>,
/// The content of the request to deliver to the application
#[serde(with = "json_as_base64")]
message: Vec<u8>,
/// The id to reply to
#[serde(with = "json_as_string")]
id: OperationId,
}
impl VeilidAppCall {
pub fn new(sender: Option<TypedKey>, message: Vec<u8>, id: OperationId) -> Self {
Self {
sender,
message,
id,
}
}
pub fn sender(&self) -> Option<&TypedKey> {
self.sender.as_ref()
}
pub fn message(&self) -> &[u8] {
&self.message
}
pub fn id(&self) -> OperationId {
self.id
}
}
@@ -0,0 +1,56 @@
use super::*;
/// DHT Record Descriptor
#[derive(
Debug,
Clone,
PartialOrd,
Ord,
PartialEq,
Eq,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct DHTRecordDescriptor {
/// DHT Key = Hash(ownerKeyKind) of: [ ownerKeyValue, schema ]
key: TypedKey,
/// The public key of the owner
owner: PublicKey,
/// If this key is being created: Some(the secret key of the owner)
/// If this key is just being opened: None
owner_secret: Option<SecretKey>,
/// The schema in use associated with the key
schema: DHTSchema,
}
impl DHTRecordDescriptor {
pub fn new(
key: TypedKey,
owner: PublicKey,
owner_secret: Option<SecretKey>,
schema: DHTSchema,
) -> Self {
Self {
key,
owner,
owner_secret,
schema,
}
}
pub fn owner(&self) -> &PublicKey {
&self.owner
}
pub fn owner_secret(&self) -> Option<&SecretKey> {
self.owner_secret.as_ref()
}
pub fn schema(&self) -> &DHTSchema {
&self.schema
}
}
@@ -0,0 +1,18 @@
mod dht_record_descriptor;
mod schema;
mod value_data;
mod value_subkey_range_set;
use super::*;
pub use dht_record_descriptor::*;
pub use schema::*;
pub use value_data::*;
pub use value_subkey_range_set::*;
/// Value subkey
pub type ValueSubkey = u32;
/// Value subkey range
pub type ValueSubkeyRange = (u32, u32);
/// Value sequence number
pub type ValueSeqNum = u32;
@@ -0,0 +1,84 @@
use super::*;
/// Default DHT Schema (DFLT)
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Ord,
PartialOrd,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct DHTSchemaDFLT {
/// Owner subkey count
pub o_cnt: u16,
}
impl DHTSchemaDFLT {
pub const FCC: [u8; 4] = *b"DFLT";
pub const FIXED_SIZE: usize = 6;
/// Build the data representation of the schema
pub fn compile(&self) -> Vec<u8> {
let mut out = Vec::<u8>::with_capacity(Self::FIXED_SIZE);
// kind
out.extend_from_slice(&Self::FCC);
// o_cnt
out.extend_from_slice(&self.o_cnt.to_le_bytes());
out
}
/// Get the number of subkeys this schema allocates
pub fn subkey_count(&self) -> usize {
self.o_cnt as usize
}
/// Get the data size of this schema beyond the size of the structure itself
pub fn data_size(&self) -> usize {
0
}
/// Check a subkey value data against the schema
pub fn check_subkey_value_data(
&self,
owner: &PublicKey,
subkey: ValueSubkey,
value_data: &ValueData,
) -> bool {
let subkey = subkey as usize;
// Check is subkey is in owner range
if subkey < (self.o_cnt as usize) {
// Check value data has valid writer
if value_data.writer() == owner {
return true;
}
// Wrong writer
return false;
}
// Subkey out of range
false
}
}
impl TryFrom<&[u8]> for DHTSchemaDFLT {
type Error = VeilidAPIError;
fn try_from(b: &[u8]) -> Result<Self, Self::Error> {
if b.len() != Self::FIXED_SIZE {
apibail_generic!("invalid size");
}
if &b[0..4] != &Self::FCC {
apibail_generic!("wrong fourcc");
}
let o_cnt = u16::from_le_bytes(b[4..6].try_into().map_err(VeilidAPIError::internal)?);
Ok(Self { o_cnt })
}
}
@@ -0,0 +1,97 @@
mod dflt;
mod smpl;
use super::*;
pub use dflt::*;
pub use smpl::*;
/// Enum over all the supported DHT Schemas
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Ord,
PartialOrd,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
#[serde(tag = "kind")]
pub enum DHTSchema {
DFLT(DHTSchemaDFLT),
SMPL(DHTSchemaSMPL),
}
impl DHTSchema {
pub fn dflt(o_cnt: u16) -> DHTSchema {
DHTSchema::DFLT(DHTSchemaDFLT { o_cnt })
}
pub fn smpl(o_cnt: u16, members: Vec<DHTSchemaSMPLMember>) -> DHTSchema {
DHTSchema::SMPL(DHTSchemaSMPL { o_cnt, members })
}
/// Build the data representation of the schema
pub fn compile(&self) -> Vec<u8> {
match self {
DHTSchema::DFLT(d) => d.compile(),
DHTSchema::SMPL(s) => s.compile(),
}
}
/// Get the number of subkeys this schema allocates
pub fn subkey_count(&self) -> usize {
match self {
DHTSchema::DFLT(d) => d.subkey_count(),
DHTSchema::SMPL(s) => s.subkey_count(),
}
}
/// Get the data size of this schema beyond the size of the structure itself
pub fn data_size(&self) -> usize {
match self {
DHTSchema::DFLT(d) => d.data_size(),
DHTSchema::SMPL(s) => s.data_size(),
}
}
/// Check a subkey value data against the schema
pub fn check_subkey_value_data(
&self,
owner: &PublicKey,
subkey: ValueSubkey,
value_data: &ValueData,
) -> bool {
match self {
DHTSchema::DFLT(d) => d.check_subkey_value_data(owner, subkey, value_data),
DHTSchema::SMPL(s) => s.check_subkey_value_data(owner, subkey, value_data),
}
}
}
impl Default for DHTSchema {
fn default() -> Self {
Self::dflt(1)
}
}
impl TryFrom<&[u8]> for DHTSchema {
type Error = VeilidAPIError;
fn try_from(b: &[u8]) -> Result<Self, Self::Error> {
if b.len() < 4 {
apibail_generic!("invalid size");
}
let fcc: [u8; 4] = b[0..4].try_into().unwrap();
match fcc {
DHTSchemaDFLT::FCC => Ok(DHTSchema::DFLT(DHTSchemaDFLT::try_from(b)?)),
DHTSchemaSMPL::FCC => Ok(DHTSchema::SMPL(DHTSchemaSMPL::try_from(b)?)),
_ => {
apibail_generic!("unknown fourcc");
}
}
}
}
@@ -0,0 +1,152 @@
use super::*;
/// Simple DHT Schema (SMPL) Member
#[derive(
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct DHTSchemaSMPLMember {
/// Member key
pub m_key: PublicKey,
/// Member subkey count
pub m_cnt: u16,
}
/// Simple DHT Schema (SMPL)
#[derive(
Debug,
Clone,
PartialEq,
Eq,
Ord,
PartialOrd,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct DHTSchemaSMPL {
/// Owner subkey count
pub o_cnt: u16,
/// Members
pub members: Vec<DHTSchemaSMPLMember>,
}
impl DHTSchemaSMPL {
pub const FCC: [u8; 4] = *b"SMPL";
pub const FIXED_SIZE: usize = 6;
/// Build the data representation of the schema
pub fn compile(&self) -> Vec<u8> {
let mut out = Vec::<u8>::with_capacity(
Self::FIXED_SIZE + (self.members.len() * (PUBLIC_KEY_LENGTH + 2)),
);
// kind
out.extend_from_slice(&Self::FCC);
// o_cnt
out.extend_from_slice(&self.o_cnt.to_le_bytes());
// members
for m in &self.members {
// m_key
out.extend_from_slice(&m.m_key.bytes);
// m_cnt
out.extend_from_slice(&m.m_cnt.to_le_bytes());
}
out
}
/// Get the number of subkeys this schema allocates
pub fn subkey_count(&self) -> usize {
self.members
.iter()
.fold(self.o_cnt as usize, |acc, x| acc + (x.m_cnt as usize))
}
/// Get the data size of this schema beyond the size of the structure itself
pub fn data_size(&self) -> usize {
self.members.len() * mem::size_of::<DHTSchemaSMPLMember>()
}
/// Check a subkey value data against the schema
pub fn check_subkey_value_data(
&self,
owner: &PublicKey,
subkey: ValueSubkey,
value_data: &ValueData,
) -> bool {
let mut cur_subkey = subkey as usize;
// Check is subkey is in owner range
if cur_subkey < (self.o_cnt as usize) {
// Check value data has valid writer
if value_data.writer() == owner {
return true;
}
// Wrong writer
return false;
}
cur_subkey -= self.o_cnt as usize;
// Check all member ranges
for m in &self.members {
// Check if subkey is in member range
if cur_subkey < (m.m_cnt as usize) {
// Check value data has valid writer
if value_data.writer() == &m.m_key {
return true;
}
// Wrong writer
return false;
}
cur_subkey -= m.m_cnt as usize;
}
// Subkey out of range
false
}
}
impl TryFrom<&[u8]> for DHTSchemaSMPL {
type Error = VeilidAPIError;
fn try_from(b: &[u8]) -> Result<Self, Self::Error> {
if b.len() != Self::FIXED_SIZE {
apibail_generic!("invalid size");
}
if &b[0..4] != &Self::FCC {
apibail_generic!("wrong fourcc");
}
if (b.len() - Self::FIXED_SIZE) % (PUBLIC_KEY_LENGTH + 2) != 0 {
apibail_generic!("invalid member length");
}
let o_cnt = u16::from_le_bytes(b[4..6].try_into().map_err(VeilidAPIError::internal)?);
let members_len = (b.len() - Self::FIXED_SIZE) / (PUBLIC_KEY_LENGTH + 2);
let mut members: Vec<DHTSchemaSMPLMember> = Vec::with_capacity(members_len);
for n in 0..members_len {
let mstart = Self::FIXED_SIZE + n * (PUBLIC_KEY_LENGTH + 2);
let m_key = PublicKey::try_from(&b[mstart..mstart + PUBLIC_KEY_LENGTH])
.map_err(VeilidAPIError::internal)?;
let m_cnt = u16::from_le_bytes(
b[mstart + PUBLIC_KEY_LENGTH..mstart + PUBLIC_KEY_LENGTH + 2]
.try_into()
.map_err(VeilidAPIError::internal)?,
);
members.push(DHTSchemaSMPLMember { m_key, m_cnt });
}
Ok(Self { o_cnt, members })
}
}
@@ -0,0 +1,54 @@
use super::*;
#[derive(
Clone,
Debug,
Default,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct ValueData {
seq: ValueSeqNum,
data: Vec<u8>,
writer: PublicKey,
}
impl ValueData {
pub const MAX_LEN: usize = 32768;
pub fn new(data: Vec<u8>, writer: PublicKey) -> Self {
assert!(data.len() <= Self::MAX_LEN);
Self {
seq: 0,
data,
writer,
}
}
pub fn new_with_seq(seq: ValueSeqNum, data: Vec<u8>, writer: PublicKey) -> Self {
assert!(data.len() <= Self::MAX_LEN);
Self { seq, data, writer }
}
pub fn seq(&self) -> ValueSeqNum {
self.seq
}
pub fn writer(&self) -> &PublicKey {
&self.writer
}
pub fn data(&self) -> &[u8] {
&self.data
}
pub fn total_size(&self) -> usize {
mem::size_of::<Self>() + self.data.len()
}
}
@@ -0,0 +1,51 @@
use super::*;
use core::ops::{Deref, DerefMut};
use range_set_blaze::*;
#[derive(
Clone,
Debug,
Default,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct ValueSubkeyRangeSet {
#[with(RkyvRangeSetBlaze)]
#[serde(with = "serialize_range_set_blaze")]
data: RangeSetBlaze<ValueSubkey>,
}
impl ValueSubkeyRangeSet {
pub fn new() -> Self {
Self {
data: Default::default(),
}
}
pub fn single(value: ValueSubkey) -> Self {
let mut data = RangeSetBlaze::new();
data.insert(value);
Self { data }
}
}
impl Deref for ValueSubkeyRangeSet {
type Target = RangeSetBlaze<ValueSubkey>;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl DerefMut for ValueSubkeyRangeSet {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
@@ -0,0 +1,65 @@
use super::*;
/// FOURCC code
#[derive(
Copy,
Default,
Clone,
Hash,
PartialOrd,
Ord,
PartialEq,
Eq,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes, PartialOrd, Ord, PartialEq, Eq, Hash))]
pub struct FourCC(pub [u8; 4]);
impl From<[u8; 4]> for FourCC {
fn from(b: [u8; 4]) -> Self {
Self(b)
}
}
impl From<u32> for FourCC {
fn from(u: u32) -> Self {
Self(u.to_be_bytes())
}
}
impl From<FourCC> for u32 {
fn from(u: FourCC) -> Self {
u32::from_be_bytes(u.0)
}
}
impl TryFrom<&[u8]> for FourCC {
type Error = VeilidAPIError;
fn try_from(b: &[u8]) -> Result<Self, Self::Error> {
Ok(Self(b.try_into().map_err(VeilidAPIError::generic)?))
}
}
impl fmt::Display for FourCC {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", String::from_utf8_lossy(&self.0))
}
}
impl fmt::Debug for FourCC {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", String::from_utf8_lossy(&self.0))
}
}
impl FromStr for FourCC {
type Err = VeilidAPIError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(
s.as_bytes().try_into().map_err(VeilidAPIError::generic)?,
))
}
}
+21
View File
@@ -0,0 +1,21 @@
mod aligned_u64;
mod app_message_call;
mod dht;
mod fourcc;
mod safety;
mod stats;
mod tunnel;
mod veilid_log;
mod veilid_state;
use super::*;
pub use aligned_u64::*;
pub use app_message_call::*;
pub use dht::*;
pub use fourcc::*;
pub use safety::*;
pub use stats::*;
pub use tunnel::*;
pub use veilid_log::*;
pub use veilid_state::*;
+125
View File
@@ -0,0 +1,125 @@
use super::*;
// Ordering here matters, >= is used to check strength of sequencing requirement
#[derive(
Copy,
Clone,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
pub enum Sequencing {
NoPreference,
PreferOrdered,
EnsureOrdered,
}
impl Default for Sequencing {
fn default() -> Self {
Self::NoPreference
}
}
// Ordering here matters, >= is used to check strength of stability requirement
#[derive(
Copy,
Clone,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
pub enum Stability {
LowLatency,
Reliable,
}
impl Default for Stability {
fn default() -> Self {
Self::LowLatency
}
}
/// The choice of safety route to include in compiled routes
#[derive(
Copy,
Clone,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
pub enum SafetySelection {
/// Don't use a safety route, only specify the sequencing preference
Unsafe(Sequencing),
/// Use a safety route and parameters specified by a SafetySpec
Safe(SafetySpec),
}
impl SafetySelection {
pub fn get_sequencing(&self) -> Sequencing {
match self {
SafetySelection::Unsafe(seq) => *seq,
SafetySelection::Safe(ss) => ss.sequencing,
}
}
}
impl Default for SafetySelection {
fn default() -> Self {
Self::Unsafe(Sequencing::NoPreference)
}
}
/// Options for safety routes (sender privacy)
#[derive(
Copy,
Clone,
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct SafetySpec {
/// preferred safety route set id if it still exists
pub preferred_route: Option<RouteId>,
/// must be greater than 0
pub hop_count: usize,
/// prefer reliability over speed
pub stability: Stability,
/// prefer connection-oriented sequenced protocols
pub sequencing: Sequencing,
}
+113
View File
@@ -0,0 +1,113 @@
use super::*;
#[derive(
Clone,
Debug,
Default,
PartialEq,
Eq,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct LatencyStats {
#[serde(with = "json_as_string")]
pub fastest: TimestampDuration, // fastest latency in the ROLLING_LATENCIES_SIZE last latencies
#[serde(with = "json_as_string")]
pub average: TimestampDuration, // average latency over the ROLLING_LATENCIES_SIZE last latencies
#[serde(with = "json_as_string")]
pub slowest: TimestampDuration, // slowest latency in the ROLLING_LATENCIES_SIZE last latencies
}
#[derive(
Clone,
Debug,
Default,
PartialEq,
Eq,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct TransferStats {
#[serde(with = "json_as_string")]
pub total: ByteCount, // total amount transferred ever
#[serde(with = "json_as_string")]
pub maximum: ByteCount, // maximum rate over the ROLLING_TRANSFERS_SIZE last amounts
#[serde(with = "json_as_string")]
pub average: ByteCount, // average rate over the ROLLING_TRANSFERS_SIZE last amounts
#[serde(with = "json_as_string")]
pub minimum: ByteCount, // minimum rate over the ROLLING_TRANSFERS_SIZE last amounts
}
#[derive(
Clone,
Debug,
Default,
PartialEq,
Eq,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct TransferStatsDownUp {
pub down: TransferStats,
pub up: TransferStats,
}
#[derive(
Clone,
Debug,
Default,
PartialEq,
Eq,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct RPCStats {
pub messages_sent: u32, // number of rpcs that have been sent in the total_time range
pub messages_rcvd: u32, // number of rpcs that have been received in the total_time range
pub questions_in_flight: u32, // number of questions issued that have yet to be answered
#[serde(with = "opt_json_as_string")]
pub last_question_ts: Option<Timestamp>, // when the peer was last questioned (either successfully or not) and we wanted an answer
#[serde(with = "opt_json_as_string")]
pub last_seen_ts: Option<Timestamp>, // when the peer was last seen for any reason, including when we first attempted to reach out to it
#[serde(with = "opt_json_as_string")]
pub first_consecutive_seen_ts: Option<Timestamp>, // the timestamp of the first consecutive proof-of-life for this node (an answer or received question)
pub recent_lost_answers: u32, // number of answers that have been lost since we lost reliability
pub failed_to_send: u32, // number of messages that have failed to send since we last successfully sent one
}
#[derive(
Clone,
Debug,
Default,
PartialEq,
Eq,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct PeerStats {
#[serde(with = "json_as_string")]
pub time_added: Timestamp, // when the peer was added to the routing table
pub rpc_stats: RPCStats, // information about RPCs
pub latency: Option<LatencyStats>, // latencies for communications with the peer
pub transfer: TransferStatsDownUp, // Stats for communications with the peer
}
@@ -0,0 +1,83 @@
use super::*;
/// Tunnel identifier
pub type TunnelId = AlignedU64;
#[derive(
Copy,
Clone,
Debug,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
pub enum TunnelMode {
Raw,
Turn,
}
#[derive(
Copy,
Clone,
Debug,
PartialOrd,
PartialEq,
Eq,
Ord,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
pub enum TunnelError {
BadId, // Tunnel ID was rejected
NoEndpoint, // Endpoint was unreachable
RejectedMode, // Endpoint couldn't provide mode
NoCapacity, // Endpoint is full
}
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct TunnelEndpoint {
pub mode: TunnelMode,
pub description: String, // XXX: TODO
}
impl Default for TunnelEndpoint {
fn default() -> Self {
Self {
mode: TunnelMode::Raw,
description: "".to_string(),
}
}
}
#[derive(
Clone, Debug, Default, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct FullTunnel {
pub id: TunnelId,
pub timeout: TimestampDuration,
pub local: TunnelEndpoint,
pub remote: TunnelEndpoint,
}
#[derive(
Clone, Debug, Default, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct PartialTunnel {
pub id: TunnelId,
pub timeout: TimestampDuration,
pub local: TunnelEndpoint,
}
@@ -0,0 +1,88 @@
use super::*;
/// Log level for VeilidCore
#[derive(
Debug,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Copy,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
pub enum VeilidLogLevel {
Error = 1,
Warn,
Info,
Debug,
Trace,
}
impl VeilidLogLevel {
pub fn from_tracing_level(level: tracing::Level) -> VeilidLogLevel {
match level {
tracing::Level::ERROR => VeilidLogLevel::Error,
tracing::Level::WARN => VeilidLogLevel::Warn,
tracing::Level::INFO => VeilidLogLevel::Info,
tracing::Level::DEBUG => VeilidLogLevel::Debug,
tracing::Level::TRACE => VeilidLogLevel::Trace,
}
}
pub fn from_log_level(level: log::Level) -> VeilidLogLevel {
match level {
log::Level::Error => VeilidLogLevel::Error,
log::Level::Warn => VeilidLogLevel::Warn,
log::Level::Info => VeilidLogLevel::Info,
log::Level::Debug => VeilidLogLevel::Debug,
log::Level::Trace => VeilidLogLevel::Trace,
}
}
pub fn to_tracing_level(&self) -> tracing::Level {
match self {
Self::Error => tracing::Level::ERROR,
Self::Warn => tracing::Level::WARN,
Self::Info => tracing::Level::INFO,
Self::Debug => tracing::Level::DEBUG,
Self::Trace => tracing::Level::TRACE,
}
}
pub fn to_log_level(&self) -> log::Level {
match self {
Self::Error => log::Level::Error,
Self::Warn => log::Level::Warn,
Self::Info => log::Level::Info,
Self::Debug => log::Level::Debug,
Self::Trace => log::Level::Trace,
}
}
}
impl fmt::Display for VeilidLogLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
let text = match self {
Self::Error => "ERROR",
Self::Warn => "WARN",
Self::Info => "INFO",
Self::Debug => "DEBUG",
Self::Trace => "TRACE",
};
write!(f, "{}", text)
}
}
/// A VeilidCore log message with optional backtrace
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidLog {
pub log_level: VeilidLogLevel,
pub message: String,
pub backtrace: Option<String>,
}
@@ -0,0 +1,144 @@
use super::*;
/// Attachment abstraction for network 'signal strength'
#[derive(
Debug,
PartialEq,
Eq,
Clone,
Copy,
Serialize,
Deserialize,
RkyvArchive,
RkyvSerialize,
RkyvDeserialize,
)]
#[archive_attr(repr(u8), derive(CheckBytes))]
pub enum AttachmentState {
Detached,
Attaching,
AttachedWeak,
AttachedGood,
AttachedStrong,
FullyAttached,
OverAttached,
Detaching,
}
impl fmt::Display for AttachmentState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
let out = match self {
AttachmentState::Attaching => "attaching".to_owned(),
AttachmentState::AttachedWeak => "attached_weak".to_owned(),
AttachmentState::AttachedGood => "attached_good".to_owned(),
AttachmentState::AttachedStrong => "attached_strong".to_owned(),
AttachmentState::FullyAttached => "fully_attached".to_owned(),
AttachmentState::OverAttached => "over_attached".to_owned(),
AttachmentState::Detaching => "detaching".to_owned(),
AttachmentState::Detached => "detached".to_owned(),
};
write!(f, "{}", out)
}
}
impl TryFrom<String> for AttachmentState {
type Error = ();
fn try_from(s: String) -> Result<Self, Self::Error> {
Ok(match s.as_str() {
"attaching" => AttachmentState::Attaching,
"attached_weak" => AttachmentState::AttachedWeak,
"attached_good" => AttachmentState::AttachedGood,
"attached_strong" => AttachmentState::AttachedStrong,
"fully_attached" => AttachmentState::FullyAttached,
"over_attached" => AttachmentState::OverAttached,
"detaching" => AttachmentState::Detaching,
"detached" => AttachmentState::Detached,
_ => return Err(()),
})
}
}
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidStateAttachment {
pub state: AttachmentState,
pub public_internet_ready: bool,
pub local_network_ready: bool,
}
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct PeerTableData {
pub node_ids: Vec<TypedKey>,
pub peer_address: String,
pub peer_stats: PeerStats,
}
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidStateNetwork {
pub started: bool,
#[serde(with = "json_as_string")]
pub bps_down: ByteCount,
#[serde(with = "json_as_string")]
pub bps_up: ByteCount,
pub peers: Vec<PeerTableData>,
}
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidRouteChange {
pub dead_routes: Vec<RouteId>,
pub dead_remote_routes: Vec<RouteId>,
}
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidStateConfig {
pub config: VeilidConfigInner,
}
#[derive(
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidValueChange {
key: TypedKey,
subkeys: Vec<ValueSubkey>,
count: u32,
value: ValueData,
}
#[derive(Debug, Clone, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[archive_attr(repr(u8), derive(CheckBytes))]
#[serde(tag = "kind")]
pub enum VeilidUpdate {
Log(VeilidLog),
AppMessage(VeilidAppMessage),
AppCall(VeilidAppCall),
Attachment(VeilidStateAttachment),
Network(VeilidStateNetwork),
Config(VeilidStateConfig),
RouteChange(VeilidRouteChange),
ValueChange(VeilidValueChange),
Shutdown,
}
#[derive(Debug, Clone, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[archive_attr(repr(C), derive(CheckBytes))]
pub struct VeilidState {
pub attachment: VeilidStateAttachment,
pub network: VeilidStateNetwork,
pub config: VeilidStateConfig,
}