diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index a9b15db1fb..4d4d4d6952 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -105,26 +105,24 @@ impl BandwidthController { async fn get_aggregate_verification_key( &self, epoch_id: EpochId, - apis: &mut ApiClientsWrapper, + ecash_apis: &mut ApiClientsWrapper<'_, C>, ) -> Result where C: DkgQueryClient + Sync + Send, ::StorageError: Send + Sync + 'static, { - let ecash_apis = apis.get_or_init(epoch_id, &self.client).await?; get_aggregate_verification_key(&self.storage, epoch_id, ecash_apis).await } async fn get_coin_index_signatures( &self, epoch_id: EpochId, - apis: &mut ApiClientsWrapper, + ecash_apis: &mut ApiClientsWrapper<'_, C>, ) -> Result, BandwidthControllerError> where C: DkgQueryClient + Sync + Send, ::StorageError: Send + Sync + 'static, { - let ecash_apis = apis.get_or_init(epoch_id, &self.client).await?; get_coin_index_signatures(&self.storage, epoch_id, ecash_apis).await } @@ -132,13 +130,12 @@ impl BandwidthController { &self, epoch_id: EpochId, expiration_date: Date, - apis: &mut ApiClientsWrapper, + ecash_apis: &mut ApiClientsWrapper<'_, C>, ) -> Result, BandwidthControllerError> where C: DkgQueryClient + Sync + Send, ::StorageError: Send + Sync + 'static, { - let ecash_apis = apis.get_or_init(epoch_id, &self.client).await?; get_expiration_date_signatures(&self.storage, epoch_id, expiration_date, ecash_apis).await } @@ -154,7 +151,7 @@ impl BandwidthController { { let epoch_id = retrieved_ticketbook.ticketbook.epoch_id(); let expiration_date = retrieved_ticketbook.ticketbook.expiration_date(); - let mut api_clients = Default::default(); + let mut api_clients = ApiClientsWrapper::new(&self.client, epoch_id); let verification_key = self .get_aggregate_verification_key(epoch_id, &mut api_clients) diff --git a/common/bandwidth-controller/src/utils.rs b/common/bandwidth-controller/src/utils.rs index 9c15f5924b..2016849eb0 100644 --- a/common/bandwidth-controller/src/utils.rs +++ b/common/bandwidth-controller/src/utils.rs @@ -21,30 +21,67 @@ use rand::thread_rng; use std::fmt::Display; use std::future::Future; -// it really doesn't need the RwLock because it's never moved across tasks, -// but we need all the Send/Sync action -#[derive(Default)] -pub(crate) struct ApiClientsWrapper(Option>); - -impl ApiClientsWrapper { - pub(crate) async fn get_or_init( +pub(crate) trait EcashClientsProvider { + async fn try_get_ecash_clients( &mut self, + ) -> Result, BandwidthControllerError>; +} + +impl EcashClientsProvider for Vec { + async fn try_get_ecash_clients( + &mut self, + ) -> Result, BandwidthControllerError> { + Ok(self.clone()) + } +} + +impl EcashClientsProvider for &mut ApiClientsWrapper<'_, C> +where + C: DkgQueryClient + Sync + Send, +{ + async fn try_get_ecash_clients( + &mut self, + ) -> Result, BandwidthControllerError> { + self.clients().await + } +} + +pub(crate) enum ApiClientsWrapper<'a, C> { + Uninitialised { + query_client: &'a C, epoch_id: EpochId, - dkg_client: &C, - ) -> Result, BandwidthControllerError> + }, + Cached { + clients: Vec, + }, +} + +impl<'a, C> ApiClientsWrapper<'a, C> { + pub(crate) fn new(query_client: &'a C, epoch_id: EpochId) -> Self { + ApiClientsWrapper::Uninitialised { + query_client, + epoch_id, + } + } + + async fn clients(&mut self) -> Result, BandwidthControllerError> where C: DkgQueryClient + Sync + Send, { - if let Some(cached) = &self.0 { - return Ok(cached.clone()); + match self { + ApiClientsWrapper::Uninitialised { + query_client, + epoch_id, + } => { + let clients = all_ecash_api_clients(*query_client, *epoch_id).await?; + *self = ApiClientsWrapper::Cached { + clients: clients.clone(), + }; + + Ok(clients) + } + ApiClientsWrapper::Cached { clients } => Ok(clients.clone()), } - - let clients = all_ecash_api_clients(dkg_client, epoch_id).await?; - - // technically we don't have to be cloning all the clients here, but it's way simpler than - // dealing with locking and whatnot given the performance penalty is negligible - self.0 = Some(clients.clone()); - Ok(clients) } } @@ -76,7 +113,7 @@ where pub(crate) async fn get_aggregate_verification_key( storage: &St, epoch_id: EpochId, - ecash_apis: Vec, + mut ecash_apis: impl EcashClientsProvider, ) -> Result where St: Storage, @@ -90,6 +127,8 @@ where return Ok(stored); }; + let ecash_apis = ecash_apis.try_get_ecash_clients().await?; + let master_vk = query_random_apis_until_success( ecash_apis, |api| async move { api.api_client.master_verification_key(Some(epoch_id)).await }, @@ -115,7 +154,7 @@ where pub(crate) async fn get_coin_index_signatures( storage: &St, epoch_id: EpochId, - ecash_apis: Vec, + mut ecash_apis: impl EcashClientsProvider, ) -> Result, BandwidthControllerError> where St: Storage, @@ -129,6 +168,8 @@ where return Ok(stored); }; + let ecash_apis = ecash_apis.try_get_ecash_clients().await?; + let index_sigs = query_random_apis_until_success( ecash_apis, |api| async move { @@ -159,7 +200,7 @@ pub(crate) async fn get_expiration_date_signatures( storage: &St, epoch_id: EpochId, expiration_date: Date, - ecash_apis: Vec, + mut ecash_apis: impl EcashClientsProvider, ) -> Result, BandwidthControllerError> where St: Storage, @@ -173,6 +214,8 @@ where return Ok(stored); }; + let ecash_apis = ecash_apis.try_get_ecash_clients().await?; + let expiration_sigs = query_random_apis_until_success( ecash_apis, |api| async move { diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 588213bd09..e4e7d77ea2 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -165,6 +165,19 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +[[package]] +name = "async-compression" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + [[package]] name = "async-trait" version = "0.1.86" @@ -560,9 +573,9 @@ dependencies = [ [[package]] name = "celes" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39b9a21273925d7cc9e8a9a5f068122341336813c607014f5ef64f82b6acba58" +checksum = "54441489dce7026efc8f01d1aa996c23fa39dd615a953d0e934433a42f61dd30" dependencies = [ "serde", ] @@ -724,13 +737,12 @@ dependencies = [ [[package]] name = "colored" -version = "2.0.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ - "is-terminal", "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3715,7 +3727,7 @@ dependencies = [ "base64 0.22.1", "bip32", "bip39", - "colored 2.0.4", + "colored 2.2.0", "cosmrs 0.21.1", "cosmwasm-std", "cw-controllers", @@ -3823,7 +3835,7 @@ dependencies = [ "base64 0.13.1", "bip39", "cfg-if", - "colored 2.0.4", + "colored 2.2.0", "cosmrs 0.21.1", "cosmwasm-std", "dirs 4.0.0", @@ -4758,6 +4770,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ + "async-compression", "base64 0.22.1", "bytes", "encoding_rs", @@ -4790,6 +4803,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls 0.25.0", + "tokio-util", "tower-service", "url", "wasm-bindgen",