removes OrderedIterator and transaction batch iteration order (#16153)
In TransactionBatch, https://github.com/solana-labs/solana/blob/e50f59844/runtime/src/transaction_batch.rs#L4-L11 lock_results[i] is aligned with transactions[iteration_order[i]]: https://github.com/solana-labs/solana/blob/e50f59844/runtime/src/bank.rs#L2414-L2424 https://github.com/solana-labs/solana/blob/e50f59844/runtime/src/accounts.rs#L788-L817 However load_and_execute_transactions is iterating over lock_results[iteration_order[i]] https://github.com/solana-labs/solana/blob/e50f59844/runtime/src/bank.rs#L2878-L2889 and then returning i as for the index of the retryable transaction. If iteratorion_order is [1, 2, 0], and i is 0, then: lock_results[iteration_order[i]] = lock_results[1] which corresponds to transactions[iteration_order[1]] = transactions[2] so neither i = 0, nor iteration_order[i] = 1 gives the correct index for the corresponding transaction (which is 2). This commit removes OrderedIterator and transaction batch iteration order entirely. There is only one place in blockstore processor which the iteration order is not ordinal: https://github.com/solana-labs/solana/blob/e50f59844/ledger/src/blockstore_processor.rs#L269-L271 It seems like, instead of using an iteration order, that can shuffle entry transactions in-place.
This commit is contained in:
@@ -7,7 +7,6 @@ use crate::{
|
||||
blockhash_queue::BlockhashQueue,
|
||||
rent_collector::RentCollector,
|
||||
system_instruction_processor::{get_system_account_kind, SystemAccountKind},
|
||||
transaction_utils::OrderedIterator,
|
||||
};
|
||||
use dashmap::{
|
||||
mapref::entry::Entry::{Occupied, Vacant},
|
||||
@@ -391,7 +390,6 @@ impl Accounts {
|
||||
&self,
|
||||
ancestors: &Ancestors,
|
||||
txs: &[Transaction],
|
||||
txs_iteration_order: Option<&[usize]>,
|
||||
lock_results: Vec<TransactionCheckResult>,
|
||||
hash_queue: &BlockhashQueue,
|
||||
error_counters: &mut ErrorCounters,
|
||||
@@ -402,10 +400,10 @@ impl Accounts {
|
||||
secp256k1_program_enabled: feature_set
|
||||
.is_active(&feature_set::secp256k1_program_enabled::id()),
|
||||
};
|
||||
OrderedIterator::new(txs, txs_iteration_order)
|
||||
.zip(lock_results.into_iter())
|
||||
txs.iter()
|
||||
.zip(lock_results)
|
||||
.map(|etx| match etx {
|
||||
((_, tx), (Ok(()), nonce_rollback)) => {
|
||||
(tx, (Ok(()), nonce_rollback)) => {
|
||||
let fee_calculator = nonce_rollback
|
||||
.as_ref()
|
||||
.map(|nonce_rollback| nonce_rollback.fee_calculator())
|
||||
@@ -804,12 +802,12 @@ impl Accounts {
|
||||
pub fn lock_accounts(
|
||||
&self,
|
||||
txs: &[Transaction],
|
||||
txs_iteration_order: Option<&[usize]>,
|
||||
demote_sysvar_write_locks: bool,
|
||||
) -> Vec<Result<()>> {
|
||||
use solana_sdk::sanitize::Sanitize;
|
||||
let keys: Vec<Result<_>> = OrderedIterator::new(txs, txs_iteration_order)
|
||||
.map(|(_, tx)| {
|
||||
let keys: Vec<Result<_>> = txs
|
||||
.iter()
|
||||
.map(|tx| {
|
||||
tx.sanitize().map_err(TransactionError::from)?;
|
||||
|
||||
if Self::has_duplicates(&tx.message.account_keys) {
|
||||
@@ -836,18 +834,19 @@ impl Accounts {
|
||||
pub fn unlock_accounts(
|
||||
&self,
|
||||
txs: &[Transaction],
|
||||
txs_iteration_order: Option<&[usize]>,
|
||||
results: &[Result<()>],
|
||||
demote_sysvar_write_locks: bool,
|
||||
) {
|
||||
let mut account_locks = self.account_locks.lock().unwrap();
|
||||
debug!("bank unlock accounts");
|
||||
|
||||
OrderedIterator::new(txs, txs_iteration_order)
|
||||
.zip(results.iter())
|
||||
.for_each(|((_, tx), result)| {
|
||||
self.unlock_account(tx, result, &mut account_locks, demote_sysvar_write_locks)
|
||||
});
|
||||
for (tx, lock_result) in txs.iter().zip(results) {
|
||||
self.unlock_account(
|
||||
tx,
|
||||
lock_result,
|
||||
&mut account_locks,
|
||||
demote_sysvar_write_locks,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Store the accounts into the DB
|
||||
@@ -857,7 +856,6 @@ impl Accounts {
|
||||
&self,
|
||||
slot: Slot,
|
||||
txs: &[Transaction],
|
||||
txs_iteration_order: Option<&[usize]>,
|
||||
res: &[TransactionExecutionResult],
|
||||
loaded: &mut [TransactionLoadResult],
|
||||
rent_collector: &RentCollector,
|
||||
@@ -867,7 +865,6 @@ impl Accounts {
|
||||
) {
|
||||
let accounts_to_store = self.collect_accounts_to_store(
|
||||
txs,
|
||||
txs_iteration_order,
|
||||
res,
|
||||
loaded,
|
||||
rent_collector,
|
||||
@@ -892,7 +889,6 @@ impl Accounts {
|
||||
fn collect_accounts_to_store<'a>(
|
||||
&self,
|
||||
txs: &'a [Transaction],
|
||||
txs_iteration_order: Option<&'a [usize]>,
|
||||
res: &'a [TransactionExecutionResult],
|
||||
loaded: &'a mut [TransactionLoadResult],
|
||||
rent_collector: &RentCollector,
|
||||
@@ -901,11 +897,7 @@ impl Accounts {
|
||||
demote_sysvar_write_locks: bool,
|
||||
) -> Vec<(&'a Pubkey, &'a AccountSharedData)> {
|
||||
let mut accounts = Vec::with_capacity(loaded.len());
|
||||
for (i, ((raccs, _nonce_rollback), (_, tx))) in loaded
|
||||
.iter_mut()
|
||||
.zip(OrderedIterator::new(txs, txs_iteration_order))
|
||||
.enumerate()
|
||||
{
|
||||
for (i, ((raccs, _nonce_rollback), tx)) in loaded.iter_mut().zip(txs).enumerate() {
|
||||
if raccs.is_err() {
|
||||
continue;
|
||||
}
|
||||
@@ -1086,7 +1078,6 @@ mod tests {
|
||||
accounts.load_accounts(
|
||||
&ancestors,
|
||||
&[tx],
|
||||
None,
|
||||
vec![(Ok(()), None)],
|
||||
&hash_queue,
|
||||
error_counters,
|
||||
@@ -1689,7 +1680,6 @@ mod tests {
|
||||
let tx = Transaction::new(&[&keypair0], message, Hash::default());
|
||||
let results0 = accounts.lock_accounts(
|
||||
&[tx.clone()],
|
||||
None, // txs_iteration_order
|
||||
true, // demote_sysvar_write_locks
|
||||
);
|
||||
|
||||
@@ -1727,8 +1717,7 @@ mod tests {
|
||||
let tx1 = Transaction::new(&[&keypair1], message, Hash::default());
|
||||
let txs = vec![tx0, tx1];
|
||||
let results1 = accounts.lock_accounts(
|
||||
&txs, None, // txs_iteration_order
|
||||
true, // demote_sysvar_write_locks
|
||||
&txs, true, // demote_sysvar_write_locks
|
||||
);
|
||||
|
||||
assert!(results1[0].is_ok()); // Read-only account (keypair1) can be referenced multiple times
|
||||
@@ -1746,13 +1735,11 @@ mod tests {
|
||||
|
||||
accounts.unlock_accounts(
|
||||
&[tx],
|
||||
None, // txs_iteration_order
|
||||
&results0,
|
||||
true, // demote_sysvar_write_locks
|
||||
);
|
||||
accounts.unlock_accounts(
|
||||
&txs, None, // txs_iteration_order
|
||||
&results1, true, // demote_sysvar_write_locks
|
||||
&txs, &results1, true, // demote_sysvar_write_locks
|
||||
);
|
||||
let instructions = vec![CompiledInstruction::new(2, &(), vec![0, 1])];
|
||||
let message = Message::new_with_compiled_instructions(
|
||||
@@ -1766,7 +1753,6 @@ mod tests {
|
||||
let tx = Transaction::new(&[&keypair1], message, Hash::default());
|
||||
let results2 = accounts.lock_accounts(
|
||||
&[tx],
|
||||
None, // txs_iteration_order
|
||||
true, // demote_sysvar_write_locks
|
||||
);
|
||||
assert!(results2[0].is_ok()); // Now keypair1 account can be locked as writable
|
||||
@@ -1833,8 +1819,7 @@ mod tests {
|
||||
loop {
|
||||
let txs = vec![writable_tx.clone()];
|
||||
let results = accounts_clone.clone().lock_accounts(
|
||||
&txs, None, // txs_iteration_order
|
||||
true, // demote_sysvar_write_locks
|
||||
&txs, true, // demote_sysvar_write_locks
|
||||
);
|
||||
for result in results.iter() {
|
||||
if result.is_ok() {
|
||||
@@ -1842,8 +1827,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
accounts_clone.unlock_accounts(
|
||||
&txs, None, // txs_iteration_order
|
||||
&results, true, // demote_sysvar_write_locks
|
||||
&txs, &results, true, // demote_sysvar_write_locks
|
||||
);
|
||||
if exit_clone.clone().load(Ordering::Relaxed) {
|
||||
break;
|
||||
@@ -1854,8 +1838,7 @@ mod tests {
|
||||
for _ in 0..5 {
|
||||
let txs = vec![readonly_tx.clone()];
|
||||
let results = accounts_arc.clone().lock_accounts(
|
||||
&txs, None, // txs_iteration_order
|
||||
true, // demote_sysvar_write_locks
|
||||
&txs, true, // demote_sysvar_write_locks
|
||||
);
|
||||
if results[0].is_ok() {
|
||||
let counter_value = counter_clone.clone().load(Ordering::SeqCst);
|
||||
@@ -1863,8 +1846,7 @@ mod tests {
|
||||
assert_eq!(counter_value, counter_clone.clone().load(Ordering::SeqCst));
|
||||
}
|
||||
accounts_arc.unlock_accounts(
|
||||
&txs, None, // txs_iteration_order
|
||||
&results, true, // demote_sysvar_write_locks
|
||||
&txs, &results, true, // demote_sysvar_write_locks
|
||||
);
|
||||
thread::sleep(time::Duration::from_millis(50));
|
||||
}
|
||||
@@ -1947,7 +1929,6 @@ mod tests {
|
||||
}
|
||||
let collected_accounts = accounts.collect_accounts_to_store(
|
||||
&txs,
|
||||
None,
|
||||
&loaders,
|
||||
loaded.as_mut_slice(),
|
||||
&rent_collector,
|
||||
@@ -2017,7 +1998,6 @@ mod tests {
|
||||
accounts.load_accounts(
|
||||
&ancestors,
|
||||
&[tx],
|
||||
None,
|
||||
vec![(Ok(()), None)],
|
||||
&hash_queue,
|
||||
&mut error_counters,
|
||||
@@ -2313,7 +2293,6 @@ mod tests {
|
||||
Accounts::new_with_config(Vec::new(), &ClusterType::Development, HashSet::new(), false);
|
||||
let collected_accounts = accounts.collect_accounts_to_store(
|
||||
&txs,
|
||||
None,
|
||||
&loaders,
|
||||
loaded.as_mut_slice(),
|
||||
&rent_collector,
|
||||
@@ -2425,7 +2404,6 @@ mod tests {
|
||||
Accounts::new_with_config(Vec::new(), &ClusterType::Development, HashSet::new(), false);
|
||||
let collected_accounts = accounts.collect_accounts_to_store(
|
||||
&txs,
|
||||
None,
|
||||
&loaders,
|
||||
loaded.as_mut_slice(),
|
||||
&rent_collector,
|
||||
|
Reference in New Issue
Block a user