Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(fee): current tx_info holds validResourceBounds #505

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
51 changes: 33 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";
pub const L1_DATA: &str = "0x000000000000000000000000000000000000000000000000004c315f44415441";

/// Executes Starknet syscalls (stateful protocol hints) during the execution of an entry point
/// call.
Expand Down Expand Up @@ -462,26 +464,39 @@ 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).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, 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"), L1_DATA);
}

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
Loading