Skip to content

Commit

Permalink
feat(blockifier): add n_allocated_aliases to tx receipt
Browse files Browse the repository at this point in the history
  • Loading branch information
yoavGrs committed Nov 14, 2024
1 parent 5659c9c commit 57d134d
Show file tree
Hide file tree
Showing 13 changed files with 132 additions and 24 deletions.
1 change: 1 addition & 0 deletions crates/blockifier/src/blockifier/stateful_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ impl<S: StateReader> StatefulValidator<S> {
&execution_resources,
CallInfo::summarize_many(validate_call_info.iter()),
0,
0,
);

Ok((validate_call_info, tx_receipt))
Expand Down
1 change: 1 addition & 0 deletions crates/blockifier/src/execution.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod alias_keys;
pub mod call_info;
pub mod common_hints;
pub mod contract_address;
Expand Down
11 changes: 11 additions & 0 deletions crates/blockifier/src/execution/alias_keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use crate::state::cached_state::{CachedState, StateChanges};
use crate::state::state_api::{StateReader, StateResult};

/// Returns the number of aliases we charge the transaction for.
pub fn n_charged_invoke_aliases<S: StateReader>(
_state: &CachedState<S>,
_state_changes: &StateChanges,
) -> StateResult<usize> {
// TODO: Implement this function
Ok(0)
}
5 changes: 5 additions & 0 deletions crates/blockifier/src/fee/gas_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ pub fn get_onchain_data_segment_length(state_changes_count: &StateChangesCount)
state_changes_count.n_class_hash_updates * constants::CLASS_UPDATE_SIZE;
// For each modified storage cell: key, new value.
onchain_data_segment_length += state_changes_count.n_storage_updates * 2;
// For each modified alias storage cell: key, new value.
onchain_data_segment_length += state_changes_count.n_allocated_leaves_for_fee * 2;
// For each compiled class updated (through declare): class_hash, compiled_class_hash
onchain_data_segment_length += state_changes_count.n_compiled_class_hash_updates * 2;

Expand Down Expand Up @@ -170,19 +172,22 @@ pub fn estimate_minimal_gas_vector(
n_class_hash_updates: 0,
n_compiled_class_hash_updates: 0,
n_modified_contracts: 1,
n_allocated_leaves_for_fee: 0,
},
Transaction::Invoke(_) => StateChangesCount {
n_storage_updates: 1,
n_class_hash_updates: 0,
n_compiled_class_hash_updates: 0,
n_modified_contracts: 1,
n_allocated_leaves_for_fee: 0,
},
// DeployAccount also updates the address -> class hash mapping.
Transaction::DeployAccount(_) => StateChangesCount {
n_storage_updates: 1,
n_class_hash_updates: 1,
n_compiled_class_hash_updates: 0,
n_modified_contracts: 1,
n_allocated_leaves_for_fee: 0,
},
};

Expand Down
6 changes: 6 additions & 0 deletions crates/blockifier/src/fee/gas_usage_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ fn starknet_resources() -> StarknetResources {
n_class_hash_updates: 11,
n_compiled_class_hash_updates: 13,
n_modified_contracts: 17,
n_allocated_leaves_for_fee: 0,
});
StarknetResources::new(2_usize, 3_usize, 4_usize, state_resources, 6.into(), execution_summary)
}
Expand Down Expand Up @@ -166,32 +167,37 @@ fn test_get_event_gas_cost(
n_class_hash_updates:0,
n_compiled_class_hash_updates:0,
n_modified_contracts:0,
n_allocated_leaves_for_fee: 0,
})
]
#[case::deploy_account(StateChangesCount {
n_storage_updates: 0,
n_class_hash_updates:1,
n_compiled_class_hash_updates:0,
n_modified_contracts:1,
n_allocated_leaves_for_fee: 1,
})
]
#[case::declare(StateChangesCount {
n_storage_updates: 0,
n_class_hash_updates:0,
n_compiled_class_hash_updates:1,
n_modified_contracts:0,
n_allocated_leaves_for_fee: 1,
})
]
#[case::general_scenario(StateChangesCount {
n_storage_updates: 7,
n_class_hash_updates:11,
n_compiled_class_hash_updates:13,
n_modified_contracts:17,
n_allocated_leaves_for_fee: 19,
})
]
fn test_get_da_gas_cost_basic(#[case] state_changes_count: StateChangesCount) {
// Manual calculation.
let on_chain_data_segment_length = state_changes_count.n_storage_updates * 2
+ state_changes_count.n_allocated_leaves_for_fee * 2
+ state_changes_count.n_class_hash_updates
+ state_changes_count.n_compiled_class_hash_updates * 2
+ state_changes_count.n_modified_contracts * 2;
Expand Down
12 changes: 11 additions & 1 deletion crates/blockifier/src/fee/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct TransactionReceiptParameters<'a> {
execution_resources: &'a ExecutionResources,
tx_type: TransactionType,
reverted_steps: usize,
n_allocated_leaves_for_fee: usize,
}

