@@ -31,7 +31,6 @@ use store::{
3131 BlobInfo , DBColumn , HotColdDB , StoreConfig ,
3232} ;
3333use tempfile:: { tempdir, TempDir } ;
34- use tokio:: time:: sleep;
3534use types:: test_utils:: { SeedableRng , XorShiftRng } ;
3635use types:: * ;
3736
@@ -119,6 +118,17 @@ fn get_harness_generic(
119118 harness
120119}
121120
121+ fn count_states_descendant_of_block (
122+ store : & HotColdDB < E , BeaconNodeBackend < E > , BeaconNodeBackend < E > > ,
123+ block_root : Hash256 ,
124+ ) -> usize {
125+ let summaries = store. load_hot_state_summaries ( ) . unwrap ( ) ;
126+ summaries
127+ . iter ( )
128+ . filter ( |( _, s) | s. latest_block_root == block_root)
129+ . count ( )
130+ }
131+
122132#[ tokio:: test]
123133async fn light_client_bootstrap_test ( ) {
124134 let spec = test_spec :: < E > ( ) ;
@@ -2136,64 +2146,6 @@ async fn pruning_test(
21362146 check_no_blocks_exist ( & harness, stray_blocks. values ( ) ) ;
21372147}
21382148
2139- #[ tokio:: test]
2140- async fn garbage_collect_temp_states_from_failed_block_on_startup ( ) {
2141- let db_path = tempdir ( ) . unwrap ( ) ;
2142-
2143- // Wrap these functions to ensure the variables are dropped before we try to open another
2144- // instance of the store.
2145- let mut store = {
2146- let store = get_store ( & db_path) ;
2147- let harness = get_harness ( store. clone ( ) , LOW_VALIDATOR_COUNT ) ;
2148-
2149- let slots_per_epoch = E :: slots_per_epoch ( ) ;
2150-
2151- let genesis_state = harness. get_current_state ( ) ;
2152- let block_slot = Slot :: new ( 2 * slots_per_epoch) ;
2153- let ( ( signed_block, _) , state) = harness. make_block ( genesis_state, block_slot) . await ;
2154-
2155- let ( mut block, _) = ( * signed_block) . clone ( ) . deconstruct ( ) ;
2156-
2157- // Mutate the block to make it invalid, and re-sign it.
2158- * block. state_root_mut ( ) = Hash256 :: repeat_byte ( 0xff ) ;
2159- let proposer_index = block. proposer_index ( ) as usize ;
2160- let block = Arc :: new ( block. sign (
2161- & harness. validator_keypairs [ proposer_index] . sk ,
2162- & state. fork ( ) ,
2163- state. genesis_validators_root ( ) ,
2164- & harness. spec ,
2165- ) ) ;
2166-
2167- // The block should be rejected, but should store a bunch of temporary states.
2168- harness. set_current_slot ( block_slot) ;
2169- harness
2170- . process_block_result ( ( block, None ) )
2171- . await
2172- . unwrap_err ( ) ;
2173-
2174- assert_eq ! (
2175- store. iter_temporary_state_roots( ) . count( ) ,
2176- block_slot. as_usize( ) - 1
2177- ) ;
2178- store
2179- } ;
2180-
2181- // Wait until all the references to the store have been dropped, this helps ensure we can
2182- // re-open the store later.
2183- loop {
2184- store = if let Err ( store_arc) = Arc :: try_unwrap ( store) {
2185- sleep ( Duration :: from_millis ( 500 ) ) . await ;
2186- store_arc
2187- } else {
2188- break ;
2189- }
2190- }
2191-
2192- // On startup, the store should garbage collect all the temporary states.
2193- let store = get_store ( & db_path) ;
2194- assert_eq ! ( store. iter_temporary_state_roots( ) . count( ) , 0 ) ;
2195- }
2196-
21972149#[ tokio:: test]
21982150async fn garbage_collect_temp_states_from_failed_block_on_finalization ( ) {
21992151 let db_path = tempdir ( ) . unwrap ( ) ;
@@ -2208,6 +2160,7 @@ async fn garbage_collect_temp_states_from_failed_block_on_finalization() {
22082160 let ( ( signed_block, _) , state) = harness. make_block ( genesis_state, block_slot) . await ;
22092161
22102162 let ( mut block, _) = ( * signed_block) . clone ( ) . deconstruct ( ) ;
2163+ let bad_block_parent_root = block. parent_root ( ) ;
22112164
22122165 // Mutate the block to make it invalid, and re-sign it.
22132166 * block. state_root_mut ( ) = Hash256 :: repeat_byte ( 0xff ) ;
@@ -2226,9 +2179,11 @@ async fn garbage_collect_temp_states_from_failed_block_on_finalization() {
22262179 . await
22272180 . unwrap_err ( ) ;
22282181
2182+ // The bad block parent root is the genesis block root. There's `block_slot - 1` temporary
2183+ // states to remove + the genesis state = block_slot.
22292184 assert_eq ! (
2230- store . iter_temporary_state_roots ( ) . count ( ) ,
2231- block_slot. as_usize( ) - 1
2185+ count_states_descendant_of_block ( & store , bad_block_parent_root ) ,
2186+ block_slot. as_usize( ) ,
22322187 ) ;
22332188
22342189 // Finalize the chain without the block, which should result in pruning of all temporary states.
@@ -2245,8 +2200,12 @@ async fn garbage_collect_temp_states_from_failed_block_on_finalization() {
22452200 // Check that the finalization migration ran.
22462201 assert_ne ! ( store. get_split_slot( ) , 0 ) ;
22472202
2248- // Check that temporary states have been pruned.
2249- assert_eq ! ( store. iter_temporary_state_roots( ) . count( ) , 0 ) ;
2203+ // Check that temporary states have been pruned. The genesis block is not a descendant of the
2204+ // latest finalized checkpoint, so all its states have been pruned from the hot DB, = 0.
2205+ assert_eq ! (
2206+ count_states_descendant_of_block( & store, bad_block_parent_root) ,
2207+ 0
2208+ ) ;
22502209}
22512210
22522211#[ tokio:: test]
0 commit comments