Fixes the empty transaction bug in ThisInvokeContext::push() and adds a test for it to the bank.
This commit is contained in:
Alexander Meißner
2021-11-19 20:43:42 +01:00
committed by GitHub
parent 0bda0c3e0c
commit 8a50b6302f
4 changed files with 35 additions and 25 deletions

View File

@ -377,7 +377,8 @@ impl InstructionProcessor {
invoke_context: &mut dyn InvokeContext,
) -> Result<(), InstructionError> {
let keyed_accounts = invoke_context.get_keyed_accounts()?;
let root_account = keyed_account_at_index(keyed_accounts, 0)?;
let root_account = keyed_account_at_index(keyed_accounts, 0)
.map_err(|_| InstructionError::UnsupportedProgramId)?;
let root_id = root_account.unsigned_key();
let owner_id = &root_account.owner()?;
if solana_sdk::native_loader::check_id(owner_id) {

View File

@ -327,38 +327,21 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
return Err(InstructionError::CallDepth);
}
let program_id = if let Some(index_of_program_id) = program_indices.last() {
let program_id = &self.accounts[*index_of_program_id].0;
let contains = self
.invoke_stack
.iter()
.any(|frame| frame.program_id() == Some(program_id));
let is_last = if let Some(last_frame) = self.invoke_stack.last() {
last_frame.program_id() == Some(program_id)
} else {
false
};
if contains && !is_last {
// Reentrancy not allowed unless caller is calling itself
return Err(InstructionError::ReentrancyNotAllowed);
}
*program_id
} else {
return Err(InstructionError::UnsupportedProgramId);
};
let program_id = program_indices
.last()
.map(|index_of_program_id| &self.accounts[*index_of_program_id].0);
if self.invoke_stack.is_empty() {
let mut compute_budget = self.compute_budget;
if !self.is_feature_active(&tx_wide_compute_cap::id())
&& self.is_feature_active(&neon_evm_compute_budget::id())
&& program_id == crate::neon_evm_program::id()
&& program_id == Some(&crate::neon_evm_program::id())
{
// Bump the compute budget for neon_evm
compute_budget.max_units = compute_budget.max_units.max(500_000);
}
if !self.is_feature_active(&requestable_heap_size::id())
&& self.is_feature_active(&neon_evm_compute_budget::id())
&& program_id == crate::neon_evm_program::id()
&& program_id == Some(&crate::neon_evm_program::id())
{
// Bump the compute budget for neon_evm
compute_budget.heap_size = Some(256_usize.saturating_mul(1024));
@ -381,6 +364,20 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
Err(InstructionError::MissingAccount)
};
instruction.visit_each_account(&mut work)?;
} else {
let contains = self
.invoke_stack
.iter()
.any(|frame| frame.program_id() == program_id);
let is_last = if let Some(last_frame) = self.invoke_stack.last() {
last_frame.program_id() == program_id
} else {
false
};
if contains && !is_last {
// Reentrancy not allowed unless caller is calling itself
return Err(InstructionError::ReentrancyNotAllowed);
}
}
// Create the KeyedAccounts that will be passed to the program