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

Commit

Permalink
feat(fee): add gas cost for code bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
avi-starkware committed Feb 11, 2024
1 parent 2139251 commit b7312bf
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 14 deletions.
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

0 comments on commit b7312bf

Please sign in to comment.