From 96ab4325e38bf4cf96da8d2e81696e20ffa2c1ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Mon, 9 Jan 2023 12:39:23 +0100 Subject: [PATCH] rust-sdk: tidy --- clients/client-core/src/client/key_manager.rs | 20 +++++----- ....rs => manually_handle_keys_and_config.rs} | 38 ++++++++++++++----- .../{complex_config.rs => persist_keys.rs} | 0 sdk/rust/nym-sdk/src/error.rs | 2 + sdk/rust/nym-sdk/src/mixnet/client.rs | 17 +++++---- sdk/rust/nym-sdk/src/mixnet/keys.rs | 2 +- 6 files changed, 51 insertions(+), 28 deletions(-) rename sdk/rust/nym-sdk/examples/{complex_config2.rs => manually_handle_keys_and_config.rs} (52%) rename sdk/rust/nym-sdk/examples/{complex_config.rs => persist_keys.rs} (100%) diff --git a/clients/client-core/src/client/key_manager.rs b/clients/client-core/src/client/key_manager.rs index 69192a3394..83c9ba61f2 100644 --- a/clients/client-core/src/client/key_manager.rs +++ b/clients/client-core/src/client/key_manager.rs @@ -17,7 +17,6 @@ use std::sync::Arc; // use the old key after new one was issued. // Remember that Arc has Deref implementation for T -// WIP(JON): let's try not to have the clone #[derive(Clone)] pub struct KeyManager { /// identity key associated with the client instance. @@ -59,7 +58,7 @@ impl KeyManager { } } - pub fn new_from_keys( + pub fn from_keys( id_keypair: identity::KeyPair, enc_keypair: encryption::KeyPair, gateway_shared_key: SharedKeys, @@ -82,7 +81,7 @@ impl KeyManager { } /// Loads previously stored client keys from the disk. - fn load_keys_client_only(client_pathfinder: &ClientKeyPathfinder) -> io::Result { + fn load_client_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result { let identity_keypair: identity::KeyPair = pemstore::load_keypair(&pemstore::KeyPairPath::new( client_pathfinder.private_identity_key().to_owned(), @@ -107,7 +106,7 @@ impl KeyManager { /// Loads previously stored keys from the disk. Fails if not all, including the shared gateway /// key, is available. pub fn load_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result { - let mut key_manager = Self::load_keys_client_only(client_pathfinder)?; + let mut key_manager = Self::load_client_keys(client_pathfinder)?; let gateway_shared_key: SharedKeys = pemstore::load_key(client_pathfinder.gateway_shared_key())?; @@ -117,8 +116,12 @@ impl KeyManager { Ok(key_manager) } - pub fn load_keys_maybe_gateway(client_pathfinder: &ClientKeyPathfinder) -> io::Result { - let mut key_manager = Self::load_keys_client_only(client_pathfinder)?; + /// Loads previously stored keys from the disk. Fails if client keys are not availabe, but the + /// shared gateway key is optional. + pub fn load_keys_but_gateway_is_optional( + client_pathfinder: &ClientKeyPathfinder, + ) -> io::Result { + let mut key_manager = Self::load_client_keys(client_pathfinder)?; let gateway_shared_key: Result = pemstore::load_key(client_pathfinder.gateway_shared_key()); @@ -170,10 +173,7 @@ impl KeyManager { Ok(()) } - pub fn store_key_gateway_only( - &self, - client_pathfinder: &ClientKeyPathfinder, - ) -> io::Result<()> { + pub fn store_gateway_key(&self, client_pathfinder: &ClientKeyPathfinder) -> io::Result<()> { match self.gateway_shared_key.as_ref() { None => { return Err(io::Error::new( diff --git a/sdk/rust/nym-sdk/examples/complex_config2.rs b/sdk/rust/nym-sdk/examples/manually_handle_keys_and_config.rs similarity index 52% rename from sdk/rust/nym-sdk/examples/complex_config2.rs rename to sdk/rust/nym-sdk/examples/manually_handle_keys_and_config.rs index bacb942b41..c9c196aad9 100644 --- a/sdk/rust/nym-sdk/examples/complex_config2.rs +++ b/sdk/rust/nym-sdk/examples/manually_handle_keys_and_config.rs @@ -6,21 +6,24 @@ async fn main() { // We can set a few options let user_chosen_gateway_id = None; - let nym_api_endpointgs = vec![]; - let config = mixnet::Config::new(user_chosen_gateway_id, nym_api_endpointgs); + let nym_api_endpoints = vec!["https://validator.nymtech.net/api/".parse().unwrap()]; + + let config = mixnet::Config::new(user_chosen_gateway_id, nym_api_endpoints); let mut client = mixnet::Client::new(Some(config), None).unwrap(); + // Just some plain data to pretend we have some external storage that the application + // implementer is using. + let mut mock_storage = MockStorage::empty(); + // In this we want to provide our own gateway config struct, and handle persisting this info to disk // ourselves (e.g., as part of our own configuration file). - // NOTE: gateway shared key is written to disk according to the path given earlier - // Checks if we have a shared gateway key loaded let first_run = true; if first_run { client.register_with_gateway().await.unwrap(); - write_to_storage(client.get_keys(), client.get_gateway_endpoint().unwrap()); + mock_storage.write(client.get_keys(), client.get_gateway_endpoint().unwrap()); } else { - let (keys, gateway_config) = read_from_storage(); + let (keys, gateway_config) = mock_storage.read(); client.set_keys(&keys); client.set_gateway_endpoint(&gateway_config); } @@ -35,10 +38,25 @@ async fn main() { client.send_str("foo.bar@blah", "flappappa").await; } -fn write_to_storage(_keys: &mixnet::Keys, _gateway_config: &mixnet::GatewayEndpointConfig) { - todo!(); +#[allow(unused)] +struct MockStorage { + pub gateway_config: Option, + pub keys: Option>, } -fn read_from_storage() -> (mixnet::Keys, mixnet::GatewayEndpointConfig) { - todo!(); +impl MockStorage { + fn read(&self) -> (mixnet::Keys, mixnet::GatewayEndpointConfig) { + todo!(); + } + + fn write(&mut self, _keys: &mixnet::Keys, _gateway_config: &mixnet::GatewayEndpointConfig) { + todo!(); + } + + fn empty() -> Self { + Self { + gateway_config: None, + keys: None, + } + } } diff --git a/sdk/rust/nym-sdk/examples/complex_config.rs b/sdk/rust/nym-sdk/examples/persist_keys.rs similarity index 100% rename from sdk/rust/nym-sdk/examples/complex_config.rs rename to sdk/rust/nym-sdk/examples/persist_keys.rs diff --git a/sdk/rust/nym-sdk/src/error.rs b/sdk/rust/nym-sdk/src/error.rs index cdc6f4fa2d..18e5718e13 100644 --- a/sdk/rust/nym-sdk/src/error.rs +++ b/sdk/rust/nym-sdk/src/error.rs @@ -12,6 +12,8 @@ pub enum Error { DontOverwrite, #[error("shared gateway key file encountered that we don't want to overwrite")] DontOverwriteGatewayKey, + #[error("no gateway config available for writing")] + GatewayNotAvailableForWriting, } pub type Result = std::result::Result; diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index ec7f267dd8..70b64ad9f2 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -51,7 +51,7 @@ impl Client { let path_finder = ClientKeyPathfinder::from(paths.clone()); // Try load keys - match KeyManager::load_keys_maybe_gateway(&path_finder) { + match KeyManager::load_keys_but_gateway_is_optional(&path_finder) { Ok(key_manager) => key_manager, Err(err) => { log::debug!("Not loading keys: {err}"); @@ -140,12 +140,15 @@ impl Client { if path_finder.gateway_key_file_exists() && key_mode.is_keep() { return Err(Error::DontOverwriteGatewayKey); }; - self.key_manager.store_key_gateway_only(&path_finder)?; + self.key_manager.store_gateway_key(&path_finder)?; Ok(()) } - fn write_gateway_endpoint_config(gateway_endpoint_config_path: &Path) -> Result<()> { - let gateway_endpoint_config = toml::to_string(gateway_endpoint_config_path)?; + fn write_gateway_endpoint_config(&self, gateway_endpoint_config_path: &Path) -> Result<()> { + let gateway_endpoint_config = toml::to_string( + self.get_gateway_endpoint() + .ok_or(Error::GatewayNotAvailableForWriting)?, + )?; // Ensure the whole directory structure exists if let Some(parent_dir) = gateway_endpoint_config_path.parent() { @@ -180,15 +183,15 @@ impl Client { if self.has_gateway_key() { // If we have a gateway key from client, then we can just read the corresponding // config - println!("Has gateway key: loading"); + log::trace!("Gateway key found: loading"); self.read_gateway_endpoint_config(&paths.gateway_endpoint_config)?; } else { // If we didn't find any shared gateway key during creation, that means we first // need to register a gateway - println!("NO gateway key: registering new"); + log::trace!("Gateway key NOT found: registering new"); self.register_with_gateway().await?; self.write_gateway_key(paths.clone(), &GatewayKeyMode::Overwrite)?; - Self::write_gateway_endpoint_config(&paths.gateway_endpoint_config)?; + self.write_gateway_endpoint_config(&paths.gateway_endpoint_config)?; } } else { // If we don't have any key paths, just use ephemeral keys diff --git a/sdk/rust/nym-sdk/src/mixnet/keys.rs b/sdk/rust/nym-sdk/src/mixnet/keys.rs index cc1940f3cc..c6a60f3494 100644 --- a/sdk/rust/nym-sdk/src/mixnet/keys.rs +++ b/sdk/rust/nym-sdk/src/mixnet/keys.rs @@ -12,7 +12,7 @@ pub struct Keys { impl From for KeyManager { fn from(keys: Keys) -> Self { - KeyManager::new_from_keys( + KeyManager::from_keys( keys.identity_keypair, keys.encryption_keypair, keys.gateway_shared_key,