Skip to content

Commit

Permalink
build(fee): current tx_info holds validResourceBounds
Browse files Browse the repository at this point in the history
  • Loading branch information
nimrod-starkware committed Aug 21, 2024
1 parent ca7e160 commit f480667
Show file tree
Hide file tree
Showing 17 changed files with 115 additions and 87 deletions.
2 changes: 1 addition & 1 deletion crates/blockifier/src/concurrency/versioned_state_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ fn test_run_parallel_txs(max_resource_bounds: DeprecatedResourceBoundsMapping) {
&mut NonceManager::default(),
);
let account_tx_1 = AccountTransaction::DeployAccount(deploy_account_tx_1);
let enforce_fee = account_tx_1.create_tx_info().enforce_fee().unwrap();
let enforce_fee = account_tx_1.create_tx_info().enforce_fee();

let class_hash = grindy_account.get_class_hash();
let ctor_storage_arg = felt!(1_u8);
Expand Down
27 changes: 12 additions & 15 deletions crates/blockifier/src/execution/entry_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::execution::errors::{
};
use crate::execution::execution_utils::execute_entry_point_call;
use crate::state::state_api::State;
use crate::transaction::objects::{HasRelatedFeeType, TransactionExecutionResult, TransactionInfo};
use crate::transaction::objects::{HasRelatedFeeType, TransactionInfo};
use crate::transaction::transaction_types::TransactionType;
use crate::utils::{u128_from_usize, usize_from_u128};
use crate::versioned_constants::{GasCosts, VersionedConstants};
Expand Down Expand Up @@ -135,29 +135,26 @@ impl EntryPointExecutionContext {
tx_context: Arc<TransactionContext>,
mode: ExecutionMode,
limit_steps_by_resources: bool,
) -> TransactionExecutionResult<Self> {
let max_steps = Self::max_steps(&tx_context, &mode, limit_steps_by_resources)?;
Ok(Self {
) -> Self {
let max_steps = Self::max_steps(&tx_context, &mode, limit_steps_by_resources);
Self {
vm_run_resources: RunResources::new(max_steps),
n_emitted_events: 0,
n_sent_messages_to_l1: 0,
tx_context: tx_context.clone(),
current_recursion_depth: Default::default(),
execution_mode: mode,
})
}
}

pub fn new_validate(
tx_context: Arc<TransactionContext>,
limit_steps_by_resources: bool,
) -> TransactionExecutionResult<Self> {
) -> Self {
Self::new(tx_context, ExecutionMode::Validate, limit_steps_by_resources)
}

