Simplifies return_data accessors in InvokeContext. (#20290)

This commit is contained in:
Alexander Meißner 2021-09-29 19:11:06 +02:00 committed by GitHub
parent 57c8abf499
commit 4de5fff3ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 74 deletions

View File

@ -602,7 +602,7 @@ impl InstructionProcessor {
invoke_context.verify_and_update(instruction, account_indices, caller_write_privileges)?; invoke_context.verify_and_update(instruction, account_indices, caller_write_privileges)?;
// clear the return data // clear the return data
invoke_context.set_return_data(None); invoke_context.set_return_data(Vec::new())?;
// Invoke callee // Invoke callee
invoke_context.push( invoke_context.push(

View File

@ -230,7 +230,7 @@ fn run_program(
for i in 0..2 { for i in 0..2 {
let mut parameter_bytes = parameter_bytes.clone(); let mut parameter_bytes = parameter_bytes.clone();
{ {
invoke_context.set_return_data(None); invoke_context.set_return_data(Vec::new()).unwrap();
let mut vm = create_vm( let mut vm = create_vm(
&loader_id, &loader_id,

View File

@ -945,9 +945,9 @@ impl Executor for BpfExecutor {
trace!("BPF Program Instruction Trace:\n{}", trace_string); trace!("BPF Program Instruction Trace:\n{}", trace_string);
} }
drop(vm); drop(vm);
let return_data = invoke_context.get_return_data(); let (program_id, return_data) = invoke_context.get_return_data();
if let Some((program_id, return_data)) = return_data { if !return_data.is_empty() {
stable_log::program_return(&logger, program_id, return_data); stable_log::program_return(&logger, &program_id, return_data);
} }
match result { match result {
Ok(status) => { Ok(status) => {
@ -960,7 +960,7 @@ impl Executor for BpfExecutor {
} else { } else {
status.into() status.into()
}; };
stable_log::program_failure(&logger, program_id, &error); stable_log::program_failure(&logger, &program_id, &error);
return Err(error); return Err(error);
} }
} }
@ -974,7 +974,7 @@ impl Executor for BpfExecutor {
InstructionError::ProgramFailedToComplete InstructionError::ProgramFailedToComplete
} }
}; };
stable_log::program_failure(&logger, program_id, &error); stable_log::program_failure(&logger, &program_id, &error);
return Err(error); return Err(error);
} }
} }

View File

@ -44,7 +44,6 @@ use solana_sdk::{
use std::{ use std::{
alloc::Layout, alloc::Layout,
cell::{Ref, RefCell, RefMut}, cell::{Ref, RefCell, RefMut},
cmp::min,
mem::{align_of, size_of}, mem::{align_of, size_of},
rc::Rc, rc::Rc,
slice::from_raw_parts_mut, slice::from_raw_parts_mut,
@ -2324,24 +2323,22 @@ impl<'a> SyscallObject<BpfError> for SyscallSetReturnData<'a> {
return; return;
} }
if len == 0 { let return_data = if len == 0 {
invoke_context.set_return_data(None); Vec::new()
} else { } else {
let return_data = question_mark!( question_mark!(
translate_slice::<u8>(memory_mapping, addr, len, self.loader_id), translate_slice::<u8>(memory_mapping, addr, len, self.loader_id),
result result
); )
.to_vec()
let program_id = *question_mark!( };
question_mark!(
invoke_context invoke_context
.get_caller() .set_return_data(return_data)
.map_err(SyscallError::InstructionError), .map_err(SyscallError::InstructionError),
result result
); );
invoke_context.set_return_data(Some((program_id, return_data.to_vec())));
}
*result = Ok(0); *result = Ok(0);
} }
} }
@ -2354,7 +2351,7 @@ impl<'a> SyscallObject<BpfError> for SyscallGetReturnData<'a> {
fn call( fn call(
&mut self, &mut self,
return_data_addr: u64, return_data_addr: u64,
len: u64, mut length: u64,
program_id_addr: u64, program_id_addr: u64,
_arg4: u64, _arg4: u64,
_arg5: u64, _arg5: u64,
@ -2377,10 +2374,9 @@ impl<'a> SyscallObject<BpfError> for SyscallGetReturnData<'a> {
result result
); );
if let Some((program_id, return_data)) = invoke_context.get_return_data() { let (program_id, return_data) = invoke_context.get_return_data();
if len != 0 { length = length.min(return_data.len() as u64);
let length = min(return_data.len() as u64, len); if length != 0 {
question_mark!( question_mark!(
invoke_context invoke_context
.get_compute_meter() .get_compute_meter()
@ -2389,35 +2385,22 @@ impl<'a> SyscallObject<BpfError> for SyscallGetReturnData<'a> {
); );
let return_data_result = question_mark!( let return_data_result = question_mark!(
translate_slice_mut::<u8>( translate_slice_mut::<u8>(memory_mapping, return_data_addr, length, self.loader_id,),
memory_mapping,
return_data_addr,
length,
self.loader_id,
),
result result
); );
return_data_result.copy_from_slice(&return_data[..length as usize]); return_data_result.copy_from_slice(&return_data[..length as usize]);
let program_id_result = question_mark!( let program_id_result = question_mark!(
translate_slice_mut::<Pubkey>( translate_slice_mut::<Pubkey>(memory_mapping, program_id_addr, 1, self.loader_id,),
memory_mapping,
program_id_addr,
1,
self.loader_id,
),
result result
); );
program_id_result[0] = *program_id; program_id_result[0] = program_id;
} }
// Return the actual length, rather the length returned // Return the actual length, rather the length returned
*result = Ok(return_data.len() as u64); *result = Ok(return_data.len() as u64);
} else {
*result = Ok(0);
}
} }
} }

