Skip to content

Commit

Permalink
feat(blockifier): panic or saturate Fee arithmetic depending on 'natu…
Browse files Browse the repository at this point in the history
…ral' source of values
  • Loading branch information
dorimedini-starkware committed Oct 10, 2024
1 parent 28385eb commit a2c9f10
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
2 changes: 1 addition & 1 deletion crates/blockifier/src/execution/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ impl EntryPointExecutionContext {
// transactions derive this value from the `max_fee`.
let tx_gas_upper_bound = match tx_info {
// Fee is a larger uint type than GasAmount, so we need to saturate the division.
// This is just a computation of an upper bound, so it's safe to saturate.
TransactionInfo::Deprecated(context) => context.max_fee.saturating_div(
block_info.gas_prices.get_l1_gas_price_by_fee_type(&tx_info.fee_type()),
),
Expand All @@ -287,7 +288,6 @@ impl EntryPointExecutionContext {

// Use saturating upper bound to avoid overflow. This is safe because the upper bound is
// bounded above by the block's limit, which is a usize.

let upper_bound_u64 = if gas_per_step.is_zero() {
u64::MAX
} else {
Expand Down
21 changes: 15 additions & 6 deletions crates/starknet_api/src/execution_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ impl_from_uint_for_gas_amount!(u8, u16, u32, u64);
impl GasAmount {
pub const MAX: Self = Self(u64::MAX);

pub fn checked_add(self, rhs: Self) -> Option<Self> {
self.0.checked_add(rhs.0).map(Self)
}

pub fn saturating_add(self, rhs: Self) -> Self {
self.0.saturating_add(rhs.0).into()
}
Expand Down Expand Up @@ -142,21 +146,26 @@ impl GasVector {
/// X non-data-related gas consumption and Y bytes of data, in non-blob mode, would
/// cost (X + 16*Y) units of gas. Applying the discount ratio to the data-related
/// summand, we get total_gas = (X + Y * DGP / GP).
/// If this function is called with kzg_flag==false, then l1_data_gas==0, and this dicount
/// If this function is called with kzg_flag==false, then l1_data_gas==0, and this discount
/// function does nothing.
/// Panics on overflow.
pub fn to_discounted_l1_gas(&self, gas_prices: &GasPriceVector) -> GasAmount {
let l1_data_gas_fee = self.l1_data_gas.nonzero_saturating_mul(gas_prices.l1_data_gas_price);
let l1_data_gas_in_l1_gas_units =
l1_data_gas_fee.checked_div_ceil(gas_prices.l1_gas_price).unwrap_or_else(|| {
log::warn!(
panic!(
"Discounted L1 gas cost overflowed: division of L1 data fee ({}) by regular \
L1 gas price ({}) resulted in overflow.",
l1_data_gas_fee,
gas_prices.l1_gas_price
l1_data_gas_fee, gas_prices.l1_gas_price
);
GasAmount::MAX
});
self.l1_gas.saturating_add(l1_data_gas_in_l1_gas_units)
self.l1_gas.checked_add(l1_data_gas_in_l1_gas_units).unwrap_or_else(|| {
panic!(
"Overflow while computing discounted L1 gas: L1 gas ({}) + L1 data gas in L1 gas \
units ({}) resulted in overflow.",
self.l1_gas, l1_data_gas_in_l1_gas_units
)
})
}
}

Expand Down
3 changes: 3 additions & 0 deletions crates/starknet_api/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,9 @@ impl ValidResourceBounds {
}
}

/// Returns the maximum possible fee that can be charged for the transaction.
/// The computation is saturating, meaning that if the result is larger than the maximum
/// possible fee, the maximum possible fee is returned.
pub fn max_possible_fee(&self) -> Fee {
match self {
ValidResourceBounds::L1Gas(l1_bounds) => {
Expand Down

0 comments on commit a2c9f10

Please sign in to comment.