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

feat(fee): add gas cost for code bytes #1475

Merged
merged 1 commit into from
Feb 11, 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
1 change: 1 addition & 0 deletions crates/blockifier/src/fee/actual_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ impl<'a> ActualCostBuilder<'a> {
self.calldata_length,
self.signature_length,
self.l1_payload_size,
self.class_info,
use_kzg_da,
)?;

Expand Down
28 changes: 27 additions & 1 deletion crates/blockifier/src/fee/gas_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::transaction::objects::{
GasVector, HasRelatedFeeType, ResourcesMapping, TransactionExecutionResult,
TransactionPreValidationResult,
};
use crate::transaction::transactions::ClassInfo;
use crate::utils::{u128_from_usize, usize_from_u128};
use crate::versioned_constants::VersionedConstants;

Expand All @@ -22,13 +23,15 @@ pub mod test;
/// the Verifier) following the addition of a transaction with the given parameters to a batch;
/// e.g., a message from L2 to L1 is followed by a storage write operation in Starknet L1 contract
/// which requires gas.
#[allow(clippy::too_many_arguments)]
pub fn calculate_tx_gas_usage_vector<'a>(
versioned_constants: &VersionedConstants,
call_infos: impl Iterator<Item = &'a CallInfo>,
state_changes_count: StateChangesCount,
calldata_length: usize,
signature_length: usize,
l1_handler_payload_size: Option<usize>,
class_info: Option<ClassInfo>,
use_kzg_da: bool,
) -> TransactionExecutionResult<GasVector> {
Ok(calculate_messages_gas_vector(call_infos, l1_handler_payload_size)?
Expand All @@ -37,7 +40,8 @@ pub fn calculate_tx_gas_usage_vector<'a>(
calldata_length,
signature_length,
versioned_constants,
))
)
+ get_code_gas_cost(class_info, versioned_constants))
}

/// Returns an estimation of the gas usage for processing L1<>L2 messages on L1. Accounts for both
Expand Down Expand Up @@ -98,6 +102,28 @@ pub fn get_calldata_and_signature_gas_cost(
GasVector { l1_gas: l1_milligas / 1000, l1_data_gas: 0 }
}

// Returns the gas cost of class information added to L2 via a Declare transaction. Each code felt
// costs a fixed and configurable amount of gas. The cost is 0 for non-Declare transactions.
pub fn get_code_gas_cost(
class_info: Option<ClassInfo>,
versioned_constants: &VersionedConstants,
) -> GasVector {
if let Some(class_info) = class_info {
let total_code_size = u128_from_usize(
(class_info.bytecode_length() + class_info.sierra_program_length)
// We assume each felt is a word.
* eth_gas_constants::WORD_WIDTH
+ class_info.abi_length,
)
.expect("Failed to convert total code size from usize to u128.");
let l1_milligas =
total_code_size * versioned_constants.l2_resource_gas_costs.milligas_per_code_byte;
GasVector { l1_gas: l1_milligas / 1000, l1_data_gas: 0 }
} else {
GasVector { l1_gas: 0, l1_data_gas: 0 }
}
}

/// Returns the number of felts added to the output data availability segment as a result of adding
/// a transaction to a batch. Note that constant cells - such as the one that holds the number of
/// modified contracts - are not counted.
Expand Down
54 changes: 45 additions & 9 deletions crates/blockifier/src/fee/gas_usage_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use crate::fee::gas_usage::{
get_log_message_to_l1_emissions_cost, get_message_segment_length,
};
use crate::state::cached_state::StateChangesCount;
use crate::test_utils::contracts::FeatureContract;
use crate::test_utils::CairoVersion;
use crate::transaction::objects::GasVector;
use crate::transaction::test_utils::calculate_class_info_for_testing;
use crate::utils::{u128_from_usize, usize_from_u128};
use crate::versioned_constants::VersionedConstants;

Expand Down Expand Up @@ -62,13 +65,14 @@ fn test_get_da_gas_cost_basic(#[case] state_changes_count: StateChangesCount) {

/// This test goes over six cases. In each case, we calculate the gas usage given the parameters.
/// We then perform the same calculation manually, each time using only the relevant parameters.
/// The six cases are:
/// The seven cases are:
/// 1. An empty transaction.
/// 2. A DeployAccount transaction.
/// 3. An L1 handler.
/// 4. A transaction with L2-to-L1 messages.
/// 5. A transaction that modifies the storage.
/// 6. A combination of cases 3. 4. and 5.
/// 2. A Declare transaction.
/// 3. A DeployAccount transaction.
/// 4. An L1 handler.
/// 5. A transaction with L2-to-L1 messages.
/// 6. A transaction that modifies the storage.
/// 7. A combination of cases 4. 5. and 6.
// TODO(Aner, 29/01/24) Refactor with assert on GasVector objects.
// TODO(Aner, 29/01/24) Refactor to replace match with if when formatting is nicer
#[rstest]
Expand All @@ -82,11 +86,39 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
0,
0,
None,
None,
use_kzg_da,
)
.unwrap();
assert_eq!(empty_tx_gas_usage_vector, GasVector { l1_gas: 0, l1_data_gas: 0 });

