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.
(cherry picked from commit 3f63ed9a72
)
Co-authored-by: behzad nouri <behzadnouri@gmail.com>
This commit is contained in:
@@ -6,7 +6,6 @@ pub struct TransactionBatch<'a, 'b> {
|
||||
lock_results: Vec<Result<()>>,
|
||||
bank: &'a Bank,
|
||||
transactions: &'b [Transaction],
|
||||
iteration_order: Option<Vec<usize>>,
|
||||
pub(crate) needs_unlock: bool,
|
||||
}
|
||||
|
||||
@@ -15,17 +14,12 @@ impl<'a, 'b> TransactionBatch<'a, 'b> {
|
||||
lock_results: Vec<Result<()>>,
|
||||
bank: &'a Bank,
|
||||
transactions: &'b [Transaction],
|
||||
iteration_order: Option<Vec<usize>>,
|
||||
) -> Self {
|
||||
assert_eq!(lock_results.len(), transactions.len());
|
||||
if let Some(iteration_order) = &iteration_order {
|
||||
assert_eq!(transactions.len(), iteration_order.len());
|
||||
}
|
||||
Self {
|
||||
lock_results,
|
||||
bank,
|
||||
transactions,
|
||||
iteration_order,
|
||||
needs_unlock: true,
|
||||
}
|
||||
}
|
||||
@@ -38,14 +32,6 @@ impl<'a, 'b> TransactionBatch<'a, 'b> {
|
||||
self.transactions
|
||||
}
|
||||
|
||||
pub fn iteration_order(&self) -> Option<&[usize]> {
|
||||
self.iteration_order.as_deref()
|
||||
}
|
||||
|
||||
pub fn iteration_order_vec(&self) -> Option<Vec<usize>> {
|
||||
self.iteration_order.clone()
|
||||
}
|
||||
|
||||
pub fn bank(&self) -> &Bank {
|
||||
self.bank
|
||||
}
|
||||
@@ -69,20 +55,20 @@ mod tests {
|
||||
let (bank, txs) = setup();
|
||||
|
||||
// Test getting locked accounts
|
||||
let batch = bank.prepare_batch(&txs, None);
|
||||
let batch = bank.prepare_batch(&txs);
|
||||
|
||||
// Grab locks
|
||||
assert!(batch.lock_results().iter().all(|x| x.is_ok()));
|
||||
|
||||
// Trying to grab locks again should fail
|
||||
let batch2 = bank.prepare_batch(&txs, None);
|
||||
let batch2 = bank.prepare_batch(&txs);
|
||||
assert!(batch2.lock_results().iter().all(|x| x.is_err()));
|
||||
|
||||
// Drop the first set of locks
|
||||
drop(batch);
|
||||
|
||||
// Now grabbing locks should work again
|
||||
let batch2 = bank.prepare_batch(&txs, None);
|
||||
let batch2 = bank.prepare_batch(&txs);
|
||||
assert!(batch2.lock_results().iter().all(|x| x.is_ok()));
|
||||
}
|
||||
|
||||
@@ -95,7 +81,7 @@ mod tests {
|
||||
assert!(batch.lock_results().iter().all(|x| x.is_ok()));
|
||||
|
||||
// Grab locks
|
||||
let batch2 = bank.prepare_batch(&txs, None);
|
||||
let batch2 = bank.prepare_batch(&txs);
|
||||
assert!(batch2.lock_results().iter().all(|x| x.is_ok()));
|
||||
|
||||
// Prepare another batch without locks
|
||||
|
Reference in New Issue
Block a user