Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit 2f0b903

Browse files
AnthonyRonningbenthecarman
authored andcommitted
Wrap fedimint around an async rwlock
1 parent 9646fb8 commit 2f0b903

3 files changed

Lines changed: 73 additions & 24 deletions

File tree

Cargo.lock

Lines changed: 51 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mutiny-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ gluesql = { version = "0.15", default-features = false, features = ["memory-stor
4949
gluesql-core = "0.15.0"
5050
bincode = "1.3.3"
5151
hex = "0.4.3"
52+
async-lock = "3.2.0"
5253

5354
fedimint-client = { git = "https://github.com/fedimint/fedimint.git", rev = "51d09c76b8a15615114d4f2c2663c738d8ff3135" }
5455
fedimint-core = { git = "https://github.com/fedimint/fedimint.git", rev = "51d09c76b8a15615114d4f2c2663c738d8ff3135" }

mutiny-core/src/lib.rs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,13 @@ use crate::{nodemanager::NodeManager, nostr::ProfileType};
6767
use crate::{nostr::NostrManager, utils::sleep};
6868
use ::nostr::key::XOnlyPublicKey;
6969
use ::nostr::{Event, JsonUtil, Kind, Metadata};
70+
use async_lock::RwLock;
7071
use bdk_chain::ConfirmationTime;
7172
use bip39::Mnemonic;
7273
use bitcoin::util::bip32::ExtendedPrivKey;
7374
use bitcoin::{hashes::sha256, Network};
7475
use fedimint_core::{api::InviteCode, config::FederationId, BitcoinHash};
7576
use futures::{pin_mut, select, FutureExt};
76-
use futures_util::lock::Mutex;
7777
use lightning::{log_debug, util::logger::Logger};
7878
use lightning::{log_error, log_info, log_warn};
7979
use lightning_invoice::Bolt11Invoice;
@@ -505,7 +505,7 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
505505
.await?;
506506
(federations, Some(glue_db))
507507
} else {
508-
(Arc::new(Mutex::new(HashMap::new())), None)
508+
(Arc::new(RwLock::new(HashMap::new())), None)
509509
};
510510

511511
if !self.skip_hodl_invoices {
@@ -522,7 +522,7 @@ impl<S: MutinyStorage> MutinyWalletBuilder<S> {
522522
glue_db,
523523
node_manager,
524524
nostr,
525-
federation_storage: Arc::new(Mutex::new(federation_storage)),
525+
federation_storage: Arc::new(RwLock::new(federation_storage)),
526526
federations,
527527
stop,
528528
logger,
@@ -572,8 +572,8 @@ pub struct MutinyWallet<S: MutinyStorage> {
572572
glue_db: Option<GlueDB>,
573573
pub node_manager: Arc<NodeManager<S>>,
574574
pub nostr: Arc<NostrManager<S>>,
575-
pub federation_storage: Arc<Mutex<FederationStorage>>,
576-
pub(crate) federations: Arc<Mutex<HashMap<FederationId, Arc<FederationClient>>>>,
575+
pub federation_storage: Arc<RwLock<FederationStorage>>,
576+
pub(crate) federations: Arc<RwLock<HashMap<FederationId, Arc<FederationClient>>>>,
577577
pub stop: Arc<AtomicBool>,
578578
pub logger: Arc<MutinyLogger>,
579579
network: Network,
@@ -742,7 +742,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
742742
// Try each federation first
743743
let federation_ids = self.list_federation_ids().await?;
744744
for federation_id in federation_ids {
745-
if let Some(fedimint_client) = self.federations.lock().await.get(&federation_id) {
745+
if let Some(fedimint_client) = self.federations.read().await.get(&federation_id) {
746746
// Check if the federation has enough balance
747747
let balance = fedimint_client.get_balance().await?;
748748
if balance >= send_msat / 1_000 {
@@ -840,7 +840,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
840840
// Attempt to create federation invoice
841841
if !federation_ids.is_empty() {
842842
let federation_id = &federation_ids[0];
843-
let fedimint_client = self.federations.lock().await.get(federation_id).cloned();
843+
let fedimint_client = self.federations.read().await.get(federation_id).cloned();
844844

845845
if let Some(client) = fedimint_client {
846846
if let Ok(inv) = client
@@ -873,7 +873,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
873873
let mut activities = self.node_manager.get_activity().await?;
874874

875875
// Directly iterate over federation clients to get their activities
876-
let federations = self.federations.lock().await;
876+
let federations = self.federations.read().await;
877877
for (_fed_id, federation) in federations.iter() {
878878
let federation_activities = federation.get_activity().await?;
879879
activities.extend(federation_activities);
@@ -903,7 +903,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
903903
}
904904

905905
// If not found in node manager, search in federations
906-
let federations = self.federations.lock().await;
906+
let federations = self.federations.read().await;
907907
for (_fed_id, federation) in federations.iter() {
908908
if let Ok(invoice) = federation.get_invoice_by_hash(hash).await {
909909
return Ok(invoice);
@@ -1246,7 +1246,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
12461246

12471247
/// Lists the federation id's of the federation clients in the manager.
12481248
pub async fn list_federations(&self) -> Result<Vec<FederationIdentity>, MutinyError> {
1249-
let federations = self.federations.lock().await;
1249+
let federations = self.federations.read().await;
12501250
let federation_identities = federations
12511251
.iter()
12521252
.map(|(_, n)| n.get_mutiny_federation_identity())
@@ -1256,7 +1256,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
12561256

12571257
/// Lists the federation id's of the federation clients in the manager.
12581258
pub async fn list_federation_ids(&self) -> Result<Vec<FederationId>, MutinyError> {
1259-
let federations = self.federations.lock().await;
1259+
let federations = self.federations.read().await;
12601260
let federation_identities = federations
12611261
.iter()
12621262
.map(|(_, n)| n.fedimint_client.federation_id())
@@ -1266,12 +1266,12 @@ impl<S: MutinyStorage> MutinyWallet<S> {
12661266

12671267
/// Removes a federation by setting its archived status to true, based on the FederationId.
12681268
pub async fn remove_federation(&self, federation_id: FederationId) -> Result<(), MutinyError> {
1269-
let mut federations_guard = self.federations.lock().await;
1269+
let mut federations_guard = self.federations.write().await;
12701270

12711271
if let Some(fedimint_client) = federations_guard.get(&federation_id) {
12721272
let uuid = &fedimint_client.uuid;
12731273

1274-
let mut federation_storage_guard = self.federation_storage.lock().await;
1274+
let mut federation_storage_guard = self.federation_storage.write().await;
12751275

12761276
if federation_storage_guard.federations.contains_key(uuid) {
12771277
federation_storage_guard.federations.remove(uuid);
@@ -1292,7 +1292,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
12921292
let federation_ids = self.list_federation_ids().await?;
12931293
let mut total_balance = 0;
12941294

1295-
let federations = self.federations.lock().await;
1295+
let federations = self.federations.read().await;
12961296
for fed_id in federation_ids {
12971297
let balance = federations
12981298
.get(&fed_id)
@@ -1307,7 +1307,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
13071307
}
13081308

13091309
pub async fn get_federation_balances(&self) -> Result<FederationBalances, MutinyError> {
1310-
let federation_lock = self.federations.lock().await;
1310+
let federation_lock = self.federations.read().await;
13111311

13121312
let federation_ids = self.list_federation_ids().await?;
13131313
let mut balances = Vec::with_capacity(federation_ids.len());
@@ -1367,7 +1367,7 @@ async fn create_federations(
13671367
c: &MutinyWalletConfig,
13681368
g: GlueDB,
13691369
logger: &Arc<MutinyLogger>,
1370-
) -> Result<Arc<Mutex<HashMap<FederationId, Arc<FederationClient>>>>, MutinyError> {
1370+
) -> Result<Arc<RwLock<HashMap<FederationId, Arc<FederationClient>>>>, MutinyError> {
13711371
let federations = federation_storage.federations.into_iter();
13721372
let mut federation_map = HashMap::new();
13731373
for federation_item in federations {
@@ -1385,7 +1385,7 @@ async fn create_federations(
13851385

13861386
federation_map.insert(id, Arc::new(federation));
13871387
}
1388-
let federations = Arc::new(Mutex::new(federation_map));
1388+
let federations = Arc::new(RwLock::new(federation_map));
13891389
Ok(federations)
13901390
}
13911391

@@ -1397,14 +1397,14 @@ pub(crate) async fn create_new_federation<S: MutinyStorage>(
13971397
g: GlueDB,
13981398
network: Network,
13991399
logger: Arc<MutinyLogger>,
1400-
federation_storage: Arc<Mutex<FederationStorage>>,
1401-
federations: Arc<Mutex<HashMap<FederationId, Arc<FederationClient>>>>,
1400+
federation_storage: Arc<RwLock<FederationStorage>>,
1401+
federations: Arc<RwLock<HashMap<FederationId, Arc<FederationClient>>>>,
14021402
federation_code: InviteCode,
14031403
) -> Result<FederationIdentity, MutinyError> {
14041404
// Begin with a mutex lock so that nothing else can
14051405
// save or alter the federation list while it is about to
14061406
// be saved.
1407-
let mut federation_mutex = federation_storage.lock().await;
1407+
let mut federation_mutex = federation_storage.write().await;
14081408

14091409
// Get the current federations so that we can check if the new federation already exists
14101410
let mut existing_federations = storage.get_federations()?;
@@ -1450,7 +1450,7 @@ pub(crate) async fn create_new_federation<S: MutinyStorage>(
14501450
.get_meta("federation_expiry_timestamp");
14511451
let welcome_message = new_federation.fedimint_client.get_meta("welcome_message");
14521452
federations
1453-
.lock()
1453+
.write()
14541454
.await
14551455
.insert(federation_id, Arc::new(new_federation));
14561456

0 commit comments

Comments
 (0)