// Declare.
for cairo_version in [CairoVersion::Cairo0, CairoVersion::Cairo1] {
let empty_contract = FeatureContract::Empty(cairo_version).get_class();
let class_info = calculate_class_info_for_testing(cairo_version, empty_contract);
let code_milligas_cost = u128_from_usize(
(class_info.bytecode_length() + class_info.sierra_program_length)
* eth_gas_constants::WORD_WIDTH
+ class_info.abi_length,
)
.unwrap()
* versioned_constants.l2_resource_gas_costs.milligas_per_code_byte;
let manual_gas_vector =
GasVector { l1_gas: code_milligas_cost / 1000, ..Default::default() };
let declare_gas_usage_vector = calculate_tx_gas_usage_vector(
&versioned_constants,
std::iter::empty(),
StateChangesCount::default(),
0,
0,
None,
Some(class_info),
use_kzg_da,
)
.unwrap();
assert_eq!(manual_gas_vector, declare_gas_usage_vector);
}

// DeployAccount.

let deploy_account_state_changes_count = StateChangesCount {
Expand All @@ -97,15 +129,14 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
};

// Manual calculation.
let manual_starknet_gas_usage = 0;
let calldata_length = 0;
let signature_length = 2;
let calldata_and_signature_milligas_cost = u128_from_usize(calldata_length + signature_length)
.unwrap()
* versioned_constants.l2_resource_gas_costs.milligas_per_data_felt;
let manual_starknet_gas_usage = calldata_and_signature_milligas_cost / 1000;
let manual_gas_vector = GasVector { l1_gas: manual_starknet_gas_usage, ..Default::default() }
+ get_da_gas_cost(deploy_account_state_changes_count, use_kzg_da)
+ GasVector { l1_gas: calldata_and_signature_milligas_cost / 1000, l1_data_gas: 0 };
+ get_da_gas_cost(deploy_account_state_changes_count, use_kzg_da);

let deploy_account_gas_usage_vector = calculate_tx_gas_usage_vector(
&versioned_constants,
Expand All @@ -114,6 +145,7 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
calldata_length,
signature_length,
None,
None,
use_kzg_da,
)
.unwrap();
Expand All @@ -129,6 +161,7 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
l1_handler_payload_size,
signature_length,
Some(l1_handler_payload_size),
None,
use_kzg_da,
)
.unwrap();
Expand Down Expand Up @@ -198,6 +231,7 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
0,
0,
None,
None,
use_kzg_da,
)
.unwrap();
Expand Down Expand Up @@ -239,6 +273,7 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
0,
0,
None,
None,
use_kzg_da,
)
.unwrap();
Expand All @@ -263,6 +298,7 @@ fn test_calculate_tx_gas_usage_basic(#[values(false, true)] use_kzg_da: bool) {
l1_handler_payload_size,
signature_length,
Some(l1_handler_payload_size),
None,
use_kzg_da,
)
.unwrap();
Expand Down
2 changes: 1 addition & 1 deletion crates/blockifier/src/transaction/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub struct ClassInfo {
}

impl ClassInfo {
fn _bytecode_length(&self) -> usize {
pub fn bytecode_length(&self) -> usize {
self.contract_class.bytecode_length()
}
}
Expand Down
11 changes: 8 additions & 3 deletions crates/blockifier/src/transaction/transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use crate::execution::execution_utils::{felt_to_stark_felt, stark_felt_to_felt};
use crate::fee::fee_utils::calculate_tx_fee;
use crate::fee::gas_usage::{
calculate_tx_gas_usage_vector, estimate_minimal_gas_vector,
get_calldata_and_signature_gas_cost, get_da_gas_cost,
get_calldata_and_signature_gas_cost, get_code_gas_cost, get_da_gas_cost,
};
use crate::state::cached_state::{CachedState, StateChangesCount};
use crate::state::errors::StateError;
Expand Down Expand Up @@ -1083,6 +1083,7 @@ fn test_declare_tx(
#[values(false, true)] use_kzg_da: bool,
) {
let block_context = &BlockContext::create_for_account_testing_with_kzg(use_kzg_da);
let versioned_constants = &block_context.versioned_constants;
let empty_contract = FeatureContract::Empty(empty_contract_version);
let account = FeatureContract::AccountWithoutValidations(account_cairo_version);
let chain_info = &block_context.chain_info;
Expand Down Expand Up @@ -1133,6 +1134,8 @@ fn test_declare_tx(
);

let da_gas = declare_expected_gas_vector(tx_version, use_kzg_da);
let code_gas: GasVector = get_code_gas_cost(Some(class_info.clone()), versioned_constants);
let gas_usage = code_gas + da_gas.clone();

let expected_execution_info = TransactionExecutionInfo {
validate_call_info: expected_validate_call_info,
Expand All @@ -1142,8 +1145,8 @@ fn test_declare_tx(
da_gas: da_gas.clone(),
revert_error: None,
actual_resources: ResourcesMapping(HashMap::from([
(abi_constants::L1_GAS_USAGE.to_string(), da_gas.l1_gas.try_into().unwrap()),
(abi_constants::BLOB_GAS_USAGE.to_string(), da_gas.l1_data_gas.try_into().unwrap()),
(abi_constants::L1_GAS_USAGE.to_string(), gas_usage.l1_gas.try_into().unwrap()),
(abi_constants::BLOB_GAS_USAGE.to_string(), gas_usage.l1_data_gas.try_into().unwrap()),
(HASH_BUILTIN_NAME.to_string(), 16),
(
RANGE_CHECK_BUILTIN_NAME.to_string(),
Expand Down Expand Up @@ -1510,6 +1513,7 @@ fn test_calculate_tx_gas_usage(#[values(false, true)] use_kzg_da: bool) {
calldata_length,
signature_length,
None,
None,
use_kzg_da,
)
.unwrap();
Expand Down Expand Up @@ -1564,6 +1568,7 @@ fn test_calculate_tx_gas_usage(#[values(false, true)] use_kzg_da: bool) {
calldata_length,
signature_length,
None,
None,
use_kzg_da,
)
.unwrap();
Expand Down
Loading