Skip to content

Commit

Permalink
chore(blockifier): add charge fee flage to execute
Browse files Browse the repository at this point in the history
  • Loading branch information
meship-starkware committed Aug 12, 2024
1 parent f92adc2 commit 511d481
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 63 deletions.
7 changes: 4 additions & 3 deletions crates/blockifier/src/blockifier/stateful_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ impl<S: StateReader> StatefulValidator<S> {
&mut self,
tx: AccountTransaction,
skip_validate: bool,
charge_fee: bool,
) -> StatefulValidatorResult<()> {
// Deploy account transactions should be fully executed, since the constructor must run
// before `__validate_deploy__`. The execution already includes all necessary validations,
// so they are skipped here.
if let AccountTransaction::DeployAccount(_) = tx {
self.execute(tx)?;
self.execute(tx, charge_fee)?;
return Ok(());
}

Expand All @@ -83,8 +84,8 @@ impl<S: StateReader> StatefulValidator<S> {
Ok(())
}

fn execute(&mut self, tx: AccountTransaction) -> StatefulValidatorResult<()> {
self.tx_executor.execute(&Transaction::AccountTransaction(tx))?;
fn execute(&mut self, tx: AccountTransaction, charge_fee: bool) -> StatefulValidatorResult<()> {
self.tx_executor.execute(&Transaction::AccountTransaction(tx), charge_fee)?;
Ok(())
}

Expand Down
8 changes: 6 additions & 2 deletions crates/blockifier/src/blockifier/stateful_validator_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ fn test_transaction_validator(
// Test the stateful validator.
let mut stateful_validator = StatefulValidator::create(state, block_context);

let result = stateful_validator.perform_validations(tx, false);
let charge_fee = true;
let skip_validation = false;
let result = stateful_validator.perform_validations(tx, skip_validation, charge_fee);
assert!(result.is_ok(), "Validation failed: {:?}", result.unwrap_err());
}

Expand All @@ -91,7 +93,9 @@ fn test_transaction_validator_skip_validate() {
});

let mut stateful_validator = StatefulValidator::create(state, block_context);
let charge_fee = true;
let skip_validation = true;
// The transaction validations should be skipped and the function should return Ok.
let result = stateful_validator.perform_validations(tx, true);
let result = stateful_validator.perform_validations(tx, skip_validation, charge_fee);
assert_matches!(result, Ok(()));
}
15 changes: 10 additions & 5 deletions crates/blockifier/src/blockifier/transaction_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,14 @@ impl<S: StateReader> TransactionExecutor<S> {
pub fn execute(
&mut self,
tx: &Transaction,
charge_fee: bool,
) -> TransactionExecutorResult<TransactionExecutionInfo> {
let mut transactional_state = TransactionalState::create_transactional(
self.block_state.as_mut().expect(BLOCK_STATE_ACCESS_ERR),
);
// Executing a single transaction cannot be done in a concurrent mode.
let execution_flags =
ExecutionFlags { charge_fee: true, validate: true, concurrency_mode: false };
ExecutionFlags { charge_fee, validate: true, concurrency_mode: false };
let tx_execution_result =
tx.execute_raw(&mut transactional_state, &self.block_context, execution_flags);
match tx_execution_result {
Expand All @@ -118,10 +119,11 @@ impl<S: StateReader> TransactionExecutor<S> {
pub fn execute_txs_sequentially(
&mut self,
txs: &[Transaction],
charge_fee: bool,
) -> Vec<TransactionExecutorResult<TransactionExecutionInfo>> {
let mut results = Vec::new();
for tx in txs {
match self.execute(tx) {
match self.execute(tx, charge_fee) {
Ok(tx_execution_info) => results.push(Ok(tx_execution_info)),
Err(TransactionExecutorError::BlockFull) => break,
Err(error) => results.push(Err(error)),
Expand All @@ -134,6 +136,7 @@ impl<S: StateReader> TransactionExecutor<S> {
pub fn execute_chunk(
&mut self,
_chunk: &[Transaction],
_charge_fee: bool,
) -> Vec<TransactionExecutorResult<TransactionExecutionInfo>> {
unimplemented!()
}
Expand Down Expand Up @@ -179,10 +182,11 @@ impl<S: StateReader + Send + Sync> TransactionExecutor<S> {
pub fn execute_txs(
&mut self,
txs: &[Transaction],
charge_fee: bool,
) -> Vec<TransactionExecutorResult<TransactionExecutionInfo>> {
if !self.config.concurrency_config.enabled {
log::debug!("Executing transactions sequentially.");
self.execute_txs_sequentially(txs)
self.execute_txs_sequentially(txs, charge_fee)
} else {
log::debug!("Executing transactions concurrently.");
let chunk_size = self.config.concurrency_config.chunk_size;
Expand All @@ -201,7 +205,7 @@ impl<S: StateReader + Send + Sync> TransactionExecutor<S> {
);
txs.chunks(chunk_size)
.fold_while(Vec::new(), |mut results, chunk| {
let chunk_results = self.execute_chunk(chunk);
let chunk_results = self.execute_chunk(chunk, charge_fee);
if chunk_results.len() < chunk.len() {
// Block is full.
results.extend(chunk_results);
Expand All @@ -219,6 +223,7 @@ impl<S: StateReader + Send + Sync> TransactionExecutor<S> {
pub fn execute_chunk(
&mut self,
chunk: &[Transaction],
charge_fee: bool,
) -> Vec<TransactionExecutorResult<TransactionExecutionInfo>> {
use crate::concurrency::utils::AbortIfPanic;

Expand Down Expand Up @@ -246,7 +251,7 @@ impl<S: StateReader + Send + Sync> TransactionExecutor<S> {
// If a panic is not handled or the handling logic itself panics, then we abort
// the program.
if let Err(err) = catch_unwind(AssertUnwindSafe(|| {
worker_executor.run();
worker_executor.run(charge_fee);
})) {
// If the program panics here, the abort guard will exit the program.
// In this case, no panic message will be logged. Add the cargo flag
Expand Down
25 changes: 15 additions & 10 deletions crates/blockifier/src/blockifier/transaction_executor_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ fn tx_executor_test_body<S: StateReader>(
// TODO(Arni, 30/03/2024): Consider adding a test for the transaction execution info. If A test
// should not be added, rename the test to `test_bouncer_info`.
// TODO(Arni, 30/03/2024): Test all bouncer weights.
let _tx_execution_info = tx_executor.execute(&tx).unwrap();
let charge_fee = true;
let _tx_execution_info = tx_executor.execute(&tx, charge_fee).unwrap();
let bouncer_weights = tx_executor.bouncer.get_accumulated_weights();
assert_eq!(bouncer_weights.state_diff_size, expected_bouncer_weights.state_diff_size);
assert_eq!(
Expand Down Expand Up @@ -264,12 +265,15 @@ fn test_bouncing(#[case] initial_bouncer_weights: BouncerWeights, #[case] n_even
tx_executor.bouncer.set_accumulated_weights(initial_bouncer_weights);

tx_executor
.execute(&Transaction::AccountTransaction(emit_n_events_tx(
n_events,
account_address,
contract_address,
nonce_manager.next(account_address),
)))
.execute(
&Transaction::AccountTransaction(emit_n_events_tx(
n_events,
account_address,
contract_address,
nonce_manager.next(account_address),
)),
true, // charge_fee
)
.map_err(|error| panic!("{error:?}: {error}"))
.unwrap();
}
Expand Down Expand Up @@ -305,7 +309,8 @@ fn test_execute_txs_bouncing() {
.collect();

// Run.
let results = tx_executor.execute_txs(&txs);
let charge_fee = true;
let results = tx_executor.execute_txs(&txs, charge_fee);

// Check execution results.
let expected_offset = 3;
Expand Down Expand Up @@ -333,12 +338,12 @@ fn test_execute_txs_bouncing() {

// Check idempotency: excess transactions should not be added.
let remaining_txs = &txs[expected_offset..];
let remaining_tx_results = tx_executor.execute_txs(remaining_txs);
let remaining_tx_results = tx_executor.execute_txs(remaining_txs, charge_fee);
assert_eq!(remaining_tx_results.len(), 0);

// Reset the bouncer and add the remaining transactions.
tx_executor.bouncer = Bouncer::new(tx_executor.block_context.bouncer_config.clone());
let remaining_tx_results = tx_executor.execute_txs(remaining_txs);
let remaining_tx_results = tx_executor.execute_txs(remaining_txs, charge_fee);

assert_eq!(remaining_tx_results.len(), 2);
assert!(remaining_tx_results[0].is_ok());
Expand Down
23 changes: 11 additions & 12 deletions crates/blockifier/src/concurrency/worker_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ impl<'a, S: StateReader> WorkerExecutor<'a, S> {
}
}

pub fn run(&self) {
pub fn run(&self, charge_fee: bool) {
let mut task = Task::AskForTask;
loop {
self.commit_while_possible();
self.commit_while_possible(charge_fee);
task = match task {
Task::ExecutionTask(tx_index) => {
self.execute(tx_index);
self.execute(tx_index, charge_fee);
Task::AskForTask
}
Task::ValidationTask(tx_index) => self.validate(tx_index),
Expand All @@ -108,29 +108,28 @@ impl<'a, S: StateReader> WorkerExecutor<'a, S> {
}
}

fn commit_while_possible(&self) {
fn commit_while_possible(&self, charge_fee: bool) {
if let Some(mut transaction_committer) = self.scheduler.try_enter_commit_phase() {
while let Some(tx_index) = transaction_committer.try_commit() {
let commit_succeeded = self.commit_tx(tx_index);
let commit_succeeded = self.commit_tx(tx_index, charge_fee);
if !commit_succeeded {
transaction_committer.halt_scheduler();
}
}
}
}

fn execute(&self, tx_index: TxIndex) {
self.execute_tx(tx_index);
fn execute(&self, tx_index: TxIndex, charge_fee: bool) {
self.execute_tx(tx_index, charge_fee);
self.scheduler.finish_execution(tx_index)
}

fn execute_tx(&self, tx_index: TxIndex) {
fn execute_tx(&self, tx_index: TxIndex, charge_fee: bool) {
let mut tx_versioned_state = self.state.pin_version(tx_index);
let tx = &self.chunk[tx_index];
let mut transactional_state =
TransactionalState::create_transactional(&mut tx_versioned_state);
let execution_flags =
ExecutionFlags { charge_fee: true, validate: true, concurrency_mode: true };
let execution_flags = ExecutionFlags { charge_fee, validate: true, concurrency_mode: true };
let execution_result =
tx.execute_raw(&mut transactional_state, self.block_context, execution_flags);

Expand Down Expand Up @@ -191,7 +190,7 @@ impl<'a, S: StateReader> WorkerExecutor<'a, S> {
/// - Else (no room), do not commit. The block should be closed without the transaction.
/// * Else (execution failed), commit the transaction without fixing the call info or
/// updating the sequencer balance.
fn commit_tx(&self, tx_index: TxIndex) -> bool {
fn commit_tx(&self, tx_index: TxIndex, charge_fee: bool) -> bool {
let execution_output = lock_mutex_in_array(&self.execution_outputs, tx_index);
let execution_output_ref = execution_output.as_ref().expect(EXECUTION_OUTPUTS_UNWRAP_ERROR);
let reads = &execution_output_ref.reads;
Expand All @@ -209,7 +208,7 @@ impl<'a, S: StateReader> WorkerExecutor<'a, S> {
// Release the execution output lock as it is acquired in execution (avoid dead-lock).
drop(execution_output);

self.execute_tx(tx_index);
self.execute_tx(tx_index, charge_fee);
self.scheduler.finish_execution_during_commit(tx_index);

let execution_output = lock_mutex_in_array(&self.execution_outputs, tx_index);
Expand Down
Loading

0 comments on commit 511d481

Please sign in to comment.