start of storage manager
This commit is contained in:
@@ -112,6 +112,13 @@ impl VeilidAPI {
|
||||
}
|
||||
Err(VeilidAPIError::NotInitialized)
|
||||
}
|
||||
pub fn storage_manager(&self) -> Result<StorageManager, VeilidAPIError> {
|
||||
let inner = self.inner.lock();
|
||||
if let Some(context) = &inner.context {
|
||||
return Ok(context.storage_manager.clone());
|
||||
}
|
||||
Err(VeilidAPIError::NotInitialized)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Attach/Detach
|
||||
|
||||
@@ -34,5 +34,6 @@ use rkyv::{Archive as RkyvArchive, Deserialize as RkyvDeserialize, Serialize as
|
||||
use routing_table::{RouteSpecStore, RoutingTable};
|
||||
use rpc_processor::*;
|
||||
use serde::*;
|
||||
use storage_manager::StorageManager;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -197,39 +197,91 @@ impl RoutingContext {
|
||||
///////////////////////////////////
|
||||
/// DHT Values
|
||||
|
||||
/// Creates a new DHT value with a specified crypto kind and schema
|
||||
/// Returns the newly allocated DHT Key if successful.
|
||||
pub async fn create_value(
|
||||
&self,
|
||||
kind: CryptoKind,
|
||||
schema: &DHTSchema,
|
||||
) -> Result<TypedKey, VeilidAPIError> {
|
||||
let storage_manager = self.api.storage_manager()?;
|
||||
storage_manager
|
||||
.create_value(kind, schema, self.unlocked_inner.safety_selection)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Opens a DHT value at a specific key. Associates a secret if one is provided to provide writer capability.
|
||||
/// Returns the DHT key descriptor for the opened key if successful
|
||||
/// Value may only be opened or created once. To re-open with a different routing context, first close the value.
|
||||
pub async fn open_value(
|
||||
key: TypedKey,
|
||||
secret: Option<SecretKey>,
|
||||
) -> Result<DHTDescriptor, VeilidAPIError> {
|
||||
let storage_manager = self.api.storage_manager()?;
|
||||
storage_manager
|
||||
.open_value(key, secret, self.unlocked_inner.safety_selection)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Closes a DHT value at a specific key that was opened with create_value or open_value.
|
||||
/// Closing a value allows you to re-open it with a different routing context
|
||||
pub async fn close_value(key: TypedKey) -> Result<(), VeilidAPIError> {
|
||||
let storage_manager = self.api.storage_manager()?;
|
||||
storage_manager.close_value(key).await
|
||||
}
|
||||
|
||||
/// Gets the latest value of a subkey from the network
|
||||
/// Returns the possibly-updated value data of the subkey
|
||||
pub async fn get_value(
|
||||
&self,
|
||||
_key: TypedKey,
|
||||
_subkey: ValueSubkey,
|
||||
key: TypedKey,
|
||||
subkey: ValueSubkey,
|
||||
force_refresh: bool,
|
||||
) -> Result<ValueData, VeilidAPIError> {
|
||||
panic!("unimplemented");
|
||||
let storage_manager = self.api.storage_manager()?;
|
||||
storage_manager.get_value(key, subkey, force_refresh).await
|
||||
}
|
||||
|
||||
/// Pushes a changed subkey value to the network
|
||||
/// Returns None if the value was successfully put
|
||||
/// Returns Some(newer_value) if the value put was older than the one available on the network
|
||||
pub async fn set_value(
|
||||
&self,
|
||||
_key: TypedKey,
|
||||
_subkey: ValueSubkey,
|
||||
_value: ValueData,
|
||||
) -> Result<bool, VeilidAPIError> {
|
||||
panic!("unimplemented");
|
||||
key: TypedKey,
|
||||
subkey: ValueSubkey,
|
||||
value_data: ValueData,
|
||||
) -> Result<Option<ValueData>, VeilidAPIError> {
|
||||
let storage_manager = self.api.storage_manager()?;
|
||||
storage_manager.set_value(key, subkey, value_data).await
|
||||
}
|
||||
|
||||
/// Watches changes to an opened or created value
|
||||
/// Changes to subkeys within the subkey range are returned via a ValueChanged callback
|
||||
/// If the subkey range is empty, all subkey changes are considered
|
||||
/// Expiration can be infinite to keep the watch for the maximum amount of time
|
||||
/// Return value upon success is the amount of time allowed for the watch
|
||||
pub async fn watch_value(
|
||||
&self,
|
||||
_key: TypedKey,
|
||||
_subkeys: &[ValueSubkeyRange],
|
||||
_expiration: Timestamp,
|
||||
_count: u32,
|
||||
) -> Result<bool, VeilidAPIError> {
|
||||
panic!("unimplemented");
|
||||
key: TypedKey,
|
||||
subkeys: &[ValueSubkeyRange],
|
||||
expiration: Timestamp,
|
||||
count: u32,
|
||||
) -> Result<Timestamp, VeilidAPIError> {
|
||||
let storage_manager = self.api.storage_manager()?;
|
||||
storage_manager
|
||||
.watch_values(key, subkeys, expiration, count)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Cancels a watch early
|
||||
/// This is a convenience function that cancels watching all subkeys in a range
|
||||
pub async fn cancel_watch_value(
|
||||
&self,
|
||||
_key: TypedKey,
|
||||
_subkeys: &[ValueSubkeyRange],
|
||||
key: TypedKey,
|
||||
subkeys: &[ValueSubkeyRange],
|
||||
) -> Result<bool, VeilidAPIError> {
|
||||
panic!("unimplemented");
|
||||
let storage_manager = self.api.storage_manager()?;
|
||||
storage_manager.cancel_watch_value(key, subkey).await
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
|
||||
@@ -15,8 +15,6 @@ pub type OperationId = AlignedU64;
|
||||
pub type ByteCount = AlignedU64;
|
||||
/// Tunnel identifier
|
||||
pub type TunnelId = AlignedU64;
|
||||
/// Value schema
|
||||
pub type ValueSchema = FourCC;
|
||||
/// Value subkey
|
||||
pub type ValueSubkey = u32;
|
||||
/// Value subkey range
|
||||
@@ -356,19 +354,19 @@ pub struct VeilidState {
|
||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||
pub struct ValueData {
|
||||
pub seq: ValueSeqNum,
|
||||
pub schema: ValueSchema,
|
||||
pub data: Vec<u8>,
|
||||
pub writer: PublicKey,
|
||||
}
|
||||
impl ValueData {
|
||||
pub fn new(schema: ValueSchema, data: Vec<u8>) -> Self {
|
||||
pub fn new(data: Vec<u8>, writer: PublicKey) -> Self {
|
||||
Self {
|
||||
seq: 0,
|
||||
schema,
|
||||
data,
|
||||
writer,
|
||||
}
|
||||
}
|
||||
pub fn new_with_seq(seq: ValueSeqNum, schema: ValueSchema, data: Vec<u8>) -> Self {
|
||||
Self { seq, schema, data }
|
||||
pub fn new_with_seq(seq: ValueSeqNum, data: Vec<u8>, writer: PublicKey) -> Self {
|
||||
Self { seq, data, writer }
|
||||
}
|
||||
pub fn change(&mut self, data: Vec<u8>) {
|
||||
self.data = data;
|
||||
@@ -2402,22 +2400,129 @@ pub struct PeerStats {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Parameter for Signal operation
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
|
||||
#[archive_attr(repr(u8), derive(CheckBytes))]
|
||||
pub enum SignalInfo {
|
||||
/// UDP Hole Punch Request
|
||||
HolePunch {
|
||||
// UDP Hole Punch Request
|
||||
receipt: Vec<u8>, // Receipt to be returned after the hole punch
|
||||
peer_info: PeerInfo, // Sender's peer info
|
||||
/// /// Receipt to be returned after the hole punch
|
||||
receipt: Vec<u8>,
|
||||
/// Sender's peer info
|
||||
peer_info: PeerInfo,
|
||||
},
|
||||
/// Reverse Connection Request
|
||||
ReverseConnect {
|
||||
// Reverse Connection Request
|
||||
receipt: Vec<u8>, // Receipt to be returned by the reverse connection
|
||||
peer_info: PeerInfo, // Sender's peer info
|
||||
/// Receipt to be returned by the reverse connection
|
||||
receipt: Vec<u8>,
|
||||
/// Sender's peer info
|
||||
peer_info: PeerInfo,
|
||||
},
|
||||
// XXX: WebRTC
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Default DHT Schema (DFLT)
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
|
||||
)]
|
||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||
pub struct DHTSchemaDFLT {
|
||||
/// Owner subkey count
|
||||
pub o_cnt: u16,
|
||||
}
|
||||
|
||||
impl DHTSchemaDFLT {
|
||||
pub fn compile(&self) -> Vec<u8> {
|
||||
let mut out = Vec::<u8>::with_capacity(6);
|
||||
// kind
|
||||
out.extend_from_slice(&FourCC::from_str("DFLT").unwrap().0);
|
||||
// o_cnt
|
||||
out.extend_from_slice(&self.o_cnt.to_le_bytes());
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
/// Simple DHT Schema (SMPL) Member
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
|
||||
)]
|
||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||
pub struct DHTSchemaSMPLMember {
|
||||
/// Member key
|
||||
pub m_key: PublicKey,
|
||||
/// Member subkey countanyway,
|
||||
pub m_cnt: u16,
|
||||
}
|
||||
|
||||
/// Simple DHT Schema (SMPL)
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
|
||||
)]
|
||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||
pub struct DHTSchemaSMPL {
|
||||
/// Owner subkey count
|
||||
pub o_cnt: u16,
|
||||
/// Members
|
||||
pub members: Vec<DHTSchemaSMPLMember>,
|
||||
}
|
||||
|
||||
impl DHTSchemaSMPL {
|
||||
pub fn compile(&self) -> Vec<u8> {
|
||||
let mut out = Vec::<u8>::with_capacity(6 + (self.members.len() * (PUBLIC_KEY_LENGTH + 2)));
|
||||
// kind
|
||||
out.extend_from_slice(&FourCC::from_str("SMPL").unwrap().0);
|
||||
// o_cnt
|
||||
out.extend_from_slice(&self.o_cnt.to_le_bytes());
|
||||
// members
|
||||
for m in self.members {
|
||||
// m_key
|
||||
out.extend_from_slice(&m.m_key.bytes);
|
||||
// m_cnt
|
||||
out.extend_from_slice(&m.m_cnt.to_le_bytes());
|
||||
}
|
||||
out
|
||||
}
|
||||
}
|
||||
|
||||
/// Enum over all the supported DHT Schemas
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
|
||||
)]
|
||||
#[archive_attr(repr(u8), derive(CheckBytes))]
|
||||
#[serde(tag = "kind")]
|
||||
pub enum DHTSchema {
|
||||
DFLT(DHTSchemaDFLT),
|
||||
SMPL(DHTSchemaSMPL),
|
||||
}
|
||||
|
||||
impl DHTSchema {
|
||||
pub fn dflt(o_cnt: u16) -> DHTSchema {
|
||||
DHTSchema::DFLT(DHTSchemaDFLT { o_cnt })
|
||||
}
|
||||
pub fn smpl(o_cnt: u16, members: Vec<DHTSchemaSMPLMember>) -> DHTSchema {
|
||||
DHTSchema::SMPL(DHTSchemaSMPL { o_cnt, members })
|
||||
}
|
||||
|
||||
pub fn compile(&self) -> Vec<u8> {
|
||||
match self {
|
||||
DHTSchema::DFLT(d) => d.compile(),
|
||||
DHTSchema::SMPL(s) => s.compile(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// DHT Key Descriptor
|
||||
#[derive(
|
||||
Debug, Clone, PartialEq, Eq, Serialize, Deserialize, RkyvArchive, RkyvSerialize, RkyvDeserialize,
|
||||
)]
|
||||
#[archive_attr(repr(C), derive(CheckBytes))]
|
||||
pub struct DHTDescriptor {
|
||||
pub owner: PublicKey,
|
||||
pub schema: DHTSchema,
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#[derive(
|
||||
Copy,
|
||||
|
||||
Reference in New Issue
Block a user