@@ -70,7 +70,7 @@ pub struct HotColdDB<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> {
70
70
/// The hot database also contains all blocks.
71
71
pub hot_db : Hot ,
72
72
/// LRU cache of deserialized blocks and blobs. Updated whenever a block or blob is loaded.
73
- block_cache : Mutex < BlockCache < E > > ,
73
+ block_cache : Option < Mutex < BlockCache < E > > > ,
74
74
/// Cache of beacon states.
75
75
///
76
76
/// LOCK ORDERING: this lock must always be locked *after* the `split` if both are required.
@@ -229,7 +229,9 @@ impl<E: EthSpec> HotColdDB<E, MemoryStore<E>, MemoryStore<E>> {
229
229
cold_db : MemoryStore :: open ( ) ,
230
230
blobs_db : MemoryStore :: open ( ) ,
231
231
hot_db : MemoryStore :: open ( ) ,
232
- block_cache : Mutex :: new ( BlockCache :: new ( config. block_cache_size ) ) ,
232
+ block_cache : NonZeroUsize :: new ( config. block_cache_size )
233
+ . map ( BlockCache :: new)
234
+ . map ( Mutex :: new) ,
233
235
state_cache : Mutex :: new ( StateCache :: new (
234
236
config. state_cache_size ,
235
237
config. state_cache_headroom ,
@@ -281,7 +283,9 @@ impl<E: EthSpec> HotColdDB<E, BeaconNodeBackend<E>, BeaconNodeBackend<E>> {
281
283
blobs_db : BeaconNodeBackend :: open ( & config, blobs_db_path) ?,
282
284
cold_db : BeaconNodeBackend :: open ( & config, cold_path) ?,
283
285
hot_db,
284
- block_cache : Mutex :: new ( BlockCache :: new ( config. block_cache_size ) ) ,
286
+ block_cache : NonZeroUsize :: new ( config. block_cache_size )
287
+ . map ( BlockCache :: new)
288
+ . map ( Mutex :: new) ,
285
289
state_cache : Mutex :: new ( StateCache :: new (
286
290
config. state_cache_size ,
287
291
config. state_cache_headroom ,
@@ -488,14 +492,17 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
488
492
pub fn register_metrics ( & self ) {
489
493
let hsc_metrics = self . historic_state_cache . lock ( ) . metrics ( ) ;
490
494
491
- metrics:: set_gauge (
492
- & metrics:: STORE_BEACON_BLOCK_CACHE_SIZE ,
493
- self . block_cache . lock ( ) . block_cache . len ( ) as i64 ,
494
- ) ;
495
- metrics:: set_gauge (
496
- & metrics:: STORE_BEACON_BLOB_CACHE_SIZE ,
497
- self . block_cache . lock ( ) . blob_cache . len ( ) as i64 ,
498
- ) ;
495
+ if let Some ( block_cache) = & self . block_cache {
496
+ let cache = block_cache. lock ( ) ;
497
+ metrics:: set_gauge (
498
+ & metrics:: STORE_BEACON_BLOCK_CACHE_SIZE ,
499
+ cache. block_cache . len ( ) as i64 ,
500
+ ) ;
501
+ metrics:: set_gauge (
502
+ & metrics:: STORE_BEACON_BLOB_CACHE_SIZE ,
503
+ cache. blob_cache . len ( ) as i64 ,
504
+ ) ;
505
+ }
499
506
let state_cache = self . state_cache . lock ( ) ;
500
507
metrics:: set_gauge (
501
508
& metrics:: STORE_BEACON_STATE_CACHE_SIZE ,
@@ -553,7 +560,9 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
553
560
let block = self . block_as_kv_store_ops ( block_root, block, & mut ops) ?;
554
561
self . hot_db . do_atomically ( ops) ?;
555
562
// Update cache.
556
- self . block_cache . lock ( ) . put_block ( * block_root, block) ;
563
+ self . block_cache
564
+ . as_ref ( )
565
+ . inspect ( |cache| cache. lock ( ) . put_block ( * block_root, block) ) ;
557
566
Ok ( ( ) )
558
567
}
559
568
@@ -605,7 +614,9 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
605
614
metrics:: inc_counter ( & metrics:: BEACON_BLOCK_GET_COUNT ) ;
606
615
607
616
// Check the cache.
608
- if let Some ( block) = self . block_cache . lock ( ) . get_block ( block_root) {
617
+ if let Some ( cache) = & self . block_cache
618
+ && let Some ( block) = cache. lock ( ) . get_block ( block_root)
619
+ {
609
620
metrics:: inc_counter ( & metrics:: BEACON_BLOCK_CACHE_HIT_COUNT ) ;
610
621
return Ok ( Some ( DatabaseBlock :: Full ( block. clone ( ) ) ) ) ;
611
622
}
@@ -630,8 +641,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
630
641
631
642
// Add to cache.
632
643
self . block_cache
633
- . lock ( )
634
- . put_block ( * block_root, full_block. clone ( ) ) ;
644
+ . as_ref ( )
645
+ . inspect ( |cache| cache . lock ( ) . put_block ( * block_root, full_block. clone ( ) ) ) ;
635
646
636
647
DatabaseBlock :: Full ( full_block)
637
648
} else if !self . config . prune_payloads {
@@ -902,7 +913,9 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
902
913
903
914
/// Delete a block from the store and the block cache.
904
915
pub fn delete_block ( & self , block_root : & Hash256 ) -> Result < ( ) , Error > {
905
- self . block_cache . lock ( ) . delete ( block_root) ;
916
+ self . block_cache
917
+ . as_ref ( )
918
+ . inspect ( |cache| cache. lock ( ) . delete ( block_root) ) ;
906
919
self . hot_db
907
920
. key_delete ( DBColumn :: BeaconBlock , block_root. as_slice ( ) ) ?;
908
921
self . hot_db
@@ -917,7 +930,9 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
917
930
block_root. as_slice ( ) ,
918
931
& blobs. as_ssz_bytes ( ) ,
919
932
) ?;
920
- self . block_cache . lock ( ) . put_blobs ( * block_root, blobs) ;
933
+ self . block_cache
934
+ . as_ref ( )
935
+ . inspect ( |cache| cache. lock ( ) . put_blobs ( * block_root, blobs) ) ;
921
936
Ok ( ( ) )
922
937
}
923
938
@@ -945,9 +960,11 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
945
960
self . blobs_db
946
961
. put ( & DATA_COLUMN_CUSTODY_INFO_KEY , & data_column_custody_info) ?;
947
962
948
- self . block_cache
949
- . lock ( )
950
- . put_data_column_custody_info ( Some ( data_column_custody_info) ) ;
963
+ self . block_cache . as_ref ( ) . inspect ( |cache| {
964
+ cache
965
+ . lock ( )
966
+ . put_data_column_custody_info ( Some ( data_column_custody_info) )
967
+ } ) ;
951
968
952
969
Ok ( ( ) )
953
970
}
@@ -964,8 +981,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
964
981
& data_column. as_ssz_bytes ( ) ,
965
982
) ?;
966
983
self . block_cache
967
- . lock ( )
968
- . put_data_column ( * block_root, data_column) ;
984
+ . as_ref ( )
985
+ . inspect ( |cache| cache . lock ( ) . put_data_column ( * block_root, data_column) ) ;
969
986
}
970
987
Ok ( ( ) )
971
988
}
@@ -1399,7 +1416,7 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1399
1416
1400
1417
// Update database whilst holding a lock on cache, to ensure that the cache updates
1401
1418
// atomically with the database.
1402
- let mut guard = self . block_cache . lock ( ) ;
1419
+ let guard = self . block_cache . as_ref ( ) . map ( |cache| cache . lock ( ) ) ;
1403
1420
1404
1421
let blob_cache_ops = blobs_ops. clone ( ) ;
1405
1422
// Try to execute blobs store ops.
@@ -1446,57 +1463,68 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
1446
1463
return Err ( e) ;
1447
1464
}
1448
1465
1449
- for op in hot_db_cache_ops {
1466
+ // Delete from the state cache.
1467
+ for op in & hot_db_cache_ops {
1450
1468
match op {
1451
- StoreOp :: PutBlock ( block_root, block ) => {
1452
- guard . put_block ( block_root , ( * block ) . clone ( ) ) ;
1469
+ StoreOp :: DeleteBlock ( block_root) => {
1470
+ self . state_cache . lock ( ) . delete_block_states ( block_root ) ;
1453
1471
}
1472
+ StoreOp :: DeleteState ( state_root, _) => {
1473
+ self . state_cache . lock ( ) . delete_state ( state_root)
1474
+ }
1475
+ _ => ( ) ,
1476
+ }
1477
+ }
1454
1478
1455
- StoreOp :: PutBlobs ( _, _) => ( ) ,
1479
+ // If the block cache is enabled, also delete from the block cache.
1480
+ if let Some ( mut guard) = guard {
1481
+ for op in hot_db_cache_ops {
1482
+ match op {
1483
+ StoreOp :: PutBlock ( block_root, block) => {
1484
+ guard. put_block ( block_root, ( * block) . clone ( ) ) ;
1485
+ }
1456
1486
1457
- StoreOp :: PutDataColumns ( _, _) => ( ) ,
1487
+ StoreOp :: PutBlobs ( _, _) => ( ) ,
1458
1488
1459
- StoreOp :: PutState ( _, _) => ( ) ,
1489
+ StoreOp :: PutDataColumns ( _, _) => ( ) ,
1460
1490
1461
- StoreOp :: PutStateSummary ( _, _) => ( ) ,
1491
+ StoreOp :: PutState ( _, _) => ( ) ,
1462
1492
1463
- StoreOp :: DeleteBlock ( block_root) => {
1464
- guard. delete_block ( & block_root) ;
1465
- self . state_cache . lock ( ) . delete_block_states ( & block_root) ;
1466
- }
1493
+ StoreOp :: PutStateSummary ( _, _) => ( ) ,
1467
1494
1468
- StoreOp :: DeleteState ( state_root , _ ) => {
1469
- self . state_cache . lock ( ) . delete_state ( & state_root )
1470
- }
1495
+ StoreOp :: DeleteBlock ( block_root ) => {
1496
+ guard . delete_block ( & block_root ) ;
1497
+ }
1471
1498
1472
- StoreOp :: DeleteBlobs ( _) => ( ) ,
1499
+ StoreOp :: DeleteState ( _ , _) => ( ) ,
1473
1500
1474
- StoreOp :: DeleteDataColumns ( _ , _) => ( ) ,
1501
+ StoreOp :: DeleteBlobs ( _) => ( ) ,
1475
1502
1476
- StoreOp :: DeleteExecutionPayload ( _) => ( ) ,
1503
+ StoreOp :: DeleteDataColumns ( _ , _) => ( ) ,
1477
1504
1478
- StoreOp :: DeleteSyncCommitteeBranch ( _) => ( ) ,
1505
+ StoreOp :: DeleteExecutionPayload ( _) => ( ) ,
1479
1506
1480
- StoreOp :: KeyValueOp ( _) => ( ) ,
1481
- }
1482
- }
1507
+ StoreOp :: DeleteSyncCommitteeBranch ( _) => ( ) ,
1483
1508
1484
- for op in blob_cache_ops {
1485
- match op {
1486
- StoreOp :: PutBlobs ( block_root, blobs) => {
1487
- guard. put_blobs ( block_root, blobs) ;
1509
+ StoreOp :: KeyValueOp ( _) => ( ) ,
1488
1510
}
1511
+ }
1489
1512
1490
- StoreOp :: DeleteBlobs ( block_root) => {
1491
- guard. delete_blobs ( & block_root) ;
1492
- }
1513
+ for op in blob_cache_ops {
1514
+ match op {
1515
+ StoreOp :: PutBlobs ( block_root, blobs) => {
1516
+ guard. put_blobs ( block_root, blobs) ;
1517
+ }
1493
1518
1494
- _ => ( ) ,
1519
+ StoreOp :: DeleteBlobs ( block_root) => {
1520
+ guard. delete_blobs ( & block_root) ;
1521
+ }
1522
+
1523
+ _ => ( ) ,
1524
+ }
1495
1525
}
1496
1526
}
1497
1527
1498
- drop ( guard) ;
1499
-
1500
1528
Ok ( ( ) )
1501
1529
}
1502
1530
@@ -2425,21 +2453,23 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
2425
2453
/// If custody info doesn't exist in the cache,
2426
2454
/// try to fetch from the DB and prime the cache.
2427
2455
pub fn get_data_column_custody_info ( & self ) -> Result < Option < DataColumnCustodyInfo > , Error > {
2428
- let Some ( data_column_custody_info) = self . block_cache . lock ( ) . get_data_column_custody_info ( )
2429
- else {
2430
- let data_column_custody_info = self
2431
- . blobs_db
2432
- . get :: < DataColumnCustodyInfo > ( & DATA_COLUMN_CUSTODY_INFO_KEY ) ?;
2456
+ if let Some ( cache) = & self . block_cache
2457
+ && let Some ( data_column_custody_info) = cache. lock ( ) . get_data_column_custody_info ( )
2458
+ {
2459
+ return Ok ( Some ( data_column_custody_info) ) ;
2460
+ }
2461
+ let data_column_custody_info = self
2462
+ . blobs_db
2463
+ . get :: < DataColumnCustodyInfo > ( & DATA_COLUMN_CUSTODY_INFO_KEY ) ?;
2433
2464
2434
- // Update the cache
2435
- self . block_cache
2465
+ // Update the cache
2466
+ self . block_cache . as_ref ( ) . inspect ( |cache| {
2467
+ cache
2436
2468
. lock ( )
2437
- . put_data_column_custody_info ( data_column_custody_info. clone ( ) ) ;
2438
-
2439
- return Ok ( data_column_custody_info) ;
2440
- } ;
2469
+ . put_data_column_custody_info ( data_column_custody_info. clone ( ) )
2470
+ } ) ;
2441
2471
2442
- Ok ( Some ( data_column_custody_info) )
2472
+ Ok ( data_column_custody_info)
2443
2473
}
2444
2474
2445
2475
/// Fetch all columns for a given block from the store.
@@ -2460,9 +2490,13 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
2460
2490
/// Fetch blobs for a given block from the store.
2461
2491
pub fn get_blobs ( & self , block_root : & Hash256 ) -> Result < BlobSidecarListFromRoot < E > , Error > {
2462
2492
// Check the cache.
2463
- if let Some ( blobs) = self . block_cache . lock ( ) . get_blobs ( block_root) {
2493
+ if let Some ( blobs) = self
2494
+ . block_cache
2495
+ . as_ref ( )
2496
+ . and_then ( |cache| cache. lock ( ) . get_blobs ( block_root) . cloned ( ) )
2497
+ {
2464
2498
metrics:: inc_counter ( & metrics:: BEACON_BLOBS_CACHE_HIT_COUNT ) ;
2465
- return Ok ( blobs. clone ( ) . into ( ) ) ;
2499
+ return Ok ( blobs. into ( ) ) ;
2466
2500
}
2467
2501
2468
2502
match self
@@ -2481,8 +2515,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
2481
2515
{
2482
2516
let blobs = BlobSidecarList :: new ( blobs, max_blobs_per_block as usize ) ?;
2483
2517
self . block_cache
2484
- . lock ( )
2485
- . put_blobs ( * block_root, blobs. clone ( ) ) ;
2518
+ . as_ref ( )
2519
+ . inspect ( |cache| cache . lock ( ) . put_blobs ( * block_root, blobs. clone ( ) ) ) ;
2486
2520
2487
2521
Ok ( BlobSidecarListFromRoot :: Blobs ( blobs) )
2488
2522
} else {
@@ -2515,8 +2549,8 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
2515
2549
// Check the cache.
2516
2550
if let Some ( data_column) = self
2517
2551
. block_cache
2518
- . lock ( )
2519
- . get_data_column ( block_root, column_index)
2552
+ . as_ref ( )
2553
+ . and_then ( |cache| cache . lock ( ) . get_data_column ( block_root, column_index) )
2520
2554
{
2521
2555
metrics:: inc_counter ( & metrics:: BEACON_DATA_COLUMNS_CACHE_HIT_COUNT ) ;
2522
2556
return Ok ( Some ( data_column) ) ;
@@ -2528,9 +2562,11 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
2528
2562
) ? {
2529
2563
Some ( ref data_column_bytes) => {
2530
2564
let data_column = Arc :: new ( DataColumnSidecar :: from_ssz_bytes ( data_column_bytes) ?) ;
2531
- self . block_cache
2532
- . lock ( )
2533
- . put_data_column ( * block_root, data_column. clone ( ) ) ;
2565
+ self . block_cache . as_ref ( ) . inspect ( |cache| {
2566
+ cache
2567
+ . lock ( )
2568
+ . put_data_column ( * block_root, data_column. clone ( ) )
2569
+ } ) ;
2534
2570
Ok ( Some ( data_column) )
2535
2571
}
2536
2572
None => Ok ( None ) ,
@@ -3264,11 +3300,11 @@ impl<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<E>> HotColdDB<E, Hot, Cold>
3264
3300
}
3265
3301
3266
3302
// Remove deleted blobs from the cache.
3267
- let mut block_cache = self . block_cache . lock ( ) ;
3268
- for block_root in removed_block_roots {
3269
- block_cache. delete_blobs ( & block_root) ;
3303
+ if let Some ( mut block_cache) = self . block_cache . as_ref ( ) . map ( |cache| cache. lock ( ) ) {
3304
+ for block_root in removed_block_roots {
3305
+ block_cache. delete_blobs ( & block_root) ;
3306
+ }
3270
3307
}
3271
- drop ( block_cache) ;
3272
3308
3273
3309
let new_blob_info = BlobInfo {
3274
3310
oldest_blob_slot : Some ( end_slot + 1 ) ,
0 commit comments