simulateTransaction RPC method can now return accounts modified by the simulation (backport #17499) (#17526)

* simulateTransaction can now return accounts modified by the simulation

(cherry picked from commit cbce440af4)

# Conflicts:
#	rpc/src/parsed_token_accounts.rs

* rebase

Co-authored-by: Michael Vines <mvines@gmail.com>
This commit is contained in:
mergify[bot]
2021-05-27 00:06:05 +00:00
committed by GitHub
parent 9c549a3ccf
commit 3b22f5b833
11 changed files with 278 additions and 49 deletions

View File

@@ -2473,16 +2473,15 @@ impl Bank {
TransactionBatch::new(lock_results, &self, Cow::Borrowed(hashed_txs))
}
pub fn prepare_simulation_batch<'a, 'b>(
pub(crate) fn prepare_simulation_batch<'a, 'b>(
&'a self,
txs: &'b [Transaction],
tx: &'b Transaction,
) -> TransactionBatch<'a, 'b> {
let lock_results: Vec<_> = txs
.iter()
.map(|tx| tx.sanitize().map_err(|e| e.into()))
.collect();
let hashed_txs = txs.iter().map(HashedTransaction::from).collect();
let mut batch = TransactionBatch::new(lock_results, &self, hashed_txs);
let mut batch = TransactionBatch::new(
vec![tx.sanitize().map_err(|e| e.into())],
&self,
Cow::Owned(vec![HashedTransaction::from(tx)]),
);
batch.needs_unlock = false;
batch
}
@@ -2490,17 +2489,16 @@ impl Bank {
/// Run transactions against a frozen bank without committing the results
pub fn simulate_transaction(
&self,
transaction: Transaction,
) -> (Result<()>, TransactionLogMessages) {
transaction: &Transaction,
) -> (Result<()>, TransactionLogMessages, Vec<AccountSharedData>) {
assert!(self.is_frozen(), "simulation bank must be frozen");
let txs = &[transaction];
let batch = self.prepare_simulation_batch(txs);
let batch = self.prepare_simulation_batch(&transaction);
let mut timings = ExecuteTimings::default();
let (
_loaded_accounts,
loaded_accounts,
executed,
_inner_instructions,
log_messages,
@@ -2522,10 +2520,18 @@ impl Bank {
let log_messages = log_messages
.get(0)
.map_or(vec![], |messages| messages.to_vec());
let post_transaction_accounts = loaded_accounts
.into_iter()
.next()
.unwrap()
.0
.ok()
.map(|loaded_transaction| loaded_transaction.accounts.into_iter().collect::<Vec<_>>())
.unwrap_or_default();
debug!("simulate_transaction: {:?}", timings);
(transaction_result, log_messages)
(transaction_result, log_messages, post_transaction_accounts)
}
pub fn unlock_accounts(&self, batch: &mut TransactionBatch) {

View File

@@ -83,7 +83,7 @@ mod tests {
let (bank, txs) = setup();
// Prepare batch without locks
let batch = bank.prepare_simulation_batch(&txs);
let batch = bank.prepare_simulation_batch(&txs[0]);
assert!(batch.lock_results().iter().all(|x| x.is_ok()));
// Grab locks
@@ -91,7 +91,7 @@ mod tests {
assert!(batch2.lock_results().iter().all(|x| x.is_ok()));
// Prepare another batch without locks
let batch3 = bank.prepare_simulation_batch(&txs);
let batch3 = bank.prepare_simulation_batch(&txs[0]);
assert!(batch3.lock_results().iter().all(|x| x.is_ok()));
}