Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix transaction logs and inner ixs for leader nodes #18395

Merged
merged 2 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ledger/src/blockstore_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1199,7 +1199,7 @@ pub struct TransactionStatusBatch {
pub balances: TransactionBalancesSet,
pub token_balances: TransactionTokenBalancesSet,
pub inner_instructions: Option<Vec<Option<InnerInstructionsList>>>,
pub transaction_logs: Option<Vec<TransactionLogMessages>>,
pub transaction_logs: Option<Vec<Option<TransactionLogMessages>>>,
pub rent_debits: Vec<RentDebits>,
}

Expand All @@ -1218,7 +1218,7 @@ impl TransactionStatusSender {
balances: TransactionBalancesSet,
token_balances: TransactionTokenBalancesSet,
inner_instructions: Vec<Option<InnerInstructionsList>>,
transaction_logs: Vec<TransactionLogMessages>,
transaction_logs: Vec<Option<TransactionLogMessages>>,
rent_debits: Vec<RentDebits>,
) {
let slot = bank.slot();
Expand Down
39 changes: 15 additions & 24 deletions programs/bpf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,26 +292,24 @@ fn process_transaction_and_record_inner(
let signature = tx.signatures.get(0).unwrap().clone();
let txs = vec![tx];
let tx_batch = bank.prepare_batch(txs.iter());
let (mut results, _, mut inner, _transaction_logs) = bank.load_execute_and_commit_transactions(
&tx_batch,
MAX_PROCESSING_AGE,
false,
true,
false,
&mut ExecuteTimings::default(),
);
let inner_instructions = if inner.is_empty() {
Some(vec![vec![]])
} else {
inner.swap_remove(0)
};
let (mut results, _, mut inner_instructions, _transaction_logs) = bank
.load_execute_and_commit_transactions(
&tx_batch,
MAX_PROCESSING_AGE,
false,
true,
false,
&mut ExecuteTimings::default(),
);
let result = results
.fee_collection_results
.swap_remove(0)
.and_then(|_| bank.get_signature_status(&signature).unwrap());
(
result,
inner_instructions.expect("cpi recording should be enabled"),
inner_instructions
.swap_remove(0)
.expect("cpi recording should be enabled"),
)
}

Expand All @@ -329,8 +327,8 @@ fn execute_transactions(bank: &Bank, txs: &[Transaction]) -> Vec<ConfirmedTransa
post_balances,
..
},
mut inner_instructions,
mut transaction_logs,
inner_instructions,
transaction_logs,
) = bank.load_execute_and_commit_transactions(
&batch,
std::usize::MAX,
Expand All @@ -341,13 +339,6 @@ fn execute_transactions(bank: &Bank, txs: &[Transaction]) -> Vec<ConfirmedTransa
);
let tx_post_token_balances = collect_token_balances(&bank, &batch, &mut mint_decimals);

for _ in 0..(txs.len() - transaction_logs.len()) {
transaction_logs.push(vec![]);
}
for _ in 0..(txs.len() - inner_instructions.len()) {
inner_instructions.push(None);
}

izip!(
txs.iter(),
execution_results.into_iter(),
Expand Down Expand Up @@ -395,7 +386,7 @@ fn execute_transactions(bank: &Bank, txs: &[Transaction]) -> Vec<ConfirmedTransa
pre_token_balances: Some(pre_token_balances),
post_token_balances: Some(post_token_balances),
inner_instructions,
log_messages: Some(log_messages),
log_messages,
rewards: None,
};

Expand Down
14 changes: 7 additions & 7 deletions rpc/src/transaction_status_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,13 @@ impl TransactionStatusService {
} else {
Box::new(std::iter::repeat_with(|| None))
};
let transaction_logs_iter: Box<dyn Iterator<Item = TransactionLogMessages>> =
if let Some(transaction_logs) = transaction_logs {
Box::new(transaction_logs.into_iter())
} else {
Box::new(std::iter::repeat_with(Vec::new))
};
let transaction_logs_iter: Box<
dyn Iterator<Item = Option<TransactionLogMessages>>,
> = if let Some(transaction_logs) = transaction_logs {
Box::new(transaction_logs.into_iter())
} else {
Box::new(std::iter::repeat_with(|| None))
};
for (
transaction,
(status, nonce_rollback),
Expand Down Expand Up @@ -125,7 +126,6 @@ impl TransactionStatusService {
.collect()
});

