Skip to content

Commit

Permalink
refactor(blockifier,starknet_api): gas amount is now a u64, not a u128
Browse files Browse the repository at this point in the history
  • Loading branch information
dorimedini-starkware committed Oct 9, 2024
1 parent 9f7dbdf commit 7a28708
Show file tree
Hide file tree
Showing 19 changed files with 192 additions and 137 deletions.
4 changes: 2 additions & 2 deletions crates/blockifier/src/bouncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::state::cached_state::{StateChangesKeys, StorageEntry};
use crate::state::state_api::StateReader;
use crate::transaction::errors::TransactionExecutionError;
use crate::transaction::objects::{ExecutionResourcesTraits, TransactionExecutionResult};
use crate::utils::usize_from_u128;
use crate::utils::usize_from_u64;

#[cfg(test)]
#[path = "bouncer_test.rs"]
Expand Down Expand Up @@ -346,7 +346,7 @@ pub fn get_tx_weights<S: StateReader>(
state_changes_keys: &StateChangesKeys,
) -> TransactionExecutionResult<BouncerWeights> {
let message_resources = &tx_resources.starknet_resources.messages;
let message_starknet_gas = usize_from_u128(message_resources.get_starknet_gas_cost().l1_gas.0)
let message_starknet_gas = usize_from_u64(message_resources.get_starknet_gas_cost().l1_gas.0)
.expect("This conversion should not fail as the value is a converted usize.");
let mut additional_os_resources =
get_casm_hash_calculation_resources(state_reader, executed_class_hashes)?;
Expand Down
15 changes: 5 additions & 10 deletions crates/blockifier/src/execution/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,10 @@ impl EntryPointExecutionContext {
// New transactions derive the step limit by the L1 gas resource bounds; deprecated
// transactions derive this value from the `max_fee`.
let tx_gas_upper_bound = match tx_info {
TransactionInfo::Deprecated(context) => {
context.max_fee
/ block_info.gas_prices.get_l1_gas_price_by_fee_type(&tx_info.fee_type())
}
// Fee is a larger uint type than GasAmount, so we need to saturate the division.
TransactionInfo::Deprecated(context) => context.max_fee.saturating_div(
block_info.gas_prices.get_l1_gas_price_by_fee_type(&tx_info.fee_type()),
),
TransactionInfo::Current(context) => context.l1_resource_bounds().max_amount.into(),
};

Expand All @@ -291,12 +291,7 @@ impl EntryPointExecutionContext {
let upper_bound_u64 = if gas_per_step.is_zero() {
u64::MAX
} else {
// TODO: This panic will disappear once GasAmount is a u64.
(gas_per_step.inv()
* u64::try_from(tx_gas_upper_bound.0).unwrap_or_else(|_| {
panic!("Gas amounts cannot be more than 64 bits; got {tx_gas_upper_bound:?}.")
}))
.to_integer()
(gas_per_step.inv() * tx_gas_upper_bound.0).to_integer()
};
let tx_upper_bound = usize_from_u64(upper_bound_u64).unwrap_or_else(|_| {
log::warn!(
Expand Down
48 changes: 36 additions & 12 deletions crates/blockifier/src/fee/fee_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use crate::test_utils::{
};
use crate::transaction::objects::FeeType;
use crate::transaction::test_utils::{account_invoke_tx, all_resource_bounds, l1_resource_bounds};
use crate::utils::{u128_from_usize, u64_from_usize};
use crate::utils::u64_from_usize;
use crate::versioned_constants::VersionedConstants;

#[rstest]
Expand Down Expand Up @@ -66,7 +66,7 @@ fn test_simple_get_vm_resource_usage(
let n_reverted_steps = 0;
vm_resource_usage.n_steps =
vm_resource_usage.builtin_instance_counter.get(&BuiltinName::range_check).unwrap() - 1;
let vm_usage_in_l1_gas = u128_from_usize(
let vm_usage_in_l1_gas = u64_from_usize(
*vm_resource_usage.builtin_instance_counter.get(&BuiltinName::range_check).unwrap(),
)
.into();
Expand Down Expand Up @@ -155,9 +155,9 @@ fn test_float_get_vm_resource_usage(
fn test_discounted_gas_overdraft(
#[case] gas_price: u128,
#[case] data_gas_price: u128,
#[case] l1_gas_used: u128,
#[case] l1_data_gas_used: u128,
#[case] gas_bound: u128,
#[case] l1_gas_used: u64,
#[case] l1_data_gas_used: u64,
#[case] gas_bound: u64,
#[case] expect_failure: bool,
) {
let (l1_gas_used, l1_data_gas_used, gas_bound) =
Expand Down Expand Up @@ -207,7 +207,9 @@ fn test_discounted_gas_overdraft(
if expect_failure {
let error = report.error().unwrap();
let expected_actual_amount = l1_gas_used
+ (l1_data_gas_used.nonzero_checked_mul(data_gas_price).unwrap()) / gas_price;
+ (l1_data_gas_used.nonzero_checked_mul(data_gas_price).unwrap())
.checked_div(gas_price)
.unwrap();
assert_matches!(
error, FeeCheckError::MaxGasAmountExceeded { resource, max_amount, actual_amount }
if max_amount == gas_bound
Expand Down Expand Up @@ -292,13 +294,10 @@ fn test_post_execution_gas_overdraft_all_resource_bounds(
#[case::happy_flow_l1_gas_only(10, 0, 0, 10, 2*10)]
#[case::happy_flow_no_l2_gas(10, 20, 0, 10 + 3*20, 2*10 + 4*20)]
#[case::happy_flow_all(10, 20, 30, 10 + 3*20 + 5*30, 2*10 + 4*20 + 6*30)]
#[case::saturating_l1_gas(u128::MAX, 1, 1, u128::MAX, u128::MAX)]
#[case::saturating_l1_data_gas(1, u128::MAX, 1, u128::MAX, u128::MAX)]
#[case::saturating_l2_gas(1, 1, u128::MAX, u128::MAX, u128::MAX)]
fn test_get_fee_by_gas_vector_regression(
#[case] l1_gas: u128,
#[case] l1_data_gas: u128,
#[case] l2_gas: u128,
#[case] l1_gas: u64,
#[case] l1_data_gas: u64,
#[case] l2_gas: u64,
#[case] expected_fee_eth: u128,
#[case] expected_fee_strk: u128,
) {
Expand All @@ -322,3 +321,28 @@ fn test_get_fee_by_gas_vector_regression(
Fee(expected_fee_strk)
);
}

#[rstest]
#[case::l1_saturates(u64::MAX, 0, 0)]
#[case::l1_data_saturates(0, u64::MAX, 0)]
#[case::l2_gas_saturates(0, 0, u64::MAX)]
// TODO: Add L2 saturation case once `get_fee_by_gas_vector` implements L2 collection.
fn test_get_fee_by_gas_vector_saturation(
#[case] l1_gas: u64,
#[case] l1_data_gas: u64,
#[case] l2_gas: u64,
) {
let huge_gas_price = NonzeroGasPrice::try_from(2_u128 * u128::from(u64::MAX)).unwrap();
let mut block_info = BlockContext::create_for_account_testing().block_info;
block_info.gas_prices = GasPrices::new(
huge_gas_price,
huge_gas_price,
huge_gas_price,
huge_gas_price,
huge_gas_price,
huge_gas_price,
);
let gas_vector =
GasVector { l1_gas: l1_gas.into(), l1_data_gas: l1_data_gas.into(), l2_gas: l2_gas.into() };
assert_eq!(get_fee_by_gas_vector(&block_info, gas_vector, &FeeType::Eth), Fee(u128::MAX));
}
8 changes: 4 additions & 4 deletions crates/blockifier/src/fee/gas_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::fee::eth_gas_constants;
use crate::fee::resources::GasVector;
use crate::state::cached_state::StateChangesCount;
use crate::transaction::account_transaction::AccountTransaction;
use crate::utils::u128_from_usize;
use crate::utils::u64_from_usize;

#[cfg(test)]
#[path = "gas_usage_test.rs"]
Expand Down Expand Up @@ -43,7 +43,7 @@ pub fn get_da_gas_cost(state_changes_count: &StateChangesCount, use_kzg_da: bool
let (l1_gas, blob_gas) = if use_kzg_da {
(
0_u8.into(),
u128_from_usize(
u64_from_usize(
onchain_data_segment_length * eth_gas_constants::DATA_GAS_PER_FIELD_ELEMENT,
)
.into(),
Expand Down Expand Up @@ -71,7 +71,7 @@ pub fn get_da_gas_cost(state_changes_count: &StateChangesCount, use_kzg_da: bool
naive_cost - discount
};

(u128_from_usize(gas).into(), 0_u8.into())
(u64_from_usize(gas).into(), 0_u8.into())
};

GasVector { l1_gas, l1_data_gas: blob_gas, ..Default::default() }
Expand Down Expand Up @@ -136,7 +136,7 @@ pub fn get_log_message_to_l1_emissions_cost(l2_to_l1_payload_lengths: &[usize])

fn get_event_emission_cost(n_topics: usize, data_length: usize) -> GasVector {
GasVector::from_l1_gas(
u128_from_usize(
u64_from_usize(
eth_gas_constants::GAS_PER_LOG
+ (n_topics + constants::N_DEFAULT_TOPICS) * eth_gas_constants::GAS_PER_LOG_TOPIC
+ data_length * eth_gas_constants::GAS_PER_LOG_DATA_WORD,
Expand Down
15 changes: 7 additions & 8 deletions crates/blockifier/src/fee/gas_usage_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use crate::test_utils::{
};
use crate::transaction::objects::FeeType;
use crate::transaction::test_utils::account_invoke_tx;
use crate::utils::{u128_from_usize, u64_from_usize};
use crate::utils::u64_from_usize;
use crate::versioned_constants::{
ResourceCost,
StarknetVersion,
Expand Down Expand Up @@ -204,7 +204,7 @@ fn test_get_da_gas_cost_basic(#[case] state_changes_count: StateChangesCount) {

let computed_gas_vector = get_da_gas_cost(&state_changes_count, true);
assert_eq!(
GasVector::from_l1_data_gas(u128_from_usize(manual_blob_gas_usage).into()),
GasVector::from_l1_data_gas(u64_from_usize(manual_blob_gas_usage).into()),
computed_gas_vector
);
}
Expand Down Expand Up @@ -253,10 +253,7 @@ fn test_onchain_data_discount() {

let cost_without_discount = (state_changes_count.n_storage_updates * 2) * (512 + 100);
let actual_cost = get_da_gas_cost(&state_changes_count, use_kzg_da).l1_gas;
let cost_ratio = ResourceCost::new(
u64::try_from(actual_cost.0).unwrap(),
u64_from_usize(cost_without_discount),
);
let cost_ratio = ResourceCost::new(actual_cost.0, u64_from_usize(cost_without_discount));
assert!(cost_ratio <= ResourceCost::new(9, 10));
assert!(cost_ratio >= ResourceCost::new(88, 100));
}
Expand Down Expand Up @@ -294,10 +291,12 @@ fn test_discounted_gas_from_gas_vector_computation() {

let result_div_ceil = gas_usage.l1_gas
+ (gas_usage.l1_data_gas.nonzero_checked_mul(DEFAULT_ETH_L1_DATA_GAS_PRICE).unwrap())
.div_ceil(DEFAULT_ETH_L1_GAS_PRICE);
.checked_div_ceil(DEFAULT_ETH_L1_GAS_PRICE)
.unwrap();
let result_div_floor = gas_usage.l1_gas
+ (gas_usage.l1_data_gas.nonzero_checked_mul(DEFAULT_ETH_L1_DATA_GAS_PRICE).unwrap())
/ DEFAULT_ETH_L1_GAS_PRICE;
.checked_div(DEFAULT_ETH_L1_GAS_PRICE)
.unwrap();

assert_eq!(actual_result, result_div_ceil);
assert_eq!(actual_result, result_div_floor + 1_u8.into());
Expand Down
29 changes: 14 additions & 15 deletions crates/blockifier/src/fee/receipt_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use crate::transaction::test_utils::{
create_resource_bounds,
};
use crate::transaction::transactions::ExecutableTransaction;
use crate::utils::{u128_from_usize, u64_from_usize, usize_from_u128};
use crate::utils::{u64_from_usize, usize_from_u64};
use crate::versioned_constants::VersionedConstants;

#[fixture]
Expand Down Expand Up @@ -124,9 +124,9 @@ fn test_calculate_tx_gas_usage_basic<'a>(
let gas_per_data_felt = versioned_constants
.get_archival_data_gas_costs(&gas_vector_computation_mode)
.gas_per_data_felt;
let calldata_and_signature_gas_cost = u128::from(
(gas_per_data_felt * u64_from_usize(calldata_length + signature_length)).to_integer(),
)
let calldata_and_signature_gas_cost = (gas_per_data_felt
* u64_from_usize(calldata_length + signature_length))
.to_integer()
.into();
let manual_starknet_gas_usage_vector = match gas_vector_computation_mode {
GasVectorComputationMode::NoL2Gas => {
Expand Down Expand Up @@ -163,10 +163,9 @@ fn test_calculate_tx_gas_usage_basic<'a>(

// Manual calculation.
let message_segment_length = get_message_segment_length(&[], Some(l1_handler_payload_size));
let calldata_and_signature_gas_cost = u128::from(
(gas_per_data_felt * u64_from_usize(l1_handler_payload_size + signature_length))
.to_integer(),
)
let calldata_and_signature_gas_cost = (gas_per_data_felt
* u64_from_usize(l1_handler_payload_size + signature_length))
.to_integer()
.into();
let calldata_and_signature_gas_cost_vector = match gas_vector_computation_mode {
GasVectorComputationMode::NoL2Gas => {
Expand All @@ -177,16 +176,16 @@ fn test_calculate_tx_gas_usage_basic<'a>(
let manual_starknet_l1_gas_usage = message_segment_length
* eth_gas_constants::GAS_PER_MEMORY_WORD
+ eth_gas_constants::GAS_PER_COUNTER_DECREASE
+ usize_from_u128(
+ usize_from_u64(
get_consumed_message_to_l2_emissions_cost(Some(l1_handler_payload_size)).l1_gas.0,
)
.unwrap();
let manual_starknet_l1_gas_usage_vector =
GasVector::from_l1_gas(u128_from_usize(manual_starknet_l1_gas_usage).into());
GasVector::from_l1_gas(u64_from_usize(manual_starknet_l1_gas_usage).into());
let manual_sharp_gas_usage =
message_segment_length * eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD;
let manual_gas_computation =
GasVector::from_l1_gas(u128_from_usize(manual_sharp_gas_usage).into())
GasVector::from_l1_gas(u64_from_usize(manual_sharp_gas_usage).into())
+ manual_starknet_l1_gas_usage_vector
+ calldata_and_signature_gas_cost_vector;
assert_eq!(l1_handler_gas_usage_vector, manual_gas_computation);
Expand Down Expand Up @@ -245,16 +244,16 @@ fn test_calculate_tx_gas_usage_basic<'a>(
let n_l2_to_l1_messages = l2_to_l1_payload_lengths.len();
let manual_starknet_gas_usage = message_segment_length * eth_gas_constants::GAS_PER_MEMORY_WORD
+ n_l2_to_l1_messages * eth_gas_constants::GAS_PER_ZERO_TO_NONZERO_STORAGE_SET
+ usize_from_u128(get_log_message_to_l1_emissions_cost(&l2_to_l1_payload_lengths).l1_gas.0)
+ usize_from_u64(get_log_message_to_l1_emissions_cost(&l2_to_l1_payload_lengths).l1_gas.0)
.unwrap();
let manual_sharp_gas_usage = message_segment_length
* eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD
+ usize_from_u128(l2_to_l1_starknet_resources.state.to_gas_vector(use_kzg_da).l1_gas.0)
+ 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;
let manual_gas_computation = GasVector {
l1_gas: u128_from_usize(manual_starknet_gas_usage + manual_sharp_gas_usage).into(),
l1_gas: u64_from_usize(manual_starknet_gas_usage + manual_sharp_gas_usage).into(),
l1_data_gas: manual_sharp_blob_gas_usage,
..Default::default()
};
Expand Down Expand Up @@ -329,7 +328,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
+ storage_writings_gas_usage_vector.l1_gas
// l2_to_l1_messages_gas_usage and storage_writings_gas_usage got a discount each, while
// the combined calculation got it once.
+ u128_from_usize(fee_balance_discount).into(),
+ 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,
l2_gas: l1_handler_gas_usage_vector.l2_gas,
Expand Down
47 changes: 35 additions & 12 deletions crates/blockifier/src/fee/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::fee::gas_usage::{
use crate::state::cached_state::{StateChanges, StateChangesCount};
use crate::transaction::errors::TransactionFeeError;
use crate::transaction::objects::HasRelatedFeeType;
use crate::utils::{u128_from_usize, u64_from_usize};
use crate::utils::u64_from_usize;
use crate::versioned_constants::{
resource_cost_to_u128_ratio,
ArchivalDataGasCosts,
Expand Down Expand Up @@ -219,12 +219,24 @@ impl ArchivalDataResources {
/// Returns the cost of the transaction's emmited events in L1/L2 gas units, depending on the
/// mode.
fn get_events_gas_cost(&self, archival_gas_costs: &ArchivalDataGasCosts) -> GasAmount {
(resource_cost_to_u128_ratio(archival_gas_costs.gas_per_data_felt)
* (resource_cost_to_u128_ratio(archival_gas_costs.event_key_factor)
* self.event_summary.total_event_keys
+ self.event_summary.total_event_data_size))
.to_integer()
.into()
u64::try_from(
(resource_cost_to_u128_ratio(archival_gas_costs.gas_per_data_felt)
* (resource_cost_to_u128_ratio(archival_gas_costs.event_key_factor)
* self.event_summary.total_event_keys
+ self.event_summary.total_event_data_size))
.to_integer(),
)
.unwrap_or_else(|_| {
panic!(
"Events gas cost overflowed: {} event keys (factor: {}), data length {} (at {} \
gas per felt).",
self.event_summary.total_event_keys,
archival_gas_costs.event_key_factor,
self.event_summary.total_event_data_size,
archival_gas_costs.gas_per_data_felt
)
})
.into()
}
}

Expand All @@ -251,7 +263,7 @@ impl MessageResources {
pub fn to_gas_vector(&self) -> GasVector {
let starknet_gas_usage = self.get_starknet_gas_cost();
let sharp_gas_usage = GasVector::from_l1_gas(
u128_from_usize(
u64_from_usize(
self.message_segment_length * eth_gas_constants::SHARP_GAS_PER_MEMORY_WORD,
)
.into(),
Expand All @@ -268,7 +280,7 @@ impl MessageResources {

GasVector::from_l1_gas(
// Starknet's updateState gets the message segment as an argument.
u128_from_usize(
u64_from_usize(
self.message_segment_length * eth_gas_constants::GAS_PER_MEMORY_WORD
// Starknet's updateState increases a (storage) counter for each L2-to-L1 message.
+ n_l2_to_l1_messages * eth_gas_constants::GAS_PER_ZERO_TO_NONZERO_STORAGE_SET
Expand Down Expand Up @@ -360,8 +372,19 @@ impl GasVector {
pub fn to_discounted_l1_gas(&self, tx_context: &TransactionContext) -> GasAmount {
let gas_prices = &tx_context.block_context.block_info.gas_prices;
let fee_type = tx_context.tx_info.fee_type();
let gas_price = gas_prices.get_l1_gas_price_by_fee_type(&fee_type);
let data_gas_price = gas_prices.get_l1_data_gas_price_by_fee_type(&fee_type);
self.l1_gas + (self.l1_data_gas.nonzero_saturating_mul(data_gas_price)).div_ceil(gas_price)
let l1_gas_price = gas_prices.get_l1_gas_price_by_fee_type(&fee_type);
let l1_data_gas_price = gas_prices.get_l1_data_gas_price_by_fee_type(&fee_type);
let l1_data_gas_fee = self.l1_data_gas.nonzero_saturating_mul(l1_data_gas_price);
let l1_data_gas_in_l1_gas_units =
l1_data_gas_fee.checked_div_ceil(l1_gas_price).unwrap_or_else(|| {
log::warn!(
"Discounted L1 gas cost overflowed: division of L1 data fee {:?} by regular \
L1 gas price ({:?}) resulted in overflow.",
l1_data_gas_fee,
l1_gas_price
);
GasAmount::MAX
});
self.l1_gas.saturating_add(l1_data_gas_in_l1_gas_units)
}
}
4 changes: 2 additions & 2 deletions crates/blockifier/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ pub const DEFAULT_ETH_L1_DATA_GAS_PRICE: NonzeroGasPrice =
NonzeroGasPrice::new_unchecked(GasPrice(u128::pow(10, 6))); // Given in units of Wei.
pub const DEFAULT_STRK_L1_DATA_GAS_PRICE: NonzeroGasPrice =
NonzeroGasPrice::new_unchecked(GasPrice(u128::pow(10, 9))); // Given in units of STRK.
pub const DEFAULT_L1_DATA_GAS_MAX_AMOUNT: GasAmount = GasAmount(u128::pow(10, 6));
pub const DEFAULT_L1_DATA_GAS_MAX_AMOUNT: GasAmount = GasAmount(u64::pow(10, 6));
pub const DEFAULT_STRK_L2_GAS_PRICE: NonzeroGasPrice =
NonzeroGasPrice::new_unchecked(GasPrice(u128::pow(10, 9)));
pub const DEFAULT_L2_GAS_MAX_AMOUNT: GasAmount = GasAmount(u128::pow(10, 6));
pub const DEFAULT_L2_GAS_MAX_AMOUNT: GasAmount = GasAmount(u64::pow(10, 6));

// The block number of the BlockContext being used for testing.
pub const CURRENT_BLOCK_NUMBER: u64 = 2001;
Expand Down
Loading

0 comments on commit 7a28708

Please sign in to comment.