mirror of
https://gitlab.com/veilid/veilid.git
synced 2024-10-01 01:26:08 -04:00
Merge branch 'safety-by-default' into 'main'
Safety by default See merge request veilid/veilid!235
This commit is contained in:
commit
765ecee450
@ -372,7 +372,51 @@ impl ConnectionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Callbacks
|
/// Asynchronous Event Processor
|
||||||
|
|
||||||
|
async fn process_connection_manager_event(
|
||||||
|
&self,
|
||||||
|
event: ConnectionManagerEvent,
|
||||||
|
allow_accept: bool,
|
||||||
|
) {
|
||||||
|
match event {
|
||||||
|
ConnectionManagerEvent::Accepted(prot_conn) => {
|
||||||
|
if !allow_accept {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Async lock on the remote address for atomicity per remote
|
||||||
|
let _lock_guard = self
|
||||||
|
.arc
|
||||||
|
.address_lock_table
|
||||||
|
.lock_tag(prot_conn.flow().remote_address().socket_addr())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let mut inner = self.arc.inner.lock();
|
||||||
|
match &mut *inner {
|
||||||
|
Some(inner) => {
|
||||||
|
// Register the connection
|
||||||
|
// We don't care if this fails, since nobody here asked for the inbound connection.
|
||||||
|
// If it does, we just drop the connection
|
||||||
|
|
||||||
|
let _ = self.on_new_protocol_network_connection(inner, prot_conn);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// If this somehow happens, we're shutting down
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
ConnectionManagerEvent::Dead(mut conn) => {
|
||||||
|
let _lock_guard = self
|
||||||
|
.arc
|
||||||
|
.address_lock_table
|
||||||
|
.lock_tag(conn.flow().remote_address().socket_addr())
|
||||||
|
.await;
|
||||||
|
|
||||||
|
conn.close();
|
||||||
|
conn.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip_all)]
|
#[instrument(level = "trace", skip_all)]
|
||||||
async fn async_processor(
|
async fn async_processor(
|
||||||
@ -382,40 +426,11 @@ impl ConnectionManager {
|
|||||||
) {
|
) {
|
||||||
// Process async commands
|
// Process async commands
|
||||||
while let Ok(Ok(event)) = receiver.recv_async().timeout_at(stop_token.clone()).await {
|
while let Ok(Ok(event)) = receiver.recv_async().timeout_at(stop_token.clone()).await {
|
||||||
match event {
|
self.process_connection_manager_event(event, true).await;
|
||||||
ConnectionManagerEvent::Accepted(prot_conn) => {
|
}
|
||||||
// Async lock on the remote address for atomicity per remote
|
// Ensure receiver is drained completely
|
||||||
let _lock_guard = self
|
for event in receiver.drain() {
|
||||||
.arc
|
self.process_connection_manager_event(event, false).await;
|
||||||
.address_lock_table
|
|
||||||
.lock_tag(prot_conn.flow().remote_address().socket_addr())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let mut inner = self.arc.inner.lock();
|
|
||||||
match &mut *inner {
|
|
||||||
Some(inner) => {
|
|
||||||
// Register the connection
|
|
||||||
// We don't care if this fails, since nobody here asked for the inbound connection.
|
|
||||||
// If it does, we just drop the connection
|
|
||||||
|
|
||||||
let _ = self.on_new_protocol_network_connection(inner, prot_conn);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
// If this somehow happens, we're shutting down
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
ConnectionManagerEvent::Dead(mut conn) => {
|
|
||||||
let _lock_guard = self
|
|
||||||
.arc
|
|
||||||
.address_lock_table
|
|
||||||
.lock_tag(conn.flow().remote_address().socket_addr())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
conn.close();
|
|
||||||
conn.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,35 +11,55 @@ lazy_static! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_get_dht_value_unopened(api: VeilidAPI) {
|
pub async fn test_get_dht_value_unopened(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_open_dht_record_nonexistent_no_writer(api: VeilidAPI) {
|
pub async fn test_open_dht_record_nonexistent_no_writer(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
let result = rc.get_dht_value(*BOGUS_KEY, 0, false).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_close_dht_record_nonexistent(api: VeilidAPI) {
|
pub async fn test_close_dht_record_nonexistent(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let result = rc.close_dht_record(*BOGUS_KEY).await;
|
let result = rc.close_dht_record(*BOGUS_KEY).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_delete_dht_record_nonexistent(api: VeilidAPI) {
|
pub async fn test_delete_dht_record_nonexistent(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let result = rc.delete_dht_record(*BOGUS_KEY).await;
|
let result = rc.delete_dht_record(*BOGUS_KEY).await;
|
||||||
assert_err!(result);
|
assert_err!(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_create_delete_dht_record_simple(api: VeilidAPI) {
|
pub async fn test_create_delete_dht_record_simple(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(
|
.create_dht_record(
|
||||||
@ -55,7 +75,11 @@ pub async fn test_create_delete_dht_record_simple(api: VeilidAPI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_get_dht_value_nonexistent(api: VeilidAPI) {
|
pub async fn test_get_dht_value_nonexistent(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(
|
.create_dht_record(
|
||||||
@ -73,7 +97,11 @@ pub async fn test_get_dht_value_nonexistent(api: VeilidAPI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_set_get_dht_value(api: VeilidAPI) {
|
pub async fn test_set_get_dht_value(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(
|
.create_dht_record(
|
||||||
@ -124,7 +152,11 @@ pub async fn test_set_get_dht_value(api: VeilidAPI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_open_writer_dht_value(api: VeilidAPI) {
|
pub async fn test_open_writer_dht_value(api: VeilidAPI) {
|
||||||
let rc = api.routing_context();
|
let rc = api
|
||||||
|
.routing_context()
|
||||||
|
.unwrap()
|
||||||
|
.with_safety(SafetySelection::Unsafe(Sequencing::EnsureOrdered))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let rec = rc
|
let rec = rc
|
||||||
.create_dht_record(
|
.create_dht_record(
|
||||||
|
@ -189,8 +189,8 @@ impl VeilidAPI {
|
|||||||
// Routing Context
|
// Routing Context
|
||||||
|
|
||||||
/// Get a new `RoutingContext` object to use to send messages over the Veilid network.
|
/// Get a new `RoutingContext` object to use to send messages over the Veilid network.
|
||||||
pub fn routing_context(&self) -> RoutingContext {
|
pub fn routing_context(&self) -> VeilidAPIResult<RoutingContext> {
|
||||||
RoutingContext::new(self.clone())
|
RoutingContext::try_new(self.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a string into a target object that can be used in a [RoutingContext]
|
/// Parse a string into a target object that can be used in a [RoutingContext]
|
||||||
@ -234,8 +234,8 @@ impl VeilidAPI {
|
|||||||
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,
|
||||||
Stability::default(),
|
Stability::Reliable,
|
||||||
Sequencing::default(),
|
Sequencing::PreferOrdered,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -1394,10 +1394,10 @@ impl VeilidAPI {
|
|||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
// Get routing context with optional privacy
|
// Get routing context with optional safety
|
||||||
let rc = self.routing_context();
|
let rc = self.routing_context()?;
|
||||||
let rc = if let Some(ss) = ss {
|
let rc = if let Some(ss) = ss {
|
||||||
match rc.with_custom_privacy(ss) {
|
match rc.with_safety(ss) {
|
||||||
Err(e) => return Ok(format!("Can't use safety selection: {}", e)),
|
Err(e) => return Ok(format!("Can't use safety selection: {}", e)),
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
}
|
}
|
||||||
@ -1453,9 +1453,9 @@ impl VeilidAPI {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get routing context with optional privacy
|
// Get routing context with optional privacy
|
||||||
let rc = self.routing_context();
|
let rc = self.routing_context()?;
|
||||||
let rc = if let Some(ss) = ss {
|
let rc = if let Some(ss) = ss {
|
||||||
match rc.with_custom_privacy(ss) {
|
match rc.with_safety(ss) {
|
||||||
Err(e) => return Ok(format!("Can't use safety selection: {}", e)),
|
Err(e) => return Ok(format!("Can't use safety selection: {}", e)),
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
}
|
}
|
||||||
@ -1514,9 +1514,9 @@ impl VeilidAPI {
|
|||||||
let data = get_debug_argument_at(&args, 4, "debug_record_set", "data", get_data)?;
|
let data = get_debug_argument_at(&args, 4, "debug_record_set", "data", get_data)?;
|
||||||
|
|
||||||
// Get routing context with optional privacy
|
// Get routing context with optional privacy
|
||||||
let rc = self.routing_context();
|
let rc = self.routing_context()?;
|
||||||
let rc = if let Some(ss) = ss {
|
let rc = if let Some(ss) = ss {
|
||||||
match rc.with_custom_privacy(ss) {
|
match rc.with_safety(ss) {
|
||||||
Err(e) => return Ok(format!("Can't use safety selection: {}", e)),
|
Err(e) => return Ok(format!("Can't use safety selection: {}", e)),
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
}
|
}
|
||||||
@ -1560,7 +1560,7 @@ impl VeilidAPI {
|
|||||||
let key = get_debug_argument_at(&args, 1, "debug_record_delete", "key", get_typed_key)?;
|
let key = get_debug_argument_at(&args, 1, "debug_record_delete", "key", get_typed_key)?;
|
||||||
|
|
||||||
// Do a record delete
|
// Do a record delete
|
||||||
let rc = self.routing_context();
|
let rc = self.routing_context()?;
|
||||||
match rc.delete_dht_record(key).await {
|
match rc.delete_dht_record(key).await {
|
||||||
Err(e) => return Ok(format!("Can't delete DHT record: {}", e)),
|
Err(e) => return Ok(format!("Can't delete DHT record: {}", e)),
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
|
@ -173,7 +173,8 @@ pub enum ResponseOp {
|
|||||||
},
|
},
|
||||||
// Routing Context
|
// Routing Context
|
||||||
NewRoutingContext {
|
NewRoutingContext {
|
||||||
value: u32,
|
#[serde(flatten)]
|
||||||
|
result: ApiResult<u32>,
|
||||||
},
|
},
|
||||||
RoutingContext(Box<RoutingContextResponse>),
|
RoutingContext(Box<RoutingContextResponse>),
|
||||||
// TableDb
|
// TableDb
|
||||||
|
@ -235,20 +235,22 @@ impl JsonRequestProcessor {
|
|||||||
self.release_routing_context(rcr.rc_id);
|
self.release_routing_context(rcr.rc_id);
|
||||||
RoutingContextResponseOp::Release {}
|
RoutingContextResponseOp::Release {}
|
||||||
}
|
}
|
||||||
RoutingContextRequestOp::WithPrivacy => RoutingContextResponseOp::WithPrivacy {
|
RoutingContextRequestOp::WithDefaultSafety => {
|
||||||
result: to_json_api_result(
|
RoutingContextResponseOp::WithDefaultSafety {
|
||||||
routing_context
|
|
||||||
.clone()
|
|
||||||
.with_privacy()
|
|
||||||
.map(|new_rc| self.add_routing_context(new_rc)),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
RoutingContextRequestOp::WithCustomPrivacy { safety_selection } => {
|
|
||||||
RoutingContextResponseOp::WithCustomPrivacy {
|
|
||||||
result: to_json_api_result(
|
result: to_json_api_result(
|
||||||
routing_context
|
routing_context
|
||||||
.clone()
|
.clone()
|
||||||
.with_custom_privacy(safety_selection)
|
.with_default_safety()
|
||||||
|
.map(|new_rc| self.add_routing_context(new_rc)),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RoutingContextRequestOp::WithSafety { safety_selection } => {
|
||||||
|
RoutingContextResponseOp::WithSafety {
|
||||||
|
result: to_json_api_result(
|
||||||
|
routing_context
|
||||||
|
.clone()
|
||||||
|
.with_safety(safety_selection)
|
||||||
.map(|new_rc| self.add_routing_context(new_rc)),
|
.map(|new_rc| self.add_routing_context(new_rc)),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -259,6 +261,9 @@ impl JsonRequestProcessor {
|
|||||||
.add_routing_context(routing_context.clone().with_sequencing(sequencing)),
|
.add_routing_context(routing_context.clone().with_sequencing(sequencing)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RoutingContextRequestOp::Safety => RoutingContextResponseOp::Safety {
|
||||||
|
value: routing_context.safety(),
|
||||||
|
},
|
||||||
RoutingContextRequestOp::AppCall { target, message } => {
|
RoutingContextRequestOp::AppCall { target, message } => {
|
||||||
RoutingContextResponseOp::AppCall {
|
RoutingContextResponseOp::AppCall {
|
||||||
result: to_json_api_result_with_vec_u8(
|
result: to_json_api_result_with_vec_u8(
|
||||||
@ -597,7 +602,11 @@ impl JsonRequestProcessor {
|
|||||||
result: to_json_api_result(self.api.app_call_reply(call_id, message).await),
|
result: to_json_api_result(self.api.app_call_reply(call_id, message).await),
|
||||||
},
|
},
|
||||||
RequestOp::NewRoutingContext => ResponseOp::NewRoutingContext {
|
RequestOp::NewRoutingContext => ResponseOp::NewRoutingContext {
|
||||||
value: self.add_routing_context(self.api.routing_context()),
|
result: to_json_api_result(
|
||||||
|
self.api
|
||||||
|
.routing_context()
|
||||||
|
.map(|rc| self.add_routing_context(rc)),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
RequestOp::RoutingContext(rcr) => {
|
RequestOp::RoutingContext(rcr) => {
|
||||||
let routing_context = match self.lookup_routing_context(id, rcr.rc_id) {
|
let routing_context = match self.lookup_routing_context(id, rcr.rc_id) {
|
||||||
|
@ -18,13 +18,14 @@ pub struct RoutingContextResponse {
|
|||||||
#[serde(tag = "rc_op")]
|
#[serde(tag = "rc_op")]
|
||||||
pub enum RoutingContextRequestOp {
|
pub enum RoutingContextRequestOp {
|
||||||
Release,
|
Release,
|
||||||
WithPrivacy,
|
WithDefaultSafety,
|
||||||
WithCustomPrivacy {
|
WithSafety {
|
||||||
safety_selection: SafetySelection,
|
safety_selection: SafetySelection,
|
||||||
},
|
},
|
||||||
WithSequencing {
|
WithSequencing {
|
||||||
sequencing: Sequencing,
|
sequencing: Sequencing,
|
||||||
},
|
},
|
||||||
|
Safety,
|
||||||
AppCall {
|
AppCall {
|
||||||
target: String,
|
target: String,
|
||||||
#[serde(with = "as_human_base64")]
|
#[serde(with = "as_human_base64")]
|
||||||
@ -88,17 +89,20 @@ pub enum RoutingContextRequestOp {
|
|||||||
pub enum RoutingContextResponseOp {
|
pub enum RoutingContextResponseOp {
|
||||||
InvalidId,
|
InvalidId,
|
||||||
Release,
|
Release,
|
||||||
WithPrivacy {
|
WithDefaultSafety {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
result: ApiResult<u32>,
|
result: ApiResult<u32>,
|
||||||
},
|
},
|
||||||
WithCustomPrivacy {
|
WithSafety {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
result: ApiResult<u32>,
|
result: ApiResult<u32>,
|
||||||
},
|
},
|
||||||
WithSequencing {
|
WithSequencing {
|
||||||
value: u32,
|
value: u32,
|
||||||
},
|
},
|
||||||
|
Safety {
|
||||||
|
value: SafetySelection,
|
||||||
|
},
|
||||||
AppCall {
|
AppCall {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
#[schemars(with = "ApiResult<String>")]
|
#[schemars(with = "ApiResult<String>")]
|
||||||
|
@ -21,9 +21,9 @@ pub struct RoutingContextUnlockedInner {
|
|||||||
|
|
||||||
/// Routing contexts are the way you specify the communication preferences for Veilid.
|
/// 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
|
/// By default routing contexts have 'safety routing' enabled which offers sender privacy.
|
||||||
/// privacy, use [RoutingContext::with_privacy()]. To enable receiver privacy, you should send to a private route RouteId that you have
|
/// privacy. To disable this and send RPC operations straight from the node use [RoutingContext::with_safety()] with a [SafetySelection::Unsafe] parameter.
|
||||||
/// imported, rather than directly to a NodeId.
|
/// 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 {
|
||||||
@ -36,39 +36,48 @@ pub struct RoutingContext {
|
|||||||
impl RoutingContext {
|
impl RoutingContext {
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub(super) fn new(api: VeilidAPI) -> Self {
|
pub(super) fn try_new(api: VeilidAPI) -> VeilidAPIResult<Self> {
|
||||||
Self {
|
let config = api.config()?;
|
||||||
|
let c = config.get();
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
api,
|
api,
|
||||||
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
||||||
unlocked_inner: Arc::new(RoutingContextUnlockedInner {
|
unlocked_inner: Arc::new(RoutingContextUnlockedInner {
|
||||||
safety_selection: SafetySelection::Unsafe(Sequencing::default()),
|
safety_selection: SafetySelection::Safe(SafetySpec {
|
||||||
|
preferred_route: None,
|
||||||
|
hop_count: c.network.rpc.default_route_hop_count as usize,
|
||||||
|
stability: Stability::default(),
|
||||||
|
sequencing: Sequencing::PreferOrdered,
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn on sender privacy, enabling the use of safety routes.
|
/// Turn on sender privacy, enabling the use of safety routes. This is the default and
|
||||||
|
/// calling this function is only necessary if you have previously disable safety or used other parameters.
|
||||||
///
|
///
|
||||||
/// Default values for hop count, stability and sequencing preferences are used.
|
/// 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.
|
/// * 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.
|
/// * 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
|
/// * Sequencing default is to prefer ordered before unordered message delivery
|
||||||
///
|
///
|
||||||
/// To modify these defaults, use [RoutingContext::with_custom_privacy()].
|
/// To customize the safety selection in use, use [RoutingContext::with_safety()].
|
||||||
pub fn with_privacy(self) -> VeilidAPIResult<Self> {
|
pub fn with_default_safety(self) -> VeilidAPIResult<Self> {
|
||||||
let config = self.api.config()?;
|
let config = self.api.config()?;
|
||||||
let c = config.get();
|
let c = config.get();
|
||||||
|
|
||||||
self.with_custom_privacy(SafetySelection::Safe(SafetySpec {
|
self.with_safety(SafetySelection::Safe(SafetySpec {
|
||||||
preferred_route: None,
|
preferred_route: None,
|
||||||
hop_count: c.network.rpc.default_route_hop_count as usize,
|
hop_count: c.network.rpc.default_route_hop_count as usize,
|
||||||
stability: Stability::default(),
|
stability: Stability::default(),
|
||||||
sequencing: Sequencing::default(),
|
sequencing: Sequencing::PreferOrdered,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn on privacy using a custom [SafetySelection]
|
/// Use a custom [SafetySelection]. Can be used to disable safety via [SafetySelection::Unsafe]
|
||||||
pub fn with_custom_privacy(self, safety_selection: SafetySelection) -> VeilidAPIResult<Self> {
|
pub fn with_safety(self, safety_selection: SafetySelection) -> VeilidAPIResult<Self> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
api: self.api.clone(),
|
api: self.api.clone(),
|
||||||
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
inner: Arc::new(Mutex::new(RoutingContextInner {})),
|
||||||
@ -95,6 +104,11 @@ impl RoutingContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the safety selection in use on this routing context
|
||||||
|
pub fn safety(&self) -> SafetySelection {
|
||||||
|
self.unlocked_inner.safety_selection
|
||||||
|
}
|
||||||
|
|
||||||
fn sequencing(&self) -> Sequencing {
|
fn sequencing(&self) -> Sequencing {
|
||||||
match self.unlocked_inner.safety_selection {
|
match self.unlocked_inner.safety_selection {
|
||||||
SafetySelection::Unsafe(sequencing) => sequencing,
|
SafetySelection::Unsafe(sequencing) => sequencing,
|
||||||
|
@ -37,7 +37,12 @@ impl Default for Stability {
|
|||||||
#[derive(
|
#[derive(
|
||||||
Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
|
Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(target_arch = "wasm32", derive(Tsify), tsify(from_wasm_abi, namespace))]
|
#[cfg_attr(
|
||||||
|
target_arch = "wasm32",
|
||||||
|
derive(Tsify),
|
||||||
|
tsify(from_wasm_abi, into_wasm_abi, namespace)
|
||||||
|
)]
|
||||||
|
|
||||||
pub enum SafetySelection {
|
pub enum SafetySelection {
|
||||||
/// Don't use a safety route, only specify the sequencing preference
|
/// Don't use a safety route, only specify the sequencing preference
|
||||||
Unsafe(Sequencing),
|
Unsafe(Sequencing),
|
||||||
|
@ -239,9 +239,10 @@ abstract class VeilidRoutingContext {
|
|||||||
void close();
|
void close();
|
||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
VeilidRoutingContext withPrivacy();
|
VeilidRoutingContext withDefaultSafety();
|
||||||
VeilidRoutingContext withCustomPrivacy(SafetySelection safetySelection);
|
VeilidRoutingContext withSafety(SafetySelection safetySelection);
|
||||||
VeilidRoutingContext withSequencing(Sequencing sequencing);
|
VeilidRoutingContext withSequencing(Sequencing sequencing);
|
||||||
|
Future<SafetySelection> safety();
|
||||||
|
|
||||||
// App call/message
|
// App call/message
|
||||||
Future<Uint8List> appCall(String target, Uint8List request);
|
Future<Uint8List> appCall(String target, Uint8List request);
|
||||||
|
@ -45,12 +45,15 @@ typedef _DetachDart = void Function(int);
|
|||||||
typedef _RoutingContextDart = void Function(int);
|
typedef _RoutingContextDart = void Function(int);
|
||||||
// fn release_routing_context(id: u32)
|
// fn release_routing_context(id: u32)
|
||||||
typedef _ReleaseRoutingContextDart = int Function(int);
|
typedef _ReleaseRoutingContextDart = int Function(int);
|
||||||
// fn routing_context_with_privacy(id: u32) -> u32
|
// fn routing_context_with_default_safety(id: u32) -> u32
|
||||||
typedef _RoutingContextWithPrivacyDart = int Function(int);
|
typedef _RoutingContextWithDefaultSafetyDart = int Function(int);
|
||||||
// fn routing_context_with_custom_privacy(id: u32, stability: FfiStr)
|
// fn routing_context_with_safety(id: u32, stability: FfiStr)
|
||||||
typedef _RoutingContextWithCustomPrivacyDart = int Function(int, Pointer<Utf8>);
|
typedef _RoutingContextWithSafetyDart = int Function(int, Pointer<Utf8>);
|
||||||
// fn routing_context_with_sequencing(id: u32, sequencing: FfiStr)
|
// fn routing_context_with_sequencing(id: u32, sequencing: FfiStr)
|
||||||
typedef _RoutingContextWithSequencingDart = int Function(int, Pointer<Utf8>);
|
typedef _RoutingContextWithSequencingDart = int Function(int, Pointer<Utf8>);
|
||||||
|
// fn routing_context_safety(port: i64,
|
||||||
|
// id: u32)
|
||||||
|
typedef _RoutingContextSafetyDart = void Function(int, int);
|
||||||
// fn routing_context_app_call(port: i64,
|
// fn routing_context_app_call(port: i64,
|
||||||
// id: u32, target: FfiStr, request: FfiStr)
|
// id: u32, target: FfiStr, request: FfiStr)
|
||||||
typedef _RoutingContextAppCallDart = void Function(
|
typedef _RoutingContextAppCallDart = void Function(
|
||||||
@ -525,16 +528,16 @@ class VeilidRoutingContextFFI extends VeilidRoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
VeilidRoutingContextFFI withPrivacy() {
|
VeilidRoutingContextFFI withDefaultSafety() {
|
||||||
_ctx.ensureValid();
|
_ctx.ensureValid();
|
||||||
final newId = _ctx.ffi._routingContextWithPrivacy(_ctx.id!);
|
final newId = _ctx.ffi._routingContextWithDefaultSafety(_ctx.id!);
|
||||||
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
VeilidRoutingContextFFI withCustomPrivacy(SafetySelection safetySelection) {
|
VeilidRoutingContextFFI withSafety(SafetySelection safetySelection) {
|
||||||
_ctx.ensureValid();
|
_ctx.ensureValid();
|
||||||
final newId = _ctx.ffi._routingContextWithCustomPrivacy(
|
final newId = _ctx.ffi._routingContextWithSafety(
|
||||||
_ctx.id!, jsonEncode(safetySelection).toNativeUtf8());
|
_ctx.id!, jsonEncode(safetySelection).toNativeUtf8());
|
||||||
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
||||||
}
|
}
|
||||||
@ -547,6 +550,17 @@ class VeilidRoutingContextFFI extends VeilidRoutingContext {
|
|||||||
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<SafetySelection> safety() async {
|
||||||
|
_ctx.ensureValid();
|
||||||
|
final recvPort = ReceivePort('routing_context_safety');
|
||||||
|
final sendPort = recvPort.sendPort;
|
||||||
|
_ctx.ffi._routingContextSafety(sendPort.nativePort, _ctx.id!);
|
||||||
|
final out = await processFutureJson<SafetySelection>(
|
||||||
|
SafetySelection.fromJson, recvPort.first);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Uint8List> appCall(String target, Uint8List request) async {
|
Future<Uint8List> appCall(String target, Uint8List request) async {
|
||||||
_ctx.ensureValid();
|
_ctx.ensureValid();
|
||||||
@ -1175,17 +1189,19 @@ class VeilidFFI extends Veilid {
|
|||||||
'routing_context'),
|
'routing_context'),
|
||||||
_releaseRoutingContext = dylib.lookupFunction<Int32 Function(Uint32),
|
_releaseRoutingContext = dylib.lookupFunction<Int32 Function(Uint32),
|
||||||
_ReleaseRoutingContextDart>('release_routing_context'),
|
_ReleaseRoutingContextDart>('release_routing_context'),
|
||||||
_routingContextWithPrivacy = dylib.lookupFunction<
|
_routingContextWithDefaultSafety = dylib.lookupFunction<
|
||||||
Uint32 Function(Uint32),
|
Uint32 Function(Uint32), _RoutingContextWithDefaultSafetyDart>(
|
||||||
_RoutingContextWithPrivacyDart>('routing_context_with_privacy'),
|
'routing_context_with_default_safety'),
|
||||||
_routingContextWithCustomPrivacy = dylib.lookupFunction<
|
_routingContextWithSafety = dylib.lookupFunction<
|
||||||
Uint32 Function(Uint32, Pointer<Utf8>),
|
Uint32 Function(Uint32, Pointer<Utf8>),
|
||||||
_RoutingContextWithCustomPrivacyDart>(
|
_RoutingContextWithSafetyDart>('routing_context_with_safety'),
|
||||||
'routing_context_with_custom_privacy'),
|
|
||||||
_routingContextWithSequencing = dylib.lookupFunction<
|
_routingContextWithSequencing = dylib.lookupFunction<
|
||||||
Uint32 Function(Uint32, Pointer<Utf8>),
|
Uint32 Function(Uint32, Pointer<Utf8>),
|
||||||
_RoutingContextWithSequencingDart>(
|
_RoutingContextWithSequencingDart>(
|
||||||
'routing_context_with_sequencing'),
|
'routing_context_with_sequencing'),
|
||||||
|
_routingContextSafety = dylib.lookupFunction<
|
||||||
|
Void Function(Int64, Uint32),
|
||||||
|
_RoutingContextSafetyDart>('routing_context_safety'),
|
||||||
_routingContextAppCall = dylib.lookupFunction<
|
_routingContextAppCall = dylib.lookupFunction<
|
||||||
Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
|
Void Function(Int64, Uint32, Pointer<Utf8>, Pointer<Utf8>),
|
||||||
_RoutingContextAppCallDart>('routing_context_app_call'),
|
_RoutingContextAppCallDart>('routing_context_app_call'),
|
||||||
@ -1383,9 +1399,10 @@ class VeilidFFI extends Veilid {
|
|||||||
|
|
||||||
final _RoutingContextDart _routingContext;
|
final _RoutingContextDart _routingContext;
|
||||||
final _ReleaseRoutingContextDart _releaseRoutingContext;
|
final _ReleaseRoutingContextDart _releaseRoutingContext;
|
||||||
final _RoutingContextWithPrivacyDart _routingContextWithPrivacy;
|
final _RoutingContextWithDefaultSafetyDart _routingContextWithDefaultSafety;
|
||||||
final _RoutingContextWithCustomPrivacyDart _routingContextWithCustomPrivacy;
|
final _RoutingContextWithSafetyDart _routingContextWithSafety;
|
||||||
final _RoutingContextWithSequencingDart _routingContextWithSequencing;
|
final _RoutingContextWithSequencingDart _routingContextWithSequencing;
|
||||||
|
final _RoutingContextSafetyDart _routingContextSafety;
|
||||||
final _RoutingContextAppCallDart _routingContextAppCall;
|
final _RoutingContextAppCallDart _routingContextAppCall;
|
||||||
final _RoutingContextAppMessageDart _routingContextAppMessage;
|
final _RoutingContextAppMessageDart _routingContextAppMessage;
|
||||||
final _RoutingContextCreateDHTRecordDart _routingContextCreateDHTRecord;
|
final _RoutingContextCreateDHTRecordDart _routingContextCreateDHTRecord;
|
||||||
|
@ -68,20 +68,18 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
VeilidRoutingContextJS withPrivacy() {
|
VeilidRoutingContextJS withDefaultSafety() {
|
||||||
final id = _ctx.requireId();
|
final id = _ctx.requireId();
|
||||||
final int newId =
|
final int newId =
|
||||||
js_util.callMethod(wasm, 'routing_context_with_privacy', [id]);
|
js_util.callMethod(wasm, 'routing_context_with_default_safety', [id]);
|
||||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
VeilidRoutingContextJS withCustomPrivacy(SafetySelection safetySelection) {
|
VeilidRoutingContextJS withSafety(SafetySelection safetySelection) {
|
||||||
final id = _ctx.requireId();
|
final id = _ctx.requireId();
|
||||||
final newId = js_util.callMethod<int>(
|
final newId = js_util.callMethod<int>(
|
||||||
wasm,
|
wasm, 'routing_context_with_safety', [id, jsonEncode(safetySelection)]);
|
||||||
'routing_context_with_custom_privacy',
|
|
||||||
[id, jsonEncode(safetySelection)]);
|
|
||||||
|
|
||||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||||
}
|
}
|
||||||
@ -94,6 +92,15 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
|
|||||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<SafetySelection> safety() async {
|
||||||
|
final id = _ctx.requireId();
|
||||||
|
return SafetySelection.fromJson(jsonDecode(await _wrapApiPromise(
|
||||||
|
js_util.callMethod(wasm, 'routing_context_safety', [
|
||||||
|
id,
|
||||||
|
]))));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Uint8List> appCall(String target, Uint8List request) async {
|
Future<Uint8List> appCall(String target, Uint8List request) async {
|
||||||
final id = _ctx.requireId();
|
final id = _ctx.requireId();
|
||||||
|
@ -407,7 +407,7 @@ fn add_routing_context(
|
|||||||
pub extern "C" fn routing_context(port: i64) {
|
pub extern "C" fn routing_context(port: i64) {
|
||||||
DartIsolateWrapper::new(port).spawn_result(async move {
|
DartIsolateWrapper::new(port).spawn_result(async move {
|
||||||
let veilid_api = get_veilid_api().await?;
|
let veilid_api = get_veilid_api().await?;
|
||||||
let routing_context = veilid_api.routing_context();
|
let routing_context = veilid_api.routing_context()?;
|
||||||
let mut rc = ROUTING_CONTEXTS.lock();
|
let mut rc = ROUTING_CONTEXTS.lock();
|
||||||
let new_id = add_routing_context(&mut rc, routing_context);
|
let new_id = add_routing_context(&mut rc, routing_context);
|
||||||
APIResult::Ok(new_id)
|
APIResult::Ok(new_id)
|
||||||
@ -424,12 +424,12 @@ pub extern "C" fn release_routing_context(id: u32) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn routing_context_with_privacy(id: u32) -> u32 {
|
pub extern "C" fn routing_context_with_default_safety(id: u32) -> u32 {
|
||||||
let mut rc = ROUTING_CONTEXTS.lock();
|
let mut rc = ROUTING_CONTEXTS.lock();
|
||||||
let Some(routing_context) = rc.get(&id) else {
|
let Some(routing_context) = rc.get(&id) else {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
let Ok(routing_context) = routing_context.clone().with_privacy() else {
|
let Ok(routing_context) = routing_context.clone().with_default_safety() else {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -437,7 +437,7 @@ pub extern "C" fn routing_context_with_privacy(id: u32) -> u32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn routing_context_with_custom_privacy(id: u32, safety_selection: FfiStr) -> u32 {
|
pub extern "C" fn routing_context_with_safety(id: u32, safety_selection: FfiStr) -> u32 {
|
||||||
let safety_selection: veilid_core::SafetySelection =
|
let safety_selection: veilid_core::SafetySelection =
|
||||||
veilid_core::deserialize_opt_json(safety_selection.into_opt_string()).unwrap();
|
veilid_core::deserialize_opt_json(safety_selection.into_opt_string()).unwrap();
|
||||||
|
|
||||||
@ -445,10 +445,7 @@ pub extern "C" fn routing_context_with_custom_privacy(id: u32, safety_selection:
|
|||||||
let Some(routing_context) = rc.get(&id) else {
|
let Some(routing_context) = rc.get(&id) else {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
let Ok(routing_context) = routing_context
|
let Ok(routing_context) = routing_context.clone().with_safety(safety_selection) else {
|
||||||
.clone()
|
|
||||||
.with_custom_privacy(safety_selection)
|
|
||||||
else {
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -469,6 +466,23 @@ pub extern "C" fn routing_context_with_sequencing(id: u32, sequencing: FfiStr) -
|
|||||||
add_routing_context(&mut rc, routing_context)
|
add_routing_context(&mut rc, routing_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn routing_context_safety(port: i64, id: u32) {
|
||||||
|
DartIsolateWrapper::new(port).spawn_result_json(async move {
|
||||||
|
let routing_context = {
|
||||||
|
let rc = ROUTING_CONTEXTS.lock();
|
||||||
|
let Some(routing_context) = rc.get(&id) else {
|
||||||
|
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument(
|
||||||
|
"routing_context_app_call",
|
||||||
|
"id",
|
||||||
|
id,
|
||||||
|
));
|
||||||
|
};
|
||||||
|
routing_context.clone()
|
||||||
|
};
|
||||||
|
APIResult::Ok(routing_context.safety())
|
||||||
|
});
|
||||||
|
}
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn routing_context_app_call(port: i64, id: u32, target: FfiStr, request: FfiStr) {
|
pub extern "C" fn routing_context_app_call(port: i64, id: u32, target: FfiStr, request: FfiStr) {
|
||||||
let target_string: String = target.into_opt_string().unwrap();
|
let target_string: String = target.into_opt_string().unwrap();
|
||||||
|
@ -22,7 +22,7 @@ async def test_routing_contexts(api_connection: veilid.VeilidAPI):
|
|||||||
|
|
||||||
rc = await api_connection.new_routing_context()
|
rc = await api_connection.new_routing_context()
|
||||||
async with rc:
|
async with rc:
|
||||||
rcp = await rc.with_privacy(release=False)
|
rcp = await rc.with_default_safety(release=False)
|
||||||
async with rcp:
|
async with rcp:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -32,15 +32,15 @@ async def test_routing_contexts(api_connection: veilid.VeilidAPI):
|
|||||||
async with rc:
|
async with rc:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(
|
rc = await (await api_connection.new_routing_context()).with_safety(
|
||||||
veilid.SafetySelection.safe(
|
veilid.SafetySelection.safe(
|
||||||
veilid.SafetySpec(None, 2, veilid.Stability.RELIABLE, veilid.Sequencing.ENSURE_ORDERED)
|
veilid.SafetySpec(None, 2, veilid.Stability.LOW_LATENCY, veilid.Sequencing.NO_PREFERENCE)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await rc.release()
|
await rc.release()
|
||||||
|
|
||||||
rc = await (await api_connection.new_routing_context()).with_custom_privacy(
|
rc = await (await api_connection.new_routing_context()).with_safety(
|
||||||
veilid.SafetySelection.unsafe(veilid.Sequencing.ENSURE_ORDERED)
|
veilid.SafetySelection.unsafe(veilid.Sequencing.PREFER_ORDERED)
|
||||||
)
|
)
|
||||||
await rc.release()
|
await rc.release()
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ async def test_routing_context_app_message_loopback():
|
|||||||
await api.debug("purge routes")
|
await api.debug("purge routes")
|
||||||
|
|
||||||
# make a routing context that uses a safety route
|
# make a routing context that uses a safety route
|
||||||
rc = await (await api.new_routing_context()).with_privacy()
|
rc = await api.new_routing_context()
|
||||||
async with rc:
|
async with rc:
|
||||||
# make a new local private route
|
# make a new local private route
|
||||||
prl, blob = await api.new_private_route()
|
prl, blob = await api.new_private_route()
|
||||||
@ -104,10 +104,8 @@ async def test_routing_context_app_call_loopback():
|
|||||||
# purge routes to ensure we start fresh
|
# purge routes to ensure we start fresh
|
||||||
await api.debug("purge routes")
|
await api.debug("purge routes")
|
||||||
|
|
||||||
# make a routing context that uses a safety route
|
# make a routing context
|
||||||
rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(
|
rc = await api.new_routing_context()
|
||||||
veilid.Sequencing.ENSURE_ORDERED
|
|
||||||
)
|
|
||||||
async with rc:
|
async with rc:
|
||||||
# make a new local private route
|
# make a new local private route
|
||||||
prl, blob = await api.new_private_route()
|
prl, blob = await api.new_private_route()
|
||||||
@ -160,15 +158,10 @@ async def test_routing_context_app_message_loopback_big_packets():
|
|||||||
await api.debug("purge routes")
|
await api.debug("purge routes")
|
||||||
|
|
||||||
# make a routing context that uses a safety route
|
# make a routing context that uses a safety route
|
||||||
rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(
|
rc = await api.new_routing_context()
|
||||||
veilid.Sequencing.ENSURE_ORDERED
|
|
||||||
)
|
|
||||||
async with rc:
|
async with rc:
|
||||||
# make a new local private route
|
# make a new local private route
|
||||||
prl, blob = await api.new_custom_private_route(
|
prl, blob = await api.new_private_route()
|
||||||
[veilid.CryptoKind.CRYPTO_KIND_VLD0],
|
|
||||||
veilid.Stability.RELIABLE,
|
|
||||||
veilid.Sequencing.ENSURE_ORDERED)
|
|
||||||
|
|
||||||
# import it as a remote route as well so we can send to it
|
# import it as a remote route as well so we can send to it
|
||||||
prr = await api.import_remote_private_route(blob)
|
prr = await api.import_remote_private_route(blob)
|
||||||
@ -225,7 +218,7 @@ async def test_routing_context_app_call_loopback_big_packets():
|
|||||||
app_call_task = asyncio.create_task(app_call_queue_task_handler(api), name="app call task")
|
app_call_task = asyncio.create_task(app_call_queue_task_handler(api), name="app call task")
|
||||||
|
|
||||||
# make a routing context that uses a safety route
|
# make a routing context that uses a safety route
|
||||||
rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(
|
rc = await (await api.new_routing_context()).with_sequencing(
|
||||||
veilid.Sequencing.ENSURE_ORDERED
|
veilid.Sequencing.ENSURE_ORDERED
|
||||||
)
|
)
|
||||||
async with rc:
|
async with rc:
|
||||||
@ -269,8 +262,6 @@ async def test_routing_context_app_message_loopback_bandwidth():
|
|||||||
await api.debug("purge routes")
|
await api.debug("purge routes")
|
||||||
|
|
||||||
# make a routing context that uses a safety route
|
# make a routing context that uses a safety route
|
||||||
# rc = await (await (await api.new_routing_context()).with_privacy()).with_sequencing(veilid.Sequencing.ENSURE_ORDERED)
|
|
||||||
# rc = await (await api.new_routing_context()).with_privacy()
|
|
||||||
rc = await api.new_routing_context()
|
rc = await api.new_routing_context()
|
||||||
async with rc:
|
async with rc:
|
||||||
# make a new local private route
|
# make a new local private route
|
||||||
|
@ -22,11 +22,11 @@ class RoutingContext(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def with_privacy(self, release=True) -> Self:
|
async def with_default_safety(self, release=True) -> Self:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def with_custom_privacy(
|
async def with_safety(
|
||||||
self, safety_selection: types.SafetySelection, release=True
|
self, safety_selection: types.SafetySelection, release=True
|
||||||
) -> Self:
|
) -> Self:
|
||||||
pass
|
pass
|
||||||
@ -35,6 +35,10 @@ class RoutingContext(ABC):
|
|||||||
async def with_sequencing(self, sequencing: types.Sequencing, release=True) -> Self:
|
async def with_sequencing(self, sequencing: types.Sequencing, release=True) -> Self:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
async def safety(self) -> types.SafetySelection:
|
||||||
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def app_call(self, target: types.TypedKey | types.RouteId, request: bytes) -> bytes:
|
async def app_call(self, target: types.TypedKey | types.RouteId, request: bytes) -> bytes:
|
||||||
pass
|
pass
|
||||||
|
@ -446,26 +446,26 @@ class _JsonRoutingContext(RoutingContext):
|
|||||||
)
|
)
|
||||||
self.done = True
|
self.done = True
|
||||||
|
|
||||||
async def with_privacy(self, release=True) -> Self:
|
async def with_default_safety(self, release=True) -> Self:
|
||||||
new_rc_id = raise_api_result(
|
new_rc_id = raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
Operation.ROUTING_CONTEXT,
|
Operation.ROUTING_CONTEXT,
|
||||||
validate=validate_rc_op,
|
validate=validate_rc_op,
|
||||||
rc_id=self.rc_id,
|
rc_id=self.rc_id,
|
||||||
rc_op=RoutingContextOperation.WITH_PRIVACY,
|
rc_op=RoutingContextOperation.WITH_DEFAULT_SAFETY,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if release:
|
if release:
|
||||||
await self.release()
|
await self.release()
|
||||||
return self.__class__(self.api, new_rc_id)
|
return self.__class__(self.api, new_rc_id)
|
||||||
|
|
||||||
async def with_custom_privacy(self, safety_selection: SafetySelection, release=True) -> Self:
|
async def with_safety(self, safety_selection: SafetySelection, release=True) -> Self:
|
||||||
new_rc_id = raise_api_result(
|
new_rc_id = raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
Operation.ROUTING_CONTEXT,
|
Operation.ROUTING_CONTEXT,
|
||||||
validate=validate_rc_op,
|
validate=validate_rc_op,
|
||||||
rc_id=self.rc_id,
|
rc_id=self.rc_id,
|
||||||
rc_op=RoutingContextOperation.WITH_CUSTOM_PRIVACY,
|
rc_op=RoutingContextOperation.WITH_SAFETY,
|
||||||
safety_selection=safety_selection,
|
safety_selection=safety_selection,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -487,6 +487,19 @@ class _JsonRoutingContext(RoutingContext):
|
|||||||
await self.release()
|
await self.release()
|
||||||
return self.__class__(self.api, new_rc_id)
|
return self.__class__(self.api, new_rc_id)
|
||||||
|
|
||||||
|
async def safety(
|
||||||
|
self
|
||||||
|
) -> SafetySelection:
|
||||||
|
return SafetySelection.from_json(
|
||||||
|
raise_api_result(
|
||||||
|
await self.api.send_ndjson_request(
|
||||||
|
Operation.ROUTING_CONTEXT,
|
||||||
|
validate=validate_rc_op,
|
||||||
|
rc_id=self.rc_id,
|
||||||
|
rc_op=RoutingContextOperation.SAFETY,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
async def app_call(self, target: TypedKey | RouteId, message: bytes) -> bytes:
|
async def app_call(self, target: TypedKey | RouteId, message: bytes) -> bytes:
|
||||||
return urlsafe_b64decode_no_pad(
|
return urlsafe_b64decode_no_pad(
|
||||||
raise_api_result(
|
raise_api_result(
|
||||||
|
@ -33,9 +33,10 @@ class Operation(StrEnum):
|
|||||||
class RoutingContextOperation(StrEnum):
|
class RoutingContextOperation(StrEnum):
|
||||||
INVALID_ID = "InvalidId"
|
INVALID_ID = "InvalidId"
|
||||||
RELEASE = "Release"
|
RELEASE = "Release"
|
||||||
WITH_PRIVACY = "WithPrivacy"
|
WITH_DEFAULT_SAFETY = "WithDefaultSafety"
|
||||||
WITH_CUSTOM_PRIVACY = "WithCustomPrivacy"
|
WITH_SAFETY = "WithSafety"
|
||||||
WITH_SEQUENCING = "WithSequencing"
|
WITH_SEQUENCING = "WithSequencing"
|
||||||
|
SAFETY = "Safety"
|
||||||
APP_CALL = "AppCall"
|
APP_CALL = "AppCall"
|
||||||
APP_MESSAGE = "AppMessage"
|
APP_MESSAGE = "AppMessage"
|
||||||
CREATE_DHT_RECORD = "CreateDhtRecord"
|
CREATE_DHT_RECORD = "CreateDhtRecord"
|
||||||
|
@ -349,9 +349,34 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"value": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"error": {
|
||||||
|
"$ref": "#/definitions/VeilidAPIError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"required": [
|
"required": [
|
||||||
"op",
|
"op"
|
||||||
"value"
|
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"op": {
|
"op": {
|
||||||
@ -359,11 +384,6 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"NewRoutingContext"
|
"NewRoutingContext"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"value": {
|
|
||||||
"type": "integer",
|
|
||||||
"format": "uint32",
|
|
||||||
"minimum": 0.0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -433,7 +453,7 @@
|
|||||||
"rc_op": {
|
"rc_op": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"WithPrivacy"
|
"WithDefaultSafety"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -473,7 +493,7 @@
|
|||||||
"rc_op": {
|
"rc_op": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"WithCustomPrivacy"
|
"WithSafety"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,6 +518,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"rc_op",
|
||||||
|
"value"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"rc_op": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Safety"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"value": {
|
||||||
|
"$ref": "#/definitions/SafetySelection"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
@ -2865,6 +2903,92 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"SafetySelection": {
|
||||||
|
"description": "The choice of safety route to include in compiled routes",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "Don't use a safety route, only specify the sequencing preference",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"Unsafe"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Unsafe": {
|
||||||
|
"$ref": "#/definitions/Sequencing"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Use a safety route and parameters specified by a SafetySpec",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"Safe"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"Safe": {
|
||||||
|
"$ref": "#/definitions/SafetySpec"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SafetySpec": {
|
||||||
|
"description": "Options for safety routes (sender privacy)",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"hop_count",
|
||||||
|
"sequencing",
|
||||||
|
"stability"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"hop_count": {
|
||||||
|
"description": "must be greater than 0",
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint",
|
||||||
|
"minimum": 0.0
|
||||||
|
},
|
||||||
|
"preferred_route": {
|
||||||
|
"description": "preferred safety route set id if it still exists",
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"sequencing": {
|
||||||
|
"description": "prefer connection-oriented sequenced protocols",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/Sequencing"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"stability": {
|
||||||
|
"description": "prefer reliability over speed",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/Stability"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Sequencing": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"NoPreference",
|
||||||
|
"PreferOrdered",
|
||||||
|
"EnsureOrdered"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Stability": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"LowLatency",
|
||||||
|
"Reliable"
|
||||||
|
]
|
||||||
|
},
|
||||||
"TransferStats": {
|
"TransferStats": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -215,7 +215,7 @@
|
|||||||
"rc_op": {
|
"rc_op": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"WithPrivacy"
|
"WithDefaultSafety"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,7 +230,7 @@
|
|||||||
"rc_op": {
|
"rc_op": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"WithCustomPrivacy"
|
"WithSafety"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"safety_selection": {
|
"safety_selection": {
|
||||||
@ -256,6 +256,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"rc_op"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"rc_op": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"Safety"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
@ -328,7 +328,7 @@ fn add_routing_context(routing_context: veilid_core::RoutingContext) -> u32 {
|
|||||||
pub fn routing_context() -> Promise {
|
pub fn routing_context() -> Promise {
|
||||||
wrap_api_future_plain(async move {
|
wrap_api_future_plain(async move {
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
let routing_context = veilid_api.routing_context();
|
let routing_context = veilid_api.routing_context()?;
|
||||||
let new_id = add_routing_context(routing_context);
|
let new_id = add_routing_context(routing_context);
|
||||||
APIResult::Ok(new_id)
|
APIResult::Ok(new_id)
|
||||||
})
|
})
|
||||||
@ -344,7 +344,7 @@ pub fn release_routing_context(id: u32) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen()]
|
#[wasm_bindgen()]
|
||||||
pub fn routing_context_with_privacy(id: u32) -> u32 {
|
pub fn routing_context_with_default_safety(id: u32) -> u32 {
|
||||||
let routing_context = {
|
let routing_context = {
|
||||||
let rc = (*ROUTING_CONTEXTS).borrow();
|
let rc = (*ROUTING_CONTEXTS).borrow();
|
||||||
let Some(routing_context) = rc.get(&id) else {
|
let Some(routing_context) = rc.get(&id) else {
|
||||||
@ -352,14 +352,14 @@ pub fn routing_context_with_privacy(id: u32) -> u32 {
|
|||||||
};
|
};
|
||||||
routing_context.clone()
|
routing_context.clone()
|
||||||
};
|
};
|
||||||
let Ok(routing_context) = routing_context.with_privacy() else {
|
let Ok(routing_context) = routing_context.with_default_safety() else {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
add_routing_context(routing_context)
|
add_routing_context(routing_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen()]
|
#[wasm_bindgen()]
|
||||||
pub fn routing_context_with_custom_privacy(id: u32, safety_selection: String) -> u32 {
|
pub fn routing_context_with_safety(id: u32, safety_selection: String) -> u32 {
|
||||||
let safety_selection: veilid_core::SafetySelection =
|
let safety_selection: veilid_core::SafetySelection =
|
||||||
veilid_core::deserialize_json(&safety_selection).unwrap();
|
veilid_core::deserialize_json(&safety_selection).unwrap();
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ pub fn routing_context_with_custom_privacy(id: u32, safety_selection: String) ->
|
|||||||
};
|
};
|
||||||
routing_context.clone()
|
routing_context.clone()
|
||||||
};
|
};
|
||||||
let Ok(routing_context) = routing_context.with_custom_privacy(safety_selection) else {
|
let Ok(routing_context) = routing_context.with_safety(safety_selection) else {
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
add_routing_context(routing_context)
|
add_routing_context(routing_context)
|
||||||
@ -391,6 +391,26 @@ pub fn routing_context_with_sequencing(id: u32, sequencing: String) -> u32 {
|
|||||||
add_routing_context(routing_context)
|
add_routing_context(routing_context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen()]
|
||||||
|
pub fn routing_context_safety(id: u32) -> Promise {
|
||||||
|
wrap_api_future_json(async move {
|
||||||
|
let routing_context = {
|
||||||
|
let rc = (*ROUTING_CONTEXTS).borrow();
|
||||||
|
let Some(routing_context) = rc.get(&id) else {
|
||||||
|
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument(
|
||||||
|
"routing_context_safety",
|
||||||
|
"id",
|
||||||
|
id,
|
||||||
|
));
|
||||||
|
};
|
||||||
|
routing_context.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
let safety_selection = routing_context.safety();
|
||||||
|
APIResult::Ok(safety_selection)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen()]
|
#[wasm_bindgen()]
|
||||||
pub fn routing_context_app_call(id: u32, target_string: String, request: String) -> Promise {
|
pub fn routing_context_app_call(id: u32, target_string: String, request: String) -> Promise {
|
||||||
let request: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
let request: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
||||||
|
@ -13,7 +13,7 @@ impl VeilidRoutingContext {
|
|||||||
pub fn new() -> APIResult<VeilidRoutingContext> {
|
pub fn new() -> APIResult<VeilidRoutingContext> {
|
||||||
let veilid_api = get_veilid_api()?;
|
let veilid_api = get_veilid_api()?;
|
||||||
APIResult::Ok(VeilidRoutingContext {
|
APIResult::Ok(VeilidRoutingContext {
|
||||||
inner_routing_context: veilid_api.routing_context(),
|
inner_routing_context: veilid_api.routing_context()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,30 +105,30 @@ impl VeilidRoutingContext {
|
|||||||
APIResult::Ok(self.inner_routing_context.clone())
|
APIResult::Ok(self.inner_routing_context.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn on sender privacy, enabling the use of safety routes.
|
/// Turn on sender privacy, enabling the use of safety routes. This is the default and
|
||||||
|
/// calling this function is only necessary if you have previously disable safety or used other parameters.
|
||||||
/// Returns a new instance of VeilidRoutingContext - does not mutate.
|
/// Returns a new instance of VeilidRoutingContext - does not mutate.
|
||||||
///
|
///
|
||||||
/// Default values for hop count, stability and sequencing preferences are used.
|
/// 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.
|
/// * 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.
|
/// * 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
|
/// * Sequencing default is to have no preference for ordered vs unordered message delivery
|
||||||
pub fn withPrivacy(&self) -> APIResult<VeilidRoutingContext> {
|
///
|
||||||
|
/// To customize the safety selection in use, use [VeilidRoutingContext::withSafety].
|
||||||
|
pub fn withDefaultSafety(&self) -> APIResult<VeilidRoutingContext> {
|
||||||
let routing_context = self.getRoutingContext()?;
|
let routing_context = self.getRoutingContext()?;
|
||||||
APIResult::Ok(VeilidRoutingContext {
|
APIResult::Ok(VeilidRoutingContext {
|
||||||
inner_routing_context: routing_context.with_privacy()?,
|
inner_routing_context: routing_context.with_default_safety()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn on privacy using a custom `SafetySelection`.
|
/// Use a custom [SafetySelection]. Can be used to disable safety via [SafetySelection::Unsafe]
|
||||||
/// Returns a new instance of VeilidRoutingContext - does not mutate.
|
/// Returns a new instance of VeilidRoutingContext - does not mutate.
|
||||||
pub fn withCustomPrivacy(
|
pub fn withSafety(&self, safety_selection: SafetySelection) -> APIResult<VeilidRoutingContext> {
|
||||||
&self,
|
|
||||||
safety_selection: SafetySelection,
|
|
||||||
) -> APIResult<VeilidRoutingContext> {
|
|
||||||
let routing_context = self.getRoutingContext()?;
|
let routing_context = self.getRoutingContext()?;
|
||||||
APIResult::Ok(VeilidRoutingContext {
|
APIResult::Ok(VeilidRoutingContext {
|
||||||
inner_routing_context: routing_context.with_custom_privacy(safety_selection)?,
|
inner_routing_context: routing_context.with_safety(safety_selection)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +141,14 @@ impl VeilidRoutingContext {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the safety selection in use on this routing context
|
||||||
|
/// @returns the SafetySelection currently in use if successful.
|
||||||
|
pub fn safety(&self) -> APIResult<SafetySelection> {
|
||||||
|
let routing_context = self.getRoutingContext()?;
|
||||||
|
|
||||||
|
let safety_selection = routing_context.safety();
|
||||||
|
APIResult::Ok(safety_selection)
|
||||||
|
}
|
||||||
/// App-level unidirectional message that does not expect any value to be returned.
|
/// App-level unidirectional message that does not expect any value to be returned.
|
||||||
///
|
///
|
||||||
/// Veilid apps may use this for arbitrary message passing.
|
/// Veilid apps may use this for arbitrary message passing.
|
||||||
|
2518
veilid-wasm/tests/package-lock.json
generated
2518
veilid-wasm/tests/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -46,15 +46,15 @@ describe('VeilidRoutingContext', () => {
|
|||||||
routingContext.free();
|
routingContext.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create with privacy', async () => {
|
it('should create with default safety', async () => {
|
||||||
const routingContext = VeilidRoutingContext.create().withPrivacy();
|
const routingContext = VeilidRoutingContext.create().withDefaultSafety();
|
||||||
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
|
expect(routingContext instanceof VeilidRoutingContext).toBe(true);
|
||||||
|
|
||||||
routingContext.free();
|
routingContext.free();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create with custom privacy', async () => {
|
it('should create with safety', async () => {
|
||||||
const routingContext = VeilidRoutingContext.create().withCustomPrivacy({
|
const routingContext = VeilidRoutingContext.create().withSafety({
|
||||||
Safe: {
|
Safe: {
|
||||||
hop_count: 2,
|
hop_count: 2,
|
||||||
sequencing: 'EnsureOrdered',
|
sequencing: 'EnsureOrdered',
|
||||||
@ -80,7 +80,6 @@ describe('VeilidRoutingContext', () => {
|
|||||||
|
|
||||||
before('create routing context', () => {
|
before('create routing context', () => {
|
||||||
routingContext = VeilidRoutingContext.create()
|
routingContext = VeilidRoutingContext.create()
|
||||||
.withPrivacy()
|
|
||||||
.withSequencing('EnsureOrdered');
|
.withSequencing('EnsureOrdered');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ wasm-pack build $WASM_PACK_FLAGS --target bundler --weak-refs
|
|||||||
cd tests
|
cd tests
|
||||||
npm install
|
npm install
|
||||||
original_tmpdir=$TMPDIR
|
original_tmpdir=$TMPDIR
|
||||||
mkdir --parents ~/tmp
|
mkdir -p ~/tmp
|
||||||
export TMPDIR=~/tmp
|
export TMPDIR=~/tmp
|
||||||
npm run test:headless
|
npm run test:headless
|
||||||
export TMPDIR=$original_tmpdir
|
export TMPDIR=$original_tmpdir
|
||||||
|
Loading…
Reference in New Issue
Block a user