Adds feature reject_empty_instruction_without_program. (#21591)
This commit is contained in:
parent
015250f96c
commit
1a4a039913
|
@ -9,7 +9,8 @@ use solana_sdk::{
|
|||
compute_budget::ComputeBudget,
|
||||
feature_set::{
|
||||
demote_program_write_locks, do_support_realloc, neon_evm_compute_budget,
|
||||
remove_native_loader, requestable_heap_size, tx_wide_compute_cap, FeatureSet,
|
||||
reject_empty_instruction_without_program, remove_native_loader, requestable_heap_size,
|
||||
tx_wide_compute_cap, FeatureSet,
|
||||
},
|
||||
hash::Hash,
|
||||
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
|
||||
|
@ -218,6 +219,13 @@ impl<'a> InvokeContext<'a> {
|
|||
let program_id = program_indices
|
||||
.last()
|
||||
.map(|index_of_program_id| &self.accounts[*index_of_program_id].0);
|
||||
if program_id.is_none()
|
||||
&& self
|
||||
.feature_set
|
||||
.is_active(&reject_empty_instruction_without_program::id())
|
||||
{
|
||||
return Err(InstructionError::UnsupportedProgramId);
|
||||
}
|
||||
if self.invoke_stack.is_empty() {
|
||||
let mut compute_budget = self.compute_budget;
|
||||
if !self.feature_set.is_active(&tx_wide_compute_cap::id())
|
||||
|
|
|
@ -6506,6 +6506,7 @@ pub(crate) mod tests {
|
|||
compute_budget::ComputeBudgetInstruction,
|
||||
epoch_schedule::MINIMUM_SLOTS_PER_EPOCH,
|
||||
feature::Feature,
|
||||
feature_set::reject_empty_instruction_without_program,
|
||||
genesis_config::create_genesis_config,
|
||||
hash,
|
||||
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
|
||||
|
@ -15445,17 +15446,23 @@ pub(crate) mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn test_an_empty_transaction_without_program() {
|
||||
fn test_an_empty_instruction_without_program() {
|
||||
let (genesis_config, mint_keypair) = create_genesis_config(1);
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
|
||||
let destination = solana_sdk::pubkey::new_rand();
|
||||
let mut ix = system_instruction::transfer(&mint_keypair.pubkey(), &destination, 0);
|
||||
ix.program_id = native_loader::id(); // Empty executable account chain
|
||||
|
||||
let message = Message::new(&[ix], Some(&mint_keypair.pubkey()));
|
||||
let tx = Transaction::new(&[&mint_keypair], message, genesis_config.hash());
|
||||
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.process_transaction(&tx).unwrap();
|
||||
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.activate_feature(&reject_empty_instruction_without_program::id());
|
||||
assert_eq!(
|
||||
bank.process_transaction(&tx).unwrap_err(),
|
||||
TransactionError::InstructionError(0, InstructionError::UnsupportedProgramId),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -257,6 +257,10 @@ pub mod leave_nonce_on_success {
|
|||
solana_sdk::declare_id!("E8MkiWZNNPGU6n55jkGzyj8ghUmjCHRmDFdYYFYHxWhQ");
|
||||
}
|
||||
|
||||
pub mod reject_empty_instruction_without_program {
|
||||
solana_sdk::declare_id!("9kdtFSrXHQg3hKkbXkQ6trJ3Ja1xpJ22CTFSNAciEwmL");
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
/// Map of feature identifiers to user-visible description
|
||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||
|
@ -316,6 +320,7 @@ lazy_static! {
|
|||
(nonce_must_be_writable::id(), "nonce must be writable"),
|
||||
(spl_token_v3_3_0_release::id(), "spl-token v3.3.0 release"),
|
||||
(leave_nonce_on_success::id(), "leave nonce as is on success"),
|
||||
(reject_empty_instruction_without_program::id(), "fail instructions which have native_loader as program_id directly"),
|
||||
/*************** ADD NEW FEATURES HERE ***************/
|
||||
]
|
||||
.iter()
|
||||
|
|
Loading…
Reference in New Issue