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

Move simulate_transaction from rpc to bank #11294

Merged
merged 1 commit into from
Jul 30, 2020
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