Skip to content

Commit 8492cfc

Browse files
committed
Critical fix: OOM error - cap Bloom filter size to 500MB max
- Fixed 20GB RAM allocation on Super node startup (was 20 billion bools) - Capped Bloom filter to 500MB maximum (500M bits) - Optimized Genesis phase with smaller initial indexes (1MB for Super nodes) - Adjusted production indexes: Light 1M, Full 10M, Super 100M transactions - Added dynamic hash function adjustment for undersized filters - Genesis nodes now start with 1000x smaller indexes
1 parent ed3a1a0 commit 8492cfc

1 file changed

Lines changed: 40 additions & 8 deletions

File tree

development/qnet-integration/src/storage.rs

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,11 +1191,22 @@ impl Storage {
11911191
}
11921192

11931193
// Initialize probabilistic index for expected transactions
1194-
// For 100 years: ~150 billion transactions
1195-
let expected_txs = match storage_mode {
1196-
StorageMode::Light => 1_000_000, // Light nodes: minimal index
1197-
StorageMode::Full => 100_000_000, // Full nodes: last 100K blocks
1198-
StorageMode::Super => 1_000_000_000, // Super nodes: full history
1194+
// OPTIMIZED: Start small and grow dynamically in production
1195+
let is_genesis = std::env::var("QNET_BOOTSTRAP_ID").is_ok();
1196+
let expected_txs = if is_genesis {
1197+
// Genesis phase: Start with minimal index, will grow as needed
1198+
match storage_mode {
1199+
StorageMode::Light => 10_000, // Genesis: tiny index
1200+
StorageMode::Full => 100_000, // Genesis: small index
1201+
StorageMode::Super => 1_000_000, // Genesis: moderate index (1MB)
1202+
}
1203+
} else {
1204+
// Production phase: Scale with actual network size
1205+
match storage_mode {
1206+
StorageMode::Light => 1_000_000, // Light nodes: minimal index
1207+
StorageMode::Full => 10_000_000, // Full nodes: 10M transactions (100MB)
1208+
StorageMode::Super => 100_000_000, // Super nodes: 100M transactions (capped at 500MB)
1209+
}
11991210
};
12001211

12011212
let tx_index = Self::init_probabilistic_index(expected_txs);
@@ -2373,9 +2384,30 @@ impl Storage {
23732384

23742385
/// Initialize probabilistic index with optimal size
23752386
pub fn init_probabilistic_index(expected_elements: usize) -> ProbabilisticIndex {
2376-
// Optimal size for 0.01% false positive rate
2377-
let size = (expected_elements as f64 * 20.0) as usize;
2378-
let num_hashes = 7; // Optimal for this false positive rate
2387+
// CRITICAL FIX: Cap maximum Bloom filter size to prevent OOM
2388+
// 500 MB max for Super nodes (500M bits = ~500MB RAM)
2389+
const MAX_BLOOM_SIZE: usize = 500_000_000; // 500 million bits max
2390+
2391+
// Optimal size for 0.01% false positive rate (but capped)
2392+
let optimal_size = (expected_elements as f64 * 20.0) as usize;
2393+
let size = if optimal_size > MAX_BLOOM_SIZE {
2394+
println!("[Storage] ⚠️ Bloom filter size capped at {}MB (requested: {}MB)",
2395+
MAX_BLOOM_SIZE / 1_000_000, optimal_size / 1_000_000);
2396+
MAX_BLOOM_SIZE
2397+
} else {
2398+
optimal_size
2399+
};
2400+
2401+
// Adjust hash functions based on actual vs optimal size
2402+
let num_hashes = if optimal_size > MAX_BLOOM_SIZE {
2403+
// More hash functions when filter is undersized
2404+
10 // Compensate for higher collision rate
2405+
} else {
2406+
7 // Optimal for proper-sized filter
2407+
};
2408+
2409+
println!("[Storage] 📊 Initializing Bloom filter: {} MB for {} expected transactions",
2410+
size / 1_000_000, expected_elements);
23792411

23802412
ProbabilisticIndex {
23812413
bits: vec![false; size],

0 commit comments

Comments
 (0)