]> Untitled Git - bdk/commitdiff
Address out of memory issue caused by many txs.
authorJoey Guinta <jguinta@squareup.com>
Thu, 13 Feb 2025 17:29:39 +0000 (12:29 -0500)
committerJoey Guinta <jguinta@squareup.com>
Thu, 13 Feb 2025 17:33:43 +0000 (12:33 -0500)
For some wallets there exists a pathological case where we may try to fetch many thousands
        of transactions at once, which creates enormous memory pressure. By chunking the batch
        into more reasonably sized sub-queries, we allow time for memory to be freed.

src/blockchain/electrum.rs

index 5bfd51ef8135627e73959de25fb47cdaf91c835d..acc367dde78e54f8d04da715cac0361740c58e0d 100644 (file)
@@ -278,15 +278,20 @@ impl<'a, 'b, D: Database> TxCache<'a, 'b, D> {
             }
         }
 
-        if !need_fetch.is_empty() {
+        // For some wallets there exists a pathological case where we may try to fetch many thousands
+        // of transactions at once, which creates enormous memory pressure. By chunking the batch
+        // into more reasonably sized sub-queries, we allow time for memory to be freed.
+        for chunk in need_fetch.chunks(1000) {
             let txs = self
                 .client
-                .batch_transaction_get(need_fetch.clone())
+                .batch_transaction_get(chunk)
                 .map_err(Error::Electrum)?;
+
             let mut txs: HashMap<_, _> = txs.into_iter().map(|tx| (tx.txid(), tx)).collect();
-            for txid in need_fetch {
-                if let Some(tx) = txs.remove(txid) {
-                    self.cache.insert(*txid, tx);
+
+            for txid in chunk {
+                if let Some(tx) = txs.remove(*txid) {
+                    self.cache.insert(**txid, tx);
                 }
             }
         }