// TODO(Gilad): Use everywhere instead of passing the `actual_{fee,resources}` tuple, which often
Expand Down Expand Up @@ -61,13 +62,19 @@ impl TransactionReceipt {
execution_resources,
tx_type,
reverted_steps,
n_allocated_leaves_for_fee,
} = tx_receipt_params;

let starknet_resources = StarknetResources::new(
calldata_length,
signature_length,
code_size,
StateResources::new(state_changes, sender_address, tx_context.fee_token_address()),
StateResources::new(
state_changes,
sender_address,
tx_context.fee_token_address(),
n_allocated_leaves_for_fee,
),
l1_handler_payload_size,
execution_summary_without_fee_transfer,
);
Expand Down Expand Up @@ -128,6 +135,7 @@ impl TransactionReceipt {
execution_resources,
tx_type: TransactionType::L1Handler,
reverted_steps: 0,
n_allocated_leaves_for_fee: 0,
})
}

Expand All @@ -139,6 +147,7 @@ impl TransactionReceipt {
execution_resources: &'a ExecutionResources,
execution_summary_without_fee_transfer: ExecutionSummary,
reverted_steps: usize,
n_allocated_leaves_for_fee: usize,
) -> Self {
Self::from_params(TransactionReceiptParameters {
tx_context,
Expand All @@ -152,6 +161,7 @@ impl TransactionReceipt {
execution_resources,
tx_type: account_tx.tx_type(),
reverted_steps,
n_allocated_leaves_for_fee,
})
}
}
6 changes: 6 additions & 0 deletions crates/blockifier/src/fee/receipt_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
n_class_hash_updates: 1,
n_compiled_class_hash_updates: 0,
n_modified_contracts: 1,
n_allocated_leaves_for_fee: 0,
};

