@@ -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