start of storage manager

This commit is contained in:
John Smith
2023-04-01 20:04:20 -04:00
parent 1430f3f656
commit c78035a5d9
11 changed files with 420 additions and 41 deletions

View File

@@ -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

View File

@@ -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;
/////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -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
}
///////////////////////////////////

View File

@@ -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,