diff --git a/crates/blockifier/src/execution/entry_point.rs b/crates/blockifier/src/execution/entry_point.rs index 1376dba8d0..8c9cf87d79 100644 --- a/crates/blockifier/src/execution/entry_point.rs +++ b/crates/blockifier/src/execution/entry_point.rs @@ -282,7 +282,7 @@ impl EntryPointExecutionContext { 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(), + TransactionInfo::Current(context) => context.l1_resource_bounds().max_amount, }; // Use saturating upper bound to avoid overflow. This is safe because the upper bound is diff --git a/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs b/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs index 51ef403aa8..ecd49fc9dd 100644 --- a/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs +++ b/crates/blockifier/src/execution/syscalls/syscall_tests/get_execution_info.rs @@ -1,7 +1,9 @@ use cairo_vm::Felt252; use num_traits::Pow; +use starknet_api::block::GasPrice; use starknet_api::core::ChainId; use starknet_api::data_availability::DataAvailabilityMode; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::{ AccountDeploymentData, Calldata, @@ -143,8 +145,8 @@ fn test_get_execution_info( let nonce = nonce!(3_u16); let sender_address = test_contract_address; - let max_amount = Fee(13); - let max_price_per_unit = Fee(61); + let max_amount = GasAmount(13); + let max_price_per_unit = GasPrice(61); let expected_resource_bounds: Vec = match (test_contract, version) { (FeatureContract::LegacyTestContract, _) => vec![], @@ -154,8 +156,8 @@ fn test_get_execution_info( (_, _) => vec![ Felt::from(2u32), // Length of ResourceBounds array. felt!(Resource::L1Gas.to_hex()), // Resource. - felt!(max_amount.0), // Max amount. - felt!(max_price_per_unit.0), // Max price per unit. + max_amount.into(), // Max amount. + max_price_per_unit.into(), // Max price per unit. felt!(Resource::L2Gas.to_hex()), // Resource. Felt::ZERO, // Max amount. Felt::ZERO, // Max price per unit. @@ -209,8 +211,8 @@ fn test_get_execution_info( ..Default::default() }, resource_bounds: ValidResourceBounds::L1Gas(ResourceBounds { - max_amount: max_amount.0.try_into().expect("Failed to convert u128 to u64."), - max_price_per_unit: max_price_per_unit.0, + max_amount, + max_price_per_unit, }), tip: Tip::default(), nonce_data_availability_mode: DataAvailabilityMode::L1, diff --git a/crates/blockifier/src/fee/fee_checks.rs b/crates/blockifier/src/fee/fee_checks.rs index 383f758433..b3d6ff2032 100644 --- a/crates/blockifier/src/fee/fee_checks.rs +++ b/crates/blockifier/src/fee/fee_checks.rs @@ -75,7 +75,7 @@ impl FeeCheckReport { match &tx_context.tx_info { TransactionInfo::Current(info) => get_fee_by_gas_vector( &tx_context.block_context.block_info, - GasVector::from_l1_gas(info.l1_resource_bounds().max_amount.into()), + GasVector::from_l1_gas(info.l1_resource_bounds().max_amount), &FeeType::Strk, ), TransactionInfo::Deprecated(context) => context.max_fee, @@ -152,9 +152,9 @@ impl FeeCheckReport { gas_vector: &GasVector, ) -> FeeCheckResult<()> { for (resource, max_amount, actual_amount) in [ - (L1Gas, all_resource_bounds.l1_gas.max_amount.into(), gas_vector.l1_gas), - (L2Gas, all_resource_bounds.l2_gas.max_amount.into(), gas_vector.l2_gas), - (L1DataGas, all_resource_bounds.l1_data_gas.max_amount.into(), gas_vector.l1_data_gas), + (L1Gas, all_resource_bounds.l1_gas.max_amount, gas_vector.l1_gas), + (L2Gas, all_resource_bounds.l2_gas.max_amount, gas_vector.l2_gas), + (L1DataGas, all_resource_bounds.l1_data_gas.max_amount, gas_vector.l1_data_gas), ] { if max_amount < actual_amount { return Err(FeeCheckError::MaxGasAmountExceeded { @@ -175,10 +175,10 @@ impl FeeCheckReport { ) -> FeeCheckResult<()> { let total_discounted_gas_used = gas_vector.to_discounted_l1_gas(tx_context.get_gas_prices()); - if total_discounted_gas_used > l1_bounds.max_amount.into() { + if total_discounted_gas_used > l1_bounds.max_amount { return Err(FeeCheckError::MaxGasAmountExceeded { resource: L1Gas, - max_amount: l1_bounds.max_amount.into(), + max_amount: l1_bounds.max_amount, actual_amount: total_discounted_gas_used, }); } diff --git a/crates/blockifier/src/fee/fee_utils.rs b/crates/blockifier/src/fee/fee_utils.rs index 4646b50d5d..5cc9dda520 100644 --- a/crates/blockifier/src/fee/fee_utils.rs +++ b/crates/blockifier/src/fee/fee_utils.rs @@ -115,7 +115,7 @@ pub fn verify_can_pay_committed_bounds( // Sender will not be charged by `max_price_per_unit`, but this check should not // depend on the current gas price. { - Fee(u128::from(l1_gas.max_amount) * l1_gas.max_price_per_unit) + l1_gas.max_amount.saturating_mul(l1_gas.max_price_per_unit) } // TODO!(Aner): add tests AllResources(AllResourceBounds { l1_gas, l2_gas, l1_data_gas }) => { @@ -123,9 +123,9 @@ pub fn verify_can_pay_committed_bounds( // of the different resources. // The Sender will not be charged by`max_price_per_unit`, but this check should // not depend on the current gas price - Fee(u128::from(l1_gas.max_amount) * l1_gas.max_price_per_unit - + u128::from(l1_data_gas.max_amount) * l1_data_gas.max_price_per_unit - + u128::from(l2_gas.max_amount) * l2_gas.max_price_per_unit) + l1_gas.max_amount.saturating_mul(l1_gas.max_price_per_unit) + + l1_data_gas.max_amount.saturating_mul(l1_data_gas.max_price_per_unit) + + l2_gas.max_amount.saturating_mul(l2_gas.max_price_per_unit) } } } diff --git a/crates/blockifier/src/transaction/account_transaction.rs b/crates/blockifier/src/transaction/account_transaction.rs index 2745625d8a..14e7622e74 100644 --- a/crates/blockifier/src/transaction/account_transaction.rs +++ b/crates/blockifier/src/transaction/account_transaction.rs @@ -357,18 +357,18 @@ impl AccountTransaction { { // TODO(Aner): refactor to indicate both amount and price are too low. // TODO(Aner): refactor to return all amounts that are too low. - if minimal_gas_amount > resource_bounds.max_amount.into() { + if minimal_gas_amount > resource_bounds.max_amount { return Err(TransactionFeeError::MaxGasAmountTooLow { resource, - max_gas_amount: resource_bounds.max_amount.into(), + max_gas_amount: resource_bounds.max_amount, minimal_gas_amount, })?; } // TODO(Aner): refactor to return all prices that are too low. - if resource_bounds.max_price_per_unit < actual_gas_price.get().0 { + if resource_bounds.max_price_per_unit < actual_gas_price.get() { return Err(TransactionFeeError::MaxGasPriceTooLow { resource, - max_gas_price: resource_bounds.max_price_per_unit.into(), + max_gas_price: resource_bounds.max_price_per_unit, actual_gas_price: actual_gas_price.into(), })?; } diff --git a/crates/blockifier/src/transaction/account_transactions_test.rs b/crates/blockifier/src/transaction/account_transactions_test.rs index a7f19ff2bb..62e48972c6 100644 --- a/crates/blockifier/src/transaction/account_transactions_test.rs +++ b/crates/blockifier/src/transaction/account_transactions_test.rs @@ -5,6 +5,7 @@ use cairo_vm::types::builtin_name::BuiltinName; use cairo_vm::vm::runners::cairo_runner::ResourceTracker; use pretty_assertions::assert_eq; use rstest::rstest; +use starknet_api::block::GasPrice; use starknet_api::core::{calculate_contract_address, ClassHash, ContractAddress, PatriciaKey}; use starknet_api::execution_resources::GasAmount; use starknet_api::hash::StarkHash; @@ -200,31 +201,29 @@ fn test_assert_actual_fee_in_bounds( #[case] positive_flow: bool, #[case] deprecated_tx: bool, ) { - let actual_fee_offset = if positive_flow { 0 } else { 1 }; + let actual_fee_offset = Fee(if positive_flow { 0 } else { 1 }); if deprecated_tx { - let max_fee = 100; - let tx = account_invoke_tx(invoke_tx_args! { - max_fee: Fee(max_fee), - version: TransactionVersion::ONE, - }); + let max_fee = Fee(100); + let tx = account_invoke_tx(invoke_tx_args! { max_fee, version: TransactionVersion::ONE }); let context = Arc::new(block_context.to_tx_context(&tx)); - AccountTransaction::assert_actual_fee_in_bounds(&context, Fee(max_fee + actual_fee_offset)); + AccountTransaction::assert_actual_fee_in_bounds(&context, max_fee + actual_fee_offset); } else { // All resources. - let l1_gas = ResourceBounds { max_amount: 2, max_price_per_unit: 3 }; - let l2_gas = ResourceBounds { max_amount: 4, max_price_per_unit: 5 }; - let l1_data_gas = ResourceBounds { max_amount: 6, max_price_per_unit: 7 }; + let l1_gas = ResourceBounds { max_amount: GasAmount(2), max_price_per_unit: GasPrice(3) }; + let l2_gas = ResourceBounds { max_amount: GasAmount(4), max_price_per_unit: GasPrice(5) }; + let l1_data_gas = + ResourceBounds { max_amount: GasAmount(6), max_price_per_unit: GasPrice(7) }; let all_resource_bounds = ValidResourceBounds::AllResources(AllResourceBounds { l1_gas, l2_gas, l1_data_gas }); - let all_resource_fee = u128::from(l1_gas.max_amount) * l1_gas.max_price_per_unit - + u128::from(l2_gas.max_amount) * l2_gas.max_price_per_unit - + u128::from(l1_data_gas.max_amount) * l1_data_gas.max_price_per_unit + let all_resource_fee = l1_gas.max_amount.checked_mul(l1_gas.max_price_per_unit).unwrap() + + l2_gas.max_amount.checked_mul(l2_gas.max_price_per_unit).unwrap() + + l1_data_gas.max_amount.checked_mul(l1_data_gas.max_price_per_unit).unwrap() + actual_fee_offset; // L1 resources. let l1_resource_bounds = ValidResourceBounds::L1Gas(l1_gas); let l1_resource_fee = - u128::from(l1_gas.max_amount) * l1_gas.max_price_per_unit + actual_fee_offset; + l1_gas.max_amount.checked_mul(l1_gas.max_price_per_unit).unwrap() + actual_fee_offset; for (bounds, actual_fee) in [(all_resource_bounds, all_resource_fee), (l1_resource_bounds, l1_resource_fee)] @@ -234,7 +233,7 @@ fn test_assert_actual_fee_in_bounds( version: TransactionVersion::THREE, }); let context = Arc::new(block_context.to_tx_context(&tx)); - AccountTransaction::assert_actual_fee_in_bounds(&context, Fee(actual_fee)); + AccountTransaction::assert_actual_fee_in_bounds(&context, actual_fee); } } } diff --git a/crates/blockifier/src/transaction/errors.rs b/crates/blockifier/src/transaction/errors.rs index 6c2ae269d5..81f02f14e1 100644 --- a/crates/blockifier/src/transaction/errors.rs +++ b/crates/blockifier/src/transaction/errors.rs @@ -28,28 +28,28 @@ pub enum TransactionFeeError { #[error("Actual fee ({}) exceeded paid fee on L1 ({}).", actual_fee.0, paid_fee.0)] InsufficientFee { paid_fee: Fee, actual_fee: Fee }, #[error( - "Resources bounds (l1 gas max amount: {l1_max_amount}, l1 gas max price: {l1_max_price}, \ - l1 data max amount: {l1_data_max_amount}, l1 data max price: {l1_data_max_price}, l2 gas \ - max amount: {l2_max_amount}, l2 gas max price: {l2_max_price}) exceed balance \ - ({balance})." + "Resources bounds (l1 gas max amount: {l1_max_amount:?}, l1 gas max price: \ + {l1_max_price:?}, l1 data max amount: {l1_data_max_amount:?}, l1 data max price: \ + {l1_data_max_price:?}, l2 gas max amount: {l2_max_amount:?}, l2 gas max price: \ + {l2_max_price:?}) exceed balance ({balance})." )] ResourcesBoundsExceedBalance { - l1_max_amount: u64, - l1_max_price: u128, - l1_data_max_amount: u64, - l1_data_max_price: u128, - l2_max_amount: u64, - l2_max_price: u128, + l1_max_amount: GasAmount, + l1_max_price: GasPrice, + l1_data_max_amount: GasAmount, + l1_data_max_price: GasPrice, + l2_max_amount: GasAmount, + l2_max_price: GasPrice, balance: BigUint, }, #[error( - "Resource {resource} bounds (max amount: {max_amount}, max price): {max_price}) exceed \ - balance ({balance})." + "Resource {resource} bounds (max amount: {max_amount:?}, max price): {max_price:?}) \ + exceed balance ({balance})." )] GasBoundsExceedBalance { resource: Resource, - max_amount: u64, - max_price: u128, + max_amount: GasAmount, + max_price: GasPrice, balance: BigUint, }, #[error("Max fee ({}) exceeds balance ({balance}).", max_fee.0, )] diff --git a/crates/blockifier/src/transaction/test_utils.rs b/crates/blockifier/src/transaction/test_utils.rs index 4540acd7d2..276217f006 100644 --- a/crates/blockifier/src/transaction/test_utils.rs +++ b/crates/blockifier/src/transaction/test_utils.rs @@ -329,11 +329,11 @@ pub fn run_invoke_tx( /// Creates a `ResourceBoundsMapping` with the given `max_amount` and `max_price` for L1 gas limits. /// No guarantees on the values of the other resources bounds. // TODO: Check usages of this function and update to using all gas bounds. -pub fn l1_resource_bounds(max_amount: GasAmount, max_price: GasPrice) -> ValidResourceBounds { - ValidResourceBounds::L1Gas(ResourceBounds { - max_amount: max_amount.0, - max_price_per_unit: max_price.0, - }) +pub fn l1_resource_bounds( + max_amount: GasAmount, + max_price_per_unit: GasPrice, +) -> ValidResourceBounds { + ValidResourceBounds::L1Gas(ResourceBounds { max_amount, max_price_per_unit }) } #[fixture] @@ -364,11 +364,11 @@ pub fn create_all_resource_bounds( l1_data_max_price: GasPrice, ) -> ValidResourceBounds { ValidResourceBounds::AllResources(AllResourceBounds { - l1_gas: ResourceBounds { max_amount: l1_max_amount.0, max_price_per_unit: l1_max_price.0 }, - l2_gas: ResourceBounds { max_amount: l2_max_amount.0, max_price_per_unit: l2_max_price.0 }, + l1_gas: ResourceBounds { max_amount: l1_max_amount, max_price_per_unit: l1_max_price }, + l2_gas: ResourceBounds { max_amount: l2_max_amount, max_price_per_unit: l2_max_price }, l1_data_gas: ResourceBounds { - max_amount: l1_data_max_amount.0, - max_price_per_unit: l1_data_max_price.0, + max_amount: l1_data_max_amount, + max_price_per_unit: l1_data_max_price, }, }) } diff --git a/crates/blockifier/src/transaction/transactions_test.rs b/crates/blockifier/src/transaction/transactions_test.rs index 414b1700fd..e12e163179 100644 --- a/crates/blockifier/src/transaction/transactions_test.rs +++ b/crates/blockifier/src/transaction/transactions_test.rs @@ -983,16 +983,16 @@ fn test_insufficient_new_resource_bounds( let default_resource_bounds = AllResourceBounds { l1_gas: ResourceBounds { - max_amount: minimal_gas_vector.l1_gas.0, - max_price_per_unit: actual_strk_l1_gas_price.get().0, + max_amount: minimal_gas_vector.l1_gas, + max_price_per_unit: actual_strk_l1_gas_price.get(), }, l2_gas: ResourceBounds { - max_amount: minimal_gas_vector.l2_gas.0, - max_price_per_unit: actual_strk_l2_gas_price.get().0, + max_amount: minimal_gas_vector.l2_gas, + max_price_per_unit: actual_strk_l2_gas_price.get(), }, l1_data_gas: ResourceBounds { - max_amount: minimal_gas_vector.l1_data_gas.0, - max_price_per_unit: actual_strk_l1_data_gas_price.get().0, + max_amount: minimal_gas_vector.l1_data_gas, + max_price_per_unit: actual_strk_l1_data_gas_price.get(), }, }; @@ -1029,14 +1029,14 @@ fn test_insufficient_new_resource_bounds( (L2Gas, default_resource_bounds.l2_gas), (L1DataGas, default_resource_bounds.l1_data_gas), ] { - if resource_bounds.max_amount == 0 { + if resource_bounds.max_amount == 0_u8.into() { continue; } let mut invalid_resources = default_resource_bounds; match insufficient_resource { - L1Gas => invalid_resources.l1_gas.max_amount -= 1, - L2Gas => invalid_resources.l2_gas.max_amount -= 1, - L1DataGas => invalid_resources.l1_data_gas.max_amount -= 1, + L1Gas => invalid_resources.l1_gas.max_amount.0 -= 1, + L2Gas => invalid_resources.l2_gas.max_amount.0 -= 1, + L1DataGas => invalid_resources.l1_data_gas.max_amount.0 -= 1, } let invalid_v3_tx = account_invoke_tx(InvokeTxArgs { resource_bounds: ValidResourceBounds::AllResources(invalid_resources), @@ -1059,9 +1059,9 @@ fn test_insufficient_new_resource_bounds( for insufficient_resource in [L1Gas, L2Gas, L1DataGas] { let mut invalid_resources = default_resource_bounds; match insufficient_resource { - L1Gas => invalid_resources.l1_gas.max_price_per_unit -= 1, - L2Gas => invalid_resources.l2_gas.max_price_per_unit -= 1, - L1DataGas => invalid_resources.l1_data_gas.max_price_per_unit -= 1, + L1Gas => invalid_resources.l1_gas.max_price_per_unit.0 -= 1, + L2Gas => invalid_resources.l2_gas.max_price_per_unit.0 -= 1, + L1DataGas => invalid_resources.l1_data_gas.max_price_per_unit.0 -= 1, } let invalid_v3_tx = account_invoke_tx(InvokeTxArgs { diff --git a/crates/gateway/src/stateful_transaction_validator_test.rs b/crates/gateway/src/stateful_transaction_validator_test.rs index 1a12cde10b..4a6b09cf02 100644 --- a/crates/gateway/src/stateful_transaction_validator_test.rs +++ b/crates/gateway/src/stateful_transaction_validator_test.rs @@ -15,8 +15,10 @@ use mockall::predicate::eq; use num_bigint::BigUint; use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; +use starknet_api::block::GasPrice; use starknet_api::core::Nonce; use starknet_api::executable_transaction::Transaction; +use starknet_api::execution_resources::GasAmount; use starknet_api::test_utils::deploy_account::executable_deploy_account_tx; use starknet_api::test_utils::invoke::executable_invoke_tx; use starknet_api::transaction::Resource; @@ -36,8 +38,8 @@ pub const STATEFUL_VALIDATOR_FEE_ERROR: BlockifierStatefulValidatorError = TransactionPreValidationError::TransactionFeeError( TransactionFeeError::GasBoundsExceedBalance { resource: Resource::L1DataGas, - max_amount: VALID_L1_GAS_MAX_AMOUNT, - max_price: VALID_L1_GAS_MAX_PRICE_PER_UNIT, + max_amount: GasAmount(VALID_L1_GAS_MAX_AMOUNT), + max_price: GasPrice(VALID_L1_GAS_MAX_PRICE_PER_UNIT), balance: BigUint::ZERO, }, ), diff --git a/crates/gateway/src/stateless_transaction_validator.rs b/crates/gateway/src/stateless_transaction_validator.rs index 0a60bf2e06..2043465da7 100644 --- a/crates/gateway/src/stateless_transaction_validator.rs +++ b/crates/gateway/src/stateless_transaction_validator.rs @@ -1,3 +1,5 @@ +use starknet_api::block::GasPrice; +use starknet_api::execution_resources::GasAmount; use starknet_api::rpc_transaction::{ RpcDeclareTransaction, RpcDeployAccountTransaction, @@ -179,7 +181,9 @@ fn validate_resource_is_non_zero( resource: Resource, ) -> StatelessTransactionValidatorResult<()> { let resource_bounds = all_resource_bounds.get_bound(resource); - if resource_bounds.max_amount == 0 || resource_bounds.max_price_per_unit == 0 { + if resource_bounds.max_amount == GasAmount(0) + || resource_bounds.max_price_per_unit == GasPrice(0) + { return Err(StatelessTransactionValidatorError::ZeroResourceBounds { resource, resource_bounds, diff --git a/crates/mempool/src/mempool.rs b/crates/mempool/src/mempool.rs index 806caf1390..3fbdda2d12 100644 --- a/crates/mempool/src/mempool.rs +++ b/crates/mempool/src/mempool.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use starknet_api::block::GasPrice; use starknet_api::core::{ContractAddress, Nonce}; use starknet_api::executable_transaction::Transaction; use starknet_api::transaction::{Tip, TransactionHash, ValidResourceBounds}; @@ -135,7 +136,7 @@ impl Mempool { } // TODO(Mohammad): Rename this method once consensus API is added. - fn _update_gas_price_threshold(&mut self, threshold: u128) { + fn _update_gas_price_threshold(&mut self, threshold: GasPrice) { self.tx_queue._update_gas_price_threshold(threshold); } @@ -237,7 +238,7 @@ impl TransactionReference { } } - pub fn get_l2_gas_price(&self) -> u128 { + pub fn get_l2_gas_price(&self) -> GasPrice { self.resource_bounds.get_l2_bounds().max_price_per_unit } } diff --git a/crates/mempool/src/mempool_test.rs b/crates/mempool/src/mempool_test.rs index 48d7c21acd..5bc53a6d63 100644 --- a/crates/mempool/src/mempool_test.rs +++ b/crates/mempool/src/mempool_test.rs @@ -3,6 +3,7 @@ use std::cmp::Reverse; use mempool_test_utils::starknet_api_test_utils::test_resource_bounds_mapping; use pretty_assertions::assert_eq; use rstest::{fixture, rstest}; +use starknet_api::block::GasPrice; use starknet_api::core::{ContractAddress, PatriciaKey}; use starknet_api::executable_transaction::Transaction; use starknet_api::hash::StarkHash; @@ -280,11 +281,11 @@ fn test_get_txs_while_decreasing_gas_price_threshold() { // Test. // High gas price threshold, no transactions should be returned. - mempool._update_gas_price_threshold(1000000000000); + mempool._update_gas_price_threshold(GasPrice(1000000000000)); get_txs_and_assert_expected(&mut mempool, 1, &[]); // Low gas price threshold, the transaction should be returned. - mempool._update_gas_price_threshold(100); + mempool._update_gas_price_threshold(GasPrice(100)); get_txs_and_assert_expected(&mut mempool, 1, &[tx]); } @@ -302,11 +303,11 @@ fn test_get_txs_while_increasing_gas_price_threshold() { // Test. // Low gas price threshold, the transaction should be returned. - mempool._update_gas_price_threshold(100); + mempool._update_gas_price_threshold(GasPrice(100)); get_txs_and_assert_expected(&mut mempool, 1, &[tx_nonce_0]); // High gas price threshold, no transactions should be returned. - mempool._update_gas_price_threshold(1000000000000); + mempool._update_gas_price_threshold(GasPrice(1000000000000)); get_txs_and_assert_expected(&mut mempool, 1, &[]); } diff --git a/crates/mempool/src/transaction_queue.rs b/crates/mempool/src/transaction_queue.rs index 22f14045cf..978dfb46a7 100644 --- a/crates/mempool/src/transaction_queue.rs +++ b/crates/mempool/src/transaction_queue.rs @@ -1,7 +1,9 @@ use std::cmp::Ordering; use std::collections::{BTreeSet, HashMap}; +use starknet_api::block::GasPrice; use starknet_api::core::{ContractAddress, Nonce}; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::{ AllResourceBounds, ResourceBounds, @@ -21,7 +23,7 @@ pub mod transaction_queue_test_utils; // used. #[derive(Debug, Default, Eq, PartialEq)] pub struct TransactionQueue { - gas_price_threshold: u128, + gas_price_threshold: GasPrice, // Transactions with gas price above gas price threshold (sorted by tip). priority_queue: BTreeSet, // Transactions with gas price below gas price threshold (sorted by price). @@ -89,7 +91,7 @@ impl TransactionQueue { self.priority_queue.is_empty() } - pub fn _update_gas_price_threshold(&mut self, threshold: u128) { + pub fn _update_gas_price_threshold(&mut self, threshold: GasPrice) { match threshold.cmp(&self.gas_price_threshold) { Ordering::Less => self._promote_txs_to_priority(threshold), Ordering::Greater => self._demote_txs_to_pending(threshold), @@ -99,10 +101,10 @@ impl TransactionQueue { self.gas_price_threshold = threshold; } - fn _promote_txs_to_priority(&mut self, threshold: u128) { + fn _promote_txs_to_priority(&mut self, threshold: GasPrice) { let tmp_split_tx = PendingTransaction(TransactionReference { resource_bounds: ValidResourceBounds::AllResources(AllResourceBounds { - l2_gas: ResourceBounds { max_amount: 0, max_price_per_unit: threshold }, + l2_gas: ResourceBounds { max_amount: GasAmount(0), max_price_per_unit: threshold }, ..Default::default() }), sender_address: ContractAddress::default(), @@ -121,7 +123,7 @@ impl TransactionQueue { self.priority_queue.extend(txs_over_threshold.map(|tx| PriorityTransaction::from(tx.0))); } - fn _demote_txs_to_pending(&mut self, threshold: u128) { + fn _demote_txs_to_pending(&mut self, threshold: GasPrice) { let mut txs_to_remove = Vec::new(); // Remove all transactions from the priority queue that are below the threshold. diff --git a/crates/mempool/src/transaction_queue_test_utils.rs b/crates/mempool/src/transaction_queue_test_utils.rs index 493d8224ee..37b808f238 100644 --- a/crates/mempool/src/transaction_queue_test_utils.rs +++ b/crates/mempool/src/transaction_queue_test_utils.rs @@ -42,7 +42,12 @@ impl TransactionQueueContent { } } - TransactionQueue { priority_queue, pending_queue, address_to_tx, gas_price_threshold: 0 } + TransactionQueue { + priority_queue, + pending_queue, + address_to_tx, + gas_price_threshold: 0_u8.into(), + } } } diff --git a/crates/mempool_test_utils/src/starknet_api_test_utils.rs b/crates/mempool_test_utils/src/starknet_api_test_utils.rs index 7eb79c069c..89174e5102 100644 --- a/crates/mempool_test_utils/src/starknet_api_test_utils.rs +++ b/crates/mempool_test_utils/src/starknet_api_test_utils.rs @@ -10,9 +10,11 @@ use blockifier::test_utils::contracts::FeatureContract; use blockifier::test_utils::{create_trivial_calldata, CairoVersion}; use pretty_assertions::assert_ne; use serde_json::to_string_pretty; +use starknet_api::block::GasPrice; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::data_availability::DataAvailabilityMode; use starknet_api::executable_transaction::Transaction; +use starknet_api::execution_resources::GasAmount; use starknet_api::rpc_transaction::{ ContractClass, RpcDeclareTransactionV3, @@ -97,7 +99,7 @@ pub fn rpc_tx_for_testing( } pub const NON_EMPTY_RESOURCE_BOUNDS: ResourceBounds = - ResourceBounds { max_amount: 1, max_price_per_unit: 1 }; + ResourceBounds { max_amount: GasAmount(1), max_price_per_unit: GasPrice(1) }; // TODO(Nimrod): Delete this function. pub fn create_resource_bounds_mapping( @@ -119,16 +121,16 @@ pub fn zero_resource_bounds_mapping() -> AllResourceBounds { pub fn test_resource_bounds_mapping() -> AllResourceBounds { create_resource_bounds_mapping( ResourceBounds { - max_amount: VALID_L1_GAS_MAX_AMOUNT, - max_price_per_unit: VALID_L1_GAS_MAX_PRICE_PER_UNIT, + max_amount: GasAmount(VALID_L1_GAS_MAX_AMOUNT), + max_price_per_unit: GasPrice(VALID_L1_GAS_MAX_PRICE_PER_UNIT), }, ResourceBounds { - max_amount: VALID_L2_GAS_MAX_AMOUNT, - max_price_per_unit: VALID_L2_GAS_MAX_PRICE_PER_UNIT, + max_amount: GasAmount(VALID_L2_GAS_MAX_AMOUNT), + max_price_per_unit: GasPrice(VALID_L2_GAS_MAX_PRICE_PER_UNIT), }, ResourceBounds { - max_amount: VALID_L1_DATA_GAS_MAX_AMOUNT, - max_price_per_unit: VALID_L1_DATA_GAS_MAX_PRICE_PER_UNIT, + max_amount: GasAmount(VALID_L1_DATA_GAS_MAX_AMOUNT), + max_price_per_unit: GasPrice(VALID_L1_DATA_GAS_MAX_PRICE_PER_UNIT), }, ) } diff --git a/crates/native_blockifier/src/py_transaction.rs b/crates/native_blockifier/src/py_transaction.rs index e6886685e8..f4c54aa395 100644 --- a/crates/native_blockifier/src/py_transaction.rs +++ b/crates/native_blockifier/src/py_transaction.rs @@ -11,6 +11,8 @@ use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transaction_types::TransactionType; use pyo3::exceptions::PyValueError; use pyo3::prelude::*; +use starknet_api::block::GasPrice; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::{ DeprecatedResourceBoundsMapping, Resource, @@ -64,8 +66,8 @@ pub struct PyResourceBounds { impl From for starknet_api::transaction::ResourceBounds { fn from(py_resource_bounds: PyResourceBounds) -> Self { Self { - max_amount: py_resource_bounds.max_amount, - max_price_per_unit: py_resource_bounds.max_price_per_unit, + max_amount: GasAmount(py_resource_bounds.max_amount), + max_price_per_unit: GasPrice(py_resource_bounds.max_price_per_unit), } } } diff --git a/crates/papyrus_protobuf/src/converters/consensus_test.rs b/crates/papyrus_protobuf/src/converters/consensus_test.rs index 51810f9e61..5e32edb3c6 100644 --- a/crates/papyrus_protobuf/src/converters/consensus_test.rs +++ b/crates/papyrus_protobuf/src/converters/consensus_test.rs @@ -7,6 +7,7 @@ use papyrus_test_utils::{ use rand::Rng; use starknet_api::block::BlockHash; use starknet_api::core::ContractAddress; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::{ DeclareTransaction, DeclareTransactionV3, @@ -136,7 +137,7 @@ fn convert_proposal_to_vec_u8_and_back() { .. })) => { if let ValidResourceBounds::AllResources(ref mut bounds) = resource_bounds { - bounds.l2_gas.max_amount = 1; + bounds.l2_gas.max_amount = GasAmount(1); } } _ => {} diff --git a/crates/papyrus_protobuf/src/converters/rpc_transaction_test.rs b/crates/papyrus_protobuf/src/converters/rpc_transaction_test.rs index 7a309f1d03..7984e4dd5f 100644 --- a/crates/papyrus_protobuf/src/converters/rpc_transaction_test.rs +++ b/crates/papyrus_protobuf/src/converters/rpc_transaction_test.rs @@ -1,5 +1,7 @@ use lazy_static::lazy_static; use papyrus_test_utils::{get_rng, GetTestInstance}; +use starknet_api::block::GasPrice; +use starknet_api::execution_resources::GasAmount; use starknet_api::rpc_transaction::{ RpcDeclareTransaction, RpcDeclareTransactionV3, @@ -54,8 +56,11 @@ fn assert_transaction_to_vec_u8_and_back(transaction: RpcTransaction) { lazy_static! { static ref RESOURCE_BOUNDS_MAPPING: AllResourceBounds = AllResourceBounds { - l1_gas: ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }, - l2_gas: ResourceBounds { max_amount: 0x6, max_price_per_unit: 0x7 }, - l1_data_gas: ResourceBounds { max_amount: 0x7, max_price_per_unit: 0x8 }, + l1_gas: ResourceBounds { max_amount: GasAmount(0x5), max_price_per_unit: GasPrice(0x6) }, + l2_gas: ResourceBounds { max_amount: GasAmount(0x6), max_price_per_unit: GasPrice(0x7) }, + l1_data_gas: ResourceBounds { + max_amount: GasAmount(0x7), + max_price_per_unit: GasPrice(0x8) + }, }; } diff --git a/crates/papyrus_protobuf/src/converters/transaction.rs b/crates/papyrus_protobuf/src/converters/transaction.rs index 3179088ce6..81aaf05444 100644 --- a/crates/papyrus_protobuf/src/converters/transaction.rs +++ b/crates/papyrus_protobuf/src/converters/transaction.rs @@ -4,7 +4,9 @@ mod transaction_test; use std::convert::{TryFrom, TryInto}; use prost::Message; +use starknet_api::block::GasPrice; use starknet_api::core::{ClassHash, CompiledClassHash, EntryPointSelector, Nonce}; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::{ AccountDeploymentData, AllResourceBounds, @@ -592,15 +594,18 @@ impl TryFrom for ResourceBounds { value_as_str: format!("{max_price_per_unit_felt:?}"), } })?; - Ok(ResourceBounds { max_amount, max_price_per_unit }) + Ok(ResourceBounds { + max_amount: GasAmount(max_amount), + max_price_per_unit: GasPrice(max_price_per_unit), + }) } } impl From for protobuf::ResourceLimits { fn from(value: ResourceBounds) -> Self { protobuf::ResourceLimits { - max_amount: value.max_amount, - max_price_per_unit: Some(Felt::from(value.max_price_per_unit).into()), + max_amount: value.max_amount.0, + max_price_per_unit: Some(Felt::from(value.max_price_per_unit.0).into()), } } } diff --git a/crates/papyrus_protobuf/src/converters/transaction_test.rs b/crates/papyrus_protobuf/src/converters/transaction_test.rs index d8ac5a4967..7134299385 100644 --- a/crates/papyrus_protobuf/src/converters/transaction_test.rs +++ b/crates/papyrus_protobuf/src/converters/transaction_test.rs @@ -1,7 +1,8 @@ use lazy_static::lazy_static; use papyrus_test_utils::{get_rng, GetTestInstance}; use rand::random; -use starknet_api::execution_resources::{Builtin, ExecutionResources, GasVector}; +use starknet_api::block::GasPrice; +use starknet_api::execution_resources::{Builtin, ExecutionResources, GasAmount, GasVector}; use starknet_api::transaction::{ AllResourceBounds, DeclareTransaction, @@ -198,8 +199,17 @@ lazy_static! { }; static ref RESOURCE_BOUNDS_MAPPING: ValidResourceBounds = ValidResourceBounds::AllResources(AllResourceBounds { - l1_gas: ResourceBounds { max_amount: 0x5, max_price_per_unit: 0x6 }, - l2_gas: ResourceBounds { max_amount: 0x500, max_price_per_unit: 0x600 }, - l1_data_gas: ResourceBounds { max_amount: 0x30, max_price_per_unit: 0x30 } + l1_gas: ResourceBounds { + max_amount: GasAmount(0x5), + max_price_per_unit: GasPrice(0x6) + }, + l2_gas: ResourceBounds { + max_amount: GasAmount(0x500), + max_price_per_unit: GasPrice(0x600) + }, + l1_data_gas: ResourceBounds { + max_amount: GasAmount(0x30), + max_price_per_unit: GasPrice(0x30) + } }); } diff --git a/crates/papyrus_storage/src/serialization/serializers.rs b/crates/papyrus_storage/src/serialization/serializers.rs index 815e7f7d7e..7cd25da6be 100644 --- a/crates/papyrus_storage/src/serialization/serializers.rs +++ b/crates/papyrus_storage/src/serialization/serializers.rs @@ -367,8 +367,8 @@ auto_storage_serde! { L1DataGas = 2, } pub struct ResourceBounds { - pub max_amount: u64, - pub max_price_per_unit: u128, + pub max_amount: GasAmount, + pub max_price_per_unit: GasPrice, } pub struct SequencerContractAddress(pub ContractAddress); pub struct Signature { diff --git a/crates/papyrus_test_utils/src/lib.rs b/crates/papyrus_test_utils/src/lib.rs index a3145d67c9..321a19e412 100644 --- a/crates/papyrus_test_utils/src/lib.rs +++ b/crates/papyrus_test_utils/src/lib.rs @@ -733,8 +733,8 @@ auto_impl_get_test_instance! { L2Gas = 1, } pub struct ResourceBounds { - pub max_amount: u64, - pub max_price_per_unit: u128, + pub max_amount: GasAmount, + pub max_price_per_unit: GasPrice, } pub struct RpcContractClass { pub sierra_program: Vec, diff --git a/crates/starknet_api/src/block.rs b/crates/starknet_api/src/block.rs index c922cec750..1c74cdb859 100644 --- a/crates/starknet_api/src/block.rs +++ b/crates/starknet_api/src/block.rs @@ -7,6 +7,7 @@ use std::fmt::Display; use derive_more::Display; use itertools::Itertools; use serde::{Deserialize, Serialize}; +use starknet_types_core::felt::Felt; use starknet_types_core::hash::{Poseidon, StarkHash as CoreStarkHash}; use crate::core::{ @@ -264,6 +265,12 @@ impl From for PrefixedBytesAsHex<16_usize> { } } +impl From for Felt { + fn from(val: GasPrice) -> Self { + Felt::from(val.0) + } +} + impl GasPrice { pub const fn saturating_mul(self, rhs: GasAmount) -> Fee { #[allow(clippy::as_conversions)] diff --git a/crates/starknet_api/src/rpc_transaction_test.rs b/crates/starknet_api/src/rpc_transaction_test.rs index 92777b53ec..15faf7f2b8 100644 --- a/crates/starknet_api/src/rpc_transaction_test.rs +++ b/crates/starknet_api/src/rpc_transaction_test.rs @@ -3,7 +3,9 @@ use std::sync::Arc; use rstest::rstest; use starknet_types_core::felt::Felt; +use crate::block::GasPrice; use crate::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce, PatriciaKey}; +use crate::execution_resources::GasAmount; use crate::rpc_transaction::{ ContractClass, DataAvailabilityMode, @@ -29,9 +31,9 @@ use crate::{contract_address, felt, patricia_key}; fn create_resource_bounds_for_testing() -> AllResourceBounds { AllResourceBounds { - l1_gas: ResourceBounds { max_amount: 100, max_price_per_unit: 12 }, - l2_gas: ResourceBounds { max_amount: 58, max_price_per_unit: 31 }, - l1_data_gas: ResourceBounds { max_amount: 66, max_price_per_unit: 25 }, + l1_gas: ResourceBounds { max_amount: GasAmount(100), max_price_per_unit: GasPrice(12) }, + l2_gas: ResourceBounds { max_amount: GasAmount(58), max_price_per_unit: GasPrice(31) }, + l1_data_gas: ResourceBounds { max_amount: GasAmount(66), max_price_per_unit: GasPrice(25) }, } } diff --git a/crates/starknet_api/src/transaction.rs b/crates/starknet_api/src/transaction.rs index b8f424aa5f..28a5174f5d 100644 --- a/crates/starknet_api/src/transaction.rs +++ b/crates/starknet_api/src/transaction.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use starknet_types_core::felt::Felt; use strum_macros::EnumIter; -use crate::block::{BlockHash, BlockNumber, NonzeroGasPrice}; +use crate::block::{BlockHash, BlockNumber, GasPrice, NonzeroGasPrice}; use crate::core::{ ChainId, ClassHash, @@ -736,6 +736,7 @@ pub struct RevertedTransactionExecutionStatus { Serialize, PartialOrd, Ord, + derive_more::Add, derive_more::Deref, )] #[serde(from = "PrefixedBytesAsHex<16_usize>", into = "PrefixedBytesAsHex<16_usize>")] @@ -1028,49 +1029,53 @@ impl Resource { // TODO(Nimrod): Consider renaming this struct. pub struct ResourceBounds { // Specifies the maximum amount of each resource allowed for usage during the execution. - #[serde(serialize_with = "u64_to_hex", deserialize_with = "hex_to_u64")] - pub max_amount: u64, + #[serde(serialize_with = "gas_amount_to_hex", deserialize_with = "hex_to_gas_amount")] + pub max_amount: GasAmount, // Specifies the maximum price the user is willing to pay for each resource unit. - #[serde(serialize_with = "u128_to_hex", deserialize_with = "hex_to_u128")] - pub max_price_per_unit: u128, + #[serde(serialize_with = "gas_price_to_hex", deserialize_with = "hex_to_gas_price")] + pub max_price_per_unit: GasPrice, } impl ResourceBounds { /// Returns true iff both the max amount and the max amount per unit is zero. pub fn is_zero(&self) -> bool { - self.max_amount == 0 && self.max_price_per_unit == 0 + self.max_amount == GasAmount(0) && self.max_price_per_unit == GasPrice(0) } } -fn u64_to_hex(value: &u64, serializer: S) -> Result +fn gas_amount_to_hex(value: &GasAmount, serializer: S) -> Result where S: Serializer, { - serializer.serialize_str(&format!("0x{:x}", value)) + serializer.serialize_str(&format!("0x{:x}", value.0)) } -fn hex_to_u64<'de, D>(deserializer: D) -> Result +fn hex_to_gas_amount<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { let s: String = Deserialize::deserialize(deserializer)?; - u64::from_str_radix(s.trim_start_matches("0x"), 16).map_err(serde::de::Error::custom) + Ok(GasAmount( + u64::from_str_radix(s.trim_start_matches("0x"), 16).map_err(serde::de::Error::custom)?, + )) } -fn u128_to_hex(value: &u128, serializer: S) -> Result +fn gas_price_to_hex(value: &GasPrice, serializer: S) -> Result where S: Serializer, { - serializer.serialize_str(&format!("0x{:x}", value)) + serializer.serialize_str(&format!("0x{:x}", value.0)) } -fn hex_to_u128<'de, D>(deserializer: D) -> Result +fn hex_to_gas_price<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { let s: String = Deserialize::deserialize(deserializer)?; - u128::from_str_radix(s.trim_start_matches("0x"), 16).map_err(serde::de::Error::custom) + Ok(GasPrice( + u128::from_str_radix(s.trim_start_matches("0x"), 16).map_err(serde::de::Error::custom)?, + )) } #[derive(Debug, PartialEq)] @@ -1106,21 +1111,20 @@ impl ValidResourceBounds { } pub fn max_possible_fee(&self) -> Fee { - Fee(match self { + match self { ValidResourceBounds::L1Gas(l1_bounds) => { - let max_amount: u128 = l1_bounds.max_amount.into(); - max_amount * l1_bounds.max_price_per_unit + l1_bounds.max_amount.saturating_mul(l1_bounds.max_price_per_unit) } ValidResourceBounds::AllResources(AllResourceBounds { l1_gas, l2_gas, l1_data_gas, }) => { - u128::from(l1_gas.max_amount) * l1_gas.max_price_per_unit - + u128::from(l2_gas.max_amount) * l2_gas.max_price_per_unit - + u128::from(l1_data_gas.max_amount) * l1_data_gas.max_price_per_unit + l1_gas.max_amount.saturating_mul(l1_gas.max_price_per_unit) + + l2_gas.max_amount.saturating_mul(l2_gas.max_price_per_unit) + + l1_data_gas.max_amount.saturating_mul(l1_data_gas.max_price_per_unit) } - }) + } } pub fn get_gas_vector_computation_mode(&self) -> GasVectorComputationMode { @@ -1133,7 +1137,7 @@ impl ValidResourceBounds { // TODO(Nimrod): Default testing bounds should probably be AllResourceBounds variant. #[cfg(any(feature = "testing", test))] pub fn create_for_testing() -> Self { - Self::L1Gas(ResourceBounds { max_amount: 0, max_price_per_unit: 1 }) + Self::L1Gas(ResourceBounds { max_amount: GasAmount(0), max_price_per_unit: GasPrice(1) }) } } diff --git a/crates/starknet_api/src/transaction_hash.rs b/crates/starknet_api/src/transaction_hash.rs index 9178f0e9a0..b6b0d98c6f 100644 --- a/crates/starknet_api/src/transaction_hash.rs +++ b/crates/starknet_api/src/transaction_hash.rs @@ -200,8 +200,8 @@ fn get_concat_resource( resource_bounds: &ResourceBounds, resource_name: &ResourceName, ) -> Result { - let max_amount = resource_bounds.max_amount.to_be_bytes(); - let max_price = resource_bounds.max_price_per_unit.to_be_bytes(); + let max_amount = resource_bounds.max_amount.0.to_be_bytes(); + let max_price = resource_bounds.max_price_per_unit.0.to_be_bytes(); let concat_bytes = [[0_u8].as_slice(), resource_name.as_slice(), max_amount.as_slice(), max_price.as_slice()] .concat();