Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
test(concurrency): test commit phase in the worker logic (#1918)
Browse files Browse the repository at this point in the history
  • Loading branch information
avi-starkware authored Jun 5, 2024
1 parent cfb9c07 commit cf5d3b6
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 2 deletions.
4 changes: 4 additions & 0 deletions crates/blockifier/src/concurrency/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ impl Scheduler {
}
}

pub fn get_n_committed_txs(&self) -> usize {
*self.commit_index.lock().unwrap()
}

fn lock_tx_status(&self, tx_index: TxIndex) -> MutexGuard<'_, TransactionStatus> {
lock_mutex_in_array(&self.tx_statuses, tx_index)
}
Expand Down
106 changes: 104 additions & 2 deletions crates/blockifier/src/concurrency/worker_logic_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ fn test_worker_execute() {

});

// Concurrency settings.
let txs = [tx_success, tx_failure, tx_revert]
.into_iter()
.map(Transaction::AccountTransaction)
Expand Down Expand Up @@ -258,7 +257,6 @@ fn test_worker_validate() {

});

// Concurrency settings.
let txs = [account_tx0, account_tx1]
.into_iter()
.map(Transaction::AccountTransaction)
Expand Down Expand Up @@ -463,3 +461,107 @@ fn test_deploy_before_declare() {
let next_task = worker_executor.validate(1);
assert_eq!(next_task, Task::NoTask);
}

#[test]
fn test_worker_commit_phase() {
// Settings.
let concurrency_mode = true;
let block_context =
BlockContext::create_for_account_testing_with_concurrency_mode(concurrency_mode);

let account_contract = FeatureContract::AccountWithoutValidations(CairoVersion::Cairo1);
let test_contract = FeatureContract::TestContract(CairoVersion::Cairo0);
let chain_info = &block_context.chain_info;

// Create the state.
let state_reader =
test_state_reader(chain_info, BALANCE, &[(account_contract, 1), (test_contract, 1)]);
let safe_versioned_state = safe_versioned_state_for_testing(state_reader);

// Create transactions.
let test_contract_address = test_contract.get_instance_address(0);
let sender_address = account_contract.get_instance_address(0);
let nonce_manager = &mut NonceManager::default();
let storage_value = stark_felt!(93_u8);
let storage_key = storage_key!(1993_u16);
let calldata = create_calldata(
test_contract_address,
"test_storage_read_write",
&[*storage_key.0.key(), storage_value], // Calldata: address, value.
);
let max_fee = Fee(MAX_FEE);

let account_tx0 = account_invoke_tx(invoke_tx_args! {
sender_address,
calldata: calldata.clone(),
max_fee,
nonce: nonce_manager.next(sender_address)
});

let account_tx1 = account_invoke_tx(invoke_tx_args! {
sender_address,
calldata: calldata.clone(),
max_fee,
nonce: nonce_manager.next(sender_address)
});

let account_tx2 = account_invoke_tx(invoke_tx_args! {
sender_address,
calldata,
max_fee,
nonce: nonce_manager.next(sender_address)
});

let txs = [account_tx0, account_tx1, account_tx2]
.into_iter()
.map(Transaction::AccountTransaction)
.collect::<Vec<Transaction>>();

let worker_executor = WorkerExecutor::new(safe_versioned_state.clone(), &txs, block_context);

// Try to commit before any transaction is ready.
worker_executor.commit_while_possible().unwrap();

// Verify no transaction was committed.
assert_eq!(worker_executor.scheduler.get_n_committed_txs(), 0);

// Creates 2 active tasks.
// Creating these tasks changes the status of the first two transactions to `Executing`. If we
// skip this step, executing them will panic when reaching `finish_execution` (as their status
// will be `ReadyToExecute` and not `Executing` as expected).
assert_eq!(worker_executor.scheduler.next_task(), Task::ExecutionTask(0));
assert_eq!(worker_executor.scheduler.next_task(), Task::ExecutionTask(1));

// Execute the first two transactions.
worker_executor.execute(0);
worker_executor.execute(1);

// Commit the first two transactions (only).
worker_executor.commit_while_possible().unwrap();

// Verify the commit index is now 2.
assert_eq!(worker_executor.scheduler.get_n_committed_txs(), 2);

// Verify the status of the first two transactions is `Committed`.
assert_eq!(*worker_executor.scheduler.get_tx_status(0), TransactionStatus::Committed);
assert_eq!(*worker_executor.scheduler.get_tx_status(1), TransactionStatus::Committed);

// Create the final execution task and execute it.
assert_eq!(worker_executor.scheduler.next_task(), Task::ExecutionTask(2));
worker_executor.execute(2);

// Commit the third (and last) transaction.
worker_executor.commit_while_possible().unwrap();

// Verify the commit index is now 3, the status of the last transaction is `Committed`, and the
// next task is `Done`.
assert_eq!(worker_executor.scheduler.get_n_committed_txs(), 3);
assert_eq!(*worker_executor.scheduler.get_tx_status(2), TransactionStatus::Committed);
assert_eq!(worker_executor.scheduler.next_task(), Task::Done);

// Try to commit when all transactions are already committed.
worker_executor.commit_while_possible().unwrap();
assert_eq!(worker_executor.scheduler.get_n_committed_txs(), 3);

// TODO(Avi, 15/06/2024): Check the halt mechanism once the bouncer is supported.
}

0 comments on commit cf5d3b6

Please sign in to comment.