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

@@ -3474,6 +3474,7 @@ pub mod tests {
signature::Signature,
transaction::TransactionError,
};
use solana_transaction_status::InnerInstructions;
use solana_vote_program::{vote_instruction, vote_state::Vote};
use std::{iter::FromIterator, time::Duration};
@@ -5671,6 +5672,7 @@ pub mod tests {
fee: 42,
pre_balances: pre_balances.clone(),
post_balances: post_balances.clone(),
inner_instructions: Some(vec![]),
},
)
.unwrap();
@@ -5683,6 +5685,7 @@ pub mod tests {
fee: 42,
pre_balances: pre_balances.clone(),
post_balances: post_balances.clone(),
inner_instructions: Some(vec![]),
},
)
.unwrap();
@@ -5693,6 +5696,7 @@ pub mod tests {
fee: 42,
pre_balances,
post_balances,
inner_instructions: Some(vec![]),
}),
}
})
@@ -5985,6 +5989,10 @@ pub mod tests {
let pre_balances_vec = vec![1, 2, 3];
let post_balances_vec = vec![3, 2, 1];
let inner_instructions_vec = vec![InnerInstructions {
index: 0,
instructions: vec![CompiledInstruction::new(1, &(), vec![0])],
}];
// result not found
assert!(transaction_status_cf
@@ -6003,6 +6011,7 @@ pub mod tests {
fee: 5u64,
pre_balances: pre_balances_vec.clone(),
post_balances: post_balances_vec.clone(),
inner_instructions: Some(inner_instructions_vec.clone()),
},
)
.is_ok());
@@ -6013,6 +6022,7 @@ pub mod tests {
fee,
pre_balances,
post_balances,
inner_instructions,
} = transaction_status_cf
.get((0, Signature::default(), 0))
.unwrap()
@@ -6021,6 +6031,7 @@ pub mod tests {
assert_eq!(fee, 5u64);
assert_eq!(pre_balances, pre_balances_vec);
assert_eq!(post_balances, post_balances_vec);
assert_eq!(inner_instructions.unwrap(), inner_instructions_vec);
// insert value
assert!(transaction_status_cf
@@ -6031,6 +6042,7 @@ pub mod tests {
fee: 9u64,
pre_balances: pre_balances_vec.clone(),
post_balances: post_balances_vec.clone(),
inner_instructions: Some(inner_instructions_vec.clone()),
},
)
.is_ok());
@@ -6041,6 +6053,7 @@ pub mod tests {
fee,
pre_balances,
post_balances,
inner_instructions,
} = transaction_status_cf
.get((0, Signature::new(&[2u8; 64]), 9))
.unwrap()
@@ -6051,6 +6064,7 @@ pub mod tests {
assert_eq!(fee, 9u64);
assert_eq!(pre_balances, pre_balances_vec);
assert_eq!(post_balances, post_balances_vec);
assert_eq!(inner_instructions.unwrap(), inner_instructions_vec);
}
Blockstore::destroy(&blockstore_path).expect("Expected successful database destruction");
}
@@ -6277,6 +6291,7 @@ pub mod tests {
fee: 42u64,
pre_balances: pre_balances_vec,
post_balances: post_balances_vec,
inner_instructions: Some(vec![]),
};
let signature1 = Signature::new(&[1u8; 64]);
@@ -6406,6 +6421,10 @@ pub mod tests {
pre_balances.push(i as u64 * 10);
post_balances.push(i as u64 * 11);
}
let inner_instructions = Some(vec![InnerInstructions {
index: 0,
instructions: vec![CompiledInstruction::new(1, &(), vec![0])],
}]);
let signature = transaction.signatures[0];
blockstore
.transaction_status_cf
@@ -6416,6 +6435,7 @@ pub mod tests {
fee: 42,
pre_balances: pre_balances.clone(),
post_balances: post_balances.clone(),
inner_instructions: inner_instructions.clone(),
},
)
.unwrap();
@@ -6426,6 +6446,7 @@ pub mod tests {
fee: 42,
pre_balances,
post_balances,
inner_instructions,
}),
}
})
@@ -6865,6 +6886,7 @@ pub mod tests {
fee: x,
pre_balances: vec![],
post_balances: vec![],
inner_instructions: Some(vec![]),
},
)
.unwrap();

View File

@@ -15,7 +15,10 @@ use solana_measure::{measure::Measure, thread_mem_usage};
use solana_metrics::{datapoint_error, inc_new_counter_debug};
use solana_rayon_threadlimit::get_thread_count;
use solana_runtime::{
bank::{Bank, TransactionBalancesSet, TransactionProcessResult, TransactionResults},
bank::{
Bank, InnerInstructionsList, TransactionBalancesSet, TransactionProcessResult,
TransactionResults,
},
bank_forks::BankForks,
bank_utils,
commitment::VOTE_THRESHOLD_SIZE,
@@ -100,11 +103,13 @@ fn execute_batch(
transaction_status_sender: Option<TransactionStatusSender>,
replay_vote_sender: Option<&ReplayVoteSender>,
) -> Result<()> {
let (tx_results, balances) = batch.bank().load_execute_and_commit_transactions(
batch,
MAX_PROCESSING_AGE,
transaction_status_sender.is_some(),
);
let (tx_results, balances, inner_instructions) =
batch.bank().load_execute_and_commit_transactions(
batch,
MAX_PROCESSING_AGE,
transaction_status_sender.is_some(),
transaction_status_sender.is_some(),
);
bank_utils::find_and_send_votes(batch.transactions(), &tx_results, replay_vote_sender);
@@ -121,6 +126,7 @@ fn execute_batch(
batch.iteration_order_vec(),
processing_results,
balances,
inner_instructions,
sender,
);
}
@@ -1048,7 +1054,9 @@ pub struct TransactionStatusBatch {
pub iteration_order: Option<Vec<usize>>,
pub statuses: Vec<TransactionProcessResult>,
pub balances: TransactionBalancesSet,
pub inner_instructions: Vec<Option<InnerInstructionsList>>,
}
pub type TransactionStatusSender = Sender<TransactionStatusBatch>;
pub fn send_transaction_status_batch(
@@ -1057,6 +1065,7 @@ pub fn send_transaction_status_batch(
iteration_order: Option<Vec<usize>>,
statuses: Vec<TransactionProcessResult>,
balances: TransactionBalancesSet,
inner_instructions: Vec<Option<InnerInstructionsList>>,
transaction_status_sender: TransactionStatusSender,
) {
let slot = bank.slot();
@@ -1066,6 +1075,7 @@ pub fn send_transaction_status_batch(
iteration_order,
statuses,
balances,
inner_instructions,
}) {
trace!(
"Slot {} transaction_status send batch failed: {:?}",
@@ -2913,9 +2923,13 @@ pub mod tests {
..
},
_balances,
) = batch
.bank()
.load_execute_and_commit_transactions(&batch, MAX_PROCESSING_AGE, false);
_inner_instructions,
) = batch.bank().load_execute_and_commit_transactions(
&batch,
MAX_PROCESSING_AGE,
false,
false,
);
let (err, signature) = get_first_error(&batch, fee_collection_results).unwrap();
// First error found should be for the 2nd transaction, due to iteration_order
assert_eq!(err.unwrap_err(), TransactionError::AccountNotFound);