Skip to content

Commit 078cfdd

Browse files
yukibtcJeff Gardner
andcommitted
mls-storage: improve APIs of MLS storage traits
* Return `Result<Option<T>>` for query methods: the `Result` indicates if the backend successfully performed the query and the `Option` if the result has been found or not. * Avoid returning the argument in saving methods * Cleanup the implementation of some MLS trait methods Discussion at #839 (comment) and #839 (comment) Co-authored-by: Jeff Gardner <[email protected]> Signed-off-by: Yuki Kishimoto <[email protected]>
1 parent 3e50369 commit 078cfdd

File tree

8 files changed

+133
-154
lines changed

8 files changed

+133
-154
lines changed
Lines changed: 42 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
//! Memory-based storage implementation of the NostrMlsStorageProvider trait for Nostr MLS groups
22
33
use nostr::PublicKey;
4-
use nostr_mls_storage::groups::error::GroupError;
4+
use nostr_mls_storage::groups::error::{GroupError, InvalidGroupState};
55
use nostr_mls_storage::groups::types::*;
66
use nostr_mls_storage::groups::GroupStorage;
77
use nostr_mls_storage::messages::types::Message;
88

99
use crate::NostrMlsMemoryStorage;
1010

1111
impl GroupStorage for NostrMlsMemoryStorage {
12-
fn save_group(&self, group: Group) -> Result<Group, GroupError> {
12+
fn save_group(&self, group: Group) -> Result<(), GroupError> {
1313
// Store in the MLS group ID cache
1414
{
1515
let mut cache = self.groups_cache.write();
@@ -19,10 +19,10 @@ impl GroupStorage for NostrMlsMemoryStorage {
1919
// Store in the Nostr group ID cache
2020
{
2121
let mut cache = self.groups_by_nostr_id_cache.write();
22-
cache.put(group.nostr_group_id.clone(), group.clone());
22+
cache.put(group.nostr_group_id.clone(), group);
2323
}
2424

25-
Ok(group)
25+
Ok(())
2626
}
2727

2828
fn all_groups(&self) -> Result<Vec<Group>, GroupError> {
@@ -32,92 +32,73 @@ impl GroupStorage for NostrMlsMemoryStorage {
3232
Ok(groups)
3333
}
3434

35-
fn find_group_by_mls_group_id(&self, mls_group_id: &[u8]) -> Result<Group, GroupError> {
35+
fn find_group_by_mls_group_id(&self, mls_group_id: &[u8]) -> Result<Option<Group>, GroupError> {
3636
let cache = self.groups_cache.read();
37-
if let Some(group) = cache.peek(mls_group_id) {
38-
// Return a clone of the found group
39-
return Ok(group.clone());
40-
}
41-
42-
Err(GroupError::NotFound)
37+
Ok(cache.peek(mls_group_id).cloned())
4338
}
4439

45-
fn find_group_by_nostr_group_id(&self, nostr_group_id: &str) -> Result<Group, GroupError> {
40+
fn find_group_by_nostr_group_id(
41+
&self,
42+
nostr_group_id: &str,
43+
) -> Result<Option<Group>, GroupError> {
4644
let cache = self.groups_by_nostr_id_cache.read();
47-
if let Some(group) = cache.peek(nostr_group_id) {
48-
// Return a clone of the found group
49-
return Ok(group.clone());
50-
}
51-
52-
Err(GroupError::NotFound)
45+
Ok(cache.peek(nostr_group_id).cloned())
5346
}
5447

5548
fn messages(&self, mls_group_id: &[u8]) -> Result<Vec<Message>, GroupError> {
5649
// Check if the group exists first
5750
self.find_group_by_mls_group_id(mls_group_id)?;
5851

5952
let cache = self.messages_by_group_cache.read();
60-
if let Some(messages) = cache.peek(mls_group_id) {
61-
return Ok(messages.clone());
53+
match cache.peek(mls_group_id).cloned() {
54+
Some(messages) => Ok(messages),
55+
// If not in cache but group exists, return empty vector
56+
None => Ok(Vec::new()),
6257
}
63-
64-
// If not in cache but group exists, return empty vector
65-
Ok(Vec::new())
6658
}
6759

6860
fn admins(&self, mls_group_id: &[u8]) -> Result<Vec<PublicKey>, GroupError> {
69-
// Find the group first
70-
if let Ok(group) = self.find_group_by_mls_group_id(mls_group_id) {
71-
// Return the admin pubkeys from the group
72-
return Ok(group.admin_pubkeys);
61+
match self.find_group_by_mls_group_id(mls_group_id)? {
62+
Some(group) => Ok(group.admin_pubkeys),
63+
None => Err(GroupError::InvalidState(InvalidGroupState::NoAdmins)),
7364
}
74-
75-
Err(GroupError::NotFound)
7665
}
7766

7867
fn group_relays(&self, mls_group_id: &[u8]) -> Result<Vec<GroupRelay>, GroupError> {
7968
// Check if the group exists first
8069
self.find_group_by_mls_group_id(mls_group_id)?;
8170

8271
let cache = self.group_relays_cache.read();
83-
if let Some(relays) = cache.peek(mls_group_id) {
84-
return Ok(relays.clone());
72+
match cache.peek(mls_group_id).cloned() {
73+
Some(relays) => Ok(relays),
74+
None => Err(GroupError::InvalidState(InvalidGroupState::NoRelays)),
8575
}
86-
87-
// If not in cache but group exists, return empty vector
88-
Ok(Vec::new())
8976
}
9077

91-
fn save_group_relay(&self, group_relay: GroupRelay) -> Result<GroupRelay, GroupError> {
92-
let mls_group_id = group_relay.mls_group_id.clone();
93-
78+
fn save_group_relay(&self, group_relay: GroupRelay) -> Result<(), GroupError> {
9479
// Check if the group exists first
95-
self.find_group_by_mls_group_id(&mls_group_id)?;
96-
97-
let group_relay_clone = group_relay.clone();
80+
self.find_group_by_mls_group_id(&group_relay.mls_group_id)?;
9881

99-
{
100-
let mut cache = self.group_relays_cache.write();
101-
// Get existing relays or create new vector
102-
let relays = match cache.get(&mls_group_id) {
103-
Some(existing_relays) => {
104-
let mut new_relays = existing_relays.clone();
105-
// Add the new relay if it doesn't already exist
106-
if !new_relays
107-
.iter()
108-
.any(|r| r.relay_url == group_relay.relay_url)
109-
{
110-
new_relays.push(group_relay_clone);
111-
}
112-
new_relays
113-
}
114-
None => vec![group_relay_clone],
115-
};
82+
let mut cache = self.group_relays_cache.write();
11683

117-
// Update the cache with the new vector
118-
cache.put(mls_group_id, relays);
119-
}
84+
// Try to get the existing relays for the group
85+
match cache.get_mut(&group_relay.mls_group_id) {
86+
// If the group exists, add the new relay to the vector
87+
Some(existing_relays) => {
88+
// TODO: the time complexity here is O(n). The number of relays is likely to be small, but it's probably better to use a BTreeSet anyway.
12089

121-
Ok(group_relay)
90+
// Add the new relay if it doesn't already exist
91+
if !existing_relays.contains(&group_relay) {
92+
existing_relays.push(group_relay);
93+
}
94+
}
95+
// If the group doesn't exist, create a new vector with the new relay
96+
None => {
97+
// Update the cache with the new vector
98+
cache.put(group_relay.mls_group_id.clone(), vec![group_relay]);
99+
}
100+
};
101+
102+
Ok(())
122103
}
123104
}

crates/nostr-mls-memory-storage/src/lib.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ mod tests {
245245
// Find the group by MLS group ID
246246
let found_group = nostr_storage.find_group_by_mls_group_id(&mls_group_id);
247247
assert!(found_group.is_ok());
248-
let found_group = found_group.unwrap();
248+
let found_group = found_group.unwrap().unwrap();
249249
assert_eq!(found_group.mls_group_id, mls_group_id);
250250
assert_eq!(found_group.nostr_group_id, "test_group_123");
251251

@@ -371,9 +371,9 @@ mod tests {
371371
assert!(result.is_ok());
372372

373373
// Find the welcome by event ID
374-
let found_welcome = nostr_storage.find_welcome_by_event_id(event_id);
374+
let found_welcome = nostr_storage.find_welcome_by_event_id(&event_id);
375375
assert!(found_welcome.is_ok());
376-
let found_welcome = found_welcome.unwrap();
376+
let found_welcome = found_welcome.unwrap().unwrap();
377377
assert_eq!(found_welcome.id, event_id);
378378
assert_eq!(found_welcome.mls_group_id, vec![9, 10, 11, 12]);
379379

@@ -397,9 +397,9 @@ mod tests {
397397
assert!(result.is_ok());
398398

399399
// Find the processed welcome by event ID
400-
let found_processed_welcome = nostr_storage.find_processed_welcome_by_event_id(wrapper_id);
400+
let found_processed_welcome = nostr_storage.find_processed_welcome_by_event_id(&wrapper_id);
401401
assert!(found_processed_welcome.is_ok());
402-
let found_processed_welcome = found_processed_welcome.unwrap();
402+
let found_processed_welcome = found_processed_welcome.unwrap().unwrap();
403403
assert_eq!(found_processed_welcome.wrapper_event_id, wrapper_id);
404404
assert_eq!(found_processed_welcome.welcome_event_id, Some(event_id));
405405

@@ -466,9 +466,9 @@ mod tests {
466466
assert!(result.is_ok());
467467

468468
// Find the message by event ID
469-
let found_message = nostr_storage.find_message_by_event_id(event_id);
469+
let found_message = nostr_storage.find_message_by_event_id(&event_id);
470470
assert!(found_message.is_ok());
471-
let found_message = found_message.unwrap();
471+
let found_message = found_message.unwrap().unwrap();
472472
assert_eq!(found_message.id, event_id);
473473
assert_eq!(found_message.mls_group_id, mls_group_id);
474474

@@ -505,9 +505,9 @@ mod tests {
505505
assert!(result.is_ok());
506506

507507
// Find the processed message by event ID
508-
let found_processed_message = nostr_storage.find_processed_message_by_event_id(wrapper_id);
508+
let found_processed_message = nostr_storage.find_processed_message_by_event_id(&wrapper_id);
509509
assert!(found_processed_message.is_ok());
510-
let found_processed_message = found_processed_message.unwrap();
510+
let found_processed_message = found_processed_message.unwrap().unwrap();
511511
assert_eq!(found_processed_message.wrapper_event_id, wrapper_id);
512512
assert_eq!(found_processed_message.message_event_id, Some(event_id));
513513

@@ -545,7 +545,7 @@ mod tests {
545545
// Find the group by MLS group ID
546546
let found_group = nostr_storage.find_group_by_mls_group_id(&mls_group_id);
547547
assert!(found_group.is_ok());
548-
let found_group = found_group.unwrap();
548+
let found_group = found_group.unwrap().unwrap();
549549
assert_eq!(found_group.mls_group_id, mls_group_id);
550550
}
551551

@@ -574,7 +574,7 @@ mod tests {
574574
// Find the group by MLS group ID
575575
let found_group = nostr_storage.find_group_by_mls_group_id(&mls_group_id);
576576
assert!(found_group.is_ok());
577-
let found_group = found_group.unwrap();
577+
let found_group = found_group.unwrap().unwrap();
578578
assert_eq!(found_group.mls_group_id, mls_group_id);
579579
}
580580
}

crates/nostr-mls-memory-storage/src/messages.rs

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,35 @@ use nostr_mls_storage::messages::MessageStorage;
88
use crate::NostrMlsMemoryStorage;
99

1010
impl MessageStorage for NostrMlsMemoryStorage {
11-
fn save_message(&self, message: Message) -> Result<Message, MessageError> {
12-
{
13-
let mut cache = self.messages_cache.write();
14-
cache.put(message.id, message.clone());
15-
}
16-
17-
Ok(message)
11+
fn save_message(&self, message: Message) -> Result<(), MessageError> {
12+
let mut cache = self.messages_cache.write();
13+
cache.put(message.id, message);
14+
Ok(())
1815
}
1916

20-
fn find_message_by_event_id(&self, event_id: EventId) -> Result<Message, MessageError> {
17+
fn find_message_by_event_id(
18+
&self,
19+
event_id: &EventId,
20+
) -> Result<Option<Message>, MessageError> {
2121
let cache = self.messages_cache.read();
22-
if let Some(message) = cache.peek(&event_id) {
23-
return Ok(message.clone());
24-
}
25-
26-
Err(MessageError::NotFound)
22+
Ok(cache.peek(event_id).cloned())
2723
}
2824

2925
fn find_processed_message_by_event_id(
3026
&self,
31-
event_id: EventId,
32-
) -> Result<ProcessedMessage, MessageError> {
27+
event_id: &EventId,
28+
) -> Result<Option<ProcessedMessage>, MessageError> {
3329
let cache = self.processed_messages_cache.read();
34-
if let Some(processed_message) = cache.peek(&event_id) {
35-
return Ok(processed_message.clone());
36-
}
37-
38-
Err(MessageError::NotFound)
30+
Ok(cache.peek(event_id).cloned())
3931
}
4032

4133
fn save_processed_message(
4234
&self,
4335
processed_message: ProcessedMessage,
44-
) -> Result<ProcessedMessage, MessageError> {
45-
{
46-
let mut cache = self.processed_messages_cache.write();
47-
cache.put(
48-
processed_message.wrapper_event_id,
49-
processed_message.clone(),
50-
);
51-
}
36+
) -> Result<(), MessageError> {
37+
let mut cache = self.processed_messages_cache.write();
38+
cache.put(processed_message.wrapper_event_id, processed_message);
5239

53-
Ok(processed_message)
40+
Ok(())
5441
}
5542
}

crates/nostr-mls-memory-storage/src/welcomes.rs

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@ use nostr_mls_storage::welcomes::WelcomeStorage;
88
use crate::NostrMlsMemoryStorage;
99

1010
impl WelcomeStorage for NostrMlsMemoryStorage {
11-
fn save_welcome(&self, welcome: Welcome) -> Result<Welcome, WelcomeError> {
12-
{
13-
let mut cache = self.welcomes_cache.write();
14-
cache.put(welcome.id, welcome.clone());
15-
}
11+
fn save_welcome(&self, welcome: Welcome) -> Result<(), WelcomeError> {
12+
let mut cache = self.welcomes_cache.write();
13+
cache.put(welcome.id, welcome);
1614

17-
Ok(welcome)
15+
Ok(())
1816
}
1917

2018
fn pending_welcomes(&self) -> Result<Vec<Welcome>, WelcomeError> {
@@ -28,39 +26,29 @@ impl WelcomeStorage for NostrMlsMemoryStorage {
2826
Ok(welcomes)
2927
}
3028

31-
fn find_welcome_by_event_id(&self, event_id: EventId) -> Result<Welcome, WelcomeError> {
29+
fn find_welcome_by_event_id(
30+
&self,
31+
event_id: &EventId,
32+
) -> Result<Option<Welcome>, WelcomeError> {
3233
let cache = self.welcomes_cache.read();
33-
if let Some(welcome) = cache.peek(&event_id) {
34-
return Ok(welcome.clone());
35-
}
36-
37-
Err(WelcomeError::NotFound)
34+
Ok(cache.peek(event_id).cloned())
3835
}
3936

40-
fn find_processed_welcome_by_event_id(
37+
fn save_processed_welcome(
4138
&self,
42-
event_id: EventId,
43-
) -> Result<ProcessedWelcome, WelcomeError> {
44-
let cache = self.processed_welcomes_cache.read();
45-
if let Some(processed_welcome) = cache.peek(&event_id) {
46-
return Ok(processed_welcome.clone());
47-
}
39+
processed_welcome: ProcessedWelcome,
40+
) -> Result<(), WelcomeError> {
41+
let mut cache = self.processed_welcomes_cache.write();
42+
cache.put(processed_welcome.wrapper_event_id, processed_welcome);
4843

49-
Err(WelcomeError::NotFound)
44+
Ok(())
5045
}
5146

52-
fn save_processed_welcome(
47+
fn find_processed_welcome_by_event_id(
5348
&self,
54-
processed_welcome: ProcessedWelcome,
55-
) -> Result<ProcessedWelcome, WelcomeError> {
56-
{
57-
let mut cache = self.processed_welcomes_cache.write();
58-
cache.put(
59-
processed_welcome.wrapper_event_id,
60-
processed_welcome.clone(),
61-
);
62-
}
63-
64-
Ok(processed_welcome)
49+
event_id: &EventId,
50+
) -> Result<Option<ProcessedWelcome>, WelcomeError> {
51+
let cache = self.processed_welcomes_cache.read();
52+
Ok(cache.peek(event_id).cloned())
6553
}
6654
}

0 commit comments

Comments
 (0)