View File

@ -69,8 +69,7 @@ pub struct ThisInvokeContext<'a> {
sysvars: RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>>, sysvars: RefCell<Vec<(Pubkey, Option<Rc<Vec<u8>>>)>>,
blockhash: &'a Hash, blockhash: &'a Hash,
fee_calculator: &'a FeeCalculator, fee_calculator: &'a FeeCalculator,
// return data and program_id that set it return_data: (Pubkey, Vec<u8>),
return_data: Option<(Pubkey, Vec<u8>)>,
} }
impl<'a> ThisInvokeContext<'a> { impl<'a> ThisInvokeContext<'a> {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -109,7 +108,7 @@ impl<'a> ThisInvokeContext<'a> {
sysvars: RefCell::new(vec![]), sysvars: RefCell::new(vec![]),
blockhash, blockhash,
fee_calculator, fee_calculator,
return_data: None, return_data: (Pubkey::default(), Vec::new()),
} }
} }
} }
@ -428,11 +427,12 @@ impl<'a> InvokeContext for ThisInvokeContext<'a> {
fn get_fee_calculator(&self) -> &FeeCalculator { fn get_fee_calculator(&self) -> &FeeCalculator {
self.fee_calculator self.fee_calculator
} }
fn set_return_data(&mut self, return_data: Option<(Pubkey, Vec<u8>)>) { fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError> {
self.return_data = return_data; self.return_data = (*self.get_caller()?, data);
Ok(())
} }
fn get_return_data(&self) -> &Option<(Pubkey, Vec<u8>)> { fn get_return_data(&self) -> (Pubkey, &[u8]) {
&self.return_data (self.return_data.0, &self.return_data.1)
} }
} }
pub struct ThisLogger { pub struct ThisLogger {

View File

@ -124,9 +124,9 @@ pub trait InvokeContext {
/// Get this invocation's `FeeCalculator` /// Get this invocation's `FeeCalculator`
fn get_fee_calculator(&self) -> &FeeCalculator; fn get_fee_calculator(&self) -> &FeeCalculator;
/// Set the return data /// Set the return data
fn set_return_data(&mut self, return_data: Option<(Pubkey, Vec<u8>)>); fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError>;
/// Get the return data /// Get the return data
fn get_return_data(&self) -> &Option<(Pubkey, Vec<u8>)>; fn get_return_data(&self) -> (Pubkey, &[u8]);
} }
/// Convenience macro to log a message with an `Rc<RefCell<dyn Logger>>` /// Convenience macro to log a message with an `Rc<RefCell<dyn Logger>>`
@ -447,7 +447,7 @@ pub struct MockInvokeContext<'a> {
pub disabled_features: HashSet<Pubkey>, pub disabled_features: HashSet<Pubkey>,
pub blockhash: Hash, pub blockhash: Hash,
pub fee_calculator: FeeCalculator, pub fee_calculator: FeeCalculator,
pub return_data: Option<(Pubkey, Vec<u8>)>, pub return_data: (Pubkey, Vec<u8>),
} }
impl<'a> MockInvokeContext<'a> { impl<'a> MockInvokeContext<'a> {
@ -467,7 +467,7 @@ impl<'a> MockInvokeContext<'a> {
disabled_features: HashSet::default(), disabled_features: HashSet::default(),
blockhash: Hash::default(), blockhash: Hash::default(),
fee_calculator: FeeCalculator::default(), fee_calculator: FeeCalculator::default(),
return_data: None, return_data: (Pubkey::default(), Vec::new()),
}; };
invoke_context invoke_context
.invoke_stack .invoke_stack
@ -605,10 +605,11 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
fn get_fee_calculator(&self) -> &FeeCalculator { fn get_fee_calculator(&self) -> &FeeCalculator {
&self.fee_calculator &self.fee_calculator
} }
fn set_return_data(&mut self, return_data: Option<(Pubkey, Vec<u8>)>) { fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError> {
self.return_data = return_data; self.return_data = (*self.get_caller()?, data);
Ok(())
} }
fn get_return_data(&self) -> &Option<(Pubkey, Vec<u8>)> { fn get_return_data(&self) -> (Pubkey, &[u8]) {
&self.return_data (self.return_data.0, &self.return_data.1)
} }
} }