Record and store invoked instructions in transaction meta (#12311)

* Record invoked instructions and store in transaction meta

* Enable cpi recording if transaction sender is some

* Rename invoked to innerInstructions
This commit is contained in:
Justin Starry
2020-09-24 22:36:22 +08:00
committed by GitHub
parent 860ecdd376
commit 6601ec8f26
19 changed files with 429 additions and 98 deletions

View File

@ -1,5 +1,6 @@
use crate::{
log_collector::LogCollector, native_loader::NativeLoader, rent_collector::RentCollector,
instruction_recorder::InstructionRecorder, log_collector::LogCollector,
native_loader::NativeLoader, rent_collector::RentCollector,
};
use log::*;
use serde::{Deserialize, Serialize};
@ -11,7 +12,7 @@ use solana_sdk::{
Executor, InvokeContext, Logger, ProcessInstruction, ProcessInstructionWithContext,
},
genesis_config::ClusterType,
instruction::{CompiledInstruction, InstructionError},
instruction::{CompiledInstruction, Instruction, InstructionError},
message::Message,
native_loader,
pubkey::Pubkey,
@ -206,6 +207,7 @@ pub struct ThisInvokeContext {
compute_budget: ComputeBudget,
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
executors: Rc<RefCell<Executors>>,
instruction_recorder: Option<InstructionRecorder>,
}
impl ThisInvokeContext {
pub fn new(
@ -217,6 +219,7 @@ impl ThisInvokeContext {
is_cross_program_supported: bool,
compute_budget: ComputeBudget,
executors: Rc<RefCell<Executors>>,
instruction_recorder: Option<InstructionRecorder>,
) -> Self {
let mut program_ids = Vec::with_capacity(compute_budget.max_invoke_depth);
program_ids.push(*program_id);
@ -232,6 +235,7 @@ impl ThisInvokeContext {
remaining: compute_budget.max_units,
})),
executors,
instruction_recorder,
}
}
}
@ -294,6 +298,11 @@ impl InvokeContext for ThisInvokeContext {
fn get_executor(&mut self, pubkey: &Pubkey) -> Option<Arc<dyn Executor>> {
self.executors.borrow().get(&pubkey)
}
fn record_instruction(&self, instruction: &Instruction) {
if let Some(recorder) = &self.instruction_recorder {
recorder.record_instruction(instruction.clone());
}
}
}
pub struct ThisLogger {
log_collector: Option<Rc<LogCollector>>,
@ -667,6 +676,7 @@ impl MessageProcessor {
rent_collector: &RentCollector,
log_collector: Option<Rc<LogCollector>>,
executors: Rc<RefCell<Executors>>,
instruction_recorder: Option<InstructionRecorder>,
instruction_index: usize,
cluster_type: ClusterType,
epoch: Epoch,
@ -696,6 +706,7 @@ impl MessageProcessor {
self.is_cross_program_supported,
self.compute_budget,
executors,
instruction_recorder,
);
let keyed_accounts =
Self::create_keyed_accounts(message, instruction, executable_accounts, accounts)?;
@ -714,6 +725,7 @@ impl MessageProcessor {
/// Process a message.
/// This method calls each instruction in the message over the set of loaded Accounts
/// The accounts are committed back to the bank only if every instruction succeeds
#[allow(clippy::too_many_arguments)]
pub fn process_message(
&self,
message: &Message,
@ -722,10 +734,16 @@ impl MessageProcessor {
rent_collector: &RentCollector,
log_collector: Option<Rc<LogCollector>>,
executors: Rc<RefCell<Executors>>,
mut instruction_recorders: Option<&mut Vec<InstructionRecorder>>,
cluster_type: ClusterType,
epoch: Epoch,
) -> Result<(), TransactionError> {
for (instruction_index, instruction) in message.instructions.iter().enumerate() {
let instruction_recorder = instruction_recorders.as_mut().map(|recorders| {
let instruction_recorder = InstructionRecorder::default();
recorders.push(instruction_recorder.clone());
instruction_recorder
});
self.execute_instruction(
message,
instruction,
@ -734,6 +752,7 @@ impl MessageProcessor {
rent_collector,
log_collector.clone(),
executors.clone(),
instruction_recorder,
instruction_index,
cluster_type,
epoch,
@ -794,6 +813,7 @@ mod tests {
true,
ComputeBudget::default(),
Rc::new(RefCell::new(Executors::default())),
None,
);
// Check call depth increases and has a limit
@ -1329,6 +1349,7 @@ mod tests {
&rent_collector,
None,
executors.clone(),
None,
ClusterType::Development,
0,
);
@ -1352,6 +1373,7 @@ mod tests {
&rent_collector,
None,
executors.clone(),
None,
ClusterType::Development,
0,
);
@ -1379,6 +1401,7 @@ mod tests {
&rent_collector,
None,
executors,
None,
ClusterType::Development,
0,
);
@ -1489,6 +1512,7 @@ mod tests {
&rent_collector,
None,
executors.clone(),
None,
ClusterType::Development,
0,
);
@ -1516,6 +1540,7 @@ mod tests {
&rent_collector,
None,
executors.clone(),
None,
ClusterType::Development,
0,
);
@ -1540,6 +1565,7 @@ mod tests {
&rent_collector,
None,
executors,
None,
ClusterType::Development,
0,
);
@ -1618,6 +1644,7 @@ mod tests {
true,
ComputeBudget::default(),
Rc::new(RefCell::new(Executors::default())),
None,
);
let metas = vec![
AccountMeta::new(owned_key, false),