Extend getConfirmedBlock rpc to return account pre- and post-balances (#7543)
automerge
This commit is contained in:
@ -4550,6 +4550,12 @@ pub mod tests {
|
||||
.filter(|entry| !entry.is_tick())
|
||||
.flat_map(|entry| entry.transactions)
|
||||
.map(|transaction| {
|
||||
let mut pre_balances: Vec<u64> = vec![];
|
||||
let mut post_balances: Vec<u64> = vec![];
|
||||
for (i, _account_key) in transaction.message.account_keys.iter().enumerate() {
|
||||
pre_balances.push(i as u64 * 10);
|
||||
post_balances.push(i as u64 * 11);
|
||||
}
|
||||
let signature = transaction.signatures[0];
|
||||
ledger
|
||||
.transaction_status_cf
|
||||
@ -4558,6 +4564,8 @@ pub mod tests {
|
||||
&RpcTransactionStatus {
|
||||
status: Ok(()),
|
||||
fee: 42,
|
||||
pre_balances: pre_balances.clone(),
|
||||
post_balances: post_balances.clone(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
@ -4568,6 +4576,8 @@ pub mod tests {
|
||||
&RpcTransactionStatus {
|
||||
status: Ok(()),
|
||||
fee: 42,
|
||||
pre_balances: pre_balances.clone(),
|
||||
post_balances: post_balances.clone(),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
@ -4576,6 +4586,8 @@ pub mod tests {
|
||||
Some(RpcTransactionStatus {
|
||||
status: Ok(()),
|
||||
fee: 42,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
}),
|
||||
)
|
||||
})
|
||||
@ -4694,6 +4706,9 @@ pub mod tests {
|
||||
let blocktree = Blocktree::open(&blocktree_path).unwrap();
|
||||
let transaction_status_cf = blocktree.db.column::<cf::TransactionStatus>();
|
||||
|
||||
let pre_balances_vec = vec![1, 2, 3];
|
||||
let post_balances_vec = vec![3, 2, 1];
|
||||
|
||||
// result not found
|
||||
assert!(transaction_status_cf
|
||||
.get((0, Signature::default()))
|
||||
@ -4708,18 +4723,27 @@ pub mod tests {
|
||||
status: solana_sdk::transaction::Result::<()>::Err(
|
||||
TransactionError::AccountNotFound
|
||||
),
|
||||
fee: 5u64
|
||||
fee: 5u64,
|
||||
pre_balances: pre_balances_vec.clone(),
|
||||
post_balances: post_balances_vec.clone(),
|
||||
},
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
// result found
|
||||
let RpcTransactionStatus { status, fee } = transaction_status_cf
|
||||
let RpcTransactionStatus {
|
||||
status,
|
||||
fee,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
} = transaction_status_cf
|
||||
.get((0, Signature::default()))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
assert_eq!(status, Err(TransactionError::AccountNotFound));
|
||||
assert_eq!(fee, 5u64);
|
||||
assert_eq!(pre_balances, pre_balances_vec);
|
||||
assert_eq!(post_balances, post_balances_vec);
|
||||
|
||||
// insert value
|
||||
assert!(transaction_status_cf
|
||||
@ -4727,13 +4751,20 @@ pub mod tests {
|
||||
(9, Signature::default()),
|
||||
&RpcTransactionStatus {
|
||||
status: solana_sdk::transaction::Result::<()>::Ok(()),
|
||||
fee: 9u64
|
||||
fee: 9u64,
|
||||
pre_balances: pre_balances_vec.clone(),
|
||||
post_balances: post_balances_vec.clone(),
|
||||
},
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
// result found
|
||||
let RpcTransactionStatus { status, fee } = transaction_status_cf
|
||||
let RpcTransactionStatus {
|
||||
status,
|
||||
fee,
|
||||
pre_balances,
|
||||
post_balances,
|
||||
} = transaction_status_cf
|
||||
.get((9, Signature::default()))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
@ -4741,6 +4772,8 @@ pub mod tests {
|
||||
// deserialize
|
||||
assert_eq!(status, Ok(()));
|
||||
assert_eq!(fee, 9u64);
|
||||
assert_eq!(pre_balances, pre_balances_vec);
|
||||
assert_eq!(post_balances, post_balances_vec);
|
||||
}
|
||||
Blocktree::destroy(&blocktree_path).expect("Expected successful database destruction");
|
||||
}
|
||||
@ -4786,6 +4819,8 @@ pub mod tests {
|
||||
TransactionError::AccountNotFound,
|
||||
),
|
||||
fee: x,
|
||||
pre_balances: vec![],
|
||||
post_balances: vec![],
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
@ -14,7 +14,7 @@ use rayon::{prelude::*, ThreadPool};
|
||||
use solana_metrics::{datapoint, datapoint_error, inc_new_counter_debug};
|
||||
use solana_rayon_threadlimit::get_thread_count;
|
||||
use solana_runtime::{
|
||||
bank::{Bank, TransactionProcessResult, TransactionResults},
|
||||
bank::{Bank, TransactionBalancesSet, TransactionProcessResult, TransactionResults},
|
||||
transaction_batch::TransactionBatch,
|
||||
};
|
||||
use solana_sdk::{
|
||||
@ -54,18 +54,24 @@ fn execute_batch(
|
||||
bank: &Arc<Bank>,
|
||||
transaction_status_sender: Option<TransactionStatusSender>,
|
||||
) -> Result<()> {
|
||||
let TransactionResults {
|
||||
fee_collection_results,
|
||||
processing_results,
|
||||
} = batch
|
||||
.bank()
|
||||
.load_execute_and_commit_transactions(batch, MAX_RECENT_BLOCKHASHES);
|
||||
let (
|
||||
TransactionResults {
|
||||
fee_collection_results,
|
||||
processing_results,
|
||||
},
|
||||
balances,
|
||||
) = batch.bank().load_execute_and_commit_transactions(
|
||||
batch,
|
||||
MAX_RECENT_BLOCKHASHES,
|
||||
transaction_status_sender.is_some(),
|
||||
);
|
||||
|
||||
if let Some(sender) = transaction_status_sender {
|
||||
send_transaction_status_batch(
|
||||
bank.clone(),
|
||||
batch.transactions(),
|
||||
processing_results,
|
||||
balances,
|
||||
sender,
|
||||
);
|
||||
}
|
||||
@ -560,6 +566,7 @@ pub struct TransactionStatusBatch {
|
||||
pub bank: Arc<Bank>,
|
||||
pub transactions: Vec<Transaction>,
|
||||
pub statuses: Vec<TransactionProcessResult>,
|
||||
pub balances: TransactionBalancesSet,
|
||||
}
|
||||
pub type TransactionStatusSender = Sender<TransactionStatusBatch>;
|
||||
|
||||
@ -567,6 +574,7 @@ pub fn send_transaction_status_batch(
|
||||
bank: Arc<Bank>,
|
||||
transactions: &[Transaction],
|
||||
statuses: Vec<TransactionProcessResult>,
|
||||
balances: TransactionBalancesSet,
|
||||
transaction_status_sender: TransactionStatusSender,
|
||||
) {
|
||||
let slot = bank.slot();
|
||||
@ -574,6 +582,7 @@ pub fn send_transaction_status_batch(
|
||||
bank,
|
||||
transactions: transactions.to_vec(),
|
||||
statuses,
|
||||
balances,
|
||||
}) {
|
||||
trace!(
|
||||
"Slot {} transaction_status send batch failed: {:?}",
|
||||
|
Reference in New Issue
Block a user