@@ -491,7 +491,7 @@ impl LoadedPrograms {
491
491
self . latest_root = std:: cmp:: max ( self . latest_root , new_root) ;
492
492
}
493
493
494
- fn matches_loaded_program (
494
+ fn matches_loaded_program_criteria (
495
495
program : & Arc < LoadedProgram > ,
496
496
criteria : & LoadedProgramMatchCriteria ,
497
497
) -> bool {
@@ -504,6 +504,27 @@ impl LoadedPrograms {
504
504
}
505
505
}
506
506
507
+ fn is_entry_usable (
508
+ entry : & Arc < LoadedProgram > ,
509
+ current_slot : Slot ,
510
+ match_criteria : & LoadedProgramMatchCriteria ,
511
+ ) -> bool {
512
+ if entry
513
+ . maybe_expiration_slot
514
+ . map ( |expiration_slot| expiration_slot <= current_slot)
515
+ . unwrap_or ( false )
516
+ {
517
+ // Found an entry that's already expired. Any further entries in the list
518
+ // are older than the current one. So treat the program as missing in the
519
+ // cache and return early.
520
+ return false ;
521
+ }
522
+
523
+ Self :: matches_loaded_program_criteria ( entry, match_criteria)
524
+ // If the program was unloaded. Consider it as unusable, so it can be reloaded.
525
+ && !matches ! ( entry. program, LoadedProgramType :: Unloaded )
526
+ }
527
+
507
528
/// Extracts a subset of the programs relevant to a transaction batch
508
529
/// and returns which program accounts the accounts DB needs to load.
509
530
pub fn extract < S : WorkingSlot > (
@@ -521,25 +542,7 @@ impl LoadedPrograms {
521
542
|| entry. deployment_slot == current_slot
522
543
|| working_slot. is_ancestor ( entry. deployment_slot )
523
544
{
524
- if entry
525
- . maybe_expiration_slot
526
- . map ( |expiration_slot| current_slot >= expiration_slot)
527
- . unwrap_or ( false )
528
- {
529
- // Found an entry that's already expired. Any further entries in the list
530
- // are older than the current one. So treat the program as missing in the
531
- // cache and return early.
532
- missing. push ( key) ;
533
- return None ;
534
- }
535
-
536
- if !Self :: matches_loaded_program ( entry, & match_criteria) {
537
- missing. push ( key) ;
538
- return None ;
539
- }
540
-
541
- if matches ! ( entry. program, LoadedProgramType :: Unloaded ) {
542
- // The program was unloaded. Consider it as missing, so it can be reloaded.
545
+ if !Self :: is_entry_usable ( entry, current_slot, & match_criteria) {
543
546
missing. push ( key) ;
544
547
return None ;
545
548
}
@@ -1789,4 +1792,148 @@ mod tests {
1789
1792
0
1790
1793
) ;
1791
1794
}
1795
+
1796
+ #[ test]
1797
+ fn test_usable_entries_for_slot ( ) {
1798
+ let unloaded_entry = Arc :: new ( LoadedProgram {
1799
+ program : LoadedProgramType :: Unloaded ,
1800
+ account_size : 0 ,
1801
+ deployment_slot : 0 ,
1802
+ effective_slot : 0 ,
1803
+ maybe_expiration_slot : None ,
1804
+ usage_counter : AtomicU64 :: default ( ) ,
1805
+ } ) ;
1806
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1807
+ & unloaded_entry,
1808
+ 0 ,
1809
+ & LoadedProgramMatchCriteria :: NoCriteria
1810
+ ) ) ;
1811
+
1812
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1813
+ & unloaded_entry,
1814
+ 1 ,
1815
+ & LoadedProgramMatchCriteria :: NoCriteria
1816
+ ) ) ;
1817
+
1818
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1819
+ & unloaded_entry,
1820
+ 1 ,
1821
+ & LoadedProgramMatchCriteria :: Tombstone
1822
+ ) ) ;
1823
+
1824
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1825
+ & unloaded_entry,
1826
+ 1 ,
1827
+ & LoadedProgramMatchCriteria :: DeployedOnOrAfterSlot ( 0 )
1828
+ ) ) ;
1829
+
1830
+ let tombstone = Arc :: new ( LoadedProgram :: new_tombstone ( 0 , LoadedProgramType :: Closed ) ) ;
1831
+
1832
+ assert ! ( LoadedPrograms :: is_entry_usable(
1833
+ & tombstone,
1834
+ 0 ,
1835
+ & LoadedProgramMatchCriteria :: NoCriteria
1836
+ ) ) ;
1837
+
1838
+ assert ! ( LoadedPrograms :: is_entry_usable(
1839
+ & tombstone,
1840
+ 1 ,
1841
+ & LoadedProgramMatchCriteria :: Tombstone
1842
+ ) ) ;
1843
+
1844
+ assert ! ( LoadedPrograms :: is_entry_usable(
1845
+ & tombstone,
1846
+ 1 ,
1847
+ & LoadedProgramMatchCriteria :: NoCriteria
1848
+ ) ) ;
1849
+
1850
+ assert ! ( LoadedPrograms :: is_entry_usable(
1851
+ & tombstone,
1852
+ 1 ,
1853
+ & LoadedProgramMatchCriteria :: DeployedOnOrAfterSlot ( 0 )
1854
+ ) ) ;
1855
+
1856
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1857
+ & tombstone,
1858
+ 1 ,
1859
+ & LoadedProgramMatchCriteria :: DeployedOnOrAfterSlot ( 1 )
1860
+ ) ) ;
1861
+
1862
+ let program = new_test_loaded_program ( 0 , 1 ) ;
1863
+
1864
+ assert ! ( LoadedPrograms :: is_entry_usable(
1865
+ & program,
1866
+ 0 ,
1867
+ & LoadedProgramMatchCriteria :: NoCriteria
1868
+ ) ) ;
1869
+
1870
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1871
+ & program,
1872
+ 1 ,
1873
+ & LoadedProgramMatchCriteria :: Tombstone
1874
+ ) ) ;
1875
+
1876
+ assert ! ( LoadedPrograms :: is_entry_usable(
1877
+ & program,
1878
+ 1 ,
1879
+ & LoadedProgramMatchCriteria :: NoCriteria
1880
+ ) ) ;
1881
+
1882
+ assert ! ( LoadedPrograms :: is_entry_usable(
1883
+ & program,
1884
+ 1 ,
1885
+ & LoadedProgramMatchCriteria :: DeployedOnOrAfterSlot ( 0 )
1886
+ ) ) ;
1887
+
1888
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1889
+ & program,
1890
+ 1 ,
1891
+ & LoadedProgramMatchCriteria :: DeployedOnOrAfterSlot ( 1 )
1892
+ ) ) ;
1893
+
1894
+ let program = Arc :: new ( LoadedProgram {
1895
+ program : LoadedProgramType :: TestLoaded ,
1896
+ account_size : 0 ,
1897
+ deployment_slot : 0 ,
1898
+ effective_slot : 1 ,
1899
+ maybe_expiration_slot : Some ( 2 ) ,
1900
+ usage_counter : AtomicU64 :: default ( ) ,
1901
+ } ) ;
1902
+
1903
+ assert ! ( LoadedPrograms :: is_entry_usable(
1904
+ & program,
1905
+ 0 ,
1906
+ & LoadedProgramMatchCriteria :: NoCriteria
1907
+ ) ) ;
1908
+
1909
+ assert ! ( LoadedPrograms :: is_entry_usable(
1910
+ & program,
1911
+ 1 ,
1912
+ & LoadedProgramMatchCriteria :: NoCriteria
1913
+ ) ) ;
1914
+
1915
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1916
+ & program,
1917
+ 1 ,
1918
+ & LoadedProgramMatchCriteria :: Tombstone
1919
+ ) ) ;
1920
+
1921
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1922
+ & program,
1923
+ 2 ,
1924
+ & LoadedProgramMatchCriteria :: NoCriteria
1925
+ ) ) ;
1926
+
1927
+ assert ! ( LoadedPrograms :: is_entry_usable(
1928
+ & program,
1929
+ 1 ,
1930
+ & LoadedProgramMatchCriteria :: DeployedOnOrAfterSlot ( 0 )
1931
+ ) ) ;
1932
+
1933
+ assert ! ( !LoadedPrograms :: is_entry_usable(
1934
+ & program,
1935
+ 1 ,
1936
+ & LoadedProgramMatchCriteria :: DeployedOnOrAfterSlot ( 1 )
1937
+ ) ) ;
1938
+ }
1792
1939
}
0 commit comments