Pipe FeatureSet though InvokeContext (#12536)
* Pipe FeatureSet though InvokeContext * gate program size cap * nit
This commit is contained in:
@@ -16,7 +16,10 @@ use solana_rbpf::{
|
||||
memory_region::MemoryRegion,
|
||||
vm::{EbpfVm, Executable, InstructionMeter},
|
||||
};
|
||||
use solana_runtime::process_instruction::{ComputeMeter, Executor, InvokeContext};
|
||||
use solana_runtime::{
|
||||
feature_set::compute_budget_config2,
|
||||
process_instruction::{ComputeMeter, Executor, InvokeContext},
|
||||
};
|
||||
use solana_sdk::{
|
||||
account::{is_executable, next_keyed_account, KeyedAccount},
|
||||
bpf_loader, bpf_loader_deprecated,
|
||||
@@ -78,19 +81,29 @@ macro_rules! log{
|
||||
};
|
||||
}
|
||||
|
||||
fn map_ebpf_error(
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
e: EbpfError<BPFError>,
|
||||
) -> InstructionError {
|
||||
let logger = invoke_context.get_logger();
|
||||
log!(logger, "{}", e);
|
||||
InstructionError::InvalidAccountData
|
||||
}
|
||||
|
||||
pub fn create_and_cache_executor(
|
||||
program: &KeyedAccount,
|
||||
invoke_context: &mut dyn InvokeContext,
|
||||
) -> Result<Arc<BPFExecutor>, InstructionError> {
|
||||
let executable = EbpfVm::create_executable_from_elf(
|
||||
&program.try_account_ref()?.data,
|
||||
Some(bpf_verifier::check),
|
||||
let executable = EbpfVm::create_executable_from_elf(&program.try_account_ref()?.data, None)
|
||||
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
||||
let (_, elf_bytes) = executable
|
||||
.get_text_bytes()
|
||||
.map_err(|e| map_ebpf_error(invoke_context, e))?;
|
||||
bpf_verifier::check(
|
||||
elf_bytes,
|
||||
!invoke_context.is_feature_active(&compute_budget_config2::id()),
|
||||
)
|
||||
.map_err(|e| {
|
||||
let logger = invoke_context.get_logger();
|
||||
log!(logger, "{}", e);
|
||||
InstructionError::InvalidAccountData
|
||||
})?;
|
||||
.map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e)))?;
|
||||
let executor = Arc::new(BPFExecutor { executable });
|
||||
invoke_context.add_executor(program.unsigned_key(), executor.clone());
|
||||
Ok(executor)
|
||||
@@ -271,6 +284,7 @@ mod tests {
|
||||
use super::*;
|
||||
use rand::Rng;
|
||||
use solana_runtime::{
|
||||
feature_set::FeatureSet,
|
||||
message_processor::{Executors, ThisInvokeContext},
|
||||
process_instruction::{ComputeBudget, Logger, ProcessInstruction},
|
||||
};
|
||||
@@ -313,6 +327,7 @@ mod tests {
|
||||
pub struct MockInvokeContext {
|
||||
pub key: Pubkey,
|
||||
pub logger: MockLogger,
|
||||
pub compute_budget: ComputeBudget,
|
||||
pub compute_meter: MockComputeMeter,
|
||||
}
|
||||
impl Default for MockInvokeContext {
|
||||
@@ -320,6 +335,7 @@ mod tests {
|
||||
MockInvokeContext {
|
||||
key: Pubkey::default(),
|
||||
logger: MockLogger::default(),
|
||||
compute_budget: ComputeBudget::default(),
|
||||
compute_meter: MockComputeMeter {
|
||||
remaining: std::u64::MAX,
|
||||
},
|
||||
@@ -348,11 +364,8 @@ mod tests {
|
||||
fn get_logger(&self) -> Rc<RefCell<dyn Logger>> {
|
||||
Rc::new(RefCell::new(self.logger.clone()))
|
||||
}
|
||||
fn is_cross_program_supported(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn get_compute_budget(&self) -> ComputeBudget {
|
||||
ComputeBudget::default()
|
||||
fn get_compute_budget(&self) -> &ComputeBudget {
|
||||
&self.compute_budget
|
||||
}
|
||||
fn get_compute_meter(&self) -> Rc<RefCell<dyn ComputeMeter>> {
|
||||
Rc::new(RefCell::new(self.compute_meter.clone()))
|
||||
@@ -362,6 +375,9 @@ mod tests {
|
||||
None
|
||||
}
|
||||
fn record_instruction(&self, _instruction: &Instruction) {}
|
||||
fn is_feature_active(&self, _feature_id: &Pubkey) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
struct TestInstructionMeter {
|
||||
@@ -387,8 +403,7 @@ mod tests {
|
||||
];
|
||||
let input = &mut [0x00];
|
||||
|
||||
let executable =
|
||||
EbpfVm::create_executable_from_text_bytes(program, Some(bpf_verifier::check)).unwrap();
|
||||
let executable = EbpfVm::create_executable_from_text_bytes(program, None).unwrap();
|
||||
let mut vm = EbpfVm::<BPFError>::new(executable.as_ref()).unwrap();
|
||||
let instruction_meter = TestInstructionMeter { remaining: 10 };
|
||||
vm.execute_program_metered(input, &[], &[], instruction_meter)
|
||||
@@ -579,7 +594,6 @@ mod tests {
|
||||
vec![],
|
||||
vec![],
|
||||
None,
|
||||
true,
|
||||
ComputeBudget {
|
||||
max_units: 1,
|
||||
log_units: 100,
|
||||
@@ -590,6 +604,7 @@ mod tests {
|
||||
},
|
||||
Rc::new(RefCell::new(Executors::default())),
|
||||
None,
|
||||
Arc::new(FeatureSet::default()),
|
||||
);
|
||||
assert_eq!(
|
||||
Err(InstructionError::Custom(194969602)),
|
||||
|
Reference in New Issue
Block a user