Skip to content
This repository was archived by the owner on Jan 22, 2025. It is now read-only.
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
34 changes: 4 additions & 30 deletions core/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use solana_runtime::{
bank::Bank,
bank_forks::BankForks,
commitment::{BlockCommitmentArray, BlockCommitmentCache, CommitmentSlots},
log_collector::LogCollector,
send_transaction_service::{SendTransactionService, TransactionInfo},
};
use solana_sdk::{
Expand Down Expand Up @@ -57,7 +56,6 @@ use std::{
collections::{HashMap, HashSet},
mem::size_of,
net::SocketAddr,
rc::Rc,
str::FromStr,
sync::{
atomic::{AtomicBool, Ordering},
Expand Down Expand Up @@ -1014,29 +1012,6 @@ fn verify_token_account_filter(
}
}

/// Run transactions against a frozen bank without committing the results
fn run_transaction_simulation(
bank: &Bank,
transaction: Transaction,
) -> (transaction::Result<()>, Vec<String>) {
assert!(bank.is_frozen(), "simulation bank must be frozen");

let txs = &[transaction];
let batch = bank.prepare_simulation_batch(txs);
let log_collector = Rc::new(LogCollector::default());
let (_loaded_accounts, executed, _retryable_transactions, _transaction_count, _signature_count) = {
bank.load_and_execute_transactions(
&batch,
solana_sdk::clock::MAX_PROCESSING_AGE,
Some(log_collector.clone()),
)
};
(
executed[0].0.clone().map(|_| ()),
Rc::try_unwrap(log_collector).unwrap_or_default().into(),
)
}

/// Use a set of filters to get an iterator of keyed program accounts from a bank
fn get_filtered_program_accounts(
bank: &Arc<Bank>,
Expand Down Expand Up @@ -1797,8 +1772,7 @@ impl RpcSol for RpcSolImpl {
.into());
}

if let (Err(err), _log_output) = run_transaction_simulation(&bank, transaction.clone())
{
if let (Err(err), _log_output) = bank.simulate_transaction(transaction.clone()) {
// Note: it's possible that the transaction simulation failed but the actual
// transaction would succeed, such as when a transaction depends on an earlier
// transaction that has yet to reach max confirmations. In these cases the user
Expand Down Expand Up @@ -1832,9 +1806,9 @@ impl RpcSol for RpcSolImpl {

let bank = &*meta.bank(None);
let logs = if result.is_ok() {
let sim_result = run_transaction_simulation(&bank, transaction);
result = sim_result.0;
Some(sim_result.1)
let (transaction_result, log_messages) = bank.simulate_transaction(transaction);
result = transaction_result;
Some(log_messages)
} else {
None
};
Expand Down
23 changes: 23 additions & 0 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,29 @@ impl Bank {
batch
}

/// Run transactions against a frozen bank without committing the results
pub fn simulate_transaction(&self, transaction: Transaction) -> (Result<()>, Vec<String>) {
assert!(self.is_frozen(), "simulation bank must be frozen");

let txs = &[transaction];
let batch = self.prepare_simulation_batch(txs);
let log_collector = Rc::new(LogCollector::default());
let (
_loaded_accounts,
executed,
_retryable_transactions,
_transaction_count,
_signature_count,
) = self.load_and_execute_transactions(
&batch,
MAX_PROCESSING_AGE,
Some(log_collector.clone()),
);
let transaction_result = executed[0].0.clone().map(|_| ());
let log_messages = Rc::try_unwrap(log_collector).unwrap_or_default().into();
(transaction_result, log_messages)
}

pub fn unlock_accounts(&self, batch: &mut TransactionBatch) {
if batch.needs_unlock {
batch.needs_unlock = false;
Expand Down