// Manual calculation.
Expand Down Expand Up @@ -224,6 +225,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
n_class_hash_updates: 0,
n_compiled_class_hash_updates: 0,
n_modified_contracts: 1,
n_allocated_leaves_for_fee: 0,
};
let l2_to_l1_starknet_resources = StarknetResources::new(
0,
Expand Down Expand Up @@ -271,6 +273,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
n_class_hash_updates: 0,
n_compiled_class_hash_updates: 0,
n_modified_contracts,
n_allocated_leaves_for_fee: 0,
};
let storage_writes_starknet_resources = StarknetResources::new(
0,
Expand Down Expand Up @@ -300,6 +303,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
n_compiled_class_hash_updates: 0,
n_modified_contracts: storage_writes_state_changes_count.n_modified_contracts
+ l2_to_l1_state_changes_count.n_modified_contracts,
n_allocated_leaves_for_fee: 0,
};
let combined_cases_starknet_resources = StarknetResources::new(
l1_handler_payload_size,
Expand Down Expand Up @@ -375,6 +379,7 @@ fn test_calculate_tx_gas_usage(
n_class_hash_updates: 0,
n_modified_contracts,
n_compiled_class_hash_updates: 0,
n_allocated_leaves_for_fee: 0,
};
let starknet_resources = StarknetResources::new(
calldata_length,
Expand Down Expand Up @@ -429,6 +434,7 @@ fn test_calculate_tx_gas_usage(
n_class_hash_updates: 0,
n_modified_contracts,
n_compiled_class_hash_updates: 0,
n_allocated_leaves_for_fee: 0,
};
let execution_call_info =
&tx_execution_info.execute_call_info.expect("Execution call info should exist.");
Expand Down
8 changes: 6 additions & 2 deletions crates/blockifier/src/fee/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,14 @@ impl StateResources {
state_changes: &StateChanges,
sender_address: Option<ContractAddress>,
fee_token_address: ContractAddress,
n_allocated_leaves_for_fee: usize,
) -> Self {
Self {
state_changes_for_fee: state_changes
.count_for_fee_charge(sender_address, fee_token_address),
state_changes_for_fee: state_changes.count_for_fee_charge(
sender_address,
fee_token_address,
n_allocated_leaves_for_fee,
),
}
}

Expand Down
4 changes: 4 additions & 0 deletions crates/blockifier/src/state/cached_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,7 @@ impl StateChangesKeys {
n_class_hash_updates: self.class_hash_keys.len(),
n_compiled_class_hash_updates: self.compiled_class_hash_keys.len(),
n_modified_contracts: self.modified_contracts.len(),
n_allocated_leaves_for_fee: 0,
}
}

Expand Down Expand Up @@ -687,6 +688,7 @@ impl StateChanges {
&self,
sender_address: Option<ContractAddress>,
fee_token_address: ContractAddress,
n_allocated_leaves_for_fee: usize,
) -> StateChangesCount {
let mut modified_contracts = self.get_modified_contracts();

Expand All @@ -712,6 +714,7 @@ impl StateChanges {
n_class_hash_updates: self.0.class_hashes.len(),
n_compiled_class_hash_updates: self.0.compiled_class_hashes.len(),
n_modified_contracts: modified_contracts.len(),
n_allocated_leaves_for_fee,
}
}

Expand Down Expand Up @@ -740,4 +743,5 @@ pub struct StateChangesCount {
pub n_class_hash_updates: usize,
pub n_compiled_class_hash_updates: usize,
pub n_modified_contracts: usize,
pub n_allocated_leaves_for_fee: usize,
}
11 changes: 9 additions & 2 deletions crates/blockifier/src/state/cached_state_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,19 @@ fn test_from_state_changes_for_fee_charge(
let fee_token_address = contract_address!("0x17");
let state_changes =
create_state_changes_for_test(&mut state, sender_address, fee_token_address);
let state_changes_count = state_changes.count_for_fee_charge(sender_address, fee_token_address);
let n_allocated_leaves_for_fee = 5;
let state_changes_count = state_changes.count_for_fee_charge(
sender_address,
fee_token_address,
n_allocated_leaves_for_fee,
);
let expected_state_changes_count = StateChangesCount {
// 1 for storage update + 1 for sender balance update if sender is defined.
n_storage_updates: 1 + usize::from(sender_address.is_some()),
n_class_hash_updates: 1,
n_compiled_class_hash_updates: 1,
n_modified_contracts: 2,
n_allocated_leaves_for_fee,
};
assert_eq!(state_changes_count, expected_state_changes_count);
}
Expand Down Expand Up @@ -516,7 +522,8 @@ fn test_state_changes_keys() {
n_storage_updates: 2,
n_class_hash_updates: 1,
n_compiled_class_hash_updates: 2,
n_modified_contracts: 2
n_modified_contracts: 2,
n_allocated_leaves_for_fee: 0,
}
);

