diff --git a/packages/ciphernode/data/src/data_store.rs b/packages/ciphernode/data/src/data_store.rs index 90b4a5e1..fa813f35 100644 --- a/packages/ciphernode/data/src/data_store.rs +++ b/packages/ciphernode/data/src/data_store.rs @@ -3,10 +3,61 @@ use anyhow::Result; use crate::InMemDataStore; +pub trait IntoKey { + fn into_key(self) -> Vec; +} + +impl IntoKey for Vec { + fn into_key(self) -> Vec { + self.join("/").into_bytes() + } +} + +impl<'a> IntoKey for Vec<&'a str> { + fn into_key(self) -> Vec { + self.join("/").into_bytes() + } +} + +impl IntoKey for String { + fn into_key(self) -> Vec { + self.into_bytes() + } +} + +impl<'a> IntoKey for &'a str { + fn into_key(self) -> Vec { + self.as_bytes().to_vec() + } +} + +pub trait WithPrefix: Sized { + fn prefix(self, prefix: &str) -> Self; + fn base(self, key: &str) -> Self; +} + +impl WithPrefix for Vec { + fn prefix(self, prefix: &str) -> Self { + let Ok(encoded) = String::from_utf8(self.clone()) else { + // If this is not encoded as utf8 do nothing + return self; + }; + vec![prefix.to_string(), encoded].join("/").into_bytes() + } + + fn base(self, key: &str) -> Self { + key.to_string().into_bytes() + } +} + #[derive(Message, Clone, Debug, PartialEq, Eq, Hash)] #[rtype(result = "()")] pub struct Insert(pub Vec, pub Vec); impl Insert { + pub fn new(key: K, value: Vec) -> Self { + Self(key.into_key(), value) + } + pub fn key(&self) -> Vec { self.0.clone() } @@ -16,29 +67,61 @@ impl Insert { } } +impl WithPrefix for Insert { + fn prefix(self, prefix: &str) -> Self { + Insert(self.0.prefix(prefix), self.1) + } + + fn base(self, key: &str) -> Self { + Insert(self.0.base(key), self.1) + } +} + #[derive(Message, Clone, Debug, PartialEq, Eq, Hash)] #[rtype(result = "Option>")] pub struct Get(pub Vec); impl Get { + pub fn new(key: K) -> Self { + Self(key.into_key()) + } + pub fn key(&self) -> Vec { self.0.clone() } } +impl WithPrefix for Get { + fn prefix(self, prefix: &str) -> Self { + Get(self.0.prefix(prefix)) + } + fn base(self, key: &str) -> Self { + Get(self.0.base(key)) + } +} + #[derive(Clone)] -pub struct DataStore(Recipient, Recipient); +pub struct DataStore { + prefix: Option, + get: Recipient, + insert: Recipient, +} + impl DataStore { pub async fn read(&self, msg: Get) -> Result>> { - Ok(self.0.send(msg).await?) + Ok(self.get.send(msg).await?) } pub fn write(&self, msg: Insert) { - self.1.do_send(msg) + self.insert.do_send(msg) } // use this for testing pub fn from_in_mem(addr: Addr) -> Self { - Self(addr.clone().recipient(), addr.clone().recipient()) + Self { + get: addr.clone().recipient(), + insert: addr.clone().recipient(), + prefix: None, + } } // // use this for production @@ -47,3 +130,24 @@ impl DataStore { // Self(d.recipient(),d.recipient()) // } } + +impl WithPrefix for DataStore { + fn prefix(self, prefix: &str) -> Self { + Self { + get: self.get, + insert: self.insert, + prefix: self.prefix.map_or_else( + || Some(prefix.to_string()), + |p| Some(vec![prefix.to_string(), p].join("/")), + ), + } + } + + fn base(self, key: &str) -> Self { + Self { + get: self.get, + insert: self.insert, + prefix: Some(key.to_string()), + } + } +} diff --git a/packages/ciphernode/data/src/lib.rs b/packages/ciphernode/data/src/lib.rs index 6acf7a73..a439fca7 100644 --- a/packages/ciphernode/data/src/lib.rs +++ b/packages/ciphernode/data/src/lib.rs @@ -1,4 +1,4 @@ -mod in_mem; mod data_store; -pub use in_mem::*; +mod in_mem; pub use data_store::*; +pub use in_mem::*; diff --git a/packages/ciphernode/keyshare/src/keyshare.rs b/packages/ciphernode/keyshare/src/keyshare.rs index 113b828f..49a447f6 100644 --- a/packages/ciphernode/keyshare/src/keyshare.rs +++ b/packages/ciphernode/keyshare/src/keyshare.rs @@ -63,8 +63,7 @@ impl Handler for Keyshare { // reencrypt secretkey locally with env var - this is so we don't have to serialize a secret // best practice would be as you boot up a node you enter in a configured password from // which we derive a kdf which gets used to generate this key - self.data - .write(Insert(format!("{}/sk", e3_id).into(), sk)); + self.data.write(Insert(format!("{}/sk", e3_id).into(), sk)); // save public key against e3_id/pk self.data