Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.

Commit 833c7e1

Browse files
committed
LoadedPrograms::extract() code cleanup and unit tests
1 parent 76d1c38 commit 833c7e1

File tree

1 file changed

+167
-20
lines changed

1 file changed

+167
-20
lines changed

program-runtime/src/loaded_programs.rs

Lines changed: 167 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ impl LoadedPrograms {
491491
self.latest_root = std::cmp::max(self.latest_root, new_root);
492492
}
493493

494-
fn matches_loaded_program(
494+
fn matches_loaded_program_criteria(
495495
program: &Arc<LoadedProgram>,
496496
criteria: &LoadedProgramMatchCriteria,
497497
) -> bool {
@@ -504,6 +504,27 @@ impl LoadedPrograms {
504504
}
505505
}
506506

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+
507528
/// Extracts a subset of the programs relevant to a transaction batch
508529
/// and returns which program accounts the accounts DB needs to load.
509530
pub fn extract<S: WorkingSlot>(
@@ -521,25 +542,7 @@ impl LoadedPrograms {
521542
|| entry.deployment_slot == current_slot
522543
|| working_slot.is_ancestor(entry.deployment_slot)
523544
{
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) {
543546
missing.push(key);
544547
return None;
545548
}
@@ -1789,4 +1792,148 @@ mod tests {
17891792
0
17901793
);
17911794
}
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+
}
17921939
}

0 commit comments

Comments
 (0)