Add get_processed_sibling_instruction syscall (#22859) (#22956)

This commit is contained in:
Jack May
2022-02-08 09:21:11 -08:00
committed by GitHub
parent 5c69af607d
commit d05b5b0902
19 changed files with 864 additions and 66 deletions

View File

@ -7,9 +7,9 @@ use {
};
/// Records and compiles cross-program invoked instructions
#[derive(Clone, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct InstructionRecorder {
inner: Rc<RefCell<Vec<Instruction>>>,
inner: Rc<RefCell<Vec<(usize, Instruction)>>>,
}
impl InstructionRecorder {
@ -20,11 +20,39 @@ impl InstructionRecorder {
self.inner
.borrow()
.iter()
.map(|ix| message.try_compile_instruction(ix))
.skip(1)
.map(|(_, ix)| message.try_compile_instruction(ix))
.collect()
}
pub fn record_instruction(&self, instruction: Instruction) {
self.inner.borrow_mut().push(instruction);
pub fn record_instruction(&self, stack_height: usize, instruction: Instruction) {
self.inner.borrow_mut().push((stack_height, instruction));
}
pub fn get(&self, index: usize) -> Option<Instruction> {
self.inner
.borrow()
.get(index)
.map(|(_, instruction)| instruction.clone())
}
pub fn find(&self, stack_height: usize, index: usize) -> Option<Instruction> {
let mut current_index = 0;
self.inner
.borrow()
.iter()
.rev()
.skip(1)
.find(|(this_stack_height, _)| {
if stack_height == *this_stack_height {
if index == current_index {
return true;
} else {
current_index = current_index.saturating_add(1);
}
}
false
})
.map(|(_, instruction)| instruction.clone())
}
}

View File

@ -21,7 +21,10 @@ use {
tx_wide_compute_cap, FeatureSet,
},
hash::Hash,
instruction::{AccountMeta, CompiledInstruction, Instruction, InstructionError},
instruction::{
AccountMeta, CompiledInstruction, Instruction, InstructionError,
TRANSACTION_LEVEL_STACK_HEIGHT,
},
keyed_account::{create_keyed_accounts_unified, keyed_account_at_index, KeyedAccount},
message::{Message, SanitizedMessage},
pubkey::Pubkey,
@ -201,7 +204,7 @@ pub struct InvokeContext<'a> {
compute_meter: Rc<RefCell<ComputeMeter>>,
accounts_data_meter: AccountsDataMeter,
executors: Rc<RefCell<Executors>>,
pub instruction_recorder: Option<&'a InstructionRecorder>,
pub instruction_trace: Vec<InstructionRecorder>,
pub feature_set: Arc<FeatureSet>,
pub timings: ExecuteDetailsTimings,
pub blockhash: Hash,
@ -237,7 +240,7 @@ impl<'a> InvokeContext<'a> {
compute_meter: ComputeMeter::new_ref(compute_budget.max_units),
accounts_data_meter: AccountsDataMeter::new(current_accounts_data_len),
executors,
instruction_recorder: None,
instruction_trace: Vec::new(),
feature_set,
timings: ExecuteDetailsTimings::default(),
blockhash,
@ -375,8 +378,8 @@ impl<'a> InvokeContext<'a> {
self.invoke_stack.pop();
}
/// Current depth of the invocation stack
pub fn invoke_depth(&self) -> usize {
/// Current height of the stack
pub fn get_stack_height(&self) -> usize {
self.invoke_stack.len()
}
@ -566,9 +569,7 @@ impl<'a> InvokeContext<'a> {
prev_account_sizes.push((account, account_length));
}
if let Some(instruction_recorder) = &self.instruction_recorder {
instruction_recorder.record_instruction(instruction);
}
self.record_instruction(self.get_stack_height(), instruction);
let message = SanitizedMessage::Legacy(message);
self.process_instruction(
@ -954,6 +955,29 @@ impl<'a> InvokeContext<'a> {
pub fn get_sysvar_cache(&self) -> &SysvarCache {
&self.sysvar_cache
}
/// Record top-level instruction in the instruction trace
pub fn record_top_level_instruction(&mut self, instruction: Instruction) {
self.instruction_trace.push(InstructionRecorder::default());
self.record_instruction(TRANSACTION_LEVEL_STACK_HEIGHT, instruction);
}
/// Record instruction in the instruction trace
pub fn record_instruction(&mut self, stack_height: usize, instruction: Instruction) {
if let Some(instruction_recorder) = self.instruction_trace.last() {
instruction_recorder.record_instruction(stack_height, instruction)
}
}
/// Get the instruction trace
pub fn get_instruction_trace(&self) -> &[InstructionRecorder] {
&self.instruction_trace
}
/// Get the mutable instruction trace
pub fn get_instruction_trace_mut(&mut self) -> &mut Vec<InstructionRecorder> {
&mut self.instruction_trace
}
}
pub struct MockInvokeContextPreparation {