Skip to content

Commit 46a789b

Browse files
authored
Fix Surreal Memory Leak (#516)
1 parent 6c1851a commit 46a789b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1504
-823
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# 0.3.12
2+
3+
* impl Default for BillParticipant and BillAnonParticipant
4+
* Expose Receiver type for the PushApi trait
5+
* Fix SurrealDB Memory leak for WASM
6+
17
# 0.3.11
28

39
* Add LICENSE to crates

Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ opt-level = "s" # Optimize for size ("z" can be used for even more aggressive
1313
lto = true # Enable Link-Time Optimization
1414
codegen-units = 1 # Reduces binary size at the cost of compile time
1515

16+
[profile.dev]
17+
opt-level = 1 # Avoid surrealdb index out of bounds issue in dev build
18+
1619
[workspace.dependencies]
1720
sha2 = { version = "0.10", default-features = false }
1821
borsh = "1.5"
@@ -23,8 +26,8 @@ chrono = { version = "0.4", default-features = false, features = [
2326
"serde",
2427
"clock",
2528
] }
26-
tokio = { version = "1.43", default-features = false, features = ["rt"] }
27-
tokio_with_wasm = { version = "0.8.2", features = ["rt"] }
29+
tokio = { version = "1.43", default-features = false, features = ["rt", "sync"] }
30+
tokio_with_wasm = { version = "0.8", features = ["rt", "sync"] }
2831
async-trait = "0.1"
2932
serde_json = "1"
3033
serde = { version = "1", default-features = false, features = ["derive"] }
@@ -38,7 +41,6 @@ bip39 = { version = "2.1", features = ["rand"] }
3841
ecies = { version = "0.2", default-features = false, features = ["pure"] }
3942
nostr = { version = "0.41" }
4043
nostr-sdk = { version = "0.41", features = ["nip04", "nip59"] }
41-
getrandom = { version = "0.3.1", features = ["wasm_js"] }
4244
async-broadcast = "0.7.2"
4345
rstest = "0.25.0"
4446
secp256k1 = { version = "0.29" }

crates/bcr-ebill-api/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bcr-ebill-api"
3-
version = "0.3.11"
3+
version = "0.3.12"
44
edition = "2024"
55
license = "MIT"
66

crates/bcr-ebill-api/src/persistence/mod.rs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
use crate::Config;
2+
#[cfg(not(target_arch = "wasm32"))]
3+
use bcr_ebill_persistence::get_surreal_db;
24
use bcr_ebill_persistence::{
35
BackupStoreApi, ContactStoreApi, NostrEventOffsetStoreApi, NotificationStoreApi,
46
SurrealBackupStore, SurrealBillChainStore, SurrealBillStore, SurrealCompanyChainStore,
@@ -8,10 +10,9 @@ use bcr_ebill_persistence::{
810
company::{CompanyChainStoreApi, CompanyStoreApi},
911
db::{
1012
nostr_contact_store::SurrealNostrContactStore,
11-
nostr_send_queue::SurrealNostrEventQueueStore,
13+
nostr_send_queue::SurrealNostrEventQueueStore, surreal::SurrealWrapper,
1214
},
1315
file_upload::FileUploadStoreApi,
14-
get_surreal_db,
1516
identity::{IdentityChainStoreApi, IdentityStoreApi},
1617
nostr::{NostrContactStoreApi, NostrQueuedMessageStoreApi},
1718
};
@@ -49,13 +50,27 @@ pub struct DbContext {
4950
}
5051

5152
/// Creates a new instance of the DbContext with the given SurrealDB configuration.
52-
pub async fn get_db_context(conf: &Config) -> bcr_ebill_persistence::Result<DbContext> {
53+
pub async fn get_db_context(
54+
#[allow(unused)] conf: &Config,
55+
) -> bcr_ebill_persistence::Result<DbContext> {
56+
#[cfg(not(target_arch = "wasm32"))]
5357
let db = get_surreal_db(&conf.db_config).await?;
58+
#[cfg(not(target_arch = "wasm32"))]
59+
let surreal_wrapper = SurrealWrapper {
60+
db: db.clone(),
61+
files: false,
62+
};
5463

55-
let company_store = Arc::new(SurrealCompanyStore::new(db.clone()));
5664
#[cfg(target_arch = "wasm32")]
57-
let file_upload_store =
58-
Arc::new(bcr_ebill_persistence::db::file_upload::FileUploadStore::new(db.clone()));
65+
let surreal_wrapper = SurrealWrapper { files: false };
66+
67+
let company_store = Arc::new(SurrealCompanyStore::new(surreal_wrapper.clone()));
68+
#[cfg(target_arch = "wasm32")]
69+
let file_upload_store = Arc::new(
70+
bcr_ebill_persistence::db::file_upload::FileUploadStore::new(SurrealWrapper {
71+
files: true,
72+
}),
73+
);
5974

6075
#[cfg(not(target_arch = "wasm32"))]
6176
let file_upload_store = Arc::new(
@@ -71,20 +86,26 @@ pub async fn get_db_context(conf: &Config) -> bcr_ebill_persistence::Result<DbCo
7186
error!("Error cleaning up temp uploads: {e}");
7287
}
7388

74-
let contact_store = Arc::new(SurrealContactStore::new(db.clone()));
89+
let contact_store = Arc::new(SurrealContactStore::new(surreal_wrapper.clone()));
90+
91+
let bill_store = Arc::new(SurrealBillStore::new(surreal_wrapper.clone()));
92+
let bill_blockchain_store = Arc::new(SurrealBillChainStore::new(surreal_wrapper.clone()));
7593

76-
let bill_store = Arc::new(SurrealBillStore::new(db.clone()));
77-
let bill_blockchain_store = Arc::new(SurrealBillChainStore::new(db.clone()));
94+
let identity_store = Arc::new(SurrealIdentityStore::new(surreal_wrapper.clone()));
95+
let identity_chain_store = Arc::new(SurrealIdentityChainStore::new(surreal_wrapper.clone()));
96+
let company_chain_store = Arc::new(SurrealCompanyChainStore::new(surreal_wrapper.clone()));
7897

79-
let identity_store = Arc::new(SurrealIdentityStore::new(db.clone()));
80-
let identity_chain_store = Arc::new(SurrealIdentityChainStore::new(db.clone()));
81-
let company_chain_store = Arc::new(SurrealCompanyChainStore::new(db.clone()));
98+
let nostr_event_offset_store =
99+
Arc::new(SurrealNostrEventOffsetStore::new(surreal_wrapper.clone()));
100+
let notification_store = Arc::new(SurrealNotificationStore::new(surreal_wrapper.clone()));
82101

83-
let nostr_event_offset_store = Arc::new(SurrealNostrEventOffsetStore::new(db.clone()));
84-
let notification_store = Arc::new(SurrealNotificationStore::new(db.clone()));
102+
#[cfg(target_arch = "wasm32")]
103+
let backup_store = Arc::new(SurrealBackupStore {});
104+
105+
#[cfg(not(target_arch = "wasm32"))]
85106
let backup_store = Arc::new(SurrealBackupStore::new(db.clone()));
86-
let queued_message_store = Arc::new(SurrealNostrEventQueueStore::new(db.clone()));
87-
let nostr_contact_store = Arc::new(SurrealNostrContactStore::new(db.clone()));
107+
let queued_message_store = Arc::new(SurrealNostrEventQueueStore::new(surreal_wrapper.clone()));
108+
let nostr_contact_store = Arc::new(SurrealNostrContactStore::new(surreal_wrapper.clone()));
88109

89110
Ok(DbContext {
90111
contact_store,

crates/bcr-ebill-api/src/service/bill_service/data_fetching.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -740,9 +740,12 @@ impl BillService {
740740
current_timestamp: u64,
741741
) -> Result<BitcreditBillResult> {
742742
// if there is no such bill, we return an error
743-
if !self.store.exists(bill_id).await {
744-
return Err(Error::NotFound);
745-
}
743+
match self.store.exists(bill_id).await {
744+
Ok(true) => (),
745+
_ => {
746+
return Err(Error::NotFound);
747+
}
748+
};
746749

747750
// fetch contacts to get current contact data for participants
748751
let contacts = self.contact_store.get_map().await?;

0 commit comments

Comments
 (0)