Expand Down
46 changes: 39 additions & 7 deletions crates/blockifier/src/transaction/account_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, Nonce};
use starknet_api::data_availability::DataAvailabilityMode;
use starknet_api::executable_transaction::{
AccountTransaction as Transaction,
AccountTransaction as ExecutableAccountTransaction,
DeclareTransaction,
DeployAccountTransaction,
InvokeTransaction,
Expand All @@ -28,6 +29,7 @@ use starknet_types_core::felt::Felt;

use crate::abi::abi_utils::selector_from_name;
use crate::context::{BlockContext, TransactionContext};
use crate::execution::alias_keys::n_charged_invoke_aliases;
use crate::execution::call_info::CallInfo;
use crate::execution::contract_class::RunnableContractClass;
use crate::execution::entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext};
Expand All @@ -41,8 +43,8 @@ use crate::fee::fee_utils::{
use crate::fee::gas_usage::estimate_minimal_gas_vector;
use crate::fee::receipt::TransactionReceipt;
use crate::retdata;
use crate::state::cached_state::{StateChanges, TransactionalState};
use crate::state::state_api::{State, StateReader, UpdatableState};
use crate::state::cached_state::{CachedState, StateChanges, TransactionalState};
use crate::state::state_api::{State, StateReader, StateResult, UpdatableState};
use crate::transaction::constants;
use crate::transaction::errors::{
TransactionExecutionError,
Expand Down Expand Up @@ -595,13 +597,17 @@ impl AccountTransaction {
self.run_execute(state, &mut resources, &mut execution_context, remaining_gas)?;
}

let state_changes = state.get_actual_state_changes()?;
let n_allocated_leaves_for_fee =
self.n_charged_aliases(tx_context.clone(), state, &state_changes)?;
let tx_receipt = TransactionReceipt::from_account_tx(
self,
&tx_context,
&state.get_actual_state_changes()?,
&state_changes,
&resources,
CallInfo::summarize_many(validate_call_info.iter().chain(execute_call_info.iter())),
0,
n_allocated_leaves_for_fee,
);

let post_execution_report =
Expand Down Expand Up @@ -669,24 +675,29 @@ impl AccountTransaction {
&resources,
CallInfo::summarize_many(validate_call_info.iter()),
execution_steps_consumed,
0,
);

match execution_result {
Ok(execute_call_info) => {
let execution_state_changes = execution_state.get_actual_state_changes()?;
let n_allocated_leaves_for_fee = self.n_charged_aliases(
tx_context.clone(),
&execution_state,
&execution_state_changes,
)?;
// When execution succeeded, calculate the actual required fee before committing the
// transactional state. If max_fee is insufficient, revert the `run_execute` part.
let tx_receipt = TransactionReceipt::from_account_tx(
self,
&tx_context,
&StateChanges::merge(vec![
validate_state_changes,
execution_state.get_actual_state_changes()?,
]),
&StateChanges::merge(vec![validate_state_changes, execution_state_changes]),
&execution_resources,
CallInfo::summarize_many(
validate_call_info.iter().chain(execute_call_info.iter()),
),
0,
n_allocated_leaves_for_fee,
);
// Post-execution checks.
let post_execution_report = PostExecutionReport::new(
Expand Down Expand Up @@ -773,6 +784,27 @@ impl AccountTransaction {

self.run_revertible(state, tx_context, remaining_gas, validate, charge_fee)
}

fn n_charged_aliases<S: StateReader>(
&self,
tx_context: Arc<TransactionContext>,
state: &CachedState<S>,
state_changes: &StateChanges,
) -> StateResult<usize> {
if tx_context.as_ref().block_context.versioned_constants.enable_stateful_compression {
Ok(match self.tx {
// Charge for introducing a new class hash.
ExecutableAccountTransaction::Declare(_) => 1,
// Charge for introducing a new contract address.
ExecutableAccountTransaction::DeployAccount(_) => 1,
ExecutableAccountTransaction::Invoke(_) => {
n_charged_invoke_aliases(state, state_changes)?
}
})
} else {
Ok(0)
}
}
}

impl<U: UpdatableState> ExecutableTransaction<U> for AccountTransaction {
Expand Down
Loading

0 comments on commit 57d134d

Please sign in to comment.