Return implicit delay visibility tombstone (#31493)
This commit is contained in:
parent
c5e071c7fe
commit
9c6e7e0435
|
@ -25,6 +25,7 @@ use {
|
|||
};
|
||||
|
||||
const MAX_LOADED_ENTRY_COUNT: usize = 256;
|
||||
const DELAY_VISIBILITY_SLOT_OFFSET: Slot = 1;
|
||||
|
||||
/// Relationship between two fork IDs
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
@ -231,8 +232,8 @@ impl LoadedProgram {
|
|||
}
|
||||
|
||||
pub fn new_tombstone(slot: Slot, reason: LoadedProgramType) -> Self {
|
||||
let maybe_expiration_slot =
|
||||
matches!(reason, LoadedProgramType::DelayVisibility).then_some(slot.saturating_add(1));
|
||||
let maybe_expiration_slot = matches!(reason, LoadedProgramType::DelayVisibility)
|
||||
.then_some(slot.saturating_add(DELAY_VISIBILITY_SLOT_OFFSET));
|
||||
let tombstone = Self {
|
||||
program: reason,
|
||||
account_size: 0,
|
||||
|
@ -429,6 +430,18 @@ impl LoadedPrograms {
|
|||
|
||||
if current_slot >= entry.effective_slot {
|
||||
return Some((key, entry.clone()));
|
||||
} else if entry.effective_slot.saturating_sub(entry.deployment_slot)
|
||||
== DELAY_VISIBILITY_SLOT_OFFSET
|
||||
&& current_slot >= entry.deployment_slot
|
||||
{
|
||||
// Found a program entry on the current fork, but it's not effective
|
||||
// yet. It indicates that the program has delayed visibility. Return
|
||||
// the tombstone to reflect that.
|
||||
let delay_visibility = LoadedProgram::new_tombstone(
|
||||
entry.deployment_slot,
|
||||
LoadedProgramType::DelayVisibility,
|
||||
);
|
||||
return Some((key, Arc::new(delay_visibility)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -533,7 +546,7 @@ mod tests {
|
|||
use {
|
||||
crate::loaded_programs::{
|
||||
BlockRelation, ForkGraph, LoadedProgram, LoadedProgramMatchCriteria, LoadedProgramType,
|
||||
LoadedPrograms, LoadedProgramsForTxBatch, WorkingSlot,
|
||||
LoadedPrograms, LoadedProgramsForTxBatch, WorkingSlot, DELAY_VISIBILITY_SLOT_OFFSET,
|
||||
},
|
||||
percentage::Percentage,
|
||||
solana_rbpf::vm::BuiltInProgram,
|
||||
|
@ -1100,7 +1113,14 @@ mod tests {
|
|||
|
||||
let program2 = Pubkey::new_unique();
|
||||
assert!(!cache.replenish(program2, new_test_loaded_program(5, 6)).0);
|
||||
assert!(!cache.replenish(program2, new_test_loaded_program(11, 12)).0);
|
||||
assert!(
|
||||
!cache
|
||||
.replenish(
|
||||
program2,
|
||||
new_test_loaded_program(11, 11 + DELAY_VISIBILITY_SLOT_OFFSET)
|
||||
)
|
||||
.0
|
||||
);
|
||||
|
||||
let program3 = Pubkey::new_unique();
|
||||
assert!(!cache.replenish(program3, new_test_loaded_program(25, 26)).0);
|
||||
|
@ -1109,7 +1129,14 @@ mod tests {
|
|||
assert!(!cache.replenish(program4, new_test_loaded_program(0, 1)).0);
|
||||
assert!(!cache.replenish(program4, new_test_loaded_program(5, 6)).0);
|
||||
// The following is a special case, where effective slot is 3 slots in the future
|
||||
assert!(!cache.replenish(program4, new_test_loaded_program(15, 18)).0);
|
||||
assert!(
|
||||
!cache
|
||||
.replenish(
|
||||
program4,
|
||||
new_test_loaded_program(15, 15 + DELAY_VISIBILITY_SLOT_OFFSET)
|
||||
)
|
||||
.0
|
||||
);
|
||||
|
||||
// Current fork graph
|
||||
// 0
|
||||
|
@ -1146,7 +1173,7 @@ mod tests {
|
|||
assert!(missing.contains(&program3));
|
||||
|
||||
// Testing fork 0 - 5 - 11 - 15 - 16 with current slot at 16
|
||||
let mut working_slot = TestWorkingSlot::new(16, &[0, 5, 11, 15, 16, 18, 19, 23]);
|
||||
let mut working_slot = TestWorkingSlot::new(15, &[0, 5, 11, 15, 16, 18, 19, 23]);
|
||||
let (found, missing) = cache.extract(
|
||||
&working_slot,
|
||||
vec![
|
||||
|
@ -1158,11 +1185,17 @@ mod tests {
|
|||
.into_iter(),
|
||||
);
|
||||
|
||||
assert!(match_slot(&found, &program1, 0, 16));
|
||||
assert!(match_slot(&found, &program2, 11, 16));
|
||||
assert!(match_slot(&found, &program1, 0, 15));
|
||||
assert!(match_slot(&found, &program2, 11, 15));
|
||||
|
||||
// The effective slot of program4 deployed in slot 15 is 19. So it should not be usable in slot 16.
|
||||
assert!(match_slot(&found, &program4, 5, 16));
|
||||
// A delay visibility tombstone should be returned here.
|
||||
let tombstone = found.find(program4).expect("Failed to find the tombstone");
|
||||
assert!(matches!(
|
||||
tombstone.program,
|
||||
LoadedProgramType::DelayVisibility
|
||||
));
|
||||
assert_eq!(tombstone.deployment_slot, 15);
|
||||
|
||||
assert!(missing.contains(&program3));
|
||||
|
||||
|
@ -1222,7 +1255,13 @@ mod tests {
|
|||
);
|
||||
|
||||
assert!(match_slot(&found, &program1, 0, 11));
|
||||
assert!(match_slot(&found, &program2, 5, 11));
|
||||
// program2 was updated at slot 11, but is not effective till slot 12. The result should contain a tombstone.
|
||||
let tombstone = found.find(program2).expect("Failed to find the tombstone");
|
||||
assert!(matches!(
|
||||
tombstone.program,
|
||||
LoadedProgramType::DelayVisibility
|
||||
));
|
||||
assert_eq!(tombstone.deployment_slot, 11);
|
||||
assert!(match_slot(&found, &program4, 5, 11));
|
||||
|
||||
assert!(missing.contains(&program3));
|
||||
|
|
Loading…
Reference in New Issue