Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blockifier): compute allocation cost #2301

Merged
merged 1 commit into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/blockifier/src/fee/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl TransactionReceipt {
let da_gas = tx_resources
.starknet_resources
.state
.to_gas_vector(tx_context.block_context.block_info.use_kzg_da);
.da_gas_vector(tx_context.block_context.block_info.use_kzg_da);

Self { resources: tx_resources, gas, da_gas, fee }
}
Expand Down
35 changes: 26 additions & 9 deletions crates/blockifier/src/fee/receipt_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ fn test_calculate_tx_gas_usage_basic<'a>(
GasVectorComputationMode::All => GasVector::from_l2_gas(calldata_and_signature_gas_cost),
};
let manual_gas_vector = manual_starknet_gas_usage_vector
+ deploy_account_tx_starknet_resources.state.to_gas_vector(use_kzg_da);
+ deploy_account_tx_starknet_resources
.state
.to_gas_vector(use_kzg_da, &versioned_constants.allocation_cost);

let deploy_account_gas_usage_vector = deploy_account_tx_starknet_resources.to_gas_vector(
&versioned_constants,
Expand Down Expand Up @@ -249,10 +251,18 @@ fn test_calculate_tx_gas_usage_basic<'a>(
.unwrap();
let manual_sharp_gas_usage = message_segment_length
* eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD
+ usize_from_u64(l2_to_l1_starknet_resources.state.to_gas_vector(use_kzg_da).l1_gas.0)
.unwrap();
let manual_sharp_blob_gas_usage =
l2_to_l1_starknet_resources.state.to_gas_vector(use_kzg_da).l1_data_gas;
+ usize_from_u64(
l2_to_l1_starknet_resources
.state
.to_gas_vector(use_kzg_da, &versioned_constants.allocation_cost)
.l1_gas
.0,
)
.unwrap();
let manual_sharp_blob_gas_usage = l2_to_l1_starknet_resources
.state
.to_gas_vector(use_kzg_da, &versioned_constants.allocation_cost)
.l1_data_gas;
let manual_gas_computation = GasVector {
l1_gas: u64_from_usize(manual_starknet_gas_usage + manual_sharp_gas_usage).into(),
l1_data_gas: manual_sharp_blob_gas_usage,
Expand Down Expand Up @@ -288,7 +298,9 @@ fn test_calculate_tx_gas_usage_basic<'a>(

// Manual calculation.
// No L2 gas is used, so gas amount does not depend on gas vector computation mode.
let manual_gas_computation = storage_writes_starknet_resources.state.to_gas_vector(use_kzg_da);
let manual_gas_computation = storage_writes_starknet_resources
.state
.to_gas_vector(use_kzg_da, &versioned_constants.allocation_cost);

assert_eq!(manual_gas_computation, storage_writings_gas_usage_vector);

Expand Down Expand Up @@ -334,7 +346,10 @@ fn test_calculate_tx_gas_usage_basic<'a>(
// the combined calculation got it once.
+ u64_from_usize(fee_balance_discount).into(),
// Expected blob gas usage is from data availability only.
l1_data_gas: combined_cases_starknet_resources.state.to_gas_vector(use_kzg_da).l1_data_gas,
l1_data_gas: combined_cases_starknet_resources
.state
.to_gas_vector(use_kzg_da, &versioned_constants.allocation_cost)
.l1_data_gas,
l2_gas: l1_handler_gas_usage_vector.l2_gas,
};

Expand Down Expand Up @@ -378,11 +393,12 @@ fn test_calculate_tx_gas_usage(
n_modified_contracts,
n_compiled_class_hash_updates: 0,
};
let n_allocated_keys = 0; // This tx doesn't allocate the account balance.
let starknet_resources = StarknetResources::new(
calldata_length,
signature_length,
0,
StateResources::new_for_testing(state_changes_count, 0),
StateResources::new_for_testing(state_changes_count, n_allocated_keys),
None,
ExecutionSummary::default(),
);
Expand Down Expand Up @@ -432,6 +448,7 @@ fn test_calculate_tx_gas_usage(
n_modified_contracts,
n_compiled_class_hash_updates: 0,
};
let n_allocated_keys = 1; // Only for the recipient.
let execution_call_info =
&tx_execution_info.execute_call_info.expect("Execution call info should exist.");
let execution_summary =
Expand All @@ -440,7 +457,7 @@ fn test_calculate_tx_gas_usage(
calldata_length,
signature_length,
0,
StateResources::new_for_testing(state_changes_count, 0),
StateResources::new_for_testing(state_changes_count, n_allocated_keys),
None,
// The transfer entrypoint emits an event - pass the call info to count its resources.
execution_summary,
Expand Down
31 changes: 26 additions & 5 deletions crates/blockifier/src/fee/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::fee::gas_usage::{
use crate::state::cached_state::{StateChanges, StateChangesCountForFee};
use crate::transaction::errors::TransactionFeeError;
use crate::utils::u64_from_usize;
use crate::versioned_constants::{ArchivalDataGasCosts, VersionedConstants};
use crate::versioned_constants::{AllocationCost, ArchivalDataGasCosts, VersionedConstants};

pub type TransactionFeeResult<T> = Result<T, TransactionFeeError>;

Expand Down Expand Up @@ -139,7 +139,7 @@ impl StarknetResources {
) -> GasVector {
[
self.archival_data.to_gas_vector(versioned_constants, mode),
self.state.to_gas_vector(use_kzg_da),
self.state.to_gas_vector(use_kzg_da, &versioned_constants.allocation_cost),
self.messages.to_gas_vector(),
]
.iter()
Expand Down Expand Up @@ -186,9 +186,30 @@ impl StateResources {
}

/// Returns the gas cost of the transaction's state changes.
pub fn to_gas_vector(&self, use_kzg_da: bool) -> GasVector {
// TODO(Nimrod, 29/3/2024): delete `get_da_gas_cost` and move it's logic here.
// TODO(Yoav): Add the cost of allocating keys.
pub fn to_gas_vector(&self, use_kzg_da: bool, allocation_cost: &AllocationCost) -> GasVector {
let n_allocated_keys: u64 = self
.state_changes_for_fee
.n_allocated_keys
.try_into()
.expect("n_allocated_keys overflowed");
let allocation_gas_vector = allocation_cost.get_cost(use_kzg_da);
let total_allocation_cost =
allocation_gas_vector.checked_scalar_mul(n_allocated_keys).unwrap_or_else(|| {
panic!(
"State resources to gas vector overflowed: tried to multiply \
{allocation_gas_vector:?} by {n_allocated_keys:?}",
)
});
let da_gas_cost = self.da_gas_vector(use_kzg_da);
total_allocation_cost.checked_add(da_gas_cost).unwrap_or_else(|| {
panic!(
"State resources to gas vector overflowed: tried to add {total_allocation_cost:?} \
to {da_gas_cost:?}",
)
})
}

pub fn da_gas_vector(&self, use_kzg_da: bool) -> GasVector {
get_da_gas_cost(&self.state_changes_for_fee.state_changes_count, use_kzg_da)
}

Expand Down
4 changes: 3 additions & 1 deletion crates/blockifier/src/transaction/execution_flavors_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use crate::transaction::test_utils::{
use crate::transaction::transaction_types::TransactionType;
use crate::transaction::transactions::ExecutableTransaction;
use crate::utils::u64_from_usize;
use crate::versioned_constants::AllocationCost;
const VALIDATE_GAS_OVERHEAD: GasAmount = GasAmount(21);

struct FlavorTestInitialState {
Expand Down Expand Up @@ -714,7 +715,8 @@ fn test_simulate_validate_charge_fee_post_execution(
#[case] fee_type: FeeType,
#[case] is_deprecated: bool,
) {
let block_context = BlockContext::create_for_account_testing();
let mut block_context = BlockContext::create_for_account_testing();
block_context.versioned_constants.allocation_cost = AllocationCost::ZERO;
let gas_price = block_context.block_info.gas_prices.l1_gas_price(&fee_type);
let chain_info = &block_context.chain_info;
let fee_token_address = chain_info.fee_token_address(&fee_type);
Expand Down
5 changes: 4 additions & 1 deletion crates/blockifier/src/transaction/post_execution_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ use crate::transaction::test_utils::{
TestInitData,
};
use crate::transaction::transactions::ExecutableTransaction;
use crate::versioned_constants::AllocationCost;

fn init_data_by_version(chain_info: &ChainInfo, cairo_version: CairoVersion) -> TestInitData {
let test_contract = FeatureContract::TestContract(cairo_version);
Expand Down Expand Up @@ -87,11 +88,12 @@ fn calldata_for_write_and_transfer(
fn test_revert_on_overdraft(
max_fee: Fee,
default_all_resource_bounds: ValidResourceBounds,
block_context: BlockContext,
mut block_context: BlockContext,
#[case] version: TransactionVersion,
#[case] fee_type: FeeType,
#[values(CairoVersion::Cairo0)] cairo_version: CairoVersion,
) {
block_context.versioned_constants.allocation_cost = AllocationCost::ZERO;
let chain_info = &block_context.chain_info;
let fee_token_address = chain_info.fee_token_addresses.get_by_fee_type(&fee_type);
// An address to be written into to observe state changes.
Expand Down Expand Up @@ -268,6 +270,7 @@ fn test_revert_on_resource_overuse(
#[values(CairoVersion::Cairo0)] cairo_version: CairoVersion,
) {
block_context.block_info.use_kzg_da = true;
block_context.versioned_constants.allocation_cost = AllocationCost::ZERO;
let gas_mode = resource_bounds.get_gas_vector_computation_mode();
let fee_type = if version == TransactionVersion::THREE { FeeType::Strk } else { FeeType::Eth };
let gas_prices = block_context.block_info.gas_prices.gas_price_vector(&fee_type);
Expand Down
11 changes: 6 additions & 5 deletions crates/blockifier/src/transaction/transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ use crate::transaction::test_utils::{
};
use crate::transaction::transaction_types::TransactionType;
use crate::transaction::transactions::ExecutableTransaction;
use crate::versioned_constants::VersionedConstants;
use crate::versioned_constants::{AllocationCost, VersionedConstants};
use crate::{
check_tx_execution_error_for_custom_hint,
check_tx_execution_error_for_invalid_scenario,
Expand Down Expand Up @@ -553,7 +553,7 @@ fn test_invoke_tx(
FeatureContract::ERC20(CairoVersion::Cairo0).get_class_hash(),
);

let da_gas = starknet_resources.state.to_gas_vector(use_kzg_da);
let da_gas = starknet_resources.state.da_gas_vector(use_kzg_da);

let expected_cairo_resources = get_expected_cairo_resources(
versioned_constants,
Expand Down Expand Up @@ -1286,6 +1286,7 @@ fn test_actual_fee_gt_resource_bounds(
#[values(CairoVersion::Cairo0, CairoVersion::Cairo1)] account_cairo_version: CairoVersion,
) {
let block_context = &mut block_context;
block_context.versioned_constants.allocation_cost = AllocationCost::ZERO;
block_context.block_info.use_kzg_da = true;
let mut nonce_manager = NonceManager::default();
let gas_mode = resource_bounds.get_gas_vector_computation_mode();
Expand Down Expand Up @@ -1563,7 +1564,7 @@ fn test_declare_tx(
)
};

let da_gas = starknet_resources.state.to_gas_vector(use_kzg_da);
let da_gas = starknet_resources.state.da_gas_vector(use_kzg_da);
let expected_cairo_resources = get_expected_cairo_resources(
versioned_constants,
TransactionType::Declare,
Expand Down Expand Up @@ -2291,10 +2292,10 @@ fn test_l1_handler(#[values(false, true)] use_kzg_da: bool) {
let expected_gas = match use_kzg_da {
true => GasVector {
l1_gas: 17988_u32.into(),
l1_data_gas: 128_u32.into(),
l1_data_gas: 160_u32.into(),
l2_gas: 0_u32.into(),
},
false => GasVector::from_l1_gas(19131_u32.into()),
false => GasVector::from_l1_gas(19682_u32.into()),
};

let expected_da_gas = match use_kzg_da {
Expand Down
Loading