pub fn new_invoke(
tx_context: Arc<TransactionContext>,
limit_steps_by_resources: bool,
) -> TransactionExecutionResult<Self> {
pub fn new_invoke(tx_context: Arc<TransactionContext>, limit_steps_by_resources: bool) -> Self {
Self::new(tx_context, ExecutionMode::Execute, limit_steps_by_resources)
}

Expand All @@ -168,7 +165,7 @@ impl EntryPointExecutionContext {
tx_context: &TransactionContext,
mode: &ExecutionMode,
limit_steps_by_resources: bool,
) -> TransactionExecutionResult<usize> {
) -> usize {
let TransactionContext { block_context, tx_info } = tx_context;
let BlockContext { block_info, versioned_constants, .. } = block_context;
let block_upper_bound = match mode {
Expand All @@ -184,8 +181,8 @@ impl EntryPointExecutionContext {
.expect("Failed to convert invoke_tx_max_n_steps (u32) to usize."),
};

if !limit_steps_by_resources || !tx_info.enforce_fee()? {
return Ok(block_upper_bound);
if !limit_steps_by_resources || !tx_info.enforce_fee() {
return block_upper_bound;
}

let gas_per_step = versioned_constants
Expand Down Expand Up @@ -214,7 +211,7 @@ impl EntryPointExecutionContext {
// TODO(Ori, 1/2/2024): Write an indicative expect message explaining why the
// convertion works.
context
.l1_resource_bounds()?
.l1_resource_bounds()
.max_amount
.try_into()
.expect("Failed to convert u64 to usize.")
Expand All @@ -236,7 +233,7 @@ impl EntryPointExecutionContext {
);
usize::MAX
});
Ok(min(tx_upper_bound, block_upper_bound))
min(tx_upper_bound, block_upper_bound)
}

/// Returns the available steps in run resources.
Expand Down
52 changes: 34 additions & 18 deletions crates/blockifier/src/execution/syscalls/hint_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use cairo_vm::vm::vm_core::VirtualMachine;
use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector};
use starknet_api::deprecated_contract_class::EntryPointType;
use starknet_api::state::StorageKey;
use starknet_api::transaction::{Calldata, Resource};
use starknet_api::transaction::{AllResourceBounds, Calldata, ValidResourceBounds};
use starknet_api::StarknetApiError;
use starknet_types_core::felt::{Felt, FromStrError};
use thiserror::Error;
Expand Down Expand Up @@ -205,6 +205,8 @@ pub const INVALID_ARGUMENT: &str =
pub const L1_GAS: &str = "0x00000000000000000000000000000000000000000000000000004c315f474153";
// "L2_GAS";
pub const L2_GAS: &str = "0x00000000000000000000000000000000000000000000000000004c325f474153";
// "L1_DATA_GAS"
pub const L1_DATA_GAS: &str = "0x0000000000000000000000000000000000000000004c315f444154415f474153";

/// Executes Starknet syscalls (stateful protocol hints) during the execution of an entry point
/// call.
Expand Down Expand Up @@ -462,26 +464,40 @@ impl<'a> SyscallHintProcessor<'a> {
vm: &mut VirtualMachine,
tx_info: &CurrentTransactionInfo,
) -> SyscallResult<(Relocatable, Relocatable)> {
let l1_gas = Felt::from_hex(L1_GAS).map_err(SyscallExecutionError::from)?;
let l2_gas = Felt::from_hex(L2_GAS).map_err(SyscallExecutionError::from)?;
let flat_resource_bounds: Vec<Felt> = tx_info
.resource_bounds
.0
.iter()
.flat_map(|(resource, resource_bounds)| {
let resource = match resource {
Resource::L1Gas => l1_gas,
Resource::L2Gas => l2_gas,
Resource::L1DataGas => todo!(),
};
let l1_gas_as_felt = Felt::from_hex(L1_GAS).map_err(SyscallExecutionError::from)?;
let l2_gas_as_felt = Felt::from_hex(L2_GAS).map_err(SyscallExecutionError::from)?;
let l1_data_gas_as_felt =
Felt::from_hex(L1_DATA_GAS).map_err(SyscallExecutionError::from)?;

let flat_resource_bounds = match tx_info.resource_bounds {
ValidResourceBounds::L1Gas(l1_bounds) => {
vec![
resource,
Felt::from(resource_bounds.max_amount),
Felt::from(resource_bounds.max_price_per_unit),
l1_gas_as_felt,
Felt::from(l1_bounds.max_amount),
Felt::from(l1_bounds.max_price_per_unit),
l2_gas_as_felt,
Felt::ZERO,
Felt::ZERO,
]
})
.collect();
}
ValidResourceBounds::AllResources(AllResourceBounds {
l1_gas,
l2_gas,
l1_data_gas,
}) => {
vec![
l1_gas_as_felt,
Felt::from(l1_gas.max_amount),
Felt::from(l1_gas.max_price_per_unit),
l2_gas_as_felt,
Felt::from(l2_gas.max_amount),
Felt::from(l2_gas.max_price_per_unit),
l1_data_gas_as_felt,
Felt::from(l1_data_gas.max_amount),
Felt::from(l1_data_gas.max_price_per_unit),
]
}
};

self.allocate_data_segment(vm, &flat_resource_bounds)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::abi::abi_utils::selector_from_name;
use crate::context::ChainInfo;
use crate::execution::common_hints::ExecutionMode;
use crate::execution::entry_point::CallEntryPoint;
use crate::execution::syscalls::hint_processor::{L1_GAS, L2_GAS};
use crate::execution::syscalls::hint_processor::{L1_DATA_GAS, L1_GAS, L2_GAS};
use crate::nonce;
use crate::test_utils::contracts::FeatureContract;
use crate::test_utils::initial_test_state::test_state;
Expand Down Expand Up @@ -227,7 +227,9 @@ fn test_get_execution_info(
},
),
(Resource::L2Gas, ResourceBounds { max_amount: 0, max_price_per_unit: 0 }),
])),
]))
.try_into()
.unwrap(),
tip: Tip::default(),
nonce_data_availability_mode: DataAvailabilityMode::L1,
fee_data_availability_mode: DataAvailabilityMode::L1,
Expand Down Expand Up @@ -269,3 +271,21 @@ fn test_get_execution_info(

assert!(!result.unwrap().execution.failed);
}

#[test]
fn test_gas_types_constants() {
assert_eq!(str_to_32_bytes_in_hex("L1_GAS"), L1_GAS);
assert_eq!(str_to_32_bytes_in_hex("L2_GAS"), L2_GAS);
assert_eq!(str_to_32_bytes_in_hex("L1_DATA_GAS"), L1_DATA_GAS);
}

fn str_to_32_bytes_in_hex(s: &str) -> String {
if s.len() > 32 {
panic!("Unsupported input of length > 32.")
}
let prefix = "0x";
let padding_zeros = "0".repeat(64 - s.len() * 2); // Each string char is 2 chars in hex.
let word_in_hex: String =
s.as_bytes().iter().fold(String::new(), |s, byte| s + (&format!("{:02x}", byte)));
[prefix, &padding_zeros, &word_in_hex].into_iter().collect()
}
2 changes: 1 addition & 1 deletion crates/blockifier/src/fee/actual_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl TransactionReceipt {
)?;

