Fix panic in ProgramTestContext::warp_to_slot() when warping one slot (#22977)

warp_to_slot() first warps to one slot before desired slot in order to
freeze the bank at warp slot. This would cause issues when warping by
one slot as that would attempt to warp to the same slot and hit a sanity
check assertion.
This commit is contained in:
steviez 2022-02-07 16:21:43 -06:00 committed by GitHub
parent 5acf0f6331
commit f2d406ad5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 36 additions and 9 deletions

View File

@ -1075,26 +1075,33 @@ impl ProgramTestContext {
bank.register_tick(&Hash::new_unique());
}
// warp ahead to one slot *before* the desired slot because the warped
// bank is frozen
// Ensure that we are actually progressing forward
let working_slot = bank.slot();
if warp_slot <= working_slot {
return Err(ProgramTestError::InvalidWarpSlot);
}
// Warp ahead to one slot *before* the desired slot because the bank
// from Bank::warp_from_parent() is frozen. If the desired slot is one
// slot *after* the working_slot, no need to warp at all.
let pre_warp_slot = warp_slot - 1;
let warp_bank = bank_forks.insert(Bank::warp_from_parent(
&bank,
&Pubkey::default(),
pre_warp_slot,
));
let warp_bank = if pre_warp_slot == working_slot {
bank.freeze();
bank
} else {
bank_forks.insert(Bank::warp_from_parent(
&bank,
&Pubkey::default(),
pre_warp_slot,
))
};
bank_forks.set_root(
pre_warp_slot,
&solana_runtime::accounts_background_service::AbsRequestSender::default(),
Some(pre_warp_slot),
);
// warp bank is frozen, so go forward one slot from it
// warp_bank is frozen so go forward to get unfrozen bank at warp_slot
bank_forks.insert(Bank::new_from_parent(
&warp_bank,
&Pubkey::default(),

View File

@ -132,7 +132,7 @@ async fn clock_sysvar_updated_from_warp() {
);
let mut context = program_test.start_with_context().await;
let expected_slot = 100_000;
let mut expected_slot = 100_000;
let instruction = Instruction::new_with_bincode(
program_id,
&expected_slot,
@ -175,6 +175,26 @@ async fn clock_sysvar_updated_from_warp() {
.await
.unwrap();
// Try warping ahead one slot (corner case in warp logic)
expected_slot += 1;
assert!(context.warp_to_slot(expected_slot).is_ok());
let instruction = Instruction::new_with_bincode(
program_id,
&expected_slot,
vec![AccountMeta::new_readonly(clock::id(), false)],
);
let transaction = Transaction::new_signed_with_payer(
&[instruction],
Some(&context.payer.pubkey()),
&[&context.payer],
context.last_blockhash,
);
context
.banks_client
.process_transaction(transaction)
.await
.unwrap();
// Try warping again to the same slot
assert_eq!(
context.warp_to_slot(expected_slot).unwrap_err(),