let log_messages = Some(log_messages);
let pre_token_balances = Some(pre_token_balances);
let post_token_balances = Some(post_token_balances);
let rewards = Some(
Expand Down
85 changes: 41 additions & 44 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2675,9 +2675,7 @@ impl Bank {
);

let transaction_result = executed[0].0.clone().map(|_| ());
let log_messages = log_messages
.get(0)
.map_or(vec![], |messages| messages.to_vec());
let log_messages = log_messages.get(0).cloned().flatten().unwrap_or_default();
let post_transaction_accounts = loaded_txs
.into_iter()
.next()
Expand Down Expand Up @@ -2992,17 +2990,22 @@ impl Bank {
Ok(())
}

fn collect_log_messages(
log_collector: Option<Rc<LogCollector>>,
) -> Option<TransactionLogMessages> {
log_collector.and_then(|log_collector| Rc::try_unwrap(log_collector).map(Into::into).ok())
}

fn compile_recorded_instructions(
inner_instructions: &mut Vec<Option<InnerInstructionsList>>,
instruction_recorders: Option<Vec<InstructionRecorder>>,
message: &Message,
) {
inner_instructions.push(instruction_recorders.map(|instruction_recorders| {
) -> Option<InnerInstructionsList> {
instruction_recorders.map(|instruction_recorders| {
instruction_recorders
.into_iter()
.map(|r| r.compile_instructions(message))
.collect()
}));
})
}

/// Get any cached executors needed by the transaction
Expand Down Expand Up @@ -3069,7 +3072,7 @@ impl Bank {
Vec<TransactionLoadResult>,
Vec<TransactionExecutionResult>,
Vec<Option<InnerInstructionsList>>,
Vec<TransactionLogMessages>,
Vec<Option<TransactionLogMessages>>,
Vec<usize>,
u64,
u64,
Expand Down Expand Up @@ -3118,7 +3121,8 @@ impl Bank {
let mut signature_count: u64 = 0;
let mut inner_instructions: Vec<Option<InnerInstructionsList>> =
Vec::with_capacity(hashed_txs.len());
let mut transaction_log_messages = Vec::with_capacity(hashed_txs.len());
let mut transaction_log_messages: Vec<Option<Vec<String>>> =
Vec::with_capacity(hashed_txs.len());
let bpf_compute_budget = self
.bpf_compute_budget
.unwrap_or_else(BpfComputeBudget::new);
Expand All @@ -3127,7 +3131,11 @@ impl Bank {
.iter_mut()
.zip(hashed_txs.as_transactions_iter())
.map(|(accs, tx)| match accs {
(Err(e), _nonce_rollback) => (Err(e.clone()), None),
(Err(e), _nonce_rollback) => {
inner_instructions.push(None);
transaction_log_messages.push(None);
(Err(e.clone()), None)
}
(Ok(loaded_transaction), nonce_rollback) => {
signature_count += u64::from(tx.message().header.num_required_signatures);
let executors = self.get_executors(&tx.message, &loaded_transaction.loaders);
Expand Down Expand Up @@ -3167,20 +3175,11 @@ impl Bank {
&self.ancestors,
);

if enable_log_recording {
let log_messages: TransactionLogMessages =
Rc::try_unwrap(log_collector.unwrap_or_default())
.unwrap_or_default()
.into();

transaction_log_messages.push(log_messages);
}

Self::compile_recorded_instructions(
&mut inner_instructions,
transaction_log_messages.push(Self::collect_log_messages(log_collector));
inner_instructions.push(Self::compile_recorded_instructions(
instruction_recorders,
&tx.message,
);
));

if let Err(e) = Self::refcells_to_accounts(
&mut loaded_transaction.accounts,
Expand Down Expand Up @@ -3266,7 +3265,6 @@ impl Bank {
}

let is_vote = is_simple_vote_transaction(tx);

let store = match transaction_log_collector_config.filter {
TransactionLogCollectorFilter::All => !is_vote || mentioned_address,
TransactionLogCollectorFilter::AllWithVotes => true,
Expand All @@ -3275,12 +3273,14 @@ impl Bank {
};

if store {
transaction_log_collector.logs.push(TransactionLogInfo {
signature: tx.signatures[0],
result: r.clone(),
is_vote,
log_messages: transaction_log_messages.get(i).cloned().unwrap_or_default(),
});
if let Some(log_messages) = transaction_log_messages.get(i).cloned().flatten() {
transaction_log_collector.logs.push(TransactionLogInfo {
signature: tx.signatures[0],
result: r.clone(),
is_vote,
log_messages,
});
}
}
}

Expand Down Expand Up @@ -4036,7 +4036,7 @@ impl Bank {
TransactionResults,
TransactionBalancesSet,
Vec<Option<InnerInstructionsList>>,
Vec<TransactionLogMessages>,
Vec<Option<TransactionLogMessages>>,
) {
let pre_balances = if collect_balances {
self.collect_balances(batch)
Expand Down Expand Up @@ -10135,9 +10135,11 @@ pub(crate) mod tests {
&mut ExecuteTimings::default(),
);

assert!(inner_instructions[0].iter().all(|ix| ix.is_empty()));
assert_eq!(transaction_logs.len(), 0);
assert!(inner_instructions.iter().all(Option::is_none));
assert!(transaction_logs.iter().all(Option::is_none));

assert_eq!(inner_instructions.len(), 3);
assert_eq!(transaction_logs.len(), 3);
assert_eq!(transaction_balances_set.pre_balances.len(), 3);
assert_eq!(transaction_balances_set.post_balances.len(), 3);

Expand Down Expand Up @@ -12926,7 +12928,9 @@ pub(crate) mod tests {
let success_sig = tx0.signatures[0];
let tx1 = system_transaction::transfer(&sender1, &recipient1, 110, blockhash); // Should produce insufficient funds log
let failure_sig = tx1.signatures[0];
let txs = vec![tx1, tx0];
let mut invalid_tx = system_transaction::transfer(&sender1, &recipient1, 10, blockhash);
invalid_tx.message.header.num_required_signatures = 0; // this tx won't be processed because it has no signers
let txs = vec![invalid_tx, tx1, tx0];
let batch = bank.prepare_batch(txs.iter());

let log_results = bank
Expand All @@ -12939,17 +12943,10 @@ pub(crate) mod tests {
&mut ExecuteTimings::default(),
)
.3;
assert_eq!(log_results.len(), 2);
assert!(log_results[0]
.clone()
.pop()
.unwrap()
.contains(&"failed".to_string()));
assert!(log_results[1]
.clone()
.pop()
.unwrap()
.contains(&"success".to_string()));
assert_eq!(log_results.len(), 3);
assert!(log_results[0].as_ref().is_none());
assert!(log_results[1].as_ref().unwrap()[2].contains(&"failed".to_string()));
assert!(log_results[2].as_ref().unwrap()[1].contains(&"success".to_string()));

let stored_logs = &bank.transaction_log_collector.read().unwrap().logs;
let success_log_info = stored_logs
Expand Down