From dd306c21f777178ae1988f69a01702e0153abc88 Mon Sep 17 00:00:00 2001 From: hrxi Date: Mon, 27 Jan 2025 16:19:45 +0100 Subject: [PATCH] Make `BlsCache` locking more granular --- web-client/src/client/bls_cache.rs | 23 ++++++++++++++++------- web-client/src/client/lib.rs | 8 ++++---- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/web-client/src/client/bls_cache.rs b/web-client/src/client/bls_cache.rs index 4295610d58..ffd715e84f 100644 --- a/web-client/src/client/bls_cache.rs +++ b/web-client/src/client/bls_cache.rs @@ -1,3 +1,5 @@ +use std::cell::RefCell; + use idb::{Database, Error, KeyPath, ObjectStore, TransactionMode}; use nimiq_bls::{LazyPublicKey, PublicKey}; use nimiq_serde::{Deserialize, Serialize}; @@ -5,7 +7,7 @@ use nimiq_serde::{Deserialize, Serialize}; /// Caches decompressed BlsPublicKeys in an IndexedDB pub(crate) struct BlsCache { db: Option, - keys: Vec, + keys: RefCell>, } #[derive(Deserialize, Serialize)] @@ -34,7 +36,10 @@ impl BlsCache { } }; - BlsCache { db, keys: vec![] } + BlsCache { + db, + keys: RefCell::new(vec![]), + } } /// Add the given keys into IndexedDB. @@ -66,7 +71,7 @@ impl BlsCache { /// Fetches all bls keys from the IndexedDB and stores them, which makes /// the decompressed keys available in other places. - pub async fn init(&mut self) -> Result<(), Error> { + pub async fn init(&self) -> Result<(), Error> { if let Some(db) = &self.db { let transaction = db.transaction(&[BLS_KEYS], TransactionMode::ReadOnly)?; let bls_keys_store = transaction.object_store(BLS_KEYS)?; @@ -74,10 +79,14 @@ impl BlsCache { let js_keys = bls_keys_store.get_all(None, None)?.await?; log::info!(num = js_keys.len(), "loaded keys from idb"); - for js_key in &js_keys { - let value: BlsKeyEntry = serde_wasm_bindgen::from_value(js_key.clone()).unwrap(); - let public_key = PublicKey::trusted_deserialize(&value.public_key); - self.keys.push(LazyPublicKey::from(public_key)); + { + let mut keys = self.keys.borrow_mut(); + for js_key in &js_keys { + let value: BlsKeyEntry = + serde_wasm_bindgen::from_value(js_key.clone()).unwrap(); + let public_key = PublicKey::trusted_deserialize(&value.public_key); + keys.push(LazyPublicKey::from(public_key)); + } } transaction.await?; } else { diff --git a/web-client/src/client/lib.rs b/web-client/src/client/lib.rs index d7c1dd9ef4..1117855edc 100644 --- a/web-client/src/client/lib.rs +++ b/web-client/src/client/lib.rs @@ -116,7 +116,7 @@ pub struct Client { /// Used to await transaction events in `send_transaction`. transaction_oneshots: Rc>>>, - bls_cache: Rc>, + bls_cache: Rc, } #[wasm_bindgen] @@ -198,7 +198,7 @@ impl Client { peer_changed_listeners: Rc::new(RefCell::new(HashMap::with_capacity(1))), transaction_listeners: Rc::new(RefCell::new(HashMap::new())), transaction_oneshots: Rc::new(RefCell::new(HashMap::new())), - bls_cache: Rc::new(RefCell::new(bls_cache)), + bls_cache: Rc::new(bls_cache), }; client.setup_offline_online_event_handlers(); @@ -207,7 +207,7 @@ impl Client { client.setup_network_events(); client.setup_transaction_events().await; - if let Err(err) = client.bls_cache.borrow_mut().init().await { + if let Err(err) = client.bls_cache.init().await { log::warn!("Failed loading bls cache {}", err); } @@ -1125,7 +1125,7 @@ impl Client { .iter() .map(|validator| validator.voting_key.clone()) .collect::>(); - if let Err(error) = bls_cache.borrow_mut().add_keys(bls_keys).await { + if let Err(error) = bls_cache.add_keys(bls_keys).await { log::warn!(%error, "failed caching BLS keys"); } }