From d48f65e388dde809d2f18e0bdb647ad603d01acd Mon Sep 17 00:00:00 2001 From: Benno Zeeman <bzeeman@live.nl> Date: Tue, 1 Oct 2024 12:51:44 +0200 Subject: [PATCH] refactor(autonomi): pass vault key as parameter --- autonomi/src/client/files.rs | 29 ++++++++++++------ autonomi/src/client/mod.rs | 10 +----- autonomi/src/client/vault.rs | 59 +++++++++++------------------------- autonomi/tests/file.rs | 28 ++++++----------- 4 files changed, 49 insertions(+), 77 deletions(-) diff --git a/autonomi/src/client/files.rs b/autonomi/src/client/files.rs index 524fc6fb7e..e53ab37d32 100644 --- a/autonomi/src/client/files.rs +++ b/autonomi/src/client/files.rs @@ -14,6 +14,23 @@ pub struct Root { pub map: HashMap<PathBuf, FilePointer>, } +impl Root { + /// Deserialize from bytes. + pub fn from_bytes(data: Bytes) -> Result<Root, rmp_serde::decode::Error> { + let root: Root = rmp_serde::from_slice(&data[..])?; + + Ok(root) + } + + /// Serialize to bytes. + pub fn into_bytes(&self) -> Result<Bytes, rmp_serde::encode::Error> { + let root_serialized = rmp_serde::to_vec(&self)?; + let root_serialized = Bytes::from(root_serialized); + + Ok(root_serialized) + } +} + /// Structure that describes a file on the network. The actual data is stored in /// chunks, to be constructed with the address pointing to the data map. /// @@ -46,13 +63,7 @@ impl Client { pub async fn fetch_root(&mut self, address: XorName) -> Result<Root, UploadError> { let data = self.get(address).await?; - Self::deserialize_root(data) - } - - pub fn deserialize_root(data: Bytes) -> Result<Root, UploadError> { - let root: Root = rmp_serde::from_slice(&data[..]).expect("TODO"); - - Ok(root) + Ok(Root::from_bytes(data)?) } /// Fetch the file pointed to by the given pointer. @@ -85,9 +96,9 @@ impl Client { } let root = Root { map }; - let root_serialized = rmp_serde::to_vec(&root).expect("TODO"); + let root_serialized = root.into_bytes()?; - let xor_name = self.put(Bytes::from(root_serialized), wallet).await?; + let xor_name = self.put(root_serialized, wallet).await?; Ok((root, xor_name)) } diff --git a/autonomi/src/client/mod.rs b/autonomi/src/client/mod.rs index 2900ae12b7..e5eb967f03 100644 --- a/autonomi/src/client/mod.rs +++ b/autonomi/src/client/mod.rs @@ -9,8 +9,6 @@ pub mod vault; use std::{collections::HashSet, time::Duration}; -#[cfg(feature = "vault")] -use bls::SecretKey; use libp2p::{identity::Keypair, Multiaddr}; use sn_networking::{multiaddr_is_global, Network, NetworkBuilder, NetworkEvent}; use sn_protocol::{version::IDENTIFY_PROTOCOL_STR, CLOSE_GROUP_SIZE}; @@ -37,8 +35,6 @@ pub const CONNECT_TIMEOUT_SECS: u64 = 20; #[derive(Clone)] pub struct Client { pub(crate) network: Network, - #[cfg(feature = "vault")] - pub(crate) vault_secret_key: Option<SecretKey>, } /// Error returned by [`Client::connect`]. @@ -88,11 +84,7 @@ impl Client { receiver.await.expect("sender should not close")?; - Ok(Self { - network, - #[cfg(feature = "vault")] - vault_secret_key: None, - }) + Ok(Self { network }) } } diff --git a/autonomi/src/client/vault.rs b/autonomi/src/client/vault.rs index 527ca2b9b7..afe38c0825 100644 --- a/autonomi/src/client/vault.rs +++ b/autonomi/src/client/vault.rs @@ -17,8 +17,6 @@ use tracing::info; pub enum VaultError { #[error("Could not generate Vault secret key from entropy: {0:?}")] Bls(#[from] bls::Error), - #[error("No Vault has been defined. Use `client.with_vault_entropy` to define one.")] - NoVaultPacketDefined, #[error("Scratchpad found at {0:?} was not a valid record.")] CouldNotDeserializeVaultScratchPad(ScratchpadAddress), #[error("Protocol: {0}")] @@ -28,37 +26,22 @@ pub enum VaultError { } impl Client { - /// Add a vault secret key to the client - /// - /// The secret key is derived from the supplied entropy bytes. - pub fn with_vault_entropy(mut self, bytes: Bytes) -> Result<Self, VaultError> { - // simple hash as XORNAME_LEN == SK_LENs - let xorname = xor_name::XorName::from_content(&bytes); - // before generating the sk from these bytes. - self.vault_secret_key = Some(SecretKey::from_bytes(xorname.0)?); - - Ok(self) - } - /// Retrieves and returns a decrypted vault if one exists. - pub async fn fetch_and_decrypt_vault(&self) -> Result<Option<Bytes>, VaultError> { - let Some(vault_secret_key) = self.vault_secret_key.as_ref() else { - return Err(VaultError::NoVaultPacketDefined); - }; - - let pad = self.get_vault_from_network().await?; + pub async fn fetch_and_decrypt_vault( + &self, + secret_key: &SecretKey, + ) -> Result<Option<Bytes>, VaultError> { + let pad = self.get_vault_from_network(secret_key).await?; - Ok(pad.decrypt_data(vault_secret_key)?) + Ok(pad.decrypt_data(secret_key)?) } /// Gets the vault Scratchpad from a provided client public key - async fn get_vault_from_network(&self) -> Result<Scratchpad, VaultError> { - // let vault = self.vault.as_ref()?; - let Some(vault_secret_key) = self.vault_secret_key.as_ref() else { - return Err(VaultError::NoVaultPacketDefined); - }; - - let client_pk = vault_secret_key.public_key(); + async fn get_vault_from_network( + &self, + secret_key: &SecretKey, + ) -> Result<Scratchpad, VaultError> { + let client_pk = secret_key.public_key(); let scratch_address = ScratchpadAddress::new(client_pk); let network_address = NetworkAddress::from_scratchpad_address(scratch_address); @@ -85,23 +68,17 @@ impl Client { /// Put data into the client's VaultPacket /// - /// Returns Ok(None) early if no vault packet is defined. - /// /// Pays for a new VaultPacket if none yet created for the client. Returns the current version /// of the data on success. - pub async fn write_bytes_to_vault_if_defined( + pub async fn write_bytes_to_vault( &mut self, data: Bytes, wallet: &mut Wallet, - ) -> Result<Option<u64>, PutError> { - // Exit early if no vault packet defined - let Some(client_sk) = self.vault_secret_key.as_ref() else { - return Ok(None); - }; - - let client_pk = client_sk.public_key(); + secret_key: &SecretKey, + ) -> Result<u64, PutError> { + let client_pk = secret_key.public_key(); - let pad_res = self.get_vault_from_network().await; + let pad_res = self.get_vault_from_network(secret_key).await; let mut is_new = true; let mut scratch = if let Ok(existing_data) = pad_res { @@ -119,7 +96,7 @@ impl Client { Scratchpad::new(client_pk) }; - let next_count = scratch.update_and_sign(data, client_sk); + let next_count = scratch.update_and_sign(data, secret_key); let scratch_address = scratch.network_address(); let scratch_key = scratch_address.to_record_key(); @@ -172,6 +149,6 @@ impl Client { self.network.put_record(record, &put_cfg).await?; - Ok(Some(next_count)) + Ok(next_count) } } diff --git a/autonomi/tests/file.rs b/autonomi/tests/file.rs index 952f859631..0ecb19d292 100644 --- a/autonomi/tests/file.rs +++ b/autonomi/tests/file.rs @@ -2,10 +2,6 @@ mod common; use crate::common::{evm_network_from_env, evm_wallet_from_env_or_default}; use autonomi::Client; -#[cfg(feature = "vault")] -use bytes::Bytes; -#[cfg(feature = "vault")] -use eyre::bail; use std::time::Duration; use tokio::time::sleep; @@ -18,9 +14,6 @@ async fn file() -> Result<(), Box<dyn std::error::Error>> { let mut client = Client::connect(&[]).await.unwrap(); let wallet = evm_wallet_from_env_or_default(network); - // let data = common::gen_random_data(1024 * 1024 * 1000); - // let user_key = common::gen_random_data(32); - let (root, addr) = client .upload_from_dir("tests/file/test_dir".into(), &wallet) .await?; @@ -44,11 +37,9 @@ async fn file_into_vault() -> eyre::Result<()> { let network = evm_network_from_env(); - let mut client = Client::connect(&[]) - .await? - .with_vault_entropy(Bytes::from("at least 32 bytes of entropy here"))?; - - let wallet = evm_wallet_from_env_or_default(network); + let mut client = Client::connect(&[]).await?; + let mut wallet = evm_wallet_from_env_or_default(network); + let client_sk = bls::SecretKey::random(); let (root, addr) = client .upload_from_dir("tests/file/test_dir".into(), &wallet) @@ -56,6 +47,9 @@ async fn file_into_vault() -> eyre::Result<()> { sleep(Duration::from_secs(2)).await; let root_fetched = client.fetch_root(addr).await?; + client + .write_bytes_to_vault(root.into_bytes()?, &mut wallet, &client_sk) + .await?; assert_eq!( root.map, root_fetched.map, @@ -63,19 +57,17 @@ async fn file_into_vault() -> eyre::Result<()> { ); // now assert over the stored account packet - let new_client = Client::connect(&[]) - .await? - .with_vault_entropy(Bytes::from("at least 32 bytes of entropy here"))?; + let new_client = Client::connect(&[]).await?; - if let Some(ap) = new_client.fetch_and_decrypt_vault().await? { - let ap_root_fetched = Client::deserialize_root(ap)?; + if let Some(ap) = new_client.fetch_and_decrypt_vault(&client_sk).await? { + let ap_root_fetched = autonomi::client::files::Root::from_bytes(ap)?; assert_eq!( root.map, ap_root_fetched.map, "root fetched should match root put" ); } else { - bail!("No account packet found"); + eyre::bail!("No account packet found"); } Ok(())