// L1 handler transactions are not charged an L2 fee but it is compared to the L1 fee.
let fee = if tx_context.tx_info.enforce_fee()? || tx_type == TransactionType::L1Handler {
let fee = if tx_context.tx_info.enforce_fee() || tx_type == TransactionType::L1Handler {
tx_context.tx_info.get_fee_by_gas_vector(&tx_context.block_context.block_info, gas)
} else {
Fee(0)
Expand Down
14 changes: 7 additions & 7 deletions crates/blockifier/src/fee/fee_checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl FeeCheckReport {
actual_fee: Fee,
error: FeeCheckError,
tx_context: &TransactionContext,
) -> TransactionExecutionResult<Self> {
) -> Self {
let recommended_fee = match error {
// If the error is insufficient balance, the recommended fee is the actual fee.
// This recommendation assumes (a) the pre-validation checks were applied and pass (i.e.
Expand All @@ -75,14 +75,14 @@ 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.into()),
&FeeType::Strk,
),
TransactionInfo::Deprecated(context) => context.max_fee,
}
}
};
Ok(Self { recommended_fee, error: Some(error) })
Self { recommended_fee, error: Some(error) }
}

/// If the actual cost exceeds the resource bounds on the transaction, returns a fee check
Expand All @@ -100,7 +100,7 @@ impl FeeCheckReport {
match tx_info {
TransactionInfo::Current(context) => {
// Check L1 gas limit.
let max_l1_gas = context.l1_resource_bounds()?.max_amount.into();
let max_l1_gas = context.l1_resource_bounds().max_amount.into();

// TODO(Dori, 1/7/2024): When data gas limit is added (and enforced) in resource
// bounds, check it here as well (separately, with a different error variant if
Expand Down Expand Up @@ -172,7 +172,7 @@ impl PostValidationReport {
tx_receipt: &TransactionReceipt,
) -> TransactionExecutionResult<()> {
// If fee is not enforced, no need to check post-execution.
if !tx_context.tx_info.enforce_fee()? {
if !tx_context.tx_info.enforce_fee() {
return Ok(());
}

Expand All @@ -192,7 +192,7 @@ impl PostExecutionReport {
let TransactionReceipt { fee, .. } = tx_receipt;

// If fee is not enforced, no need to check post-execution.
if !charge_fee || !tx_context.tx_info.enforce_fee()? {
if !charge_fee || !tx_context.tx_info.enforce_fee() {
return Ok(Self(FeeCheckReport::success_report(*fee)));
}

Expand All @@ -216,7 +216,7 @@ impl PostExecutionReport {
*fee,
fee_check_error,
tx_context,
)?));
)));
}
Err(other_error) => return Err(other_error),
}
Expand Down
4 changes: 2 additions & 2 deletions crates/blockifier/src/fee/fee_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub fn verify_can_pay_committed_bounds(
let tx_info = &tx_context.tx_info;
let committed_fee = match tx_info {
TransactionInfo::Current(context) => {
let l1_bounds = context.l1_resource_bounds()?;
let l1_bounds = context.l1_resource_bounds();
let max_amount: u128 = l1_bounds.max_amount.into();
// Sender will not be charged by `max_price_per_unit`, but this check should not depend
// on the current gas price.
Expand All @@ -122,7 +122,7 @@ pub fn verify_can_pay_committed_bounds(
} else {
Err(match tx_info {
TransactionInfo::Current(context) => {
let l1_bounds = context.l1_resource_bounds()?;
let l1_bounds = context.l1_resource_bounds();
TransactionFeeError::L1GasBoundsExceedBalance {
max_amount: l1_bounds.max_amount,
max_price: l1_bounds.max_price_per_unit,
Expand Down
3 changes: 1 addition & 2 deletions crates/blockifier/src/test_utils/prices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ fn fee_transfer_resources(
Arc::new(block_context.to_tx_context(&account_invoke_tx(InvokeTxArgs::default()))),
ExecutionMode::Execute,
false,
)
.unwrap(),
),
)
.unwrap()
.resources
Expand Down
6 changes: 2 additions & 4 deletions crates/blockifier/src/test_utils/struct_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ impl CallEntryPoint {
let tx_context =
TransactionContext { block_context: BlockContext::create_for_testing(), tx_info };
let mut context =
EntryPointExecutionContext::new_invoke(Arc::new(tx_context), limit_steps_by_resources)
.unwrap();
EntryPointExecutionContext::new_invoke(Arc::new(tx_context), limit_steps_by_resources);
self.execute(state, &mut ExecutionResources::default(), &mut context)
}

Expand Down Expand Up @@ -99,8 +98,7 @@ impl CallEntryPoint {
let mut context = EntryPointExecutionContext::new_validate(
Arc::new(tx_context),
limit_steps_by_resources,
)
.unwrap();
);
self.execute(state, &mut ExecutionResources::default(), &mut context)
}
}
Expand Down
Loading

0 comments on commit f480667

Please sign in to comment.