Skip to content

Commit fc208a0

Browse files
authored
unified_scheduler_logic: replace get_account_locks_unchecked (solana-labs#2554)
1 parent 65f6466 commit fc208a0

File tree

1 file changed

+42
-26
lines changed
  • unified-scheduler-logic/src

1 file changed

+42
-26
lines changed

unified-scheduler-logic/src/lib.rs

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -772,35 +772,51 @@ impl SchedulingStateMachine {
772772
index: usize,
773773
usage_queue_loader: &mut impl FnMut(Pubkey) -> UsageQueue,
774774
) -> Task {
775-
// Calling the _unchecked() version here is safe for faster operation, because
776-
// `get_account_locks()` (the safe variant) is ensured to be called in
777-
// DefaultTransactionHandler::handle() via Bank::prepare_unlocked_batch_from_single_tx().
775+
// It's crucial for tasks to be validated with
776+
// `account_locks::validate_account_locks()` prior to the creation.
777+
// That's because it's part of protocol consensus regarding the
778+
// rejection of blocks containing malformed transactions
779+
// (`AccountLoadedTwice` and `TooManyAccountLocks`). Even more,
780+
// `SchedulingStateMachine` can't properly handle transactions with
781+
// duplicate addresses (those falling under `AccountLoadedTwice`).
778782
//
779-
// The safe variant has additional account-locking related verifications, which is crucial.
783+
// However, it's okay for now not to call `::validate_account_locks()`
784+
// here.
780785
//
781-
// Currently the replaying stage is redundantly calling `get_account_locks()` when unified
782-
// scheduler is enabled on the given transaction at the blockstore. This will be relaxed
783-
// for optimization in the future. As for banking stage with unified scheduler, it will
784-
// need to run .get_account_locks() at least once somewhere in the code path. In the
785-
// distant future, this function `create_task()` should be adjusted so that both stages do
786-
// the checks before calling this (say, with some ad-hoc type like
787-
// `SanitizedTransactionWithCheckedAccountLocks`) or do the checks here, resulting in
788-
// eliminating the redundant one in the replaying stage and in the handler.
789-
let locks = transaction.get_account_locks_unchecked();
790-
791-
let writable_locks = locks
792-
.writable
793-
.iter()
794-
.map(|address| (address, RequestedUsage::Writable));
795-
let readonly_locks = locks
796-
.readonly
786+
// Currently `replay_stage` is always calling
787+
//`::validate_account_locks()` regardless of whether unified-scheduler
788+
// is enabled or not at the blockstore
789+
// (`Bank::prepare_sanitized_batch()` is called in
790+
// `process_entries()`). This verification will be hoisted for
791+
// optimization when removing
792+
// `--block-verification-method=blockstore-processor`.
793+
//
794+
// As for `banking_stage` with unified scheduler, it will need to run
795+
// `validate_account_locks()` at least once somewhere in the code path.
796+
// In the distant future, this function (`create_task()`) should be
797+
// adjusted so that both stages do the checks before calling this or do
798+
// the checks here, to simplify the two code paths regarding the
799+
// essential `validate_account_locks` validation.
800+
//
801+
// Lastly, `validate_account_locks()` is currently called in
802+
// `DefaultTransactionHandler::handle()` via
803+
// `Bank::prepare_unlocked_batch_from_single_tx()` as well.
804+
// This redundancy is known. It was just left as-is out of abundance
805+
// of caution.
806+
let lock_contexts = transaction
807+
.message()
808+
.account_keys()
797809
.iter()
798-
.map(|address| (address, RequestedUsage::Readonly));
799-
800-
let lock_contexts = writable_locks
801-
.chain(readonly_locks)
802-
.map(|(address, requested_usage)| {
803-
LockContext::new(usage_queue_loader(**address), requested_usage)
810+
.enumerate()
811+
.map(|(index, address)| {
812+
LockContext::new(
813+
usage_queue_loader(*address),
814+
if transaction.message().is_writable(index) {
815+
RequestedUsage::Writable
816+
} else {
817+
RequestedUsage::Readonly
818+
},
819+
)
804820
})
805821
.collect();
806822

0 commit comments

Comments
 (0)