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:
@ -531,8 +531,19 @@ impl BankingStage {
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let (mut loaded_accounts, results, mut retryable_txs, tx_count, signature_count) =
|
||||
bank.load_and_execute_transactions(batch, MAX_PROCESSING_AGE, None);
|
||||
let (
|
||||
mut loaded_accounts,
|
||||
results,
|
||||
inner_instructions,
|
||||
mut retryable_txs,
|
||||
tx_count,
|
||||
signature_count,
|
||||
) = bank.load_and_execute_transactions(
|
||||
batch,
|
||||
MAX_PROCESSING_AGE,
|
||||
None,
|
||||
transaction_status_sender.is_some(),
|
||||
);
|
||||
load_execute_time.stop();
|
||||
|
||||
let freeze_lock = bank.freeze_lock();
|
||||
@ -569,6 +580,7 @@ impl BankingStage {
|
||||
batch.iteration_order_vec(),
|
||||
tx_results.processing_results,
|
||||
TransactionBalancesSet::new(pre_balances, post_balances),
|
||||
inner_instructions,
|
||||
sender,
|
||||
);
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
use crossbeam_channel::{Receiver, RecvTimeoutError};
|
||||
use itertools::izip;
|
||||
use solana_ledger::{blockstore::Blockstore, blockstore_processor::TransactionStatusBatch};
|
||||
use solana_runtime::{
|
||||
bank::{Bank, HashAgeKind},
|
||||
nonce_utils,
|
||||
transaction_utils::OrderedIterator,
|
||||
};
|
||||
use solana_transaction_status::TransactionStatusMeta;
|
||||
use solana_transaction_status::{InnerInstructions, TransactionStatusMeta};
|
||||
use std::{
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
@ -54,15 +55,23 @@ impl TransactionStatusService {
|
||||
iteration_order,
|
||||
statuses,
|
||||
balances,
|
||||
inner_instructions,
|
||||
} = write_transaction_status_receiver.recv_timeout(Duration::from_secs(1))?;
|
||||
|
||||
let slot = bank.slot();
|
||||
for ((((_, transaction), (status, hash_age_kind)), pre_balances), post_balances) in
|
||||
OrderedIterator::new(&transactions, iteration_order.as_deref())
|
||||
.zip(statuses)
|
||||
.zip(balances.pre_balances)
|
||||
.zip(balances.post_balances)
|
||||
{
|
||||
for (
|
||||
(_, transaction),
|
||||
(status, hash_age_kind),
|
||||
pre_balances,
|
||||
post_balances,
|
||||
inner_instructions,
|
||||
) in izip!(
|
||||
OrderedIterator::new(&transactions, iteration_order.as_deref()),
|
||||
statuses,
|
||||
balances.pre_balances,
|
||||
balances.post_balances,
|
||||
inner_instructions
|
||||
) {
|
||||
if Bank::can_commit(&status) && !transaction.signatures.is_empty() {
|
||||
let fee_calculator = match hash_age_kind {
|
||||
Some(HashAgeKind::DurableNonce(_, account)) => {
|
||||
@ -77,6 +86,19 @@ impl TransactionStatusService {
|
||||
);
|
||||
let (writable_keys, readonly_keys) =
|
||||
transaction.message.get_account_keys_by_lock_type();
|
||||
|
||||
let inner_instructions = inner_instructions.map(|inner_instructions| {
|
||||
inner_instructions
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(index, instructions)| InnerInstructions {
|
||||
index: index as u8,
|
||||
instructions,
|
||||
})
|
||||
.filter(|i| !i.instructions.is_empty())
|
||||
.collect()
|
||||
});
|
||||
|
||||
blockstore
|
||||
.write_transaction_status(
|
||||
slot,
|
||||
@ -88,6 +110,7 @@ impl TransactionStatusService {
|
||||
fee,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
inner_instructions,
|
||||
},
|
||||
)
|
||||
.expect("Expect database write to succeed");
|
||||
|
Reference in New Issue
Block a user