@@ -2514,7 +2514,7 @@ async fn pruning_test(
2514
2514
}
2515
2515
2516
2516
#[ tokio:: test]
2517
- async fn garbage_collect_temp_states_from_failed_block ( ) {
2517
+ async fn garbage_collect_temp_states_from_failed_block_on_startup ( ) {
2518
2518
let db_path = tempdir ( ) . unwrap ( ) ;
2519
2519
2520
2520
// Wrap these functions to ensure the variables are dropped before we try to open another
@@ -2571,6 +2571,61 @@ async fn garbage_collect_temp_states_from_failed_block() {
2571
2571
assert_eq ! ( store. iter_temporary_state_roots( ) . count( ) , 0 ) ;
2572
2572
}
2573
2573
2574
+ #[ tokio:: test]
2575
+ async fn garbage_collect_temp_states_from_failed_block_on_finalization ( ) {
2576
+ let db_path = tempdir ( ) . unwrap ( ) ;
2577
+
2578
+ let store = get_store ( & db_path) ;
2579
+ let harness = get_harness ( store. clone ( ) , LOW_VALIDATOR_COUNT ) ;
2580
+
2581
+ let slots_per_epoch = E :: slots_per_epoch ( ) ;
2582
+
2583
+ let genesis_state = harness. get_current_state ( ) ;
2584
+ let block_slot = Slot :: new ( 2 * slots_per_epoch) ;
2585
+ let ( ( signed_block, _) , state) = harness. make_block ( genesis_state, block_slot) . await ;
2586
+
2587
+ let ( mut block, _) = ( * signed_block) . clone ( ) . deconstruct ( ) ;
2588
+
2589
+ // Mutate the block to make it invalid, and re-sign it.
2590
+ * block. state_root_mut ( ) = Hash256 :: repeat_byte ( 0xff ) ;
2591
+ let proposer_index = block. proposer_index ( ) as usize ;
2592
+ let block = Arc :: new ( block. sign (
2593
+ & harness. validator_keypairs [ proposer_index] . sk ,
2594
+ & state. fork ( ) ,
2595
+ state. genesis_validators_root ( ) ,
2596
+ & harness. spec ,
2597
+ ) ) ;
2598
+
2599
+ // The block should be rejected, but should store a bunch of temporary states.
2600
+ harness. set_current_slot ( block_slot) ;
2601
+ harness
2602
+ . process_block_result ( ( block, None ) )
2603
+ . await
2604
+ . unwrap_err ( ) ;
2605
+
2606
+ assert_eq ! (
2607
+ store. iter_temporary_state_roots( ) . count( ) ,
2608
+ block_slot. as_usize( ) - 1
2609
+ ) ;
2610
+
2611
+ // Finalize the chain without the block, which should result in pruning of all temporary states.
2612
+ let blocks_required_to_finalize = 3 * slots_per_epoch;
2613
+ harness. advance_slot ( ) ;
2614
+ harness
2615
+ . extend_chain (
2616
+ blocks_required_to_finalize as usize ,
2617
+ BlockStrategy :: OnCanonicalHead ,
2618
+ AttestationStrategy :: AllValidators ,
2619
+ )
2620
+ . await ;
2621
+
2622
+ // Check that the finalization migration ran.
2623
+ assert_ne ! ( store. get_split_slot( ) , 0 ) ;
2624
+
2625
+ // Check that temporary states have been pruned.
2626
+ assert_eq ! ( store. iter_temporary_state_roots( ) . count( ) , 0 ) ;
2627
+ }
2628
+
2574
2629
#[ tokio:: test]
2575
2630
async fn weak_subjectivity_sync_easy ( ) {
2576
2631
let num_initial_slots = E :: slots_per_epoch ( ) * 11 ;
0 commit comments