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)?;
// clear the return data
invoke_context.set_return_data(None);
invoke_context.set_return_data(Vec::new())?;
// Invoke callee
invoke_context.push(

View File

@ -230,7 +230,7 @@ fn run_program(
for i in 0..2 {
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(
&loader_id,

View File

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

View File

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

View File

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

View File

@ -124,9 +124,9 @@ pub trait InvokeContext {
/// Get this invocation's `FeeCalculator`
fn get_fee_calculator(&self) -> &FeeCalculator;
/// 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
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>>`
@ -447,7 +447,7 @@ pub struct MockInvokeContext<'a> {
pub disabled_features: HashSet<Pubkey>,
pub blockhash: Hash,
pub fee_calculator: FeeCalculator,
pub return_data: Option<(Pubkey, Vec<u8>)>,
pub return_data: (Pubkey, Vec<u8>),
}
impl<'a> MockInvokeContext<'a> {
@ -467,7 +467,7 @@ impl<'a> MockInvokeContext<'a> {
disabled_features: HashSet::default(),
blockhash: Hash::default(),
fee_calculator: FeeCalculator::default(),
return_data: None,
return_data: (Pubkey::default(), Vec::new()),
};
invoke_context
.invoke_stack
@ -605,10 +605,11 @@ impl<'a> InvokeContext for MockInvokeContext<'a> {
fn get_fee_calculator(&self) -> &FeeCalculator {
&self.fee_calculator
}
fn set_return_data(&mut self, return_data: Option<(Pubkey, Vec<u8>)>) {
self.return_data = return_data;
fn set_return_data(&mut self, data: Vec<u8>) -> Result<(), InstructionError> {
self.return_data = (*self.get_caller()?, data);
Ok(())
}
fn get_return_data(&self) -> &Option<(Pubkey, Vec<u8>)> {
&self.return_data
fn get_return_data(&self) -> (Pubkey, &[u8]) {
(self.return_data.0, &self.return_data.1)
}
}