mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-07-28 01:15:23 -04:00
allow_offline flag for set_dht_value
This commit is contained in:
parent
eda436f264
commit
b7d725ab12
36 changed files with 751 additions and 98 deletions
|
@ -1,5 +1,11 @@
|
||||||
**UNRELEASED**
|
**UNRELEASED**
|
||||||
|
|
||||||
|
- _BREAKING API CHANGES_:
|
||||||
|
- set_dht_value now accepts a new flag called `allow_offline`, which defaults to `true`.
|
||||||
|
- The previous `writer: Option<KeyPair>` argument position is now `options: Option<SetDHTValueOptions>`
|
||||||
|
- This will only be a breaking change for anyone utilizing the previous `writer` argument.
|
||||||
|
- `writer` is now a member of `SetDHTValueOptions`, alongside the new `allow_offline` property.
|
||||||
|
|
||||||
- veilid-core:
|
- veilid-core:
|
||||||
- Add private route example
|
- Add private route example
|
||||||
- Add `require_inbound_relay` option in VeilidConfig. Default is false, but if enabled, forces OutboundOnly/InboundRelay mode. Can be used as an extra layer of IP address obscurity for some threat models. (@neequ57)
|
- Add `require_inbound_relay` option in VeilidConfig. Default is false, but if enabled, forces OutboundOnly/InboundRelay mode. Can be used as an extra layer of IP address obscurity for some threat models. (@neequ57)
|
||||||
|
|
|
@ -145,11 +145,11 @@ impl StorageManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Validate with schema
|
// Validate with schema
|
||||||
if !schema.check_subkey_value_data(
|
if schema.check_subkey_value_data(
|
||||||
descriptor.owner(),
|
descriptor.owner(),
|
||||||
subkey,
|
subkey,
|
||||||
value.value_data(),
|
value.value_data(),
|
||||||
) {
|
).is_err() {
|
||||||
// Validation failed, ignore this value
|
// Validation failed, ignore this value
|
||||||
// Move to the next node
|
// Move to the next node
|
||||||
return Ok(FanoutCallOutput{peer_info_list: vec![], disposition: FanoutCallDisposition::Invalid});
|
return Ok(FanoutCallOutput{peer_info_list: vec![], disposition: FanoutCallDisposition::Invalid});
|
||||||
|
|
|
@ -727,7 +727,7 @@ impl StorageManager {
|
||||||
record_key: TypedRecordKey,
|
record_key: TypedRecordKey,
|
||||||
subkey: ValueSubkey,
|
subkey: ValueSubkey,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
writer: Option<KeyPair>,
|
options: Option<SetDHTValueOptions>,
|
||||||
) -> VeilidAPIResult<Option<ValueData>> {
|
) -> VeilidAPIResult<Option<ValueData>> {
|
||||||
let mut inner = self.inner.lock().await;
|
let mut inner = self.inner.lock().await;
|
||||||
|
|
||||||
|
@ -748,7 +748,11 @@ impl StorageManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use the specified writer, or if not specified, the default writer when the record was opened
|
// Use the specified writer, or if not specified, the default writer when the record was opened
|
||||||
let opt_writer = writer.or(opt_writer);
|
let opt_writer = options.as_ref().and_then(|o| o.writer).or(opt_writer);
|
||||||
|
let allow_offline = options
|
||||||
|
.unwrap_or_default()
|
||||||
|
.allow_offline
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
// If we don't have a writer then we can't write
|
// If we don't have a writer then we can't write
|
||||||
let Some(writer) = opt_writer else {
|
let Some(writer) = opt_writer else {
|
||||||
|
@ -781,9 +785,13 @@ impl StorageManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Validate with schema
|
// Validate with schema
|
||||||
if !schema.check_subkey_value_data(descriptor.owner(), subkey, &value_data) {
|
if let Err(e) = schema.check_subkey_value_data(descriptor.owner(), subkey, &value_data) {
|
||||||
|
veilid_log!(self debug "schema validation error: {}", e);
|
||||||
// Validation failed, ignore this value
|
// Validation failed, ignore this value
|
||||||
apibail_generic!("failed schema validation");
|
apibail_generic!(format!(
|
||||||
|
"failed schema validation: {}:{}",
|
||||||
|
record_key, subkey
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign the new value data with the writer
|
// Sign the new value data with the writer
|
||||||
|
@ -821,10 +829,19 @@ impl StorageManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
if already_writing || !self.dht_is_online() {
|
if already_writing || !self.dht_is_online() {
|
||||||
|
if allow_offline == AllowOffline(true) {
|
||||||
veilid_log!(self debug "Writing subkey offline: {}:{} len={}", record_key, subkey, signed_value_data.value_data().data().len() );
|
veilid_log!(self debug "Writing subkey offline: {}:{} len={}", record_key, subkey, signed_value_data.value_data().data().len() );
|
||||||
// Add to offline writes to flush
|
// Add to offline writes to flush
|
||||||
Self::add_offline_subkey_write_inner(&mut inner, record_key, subkey, safety_selection);
|
Self::add_offline_subkey_write_inner(
|
||||||
|
&mut inner,
|
||||||
|
record_key,
|
||||||
|
subkey,
|
||||||
|
safety_selection,
|
||||||
|
);
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
|
} else {
|
||||||
|
apibail_try_again!("offline, try again later");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Drop the lock for network access
|
// Drop the lock for network access
|
||||||
|
@ -847,12 +864,17 @@ impl StorageManager {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// Failed to write, try again later
|
// Failed to write, try again later
|
||||||
let mut inner = self.inner.lock().await;
|
let mut inner = self.inner.lock().await;
|
||||||
|
|
||||||
|
if allow_offline == AllowOffline(true) {
|
||||||
Self::add_offline_subkey_write_inner(
|
Self::add_offline_subkey_write_inner(
|
||||||
&mut inner,
|
&mut inner,
|
||||||
record_key,
|
record_key,
|
||||||
subkey,
|
subkey,
|
||||||
safety_selection,
|
safety_selection,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
apibail_try_again!("offline, try again later");
|
||||||
|
}
|
||||||
|
|
||||||
// Remove from active subkey writes
|
// Remove from active subkey writes
|
||||||
let asw = inner.active_subkey_writes.get_mut(&record_key).unwrap();
|
let asw = inner.active_subkey_writes.get_mut(&record_key).unwrap();
|
||||||
|
|
|
@ -142,11 +142,11 @@ impl StorageManager {
|
||||||
veilid_log!(registry debug "SetValue got value back: len={} seq={}", value.value_data().data().len(), value.value_data().seq());
|
veilid_log!(registry debug "SetValue got value back: len={} seq={}", value.value_data().data().len(), value.value_data().seq());
|
||||||
|
|
||||||
// Validate with schema
|
// Validate with schema
|
||||||
if !ctx.schema.check_subkey_value_data(
|
if ctx.schema.check_subkey_value_data(
|
||||||
descriptor.owner(),
|
descriptor.owner(),
|
||||||
subkey,
|
subkey,
|
||||||
value.value_data(),
|
value.value_data(),
|
||||||
) {
|
).is_err() {
|
||||||
// Validation failed, ignore this value and pretend we never saw this node
|
// Validation failed, ignore this value and pretend we never saw this node
|
||||||
return Ok(FanoutCallOutput{peer_info_list: vec![], disposition: FanoutCallDisposition::Invalid});
|
return Ok(FanoutCallOutput{peer_info_list: vec![], disposition: FanoutCallDisposition::Invalid});
|
||||||
}
|
}
|
||||||
|
@ -474,7 +474,10 @@ impl StorageManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Validate new value with schema
|
// Validate new value with schema
|
||||||
if !schema.check_subkey_value_data(actual_descriptor.owner(), subkey, value.value_data()) {
|
if schema
|
||||||
|
.check_subkey_value_data(actual_descriptor.owner(), subkey, value.value_data())
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
// Validation failed, ignore this value
|
// Validation failed, ignore this value
|
||||||
return Ok(NetworkResult::invalid_message("failed schema validation"));
|
return Ok(NetworkResult::invalid_message("failed schema validation"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1179,11 +1179,10 @@ impl StorageManager {
|
||||||
let schema = descriptor.schema()?;
|
let schema = descriptor.schema()?;
|
||||||
|
|
||||||
// Validate with schema
|
// Validate with schema
|
||||||
if !schema.check_subkey_value_data(
|
if schema
|
||||||
descriptor.owner(),
|
.check_subkey_value_data(descriptor.owner(), first_subkey, value.value_data())
|
||||||
first_subkey,
|
.is_err()
|
||||||
value.value_data(),
|
{
|
||||||
) {
|
|
||||||
// Validation failed, ignore this value
|
// Validation failed, ignore this value
|
||||||
// Move to the next node
|
// Move to the next node
|
||||||
return Ok(NetworkResult::invalid_message(format!(
|
return Ok(NetworkResult::invalid_message(format!(
|
||||||
|
|
|
@ -319,7 +319,15 @@ pub async fn test_open_writer_dht_value(api: VeilidAPI) {
|
||||||
|
|
||||||
// Verify subkey 0 can be set because we have overridden with the correct writer
|
// Verify subkey 0 can be set because we have overridden with the correct writer
|
||||||
let set_dht_test_value_0_result = rc
|
let set_dht_test_value_0_result = rc
|
||||||
.set_dht_value(key, 0, test_value_1.clone(), Some(keypair))
|
.set_dht_value(
|
||||||
|
key,
|
||||||
|
0,
|
||||||
|
test_value_1.clone(),
|
||||||
|
Some(SetDHTValueOptions {
|
||||||
|
writer: Some(keypair),
|
||||||
|
allow_offline: None,
|
||||||
|
}),
|
||||||
|
)
|
||||||
.await;
|
.await;
|
||||||
assert!(set_dht_test_value_0_result.is_ok());
|
assert!(set_dht_test_value_0_result.is_ok());
|
||||||
|
|
||||||
|
@ -327,6 +335,69 @@ pub async fn test_open_writer_dht_value(api: VeilidAPI) {
|
||||||
rc.delete_dht_record(key).await.unwrap();
|
rc.delete_dht_record(key).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn test_set_dht_value_allow_offline(api: VeilidAPI) {
|
||||||
|
let rc = api.routing_context().unwrap();
|
||||||
|
|
||||||
|
// Create a DHT record
|
||||||
|
let rec = rc
|
||||||
|
.create_dht_record(DHTSchema::dflt(1).unwrap(), None, Some(CRYPTO_KIND_VLD0))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let dht_key = *rec.key();
|
||||||
|
|
||||||
|
let test_value = String::from("Test offline value").as_bytes().to_vec();
|
||||||
|
|
||||||
|
// Test 1: Default behavior (options = None) should allow offline writes
|
||||||
|
let set_result = rc.set_dht_value(dht_key, 0, test_value.clone(), None).await;
|
||||||
|
assert!(set_result.is_ok());
|
||||||
|
|
||||||
|
// Test 2: Default behavior (allow_offline = None) should allow offline writes
|
||||||
|
let set_result = rc
|
||||||
|
.set_dht_value(
|
||||||
|
dht_key,
|
||||||
|
0,
|
||||||
|
test_value.clone(),
|
||||||
|
Some(SetDHTValueOptions {
|
||||||
|
writer: None,
|
||||||
|
allow_offline: None,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert!(set_result.is_ok());
|
||||||
|
|
||||||
|
// Test 3: Explicitly allow offline writes
|
||||||
|
let set_result = rc
|
||||||
|
.set_dht_value(
|
||||||
|
dht_key,
|
||||||
|
1,
|
||||||
|
test_value.clone(),
|
||||||
|
Some(SetDHTValueOptions {
|
||||||
|
writer: None,
|
||||||
|
allow_offline: Some(AllowOffline(true)),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert!(set_result.is_ok());
|
||||||
|
|
||||||
|
// Test 4: Disallow offline writes
|
||||||
|
let set_result = rc
|
||||||
|
.set_dht_value(
|
||||||
|
dht_key,
|
||||||
|
2,
|
||||||
|
test_value.clone(),
|
||||||
|
Some(SetDHTValueOptions {
|
||||||
|
writer: None,
|
||||||
|
allow_offline: Some(AllowOffline(false)),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
assert!(set_result.is_err());
|
||||||
|
assert!(set_result.unwrap_err().to_string().contains("offline"));
|
||||||
|
|
||||||
|
rc.close_dht_record(dht_key).await.unwrap();
|
||||||
|
rc.delete_dht_record(dht_key).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
// Network-related code to make sure veilid node is connetected to other peers
|
// Network-related code to make sure veilid node is connetected to other peers
|
||||||
|
|
||||||
async fn wait_for_public_internet_ready(api: &VeilidAPI) {
|
async fn wait_for_public_internet_ready(api: &VeilidAPI) {
|
||||||
|
@ -364,6 +435,7 @@ pub async fn test_all() {
|
||||||
test_create_dht_record_with_owner(api.clone()).await;
|
test_create_dht_record_with_owner(api.clone()).await;
|
||||||
test_set_get_dht_value(api.clone()).await;
|
test_set_get_dht_value(api.clone()).await;
|
||||||
test_open_writer_dht_value(api.clone()).await;
|
test_open_writer_dht_value(api.clone()).await;
|
||||||
|
test_set_dht_value_allow_offline(api.clone()).await;
|
||||||
|
|
||||||
api.shutdown().await;
|
api.shutdown().await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1669,7 +1669,15 @@ impl VeilidAPI {
|
||||||
|
|
||||||
// Do a record set
|
// Do a record set
|
||||||
let value = match rc
|
let value = match rc
|
||||||
.set_dht_value(key, subkey as ValueSubkey, data, writer)
|
.set_dht_value(
|
||||||
|
key,
|
||||||
|
subkey as ValueSubkey,
|
||||||
|
data,
|
||||||
|
Some(SetDHTValueOptions {
|
||||||
|
writer,
|
||||||
|
allow_offline: None,
|
||||||
|
}),
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
@ -435,15 +435,15 @@ impl RoutingContext {
|
||||||
key: TypedRecordKey,
|
key: TypedRecordKey,
|
||||||
subkey: ValueSubkey,
|
subkey: ValueSubkey,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
writer: Option<KeyPair>,
|
options: Option<SetDHTValueOptions>,
|
||||||
) -> VeilidAPIResult<Option<ValueData>> {
|
) -> VeilidAPIResult<Option<ValueData>> {
|
||||||
veilid_log!(self debug
|
veilid_log!(self debug
|
||||||
"RoutingContext::set_dht_value(self: {:?}, key: {:?}, subkey: {:?}, data: len={}, writer: {:?})", self, key, subkey, data.len(), writer);
|
"RoutingContext::set_dht_value(self: {:?}, key: {:?}, subkey: {:?}, data: len={}, options: {:?})", self, key, subkey, data.len(), options);
|
||||||
|
|
||||||
Crypto::validate_crypto_kind(key.kind)?;
|
Crypto::validate_crypto_kind(key.kind)?;
|
||||||
|
|
||||||
let storage_manager = self.api.core_context()?.storage_manager();
|
let storage_manager = self.api.core_context()?.storage_manager();
|
||||||
Box::pin(storage_manager.set_value(key, subkey, data, writer)).await
|
Box::pin(storage_manager.set_value(key, subkey, data, options)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add or update a watch to a DHT value that informs the user via an VeilidUpdate::ValueChange callback when the record has subkeys change.
|
/// Add or update a watch to a DHT value that informs the user via an VeilidUpdate::ValueChange callback when the record has subkeys change.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
mod dht_record_descriptor;
|
mod dht_record_descriptor;
|
||||||
mod dht_record_report;
|
mod dht_record_report;
|
||||||
mod schema;
|
mod schema;
|
||||||
|
mod set_dht_value_options;
|
||||||
mod value_data;
|
mod value_data;
|
||||||
mod value_subkey_range_set;
|
mod value_subkey_range_set;
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ use super::*;
|
||||||
pub use dht_record_descriptor::*;
|
pub use dht_record_descriptor::*;
|
||||||
pub use dht_record_report::*;
|
pub use dht_record_report::*;
|
||||||
pub use schema::*;
|
pub use schema::*;
|
||||||
|
pub use set_dht_value_options::*;
|
||||||
pub use value_data::*;
|
pub use value_data::*;
|
||||||
pub use value_subkey_range_set::*;
|
pub use value_subkey_range_set::*;
|
||||||
|
|
||||||
|
|
|
@ -62,13 +62,12 @@ impl DHTSchemaDFLT {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check a subkey value data against the schema
|
/// Check a subkey value data against the schema
|
||||||
#[must_use]
|
|
||||||
pub fn check_subkey_value_data(
|
pub fn check_subkey_value_data(
|
||||||
&self,
|
&self,
|
||||||
owner: &PublicKey,
|
owner: &PublicKey,
|
||||||
subkey: ValueSubkey,
|
subkey: ValueSubkey,
|
||||||
value_data: &ValueData,
|
value_data: &ValueData,
|
||||||
) -> bool {
|
) -> VeilidAPIResult<()> {
|
||||||
let subkey = subkey as usize;
|
let subkey = subkey as usize;
|
||||||
|
|
||||||
// Check if subkey is in owner range
|
// Check if subkey is in owner range
|
||||||
|
@ -80,19 +79,27 @@ impl DHTSchemaDFLT {
|
||||||
|
|
||||||
// Ensure value size is within additional limit
|
// Ensure value size is within additional limit
|
||||||
if value_data.data_size() <= max_value_len {
|
if value_data.data_size() <= max_value_len {
|
||||||
return true;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value too big
|
// Value too big
|
||||||
return false;
|
apibail_invalid_argument!(
|
||||||
|
"value too big",
|
||||||
|
"data",
|
||||||
|
format!("{:?}", value_data.data())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrong writer
|
// Wrong writer
|
||||||
return false;
|
apibail_invalid_argument!(
|
||||||
|
"wrong writer",
|
||||||
|
"writer",
|
||||||
|
format!("{:?}", value_data.writer())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subkey out of range
|
// Subkey out of range
|
||||||
false
|
apibail_invalid_argument!("subkey out of range", "subkey", subkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a key is a schema member
|
/// Check if a key is a schema member
|
||||||
|
|
|
@ -64,13 +64,12 @@ impl DHTSchema {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check a subkey value data against the schema
|
/// Check a subkey value data against the schema
|
||||||
#[must_use]
|
|
||||||
pub fn check_subkey_value_data(
|
pub fn check_subkey_value_data(
|
||||||
&self,
|
&self,
|
||||||
owner: &PublicKey,
|
owner: &PublicKey,
|
||||||
subkey: ValueSubkey,
|
subkey: ValueSubkey,
|
||||||
value_data: &ValueData,
|
value_data: &ValueData,
|
||||||
) -> bool {
|
) -> VeilidAPIResult<()> {
|
||||||
match self {
|
match self {
|
||||||
DHTSchema::DFLT(d) => d.check_subkey_value_data(owner, subkey, value_data),
|
DHTSchema::DFLT(d) => d.check_subkey_value_data(owner, subkey, value_data),
|
||||||
DHTSchema::SMPL(s) => s.check_subkey_value_data(owner, subkey, value_data),
|
DHTSchema::SMPL(s) => s.check_subkey_value_data(owner, subkey, value_data),
|
||||||
|
|
|
@ -107,13 +107,12 @@ impl DHTSchemaSMPL {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check a subkey value data against the schema
|
/// Check a subkey value data against the schema
|
||||||
#[must_use]
|
|
||||||
pub fn check_subkey_value_data(
|
pub fn check_subkey_value_data(
|
||||||
&self,
|
&self,
|
||||||
owner: &PublicKey,
|
owner: &PublicKey,
|
||||||
subkey: ValueSubkey,
|
subkey: ValueSubkey,
|
||||||
value_data: &ValueData,
|
value_data: &ValueData,
|
||||||
) -> bool {
|
) -> VeilidAPIResult<()> {
|
||||||
let mut cur_subkey = subkey as usize;
|
let mut cur_subkey = subkey as usize;
|
||||||
|
|
||||||
let max_value_len = usize::min(
|
let max_value_len = usize::min(
|
||||||
|
@ -127,14 +126,22 @@ impl DHTSchemaSMPL {
|
||||||
if value_data.writer() == owner {
|
if value_data.writer() == owner {
|
||||||
// Ensure value size is within additional limit
|
// Ensure value size is within additional limit
|
||||||
if value_data.data_size() <= max_value_len {
|
if value_data.data_size() <= max_value_len {
|
||||||
return true;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value too big
|
// Value too big
|
||||||
return false;
|
apibail_invalid_argument!(
|
||||||
|
"value too big",
|
||||||
|
"data",
|
||||||
|
format!("{:?}", value_data.data())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Wrong writer
|
// Wrong writer
|
||||||
return false;
|
apibail_invalid_argument!(
|
||||||
|
"wrong writer",
|
||||||
|
"writer",
|
||||||
|
format!("{:?}", value_data.writer())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
cur_subkey -= self.o_cnt as usize;
|
cur_subkey -= self.o_cnt as usize;
|
||||||
|
|
||||||
|
@ -146,20 +153,28 @@ impl DHTSchemaSMPL {
|
||||||
if value_data.writer() == &m.m_key {
|
if value_data.writer() == &m.m_key {
|
||||||
// Ensure value size is in allowed range
|
// Ensure value size is in allowed range
|
||||||
if value_data.data_size() <= max_value_len {
|
if value_data.data_size() <= max_value_len {
|
||||||
return true;
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value too big
|
// Value too big
|
||||||
return false;
|
apibail_invalid_argument!(
|
||||||
|
"value too big",
|
||||||
|
"data",
|
||||||
|
format!("{:?}", value_data.data())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Wrong writer
|
// Wrong writer
|
||||||
return false;
|
apibail_invalid_argument!(
|
||||||
|
"wrong writer",
|
||||||
|
"writer",
|
||||||
|
format!("{:?}", value_data.writer())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
cur_subkey -= m.m_cnt as usize;
|
cur_subkey -= m.m_cnt as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subkey out of range
|
// Subkey out of range
|
||||||
false
|
apibail_invalid_argument!("subkey out of range", "subkey", subkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a key is a schema member
|
/// Check if a key is a schema member
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
use crate::{Deserialize, JsonSchema, KeyPair, Serialize};
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
|
||||||
|
use crate::Tsify;
|
||||||
|
|
||||||
|
#[derive(Debug, JsonSchema, Serialize, Deserialize, PartialEq, Eq, Clone)]
|
||||||
|
#[cfg_attr(
|
||||||
|
all(target_arch = "wasm32", target_os = "unknown"),
|
||||||
|
derive(Tsify),
|
||||||
|
tsify(from_wasm_abi, into_wasm_abi)
|
||||||
|
)]
|
||||||
|
pub struct AllowOffline(pub bool);
|
||||||
|
impl Default for AllowOffline {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, JsonSchema, Serialize, Deserialize, Clone)]
|
||||||
|
#[cfg_attr(
|
||||||
|
all(target_arch = "wasm32", target_os = "unknown"),
|
||||||
|
derive(Tsify),
|
||||||
|
tsify(from_wasm_abi, into_wasm_abi)
|
||||||
|
)]
|
||||||
|
pub struct SetDHTValueOptions {
|
||||||
|
#[schemars(with = "Option<String>")]
|
||||||
|
pub writer: Option<KeyPair>,
|
||||||
|
/// Defaults to true. If false, the value will not be written if the node is offline,
|
||||||
|
/// and a TryAgain error will be returned.
|
||||||
|
pub allow_offline: Option<AllowOffline>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SetDHTValueOptions {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
writer: None,
|
||||||
|
allow_offline: Some(AllowOffline(true)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -244,7 +244,8 @@ Future<void> testOpenWriterDHTValue() async {
|
||||||
// Should have prior sequence number as its returned value because it
|
// Should have prior sequence number as its returned value because it
|
||||||
// exists online at seq 0
|
// exists online at seq 0
|
||||||
vdtemp = await rc.setDHTValue(key, 0, va,
|
vdtemp = await rc.setDHTValue(key, 0, va,
|
||||||
writer: KeyPair(key: owner, secret: secret));
|
options:
|
||||||
|
SetDHTValueOptions(writer: KeyPair(key: owner, secret: secret)));
|
||||||
expect(vdtemp, isNotNull);
|
expect(vdtemp, isNotNull);
|
||||||
expect(vdtemp!.data, equals(vb));
|
expect(vdtemp!.data, equals(vb));
|
||||||
expect(vdtemp.seq, equals(0));
|
expect(vdtemp.seq, equals(0));
|
||||||
|
@ -252,7 +253,8 @@ Future<void> testOpenWriterDHTValue() async {
|
||||||
|
|
||||||
// Should update the second time to seq 1
|
// Should update the second time to seq 1
|
||||||
vdtemp = await rc.setDHTValue(key, 0, va,
|
vdtemp = await rc.setDHTValue(key, 0, va,
|
||||||
writer: KeyPair(key: owner, secret: secret));
|
options:
|
||||||
|
SetDHTValueOptions(writer: KeyPair(key: owner, secret: secret)));
|
||||||
expect(vdtemp, isNull);
|
expect(vdtemp, isNull);
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
|
|
|
@ -13,10 +13,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
|
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.12.0"
|
version: "2.13.0"
|
||||||
async_tools:
|
async_tools:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -101,10 +101,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc"
|
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.2"
|
version: "1.3.3"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -195,10 +195,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: leak_tracker
|
name: leak_tracker
|
||||||
sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec
|
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "10.0.8"
|
version: "10.0.9"
|
||||||
leak_tracker_flutter_testing:
|
leak_tracker_flutter_testing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -450,7 +450,7 @@ packages:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "0.4.4"
|
version: "0.4.7"
|
||||||
veilid_test:
|
veilid_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
|
@ -462,18 +462,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vm_service
|
name: vm_service
|
||||||
sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14"
|
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.3.1"
|
version: "15.0.0"
|
||||||
webdriver:
|
webdriver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: webdriver
|
name: webdriver
|
||||||
sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8"
|
sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.4"
|
version: "3.1.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -273,6 +273,25 @@ enum DHTReportScope {
|
||||||
String toJson() => name.toPascalCase();
|
String toJson() => name.toPascalCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SetDHTValueOptions
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class SetDHTValueOptions with _$SetDHTValueOptions {
|
||||||
|
const factory SetDHTValueOptions({
|
||||||
|
KeyPair? writer,
|
||||||
|
bool? allowOffline,
|
||||||
|
}) = _SetDHTValueOptions;
|
||||||
|
|
||||||
|
factory SetDHTValueOptions.fromJson(dynamic json) =>
|
||||||
|
_$SetDHTValueOptionsFromJson(json as Map<String, dynamic>);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'writer': writer,
|
||||||
|
'allow_offline': allowOffline,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
/// VeilidRoutingContext
|
/// VeilidRoutingContext
|
||||||
|
|
||||||
|
@ -300,7 +319,7 @@ abstract class VeilidRoutingContext {
|
||||||
Future<ValueData?> getDHTValue(TypedKey key, int subkey,
|
Future<ValueData?> getDHTValue(TypedKey key, int subkey,
|
||||||
{bool forceRefresh = false});
|
{bool forceRefresh = false});
|
||||||
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data,
|
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data,
|
||||||
{KeyPair? writer});
|
{SetDHTValueOptions? options});
|
||||||
Future<bool> watchDHTValues(TypedKey key,
|
Future<bool> watchDHTValues(TypedKey key,
|
||||||
{List<ValueSubkeyRange>? subkeys, Timestamp? expiration, int? count});
|
{List<ValueSubkeyRange>? subkeys, Timestamp? expiration, int? count});
|
||||||
Future<bool> cancelDHTWatch(TypedKey key, {List<ValueSubkeyRange>? subkeys});
|
Future<bool> cancelDHTWatch(TypedKey key, {List<ValueSubkeyRange>? subkeys});
|
||||||
|
|
|
@ -1453,4 +1453,165 @@ class __$DHTRecordReportCopyWithImpl<$Res>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$SetDHTValueOptions {
|
||||||
|
KeyPair? get writer;
|
||||||
|
bool? get allowOffline;
|
||||||
|
|
||||||
|
/// Create a copy of SetDHTValueOptions
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$SetDHTValueOptionsCopyWith<SetDHTValueOptions> get copyWith =>
|
||||||
|
_$SetDHTValueOptionsCopyWithImpl<SetDHTValueOptions>(
|
||||||
|
this as SetDHTValueOptions, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this SetDHTValueOptions to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is SetDHTValueOptions &&
|
||||||
|
(identical(other.writer, writer) || other.writer == writer) &&
|
||||||
|
(identical(other.allowOffline, allowOffline) ||
|
||||||
|
other.allowOffline == allowOffline));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, writer, allowOffline);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SetDHTValueOptions(writer: $writer, allowOffline: $allowOffline)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $SetDHTValueOptionsCopyWith<$Res> {
|
||||||
|
factory $SetDHTValueOptionsCopyWith(
|
||||||
|
SetDHTValueOptions value, $Res Function(SetDHTValueOptions) _then) =
|
||||||
|
_$SetDHTValueOptionsCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({KeyPair? writer, bool? allowOffline});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$SetDHTValueOptionsCopyWithImpl<$Res>
|
||||||
|
implements $SetDHTValueOptionsCopyWith<$Res> {
|
||||||
|
_$SetDHTValueOptionsCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final SetDHTValueOptions _self;
|
||||||
|
final $Res Function(SetDHTValueOptions) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SetDHTValueOptions
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? writer = freezed,
|
||||||
|
Object? allowOffline = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
writer: freezed == writer
|
||||||
|
? _self.writer
|
||||||
|
: writer // ignore: cast_nullable_to_non_nullable
|
||||||
|
as KeyPair?,
|
||||||
|
allowOffline: freezed == allowOffline
|
||||||
|
? _self.allowOffline
|
||||||
|
: allowOffline // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _SetDHTValueOptions implements SetDHTValueOptions {
|
||||||
|
const _SetDHTValueOptions({this.writer, this.allowOffline});
|
||||||
|
factory _SetDHTValueOptions.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SetDHTValueOptionsFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final KeyPair? writer;
|
||||||
|
@override
|
||||||
|
final bool? allowOffline;
|
||||||
|
|
||||||
|
/// Create a copy of SetDHTValueOptions
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SetDHTValueOptionsCopyWith<_SetDHTValueOptions> get copyWith =>
|
||||||
|
__$SetDHTValueOptionsCopyWithImpl<_SetDHTValueOptions>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$SetDHTValueOptionsToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _SetDHTValueOptions &&
|
||||||
|
(identical(other.writer, writer) || other.writer == writer) &&
|
||||||
|
(identical(other.allowOffline, allowOffline) ||
|
||||||
|
other.allowOffline == allowOffline));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, writer, allowOffline);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'SetDHTValueOptions(writer: $writer, allowOffline: $allowOffline)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SetDHTValueOptionsCopyWith<$Res>
|
||||||
|
implements $SetDHTValueOptionsCopyWith<$Res> {
|
||||||
|
factory _$SetDHTValueOptionsCopyWith(
|
||||||
|
_SetDHTValueOptions value, $Res Function(_SetDHTValueOptions) _then) =
|
||||||
|
__$SetDHTValueOptionsCopyWithImpl;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({KeyPair? writer, bool? allowOffline});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$SetDHTValueOptionsCopyWithImpl<$Res>
|
||||||
|
implements _$SetDHTValueOptionsCopyWith<$Res> {
|
||||||
|
__$SetDHTValueOptionsCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _SetDHTValueOptions _self;
|
||||||
|
final $Res Function(_SetDHTValueOptions) _then;
|
||||||
|
|
||||||
|
/// Create a copy of SetDHTValueOptions
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$Res call({
|
||||||
|
Object? writer = freezed,
|
||||||
|
Object? allowOffline = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_SetDHTValueOptions(
|
||||||
|
writer: freezed == writer
|
||||||
|
? _self.writer
|
||||||
|
: writer // ignore: cast_nullable_to_non_nullable
|
||||||
|
as KeyPair?,
|
||||||
|
allowOffline: freezed == allowOffline
|
||||||
|
? _self.allowOffline
|
||||||
|
: allowOffline // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// dart format on
|
// dart format on
|
||||||
|
|
|
@ -128,3 +128,15 @@ Map<String, dynamic> _$DHTRecordReportToJson(_DHTRecordReport instance) =>
|
||||||
'local_seqs': instance.localSeqs,
|
'local_seqs': instance.localSeqs,
|
||||||
'network_seqs': instance.networkSeqs,
|
'network_seqs': instance.networkSeqs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_SetDHTValueOptions _$SetDHTValueOptionsFromJson(Map<String, dynamic> json) =>
|
||||||
|
_SetDHTValueOptions(
|
||||||
|
writer: json['writer'] == null ? null : KeyPair.fromJson(json['writer']),
|
||||||
|
allowOffline: json['allow_offline'] as bool?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$SetDHTValueOptionsToJson(_SetDHTValueOptions instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'writer': instance.writer?.toJson(),
|
||||||
|
'allow_offline': instance.allowOffline,
|
||||||
|
};
|
||||||
|
|
|
@ -266,6 +266,18 @@ sealed class VeilidConfigProtocol with _$VeilidConfigProtocol {
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class VeilidConfigPrivacy with _$VeilidConfigPrivacy {
|
||||||
|
const factory VeilidConfigPrivacy({
|
||||||
|
required bool requireInboundRelay,
|
||||||
|
}) = _VeilidConfigPrivacy;
|
||||||
|
|
||||||
|
factory VeilidConfigPrivacy.fromJson(dynamic json) =>
|
||||||
|
_$VeilidConfigPrivacyFromJson(json as Map<String, dynamic>);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
sealed class VeilidConfigTLS with _$VeilidConfigTLS {
|
sealed class VeilidConfigTLS with _$VeilidConfigTLS {
|
||||||
const factory VeilidConfigTLS({
|
const factory VeilidConfigTLS({
|
||||||
|
@ -370,6 +382,7 @@ sealed class VeilidConfigNetwork with _$VeilidConfigNetwork {
|
||||||
required VeilidConfigTLS tls,
|
required VeilidConfigTLS tls,
|
||||||
required VeilidConfigApplication application,
|
required VeilidConfigApplication application,
|
||||||
required VeilidConfigProtocol protocol,
|
required VeilidConfigProtocol protocol,
|
||||||
|
required VeilidConfigPrivacy privacy,
|
||||||
String? networkKeyPassword,
|
String? networkKeyPassword,
|
||||||
}) = _VeilidConfigNetwork;
|
}) = _VeilidConfigNetwork;
|
||||||
|
|
||||||
|
|
|
@ -4296,6 +4296,169 @@ class __$VeilidConfigProtocolCopyWithImpl<$Res>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$VeilidConfigPrivacy implements DiagnosticableTreeMixin {
|
||||||
|
bool get requireInboundRelay;
|
||||||
|
|
||||||
|
/// Create a copy of VeilidConfigPrivacy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VeilidConfigPrivacyCopyWith<VeilidConfigPrivacy> get copyWith =>
|
||||||
|
_$VeilidConfigPrivacyCopyWithImpl<VeilidConfigPrivacy>(
|
||||||
|
this as VeilidConfigPrivacy, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this VeilidConfigPrivacy to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'VeilidConfigPrivacy'))
|
||||||
|
..add(DiagnosticsProperty('requireInboundRelay', requireInboundRelay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is VeilidConfigPrivacy &&
|
||||||
|
(identical(other.requireInboundRelay, requireInboundRelay) ||
|
||||||
|
other.requireInboundRelay == requireInboundRelay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, requireInboundRelay);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||||
|
return 'VeilidConfigPrivacy(requireInboundRelay: $requireInboundRelay)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $VeilidConfigPrivacyCopyWith<$Res> {
|
||||||
|
factory $VeilidConfigPrivacyCopyWith(
|
||||||
|
VeilidConfigPrivacy value, $Res Function(VeilidConfigPrivacy) _then) =
|
||||||
|
_$VeilidConfigPrivacyCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({bool requireInboundRelay});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$VeilidConfigPrivacyCopyWithImpl<$Res>
|
||||||
|
implements $VeilidConfigPrivacyCopyWith<$Res> {
|
||||||
|
_$VeilidConfigPrivacyCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final VeilidConfigPrivacy _self;
|
||||||
|
final $Res Function(VeilidConfigPrivacy) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VeilidConfigPrivacy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? requireInboundRelay = null,
|
||||||
|
}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
requireInboundRelay: null == requireInboundRelay
|
||||||
|
? _self.requireInboundRelay
|
||||||
|
: requireInboundRelay // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
class _VeilidConfigPrivacy
|
||||||
|
with DiagnosticableTreeMixin
|
||||||
|
implements VeilidConfigPrivacy {
|
||||||
|
const _VeilidConfigPrivacy({required this.requireInboundRelay});
|
||||||
|
factory _VeilidConfigPrivacy.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$VeilidConfigPrivacyFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
final bool requireInboundRelay;
|
||||||
|
|
||||||
|
/// Create a copy of VeilidConfigPrivacy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$VeilidConfigPrivacyCopyWith<_VeilidConfigPrivacy> get copyWith =>
|
||||||
|
__$VeilidConfigPrivacyCopyWithImpl<_VeilidConfigPrivacy>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$VeilidConfigPrivacyToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||||
|
properties
|
||||||
|
..add(DiagnosticsProperty('type', 'VeilidConfigPrivacy'))
|
||||||
|
..add(DiagnosticsProperty('requireInboundRelay', requireInboundRelay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _VeilidConfigPrivacy &&
|
||||||
|
(identical(other.requireInboundRelay, requireInboundRelay) ||
|
||||||
|
other.requireInboundRelay == requireInboundRelay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, requireInboundRelay);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||||
|
return 'VeilidConfigPrivacy(requireInboundRelay: $requireInboundRelay)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$VeilidConfigPrivacyCopyWith<$Res>
|
||||||
|
implements $VeilidConfigPrivacyCopyWith<$Res> {
|
||||||
|
factory _$VeilidConfigPrivacyCopyWith(_VeilidConfigPrivacy value,
|
||||||
|
$Res Function(_VeilidConfigPrivacy) _then) =
|
||||||
|
__$VeilidConfigPrivacyCopyWithImpl;
|
||||||
|
@override
|
||||||
|
@useResult
|
||||||
|
$Res call({bool requireInboundRelay});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$VeilidConfigPrivacyCopyWithImpl<$Res>
|
||||||
|
implements _$VeilidConfigPrivacyCopyWith<$Res> {
|
||||||
|
__$VeilidConfigPrivacyCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _VeilidConfigPrivacy _self;
|
||||||
|
final $Res Function(_VeilidConfigPrivacy) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VeilidConfigPrivacy
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$Res call({
|
||||||
|
Object? requireInboundRelay = null,
|
||||||
|
}) {
|
||||||
|
return _then(_VeilidConfigPrivacy(
|
||||||
|
requireInboundRelay: null == requireInboundRelay
|
||||||
|
? _self.requireInboundRelay
|
||||||
|
: requireInboundRelay // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$VeilidConfigTLS implements DiagnosticableTreeMixin {
|
mixin _$VeilidConfigTLS implements DiagnosticableTreeMixin {
|
||||||
String get certificatePath;
|
String get certificatePath;
|
||||||
|
@ -5922,6 +6085,7 @@ mixin _$VeilidConfigNetwork implements DiagnosticableTreeMixin {
|
||||||
VeilidConfigTLS get tls;
|
VeilidConfigTLS get tls;
|
||||||
VeilidConfigApplication get application;
|
VeilidConfigApplication get application;
|
||||||
VeilidConfigProtocol get protocol;
|
VeilidConfigProtocol get protocol;
|
||||||
|
VeilidConfigPrivacy get privacy;
|
||||||
String? get networkKeyPassword;
|
String? get networkKeyPassword;
|
||||||
|
|
||||||
/// Create a copy of VeilidConfigNetwork
|
/// Create a copy of VeilidConfigNetwork
|
||||||
|
@ -5965,6 +6129,7 @@ mixin _$VeilidConfigNetwork implements DiagnosticableTreeMixin {
|
||||||
..add(DiagnosticsProperty('tls', tls))
|
..add(DiagnosticsProperty('tls', tls))
|
||||||
..add(DiagnosticsProperty('application', application))
|
..add(DiagnosticsProperty('application', application))
|
||||||
..add(DiagnosticsProperty('protocol', protocol))
|
..add(DiagnosticsProperty('protocol', protocol))
|
||||||
|
..add(DiagnosticsProperty('privacy', privacy))
|
||||||
..add(DiagnosticsProperty('networkKeyPassword', networkKeyPassword));
|
..add(DiagnosticsProperty('networkKeyPassword', networkKeyPassword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6012,6 +6177,7 @@ mixin _$VeilidConfigNetwork implements DiagnosticableTreeMixin {
|
||||||
other.application == application) &&
|
other.application == application) &&
|
||||||
(identical(other.protocol, protocol) ||
|
(identical(other.protocol, protocol) ||
|
||||||
other.protocol == protocol) &&
|
other.protocol == protocol) &&
|
||||||
|
(identical(other.privacy, privacy) || other.privacy == privacy) &&
|
||||||
(identical(other.networkKeyPassword, networkKeyPassword) ||
|
(identical(other.networkKeyPassword, networkKeyPassword) ||
|
||||||
other.networkKeyPassword == networkKeyPassword));
|
other.networkKeyPassword == networkKeyPassword));
|
||||||
}
|
}
|
||||||
|
@ -6038,12 +6204,13 @@ mixin _$VeilidConfigNetwork implements DiagnosticableTreeMixin {
|
||||||
tls,
|
tls,
|
||||||
application,
|
application,
|
||||||
protocol,
|
protocol,
|
||||||
|
privacy,
|
||||||
networkKeyPassword
|
networkKeyPassword
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||||
return 'VeilidConfigNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, routingTable: $routingTable, rpc: $rpc, dht: $dht, upnp: $upnp, detectAddressChanges: $detectAddressChanges, restrictedNatRetries: $restrictedNatRetries, tls: $tls, application: $application, protocol: $protocol, networkKeyPassword: $networkKeyPassword)';
|
return 'VeilidConfigNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, routingTable: $routingTable, rpc: $rpc, dht: $dht, upnp: $upnp, detectAddressChanges: $detectAddressChanges, restrictedNatRetries: $restrictedNatRetries, tls: $tls, application: $application, protocol: $protocol, privacy: $privacy, networkKeyPassword: $networkKeyPassword)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6072,6 +6239,7 @@ abstract mixin class $VeilidConfigNetworkCopyWith<$Res> {
|
||||||
VeilidConfigTLS tls,
|
VeilidConfigTLS tls,
|
||||||
VeilidConfigApplication application,
|
VeilidConfigApplication application,
|
||||||
VeilidConfigProtocol protocol,
|
VeilidConfigProtocol protocol,
|
||||||
|
VeilidConfigPrivacy privacy,
|
||||||
String? networkKeyPassword});
|
String? networkKeyPassword});
|
||||||
|
|
||||||
$VeilidConfigRoutingTableCopyWith<$Res> get routingTable;
|
$VeilidConfigRoutingTableCopyWith<$Res> get routingTable;
|
||||||
|
@ -6080,6 +6248,7 @@ abstract mixin class $VeilidConfigNetworkCopyWith<$Res> {
|
||||||
$VeilidConfigTLSCopyWith<$Res> get tls;
|
$VeilidConfigTLSCopyWith<$Res> get tls;
|
||||||
$VeilidConfigApplicationCopyWith<$Res> get application;
|
$VeilidConfigApplicationCopyWith<$Res> get application;
|
||||||
$VeilidConfigProtocolCopyWith<$Res> get protocol;
|
$VeilidConfigProtocolCopyWith<$Res> get protocol;
|
||||||
|
$VeilidConfigPrivacyCopyWith<$Res> get privacy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
@ -6113,6 +6282,7 @@ class _$VeilidConfigNetworkCopyWithImpl<$Res>
|
||||||
Object? tls = null,
|
Object? tls = null,
|
||||||
Object? application = null,
|
Object? application = null,
|
||||||
Object? protocol = null,
|
Object? protocol = null,
|
||||||
|
Object? privacy = null,
|
||||||
Object? networkKeyPassword = freezed,
|
Object? networkKeyPassword = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_self.copyWith(
|
return _then(_self.copyWith(
|
||||||
|
@ -6188,6 +6358,10 @@ class _$VeilidConfigNetworkCopyWithImpl<$Res>
|
||||||
? _self.protocol
|
? _self.protocol
|
||||||
: protocol // ignore: cast_nullable_to_non_nullable
|
: protocol // ignore: cast_nullable_to_non_nullable
|
||||||
as VeilidConfigProtocol,
|
as VeilidConfigProtocol,
|
||||||
|
privacy: null == privacy
|
||||||
|
? _self.privacy
|
||||||
|
: privacy // ignore: cast_nullable_to_non_nullable
|
||||||
|
as VeilidConfigPrivacy,
|
||||||
networkKeyPassword: freezed == networkKeyPassword
|
networkKeyPassword: freezed == networkKeyPassword
|
||||||
? _self.networkKeyPassword
|
? _self.networkKeyPassword
|
||||||
: networkKeyPassword // ignore: cast_nullable_to_non_nullable
|
: networkKeyPassword // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -6254,6 +6428,16 @@ class _$VeilidConfigNetworkCopyWithImpl<$Res>
|
||||||
return _then(_self.copyWith(protocol: value));
|
return _then(_self.copyWith(protocol: value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of VeilidConfigNetwork
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VeilidConfigPrivacyCopyWith<$Res> get privacy {
|
||||||
|
return $VeilidConfigPrivacyCopyWith<$Res>(_self.privacy, (value) {
|
||||||
|
return _then(_self.copyWith(privacy: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
@ -6280,6 +6464,7 @@ class _VeilidConfigNetwork
|
||||||
required this.tls,
|
required this.tls,
|
||||||
required this.application,
|
required this.application,
|
||||||
required this.protocol,
|
required this.protocol,
|
||||||
|
required this.privacy,
|
||||||
this.networkKeyPassword});
|
this.networkKeyPassword});
|
||||||
factory _VeilidConfigNetwork.fromJson(Map<String, dynamic> json) =>
|
factory _VeilidConfigNetwork.fromJson(Map<String, dynamic> json) =>
|
||||||
_$VeilidConfigNetworkFromJson(json);
|
_$VeilidConfigNetworkFromJson(json);
|
||||||
|
@ -6321,6 +6506,8 @@ class _VeilidConfigNetwork
|
||||||
@override
|
@override
|
||||||
final VeilidConfigProtocol protocol;
|
final VeilidConfigProtocol protocol;
|
||||||
@override
|
@override
|
||||||
|
final VeilidConfigPrivacy privacy;
|
||||||
|
@override
|
||||||
final String? networkKeyPassword;
|
final String? networkKeyPassword;
|
||||||
|
|
||||||
/// Create a copy of VeilidConfigNetwork
|
/// Create a copy of VeilidConfigNetwork
|
||||||
|
@ -6369,6 +6556,7 @@ class _VeilidConfigNetwork
|
||||||
..add(DiagnosticsProperty('tls', tls))
|
..add(DiagnosticsProperty('tls', tls))
|
||||||
..add(DiagnosticsProperty('application', application))
|
..add(DiagnosticsProperty('application', application))
|
||||||
..add(DiagnosticsProperty('protocol', protocol))
|
..add(DiagnosticsProperty('protocol', protocol))
|
||||||
|
..add(DiagnosticsProperty('privacy', privacy))
|
||||||
..add(DiagnosticsProperty('networkKeyPassword', networkKeyPassword));
|
..add(DiagnosticsProperty('networkKeyPassword', networkKeyPassword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6416,6 +6604,7 @@ class _VeilidConfigNetwork
|
||||||
other.application == application) &&
|
other.application == application) &&
|
||||||
(identical(other.protocol, protocol) ||
|
(identical(other.protocol, protocol) ||
|
||||||
other.protocol == protocol) &&
|
other.protocol == protocol) &&
|
||||||
|
(identical(other.privacy, privacy) || other.privacy == privacy) &&
|
||||||
(identical(other.networkKeyPassword, networkKeyPassword) ||
|
(identical(other.networkKeyPassword, networkKeyPassword) ||
|
||||||
other.networkKeyPassword == networkKeyPassword));
|
other.networkKeyPassword == networkKeyPassword));
|
||||||
}
|
}
|
||||||
|
@ -6442,12 +6631,13 @@ class _VeilidConfigNetwork
|
||||||
tls,
|
tls,
|
||||||
application,
|
application,
|
||||||
protocol,
|
protocol,
|
||||||
|
privacy,
|
||||||
networkKeyPassword
|
networkKeyPassword
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||||
return 'VeilidConfigNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, routingTable: $routingTable, rpc: $rpc, dht: $dht, upnp: $upnp, detectAddressChanges: $detectAddressChanges, restrictedNatRetries: $restrictedNatRetries, tls: $tls, application: $application, protocol: $protocol, networkKeyPassword: $networkKeyPassword)';
|
return 'VeilidConfigNetwork(connectionInitialTimeoutMs: $connectionInitialTimeoutMs, connectionInactivityTimeoutMs: $connectionInactivityTimeoutMs, maxConnectionsPerIp4: $maxConnectionsPerIp4, maxConnectionsPerIp6Prefix: $maxConnectionsPerIp6Prefix, maxConnectionsPerIp6PrefixSize: $maxConnectionsPerIp6PrefixSize, maxConnectionFrequencyPerMin: $maxConnectionFrequencyPerMin, clientAllowlistTimeoutMs: $clientAllowlistTimeoutMs, reverseConnectionReceiptTimeMs: $reverseConnectionReceiptTimeMs, holePunchReceiptTimeMs: $holePunchReceiptTimeMs, routingTable: $routingTable, rpc: $rpc, dht: $dht, upnp: $upnp, detectAddressChanges: $detectAddressChanges, restrictedNatRetries: $restrictedNatRetries, tls: $tls, application: $application, protocol: $protocol, privacy: $privacy, networkKeyPassword: $networkKeyPassword)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6478,6 +6668,7 @@ abstract mixin class _$VeilidConfigNetworkCopyWith<$Res>
|
||||||
VeilidConfigTLS tls,
|
VeilidConfigTLS tls,
|
||||||
VeilidConfigApplication application,
|
VeilidConfigApplication application,
|
||||||
VeilidConfigProtocol protocol,
|
VeilidConfigProtocol protocol,
|
||||||
|
VeilidConfigPrivacy privacy,
|
||||||
String? networkKeyPassword});
|
String? networkKeyPassword});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -6492,6 +6683,8 @@ abstract mixin class _$VeilidConfigNetworkCopyWith<$Res>
|
||||||
$VeilidConfigApplicationCopyWith<$Res> get application;
|
$VeilidConfigApplicationCopyWith<$Res> get application;
|
||||||
@override
|
@override
|
||||||
$VeilidConfigProtocolCopyWith<$Res> get protocol;
|
$VeilidConfigProtocolCopyWith<$Res> get protocol;
|
||||||
|
@override
|
||||||
|
$VeilidConfigPrivacyCopyWith<$Res> get privacy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
@ -6525,6 +6718,7 @@ class __$VeilidConfigNetworkCopyWithImpl<$Res>
|
||||||
Object? tls = null,
|
Object? tls = null,
|
||||||
Object? application = null,
|
Object? application = null,
|
||||||
Object? protocol = null,
|
Object? protocol = null,
|
||||||
|
Object? privacy = null,
|
||||||
Object? networkKeyPassword = freezed,
|
Object? networkKeyPassword = freezed,
|
||||||
}) {
|
}) {
|
||||||
return _then(_VeilidConfigNetwork(
|
return _then(_VeilidConfigNetwork(
|
||||||
|
@ -6600,6 +6794,10 @@ class __$VeilidConfigNetworkCopyWithImpl<$Res>
|
||||||
? _self.protocol
|
? _self.protocol
|
||||||
: protocol // ignore: cast_nullable_to_non_nullable
|
: protocol // ignore: cast_nullable_to_non_nullable
|
||||||
as VeilidConfigProtocol,
|
as VeilidConfigProtocol,
|
||||||
|
privacy: null == privacy
|
||||||
|
? _self.privacy
|
||||||
|
: privacy // ignore: cast_nullable_to_non_nullable
|
||||||
|
as VeilidConfigPrivacy,
|
||||||
networkKeyPassword: freezed == networkKeyPassword
|
networkKeyPassword: freezed == networkKeyPassword
|
||||||
? _self.networkKeyPassword
|
? _self.networkKeyPassword
|
||||||
: networkKeyPassword // ignore: cast_nullable_to_non_nullable
|
: networkKeyPassword // ignore: cast_nullable_to_non_nullable
|
||||||
|
@ -6666,6 +6864,16 @@ class __$VeilidConfigNetworkCopyWithImpl<$Res>
|
||||||
return _then(_self.copyWith(protocol: value));
|
return _then(_self.copyWith(protocol: value));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a copy of VeilidConfigNetwork
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VeilidConfigPrivacyCopyWith<$Res> get privacy {
|
||||||
|
return $VeilidConfigPrivacyCopyWith<$Res>(_self.privacy, (value) {
|
||||||
|
return _then(_self.copyWith(privacy: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
|
@ -314,6 +314,17 @@ Map<String, dynamic> _$VeilidConfigProtocolToJson(
|
||||||
'wss': instance.wss.toJson(),
|
'wss': instance.wss.toJson(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_VeilidConfigPrivacy _$VeilidConfigPrivacyFromJson(Map<String, dynamic> json) =>
|
||||||
|
_VeilidConfigPrivacy(
|
||||||
|
requireInboundRelay: json['require_inbound_relay'] as bool,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$VeilidConfigPrivacyToJson(
|
||||||
|
_VeilidConfigPrivacy instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'require_inbound_relay': instance.requireInboundRelay,
|
||||||
|
};
|
||||||
|
|
||||||
_VeilidConfigTLS _$VeilidConfigTLSFromJson(Map<String, dynamic> json) =>
|
_VeilidConfigTLS _$VeilidConfigTLSFromJson(Map<String, dynamic> json) =>
|
||||||
_VeilidConfigTLS(
|
_VeilidConfigTLS(
|
||||||
certificatePath: json['certificate_path'] as String,
|
certificatePath: json['certificate_path'] as String,
|
||||||
|
@ -472,6 +483,7 @@ _VeilidConfigNetwork _$VeilidConfigNetworkFromJson(Map<String, dynamic> json) =>
|
||||||
tls: VeilidConfigTLS.fromJson(json['tls']),
|
tls: VeilidConfigTLS.fromJson(json['tls']),
|
||||||
application: VeilidConfigApplication.fromJson(json['application']),
|
application: VeilidConfigApplication.fromJson(json['application']),
|
||||||
protocol: VeilidConfigProtocol.fromJson(json['protocol']),
|
protocol: VeilidConfigProtocol.fromJson(json['protocol']),
|
||||||
|
privacy: VeilidConfigPrivacy.fromJson(json['privacy']),
|
||||||
networkKeyPassword: json['network_key_password'] as String?,
|
networkKeyPassword: json['network_key_password'] as String?,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -499,6 +511,7 @@ Map<String, dynamic> _$VeilidConfigNetworkToJson(
|
||||||
'tls': instance.tls.toJson(),
|
'tls': instance.tls.toJson(),
|
||||||
'application': instance.application.toJson(),
|
'application': instance.application.toJson(),
|
||||||
'protocol': instance.protocol.toJson(),
|
'protocol': instance.protocol.toJson(),
|
||||||
|
'privacy': instance.privacy.toJson(),
|
||||||
'network_key_password': instance.networkKeyPassword,
|
'network_key_password': instance.networkKeyPassword,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -696,17 +696,17 @@ class VeilidRoutingContextFFI extends VeilidRoutingContext {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data,
|
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data,
|
||||||
{KeyPair? writer}) async {
|
{SetDHTValueOptions? options}) async {
|
||||||
_ctx.ensureValid();
|
_ctx.ensureValid();
|
||||||
final nativeKey = jsonEncode(key).toNativeUtf8();
|
final nativeKey = jsonEncode(key).toNativeUtf8();
|
||||||
final nativeData = base64UrlNoPadEncode(data).toNativeUtf8();
|
final nativeData = base64UrlNoPadEncode(data).toNativeUtf8();
|
||||||
final nativeWriter =
|
final nativeOptions =
|
||||||
writer != null ? jsonEncode(writer).toNativeUtf8() : nullptr;
|
options != null ? jsonEncode(options).toNativeUtf8() : nullptr;
|
||||||
|
|
||||||
final recvPort = ReceivePort('routing_context_set_dht_value');
|
final recvPort = ReceivePort('routing_context_set_dht_value');
|
||||||
final sendPort = recvPort.sendPort;
|
final sendPort = recvPort.sendPort;
|
||||||
_ctx.ffi._routingContextSetDHTValue(sendPort.nativePort, _ctx.id!,
|
_ctx.ffi._routingContextSetDHTValue(sendPort.nativePort, _ctx.id!,
|
||||||
nativeKey, subkey, nativeData, nativeWriter);
|
nativeKey, subkey, nativeData, nativeOptions);
|
||||||
final valueData =
|
final valueData =
|
||||||
await processFutureOptJson(ValueData.fromJson, recvPort.first);
|
await processFutureOptJson(ValueData.fromJson, recvPort.first);
|
||||||
return valueData;
|
return valueData;
|
||||||
|
|
|
@ -193,7 +193,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data,
|
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data,
|
||||||
{KeyPair? writer}) async {
|
{SetDHTValueOptions? options}) async {
|
||||||
final id = _ctx.requireId();
|
final id = _ctx.requireId();
|
||||||
final opt = await _wrapApiPromise<String?>(
|
final opt = await _wrapApiPromise<String?>(
|
||||||
js_util.callMethod(wasm, 'routing_context_set_dht_value', [
|
js_util.callMethod(wasm, 'routing_context_set_dht_value', [
|
||||||
|
@ -201,7 +201,7 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
|
||||||
jsonEncode(key),
|
jsonEncode(key),
|
||||||
subkey,
|
subkey,
|
||||||
base64UrlNoPadEncode(data),
|
base64UrlNoPadEncode(data),
|
||||||
if (writer != null) jsonEncode(writer) else null
|
if (options != null) jsonEncode(options) else null
|
||||||
]));
|
]));
|
||||||
if (opt == null) {
|
if (opt == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -793,14 +793,14 @@ pub extern "C" fn routing_context_set_dht_value(
|
||||||
key: FfiStr,
|
key: FfiStr,
|
||||||
subkey: u32,
|
subkey: u32,
|
||||||
data: FfiStr,
|
data: FfiStr,
|
||||||
writer: FfiStr,
|
options: FfiStr,
|
||||||
) {
|
) {
|
||||||
let key: veilid_core::TypedRecordKey =
|
let key: veilid_core::TypedRecordKey =
|
||||||
veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap();
|
veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap();
|
||||||
let data: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
let data: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
||||||
.decode(data.into_opt_string().unwrap().as_bytes())
|
.decode(data.into_opt_string().unwrap().as_bytes())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let writer: Option<veilid_core::KeyPair> = writer
|
let options: Option<veilid_core::SetDHTValueOptions> = options
|
||||||
.into_opt_string()
|
.into_opt_string()
|
||||||
.map(|s| veilid_core::deserialize_json(&s).unwrap());
|
.map(|s| veilid_core::deserialize_json(&s).unwrap());
|
||||||
|
|
||||||
|
@ -809,7 +809,7 @@ pub extern "C" fn routing_context_set_dht_value(
|
||||||
let routing_context = get_routing_context(id, "routing_context_set_dht_value")?;
|
let routing_context = get_routing_context(id, "routing_context_set_dht_value")?;
|
||||||
|
|
||||||
let res = routing_context
|
let res = routing_context
|
||||||
.set_dht_value(key, subkey, data, writer)
|
.set_dht_value(key, subkey, data, options)
|
||||||
.await?;
|
.await?;
|
||||||
APIResult::Ok(res)
|
APIResult::Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,14 +238,14 @@ async def test_open_writer_dht_value(api_connection: veilid.VeilidAPI):
|
||||||
|
|
||||||
# Verify subkey 0 can be set because override with the right writer
|
# Verify subkey 0 can be set because override with the right writer
|
||||||
# Should have prior sequence number as its returned value because it exists online at seq 0
|
# Should have prior sequence number as its returned value because it exists online at seq 0
|
||||||
vdtemp = await rc.set_dht_value(key, ValueSubkey(0), va, veilid.KeyPair.from_parts(owner, secret))
|
vdtemp = await rc.set_dht_value(key, ValueSubkey(0), va, veilid.SetDHTValueOptions(veilid.KeyPair.from_parts(owner, secret)))
|
||||||
assert vdtemp is not None
|
assert vdtemp is not None
|
||||||
assert vdtemp.data == vb
|
assert vdtemp.data == vb
|
||||||
assert vdtemp.seq == 0
|
assert vdtemp.seq == 0
|
||||||
assert vdtemp.writer == owner
|
assert vdtemp.writer == owner
|
||||||
|
|
||||||
# Should update the second time to seq 1
|
# Should update the second time to seq 1
|
||||||
vdtemp = await rc.set_dht_value(key, ValueSubkey(0), va, veilid.KeyPair.from_parts(owner, secret))
|
vdtemp = await rc.set_dht_value(key, ValueSubkey(0), va, veilid.SetDHTValueOptions(veilid.KeyPair.from_parts(owner, secret)))
|
||||||
assert vdtemp is None
|
assert vdtemp is None
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
|
|
|
@ -84,7 +84,7 @@ class RoutingContext(ABC):
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def set_dht_value(
|
async def set_dht_value(
|
||||||
self, key: types.TypedKey, subkey: types.ValueSubkey, data: bytes, writer: Optional[types.KeyPair] = None
|
self, key: types.TypedKey, subkey: types.ValueSubkey, data: bytes, options: Optional[types.SetDHTValueOptions] = None
|
||||||
) -> Optional[types.ValueData]:
|
) -> Optional[types.ValueData]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ from .types import (
|
||||||
SafetySelection,
|
SafetySelection,
|
||||||
SecretKey,
|
SecretKey,
|
||||||
Sequencing,
|
Sequencing,
|
||||||
|
SetDHTValueOptions,
|
||||||
SharedSecret,
|
SharedSecret,
|
||||||
Signature,
|
Signature,
|
||||||
Stability,
|
Stability,
|
||||||
|
@ -721,12 +722,12 @@ class _JsonRoutingContext(RoutingContext):
|
||||||
return None if ret is None else ValueData.from_json(ret)
|
return None if ret is None else ValueData.from_json(ret)
|
||||||
|
|
||||||
async def set_dht_value(
|
async def set_dht_value(
|
||||||
self, key: TypedKey, subkey: ValueSubkey, data: bytes, writer: Optional[KeyPair] = None
|
self, key: TypedKey, subkey: ValueSubkey, data: bytes, options: Optional[SetDHTValueOptions] = None
|
||||||
) -> Optional[ValueData]:
|
) -> Optional[ValueData]:
|
||||||
assert isinstance(key, TypedKey)
|
assert isinstance(key, TypedKey)
|
||||||
assert isinstance(subkey, ValueSubkey)
|
assert isinstance(subkey, ValueSubkey)
|
||||||
assert isinstance(data, bytes)
|
assert isinstance(data, bytes)
|
||||||
assert writer is None or isinstance(writer, KeyPair)
|
assert options is None or isinstance(options, SetDHTValueOptions)
|
||||||
|
|
||||||
ret = raise_api_result(
|
ret = raise_api_result(
|
||||||
await self.api.send_ndjson_request(
|
await self.api.send_ndjson_request(
|
||||||
|
@ -737,7 +738,7 @@ class _JsonRoutingContext(RoutingContext):
|
||||||
key=key,
|
key=key,
|
||||||
subkey=subkey,
|
subkey=subkey,
|
||||||
data=data,
|
data=data,
|
||||||
writer=writer,
|
options=options,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return None if ret is None else ValueData.from_json(ret)
|
return None if ret is None else ValueData.from_json(ret)
|
||||||
|
|
|
@ -3944,6 +3944,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"VeilidCapability": {
|
"VeilidCapability": {
|
||||||
|
"description": "A four-character code",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
|
|
|
@ -461,6 +461,16 @@
|
||||||
"key": {
|
"key": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"options": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/SetDHTValueOptions"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"rc_op": {
|
"rc_op": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
@ -471,12 +481,6 @@
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"format": "uint32",
|
"format": "uint32",
|
||||||
"minimum": 0.0
|
"minimum": 0.0
|
||||||
},
|
|
||||||
"writer": {
|
|
||||||
"type": [
|
|
||||||
"string",
|
|
||||||
"null"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1656,6 +1660,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
|
"AllowOffline": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"DHTReportScope": {
|
"DHTReportScope": {
|
||||||
"description": "DHT Record Report Scope",
|
"description": "DHT Record Report Scope",
|
||||||
"oneOf": [
|
"oneOf": [
|
||||||
|
@ -1852,6 +1859,28 @@
|
||||||
"EnsureOrdered"
|
"EnsureOrdered"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"SetDHTValueOptions": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"allow_offline": {
|
||||||
|
"description": "Defaults to true. If false, the value will not be written if the node is offline, and a TryAgain error will be returned.",
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/AllowOffline"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"writer": {
|
||||||
|
"type": [
|
||||||
|
"string",
|
||||||
|
"null"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"Stability": {
|
"Stability": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
|
|
|
@ -431,6 +431,27 @@ class DHTRecordReport:
|
||||||
return self.__dict__
|
return self.__dict__
|
||||||
|
|
||||||
|
|
||||||
|
class SetDHTValueOptions:
|
||||||
|
writer: Optional[KeyPair]
|
||||||
|
allow_offline: Optional[bool]
|
||||||
|
|
||||||
|
def __init__(self, writer: Optional[KeyPair], allow_offline: Optional[bool] = None):
|
||||||
|
self.writer = writer
|
||||||
|
self.allow_offline = allow_offline
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"<{self.__class__.__name__}(writer={self.writer!r}, allow_offline={self.allow_offline!r})>"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, j: dict) -> Self:
|
||||||
|
return cls(
|
||||||
|
KeyPair(j["writer"]) if "writer" in j else None,
|
||||||
|
j["allow_offline"] if "allow_offline" in j else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
def to_json(self) -> dict:
|
||||||
|
return self.__dict__
|
||||||
|
|
||||||
@total_ordering
|
@total_ordering
|
||||||
class ValueData:
|
class ValueData:
|
||||||
seq: ValueSeqNum
|
seq: ValueSeqNum
|
||||||
|
|
|
@ -324,11 +324,11 @@ impl JsonRequestProcessor {
|
||||||
key,
|
key,
|
||||||
subkey,
|
subkey,
|
||||||
data,
|
data,
|
||||||
writer,
|
options,
|
||||||
} => RoutingContextResponseOp::SetDhtValue {
|
} => RoutingContextResponseOp::SetDhtValue {
|
||||||
result: to_json_api_result(
|
result: to_json_api_result(
|
||||||
routing_context
|
routing_context
|
||||||
.set_dht_value(key, subkey, data, writer)
|
.set_dht_value(key, subkey, data, options)
|
||||||
.await,
|
.await,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -72,8 +72,7 @@ pub enum RoutingContextRequestOp {
|
||||||
#[serde(with = "as_human_base64")]
|
#[serde(with = "as_human_base64")]
|
||||||
#[schemars(with = "String")]
|
#[schemars(with = "String")]
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
#[schemars(with = "Option<String>")]
|
options: Option<SetDHTValueOptions>,
|
||||||
writer: Option<KeyPair>,
|
|
||||||
},
|
},
|
||||||
WatchDhtValues {
|
WatchDhtValues {
|
||||||
#[schemars(with = "String")]
|
#[schemars(with = "String")]
|
||||||
|
|
|
@ -593,7 +593,7 @@ pub fn routing_context_set_dht_value(
|
||||||
key: String,
|
key: String,
|
||||||
subkey: u32,
|
subkey: u32,
|
||||||
data: String,
|
data: String,
|
||||||
writer: Option<String>,
|
options: Option<String>,
|
||||||
) -> Promise {
|
) -> Promise {
|
||||||
wrap_api_future_json(async move {
|
wrap_api_future_json(async move {
|
||||||
let key: veilid_core::TypedRecordKey =
|
let key: veilid_core::TypedRecordKey =
|
||||||
|
@ -601,15 +601,16 @@ pub fn routing_context_set_dht_value(
|
||||||
let data: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
let data: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
||||||
.decode(data.as_bytes())
|
.decode(data.as_bytes())
|
||||||
.map_err(VeilidAPIError::generic)?;
|
.map_err(VeilidAPIError::generic)?;
|
||||||
let writer: Option<veilid_core::KeyPair> = match writer {
|
|
||||||
Some(s) => veilid_core::deserialize_json(&s).map_err(VeilidAPIError::generic)?,
|
let options: Option<veilid_core::SetDHTValueOptions> = match options {
|
||||||
|
Some(s) => Some(veilid_core::deserialize_json(&s).map_err(VeilidAPIError::generic)?),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let routing_context = get_routing_context(id, "routing_context_set_dht_value")?;
|
let routing_context = get_routing_context(id, "routing_context_set_dht_value")?;
|
||||||
|
|
||||||
let res = routing_context
|
let res = routing_context
|
||||||
.set_dht_value(key, subkey, data, writer)
|
.set_dht_value(key, subkey, data, options)
|
||||||
.await?;
|
.await?;
|
||||||
APIResult::Ok(res)
|
APIResult::Ok(res)
|
||||||
})
|
})
|
||||||
|
|
|
@ -322,17 +322,14 @@ impl VeilidRoutingContext {
|
||||||
key: String,
|
key: String,
|
||||||
subkey: u32,
|
subkey: u32,
|
||||||
data: Box<[u8]>,
|
data: Box<[u8]>,
|
||||||
writer: Option<String>,
|
options: Option<SetDHTValueOptions>,
|
||||||
) -> APIResult<Option<ValueData>> {
|
) -> APIResult<Option<ValueData>> {
|
||||||
let key = TypedRecordKey::from_str(&key)?;
|
let key = TypedRecordKey::from_str(&key)?;
|
||||||
let data = data.into_vec();
|
let data = data.into_vec();
|
||||||
let writer = writer
|
|
||||||
.map(|writer| KeyPair::from_str(&writer))
|
|
||||||
.map_or(APIResult::Ok(None), |r| r.map(Some))?;
|
|
||||||
|
|
||||||
let routing_context = self.getRoutingContext()?;
|
let routing_context = self.getRoutingContext()?;
|
||||||
let res = routing_context
|
let res = routing_context
|
||||||
.set_dht_value(key, subkey, data, writer)
|
.set_dht_value(key, subkey, data, options)
|
||||||
.await?;
|
.await?;
|
||||||
APIResult::Ok(res)
|
APIResult::Ok(res)
|
||||||
}
|
}
|
||||||
|
|
2
veilid-wasm/tests/package-lock.json
generated
2
veilid-wasm/tests/package-lock.json
generated
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
"../pkg": {
|
"../pkg": {
|
||||||
"name": "veilid-wasm",
|
"name": "veilid-wasm",
|
||||||
"version": "0.4.6",
|
"version": "0.4.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MPL-2.0"
|
"license": "MPL-2.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -225,7 +225,10 @@ describe('VeilidRoutingContext', () => {
|
||||||
dhtRecord.key,
|
dhtRecord.key,
|
||||||
0,
|
0,
|
||||||
textEncoder.encode(`${data}👋`),
|
textEncoder.encode(`${data}👋`),
|
||||||
`${dhtRecord.owner}:${dhtRecord.owner_secret}`
|
{
|
||||||
|
writer: `${dhtRecord.owner}:${dhtRecord.owner_secret}`,
|
||||||
|
allow_offline: undefined
|
||||||
|
}
|
||||||
);
|
);
|
||||||
expect(setValueRes).toBeUndefined();
|
expect(setValueRes).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue