diff --git a/runtime/src/bank_forks.rs b/runtime/src/bank_forks.rs index dc8e31e14a281d..7ec4e8b3bb03e0 100644 --- a/runtime/src/bank_forks.rs +++ b/runtime/src/bank_forks.rs @@ -727,12 +727,27 @@ mod tests { solana_vote_program::vote_state::BlockTimestamp, }; + // This test verifies that BankForks::new_rw_arc() doesn't create a reference cycle. + // + // Before PR #1893, there was a cycle: + // Arc> → Bank → ProgramCache → Arc> + // + // This happened because new_rw_arc() called: + // root_bank.set_fork_graph_in_program_cache(bank_forks.clone()) + // + // The fix changed it to use a Weak reference: + // root_bank.set_fork_graph_in_program_cache(Arc::downgrade(&bank_forks)) + // + // Breaking the cycle: + // Arc> → Bank → ProgramCache → Weak> + // + // Without the fix: strong_count == 2 (the clone creates an extra strong ref) + // With the fix: strong_count == 1 (only the returned Arc holds a strong ref) #[test] fn test_bank_forks_new_rw_arc_memory_leak() { - for _ in 0..1000 { - let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); - BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); - } + let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000); + let bank_forks = BankForks::new_rw_arc(Bank::new_for_tests(&genesis_config)); + assert_eq!(Arc::strong_count(&bank_forks), 1); } #[test]