From 5411b13c6f83e3c962b1ef30fbdf391e6326b676 Mon Sep 17 00:00:00 2001 From: sistemd Date: Mon, 3 Feb 2025 11:41:28 +0100 Subject: [PATCH 1/3] search l2 gas limit for post 0.13.4 transactions --- crates/executor/src/estimate.rs | 426 +++++++++- .../l2_gas_accounting/l2_gas_accounting.casm | 781 ++++++++++++++++++ ...counting_HelloStarknet.contract_class.json | 611 ++++++++++++++ .../contracts/l2_gas_accounting/lib.cairo | 137 +++ crates/rpc/src/method/estimate_fee.rs | 167 ++++ 5 files changed, 2090 insertions(+), 32 deletions(-) create mode 100644 crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.casm create mode 100644 crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting_HelloStarknet.contract_class.json create mode 100644 crates/rpc/fixtures/contracts/l2_gas_accounting/lib.cairo diff --git a/crates/executor/src/estimate.rs b/crates/executor/src/estimate.rs index 0580a4b87e..cc1e931f71 100644 --- a/crates/executor/src/estimate.rs +++ b/crates/executor/src/estimate.rs @@ -1,8 +1,13 @@ +use blockifier::state::cached_state::CachedState; +use blockifier::state::state_api::UpdatableState; +use blockifier::transaction::objects::TransactionExecutionInfo; use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transactions::ExecutableTransaction; +use starknet_api::execution_resources::GasAmount; use super::error::TransactionExecutionError; use super::execution_state::ExecutionState; +use super::transaction::transaction_hash; use super::types::FeeEstimate; pub fn estimate( @@ -13,54 +18,411 @@ pub fn estimate( let (mut state, block_context) = execution_state.starknet_state()?; - let mut fees = Vec::with_capacity(transactions.len()); - for (transaction_idx, transaction) in transactions.into_iter().enumerate() { - let _span = tracing::debug_span!("estimate", transaction_hash=%super::transaction::transaction_hash(&transaction), %block_number, %transaction_idx).entered(); + transactions + .into_iter() + .enumerate() + .map(|(tx_index, mut tx)| { + let _span = tracing::debug_span!( + "estimate", + block_number = %block_number, + transaction_hash = %transaction_hash(&tx), + transaction_index = %tx_index + ) + .entered(); - let fee_type = super::transaction::fee_type(&transaction); + let tx_info = match fee_estimation_version(&tx) { + FeeEstimationVersion::WithoutL2Gas => { + execute_transaction(&tx, tx_index, &mut state, &block_context) + } + FeeEstimationVersion::WithL2Gas => find_l2_gas_limit_and_execute_transaction( + &mut tx, + tx_index, + &mut state, + &block_context, + ), + }?; + + tracing::trace!( + actual_fee = %tx_info.receipt.fee.0, + actual_resources = ?tx_info.receipt.resources, + "Transaction estimation finished" + ); + + Ok(FeeEstimate::from_tx_and_tx_info( + &tx, + &tx_info, + &block_context, + )) + }) + .collect() +} + +/// The margin for the binary search for the minimal L2 gas limit. +const L2_GAS_SEARCH_MARGIN: GasAmount = GasAmount(100); + +/// Searches for the minimal L2 gas limit (within a certain margin) that allows +/// the transaction to execute without running out of L2 gas. Uses this limit to +/// execute the transaction. Exceeding the user provided L2 gas limit is not +/// allowed. +/// +/// This is needed because Starknet 0.13.4 introduced runtime L2 gas accounting +/// which could lead to transactions being reverted because of insufficient L2 +/// gas, even though the limit was set to the L2 gas cost of the transaction +/// (because the worst-case path gas requirements are larger than the actual +/// cost). +fn find_l2_gas_limit_and_execute_transaction( + tx: &mut Transaction, + tx_index: usize, + state: &mut S, + block_context: &blockifier::context::BlockContext, +) -> Result +where + S: UpdatableState, +{ + let initial_l2_gas_limit = get_l2_gas_limit(tx); + + // Start with MAX gas limit to get the consumed L2 gas. + update_l2_gas_limit(tx, GasAmount::MAX); + let tx_info = match simulate_transaction(tx, tx_index, state, block_context) { + Ok(tx_info) => tx_info, + Err(TransactionSimulationError::ExecutionError(error)) => { + return Err(error); + } + Err(TransactionSimulationError::OutOfGas) => { + unreachable!("Transaction should not run out of gas with MAX gas limit") + } + }; + + let l2_gas_consumed = tx_info.receipt.gas.l2_gas; + + // TODO: g = (1 + EPSILON) * g + // This step is missing. Check what EPSILON is, then implement it. + + let mut lower_bound = l2_gas_consumed; + let mut upper_bound = GasAmount::MAX; + + let mut current_l2_gas_limit = midpoint(lower_bound, upper_bound); + + // Run a binary search to find the minimal gas limit that still allows the + // transaction to execute without running out of L2 gas. + loop { + tracing::debug!(current_limit=%current_l2_gas_limit, "Searching for minimal L2 gas limit"); + update_l2_gas_limit(tx, current_l2_gas_limit); + + match simulate_transaction(tx, tx_index, state, block_context) { + Ok(_) => { + if search_done(lower_bound, upper_bound, L2_GAS_SEARCH_MARGIN) { + break; + } + + upper_bound = current_l2_gas_limit; + current_l2_gas_limit = midpoint(lower_bound, upper_bound); + } + Err(TransactionSimulationError::OutOfGas) => { + lower_bound = current_l2_gas_limit; + current_l2_gas_limit = midpoint(lower_bound, upper_bound); + } + Err(TransactionSimulationError::ExecutionError(error)) => { + return Err(error); + } + } + } + + if current_l2_gas_limit > initial_l2_gas_limit { + tracing::debug!( + initial_limit=%initial_l2_gas_limit, + final_limit=%current_l2_gas_limit, + "Initial L2 gas limit exceeded" + ); + // Set the L2 gas limit to zero so that the transaction reverts. + update_l2_gas_limit(tx, GasAmount::ZERO); + return execute_transaction(tx, tx_index, state, block_context); + } + + // Finally, execute the transaction with the found L2 gas limit and set that + // limit as the estimate. + let mut tx_info = execute_transaction(tx, tx_index, state, block_context) + .expect("Transaction already executed successfully"); + tx_info.receipt.gas.l2_gas = current_l2_gas_limit; + + Ok(tx_info) +} + +/// Calculates the midpoint between two gas amounts without overflowing. +fn midpoint(a: GasAmount, b: GasAmount) -> GasAmount { + let GasAmount(a) = a; + let GasAmount(b) = b; + GasAmount(a + (b - a) / 2) +} + +fn search_done(lower_bound: GasAmount, upper_bound: GasAmount, search_margin: GasAmount) -> bool { + let diff = upper_bound + .checked_sub(lower_bound) + .expect("Upper bound should be greater than lower bound"); + + diff <= search_margin +} + +/// Execute the transaction and handle common errors. +fn execute_transaction( + tx: &Transaction, + tx_index: usize, + state: &mut S, + block_context: &blockifier::context::BlockContext, +) -> Result +where + S: UpdatableState, +{ + match tx.execute(state, block_context) { + Ok(tx_info) => { + if let Some(revert_error) = tx_info.revert_error { + let revert_string = revert_error.to_string(); + tracing::debug!(revert_error=%revert_string, "Transaction reverted"); + + return Err(TransactionExecutionError::ExecutionError { + transaction_index: tx_index, + error: revert_string, + error_stack: revert_error.into(), + }); + } + + Ok(tx_info) + } + Err(error) => { + tracing::debug!(%error, %tx_index, "Transaction estimation failed"); + + Err(TransactionExecutionError::new(tx_index, error)) + } + } +} + +/// Execute transaction without updating the execution state. +fn simulate_transaction( + tx: &Transaction, + tx_index: usize, + state: &mut S, + block_context: &blockifier::context::BlockContext, +) -> Result +where + S: UpdatableState, +{ + // No need to call `.abort()` since it just drops the state. + let mut tx_state = CachedState::<_>::create_transactional(state); + match tx.execute(&mut tx_state, block_context) { + Ok(tx_info) if failed_with_insufficient_l2_gas(&tx_info) => { + Err(TransactionSimulationError::OutOfGas) + } + Ok(tx_info) => Ok(tx_info), + Err(error) => { + tracing::debug!(%error, %tx_index, "Transaction simulation failed"); + let error = TransactionExecutionError::new(tx_index, error); + + Err(TransactionSimulationError::ExecutionError(error)) + } + } +} + +enum TransactionSimulationError { + OutOfGas, + ExecutionError(TransactionExecutionError), +} + +impl FeeEstimate { + fn from_tx_and_tx_info( + transaction: &Transaction, + tx_info: &TransactionExecutionInfo, + block_context: &blockifier::context::BlockContext, + ) -> Self { + let fee_type = super::transaction::fee_type(transaction); let gas_vector_computation_mode = super::transaction::gas_vector_computation_mode(&transaction); - let minimal_l1_gas_amount_vector = match &transaction { + let minimal_gas_vector = match transaction { Transaction::Account(account_transaction) => { Some(blockifier::fee::gas_usage::estimate_minimal_gas_vector( - &block_context, + block_context, account_transaction, &gas_vector_computation_mode, )) } Transaction::L1Handler(_) => None, }; - let tx_info: Result< - blockifier::transaction::objects::TransactionExecutionInfo, - blockifier::transaction::errors::TransactionExecutionError, - > = transaction.execute(&mut state, &block_context); - - match tx_info { - Ok(tx_info) => { - if let Some(revert_error) = tx_info.revert_error { - let revert_string = revert_error.to_string(); - tracing::debug!(revert_error=%revert_string, "Transaction reverted"); - return Err(TransactionExecutionError::ExecutionError { - transaction_index: transaction_idx, - error: revert_string, - error_stack: revert_error.into(), - }); + + FeeEstimate::from_tx_info_and_gas_price( + tx_info, + block_context.block_info(), + fee_type, + &minimal_gas_vector, + ) + } +} + +fn update_l2_gas_limit(transaction: &mut Transaction, gas_limit: GasAmount) { + if let Transaction::Account(ref mut account_transaction) = transaction { + use starknet_api::executable_transaction::AccountTransaction; + use starknet_api::transaction::fields::ValidResourceBounds; + + match &mut account_transaction.tx { + AccountTransaction::Declare(ref mut tx) => { + use starknet_api::transaction::DeclareTransaction; + if let DeclareTransaction::V3(ref mut tx) = &mut tx.tx { + match &mut tx.resource_bounds { + ValidResourceBounds::L1Gas(_) => {} + ValidResourceBounds::AllResources(ref mut all_resource_bounds) => { + all_resource_bounds.l2_gas.max_amount = gas_limit; + return; + } + } + } + } + AccountTransaction::DeployAccount(ref mut tx) => { + use starknet_api::transaction::DeployAccountTransaction; + if let DeployAccountTransaction::V3(ref mut tx) = &mut tx.tx { + match &mut tx.resource_bounds { + ValidResourceBounds::L1Gas(_) => {} + ValidResourceBounds::AllResources(ref mut all_resource_bounds) => { + all_resource_bounds.l2_gas.max_amount = gas_limit; + return; + } + } + } + } + AccountTransaction::Invoke(tx) => { + use starknet_api::transaction::InvokeTransaction; + if let InvokeTransaction::V3(ref mut tx) = &mut tx.tx { + match &mut tx.resource_bounds { + ValidResourceBounds::L1Gas(_) => {} + ValidResourceBounds::AllResources(ref mut all_resource_bounds) => { + all_resource_bounds.l2_gas.max_amount = gas_limit; + return; + } + } } + } + } + } + + // This function should only be called with account transaction versions that + // have L2 gas. It's a pain to set it up through the type system, so we'll + // just return early in expected cases (see match above) and panic if we get + // here. + tracing::debug!(transaction=?transaction, "update_l2_gas_limit() called with a transaction that doesn't have L2 gas"); + unreachable!(); +} - tracing::trace!(actual_fee=%tx_info.receipt.fee.0, actual_resources=?tx_info.receipt.resources, "Transaction estimation finished"); +fn get_l2_gas_limit(tx: &Transaction) -> GasAmount { + if let Transaction::Account(account_transaction) = tx { + use starknet_api::executable_transaction::AccountTransaction; + use starknet_api::transaction::fields::ValidResourceBounds; - fees.push(FeeEstimate::from_tx_info_and_gas_price( - &tx_info, - block_context.block_info(), - fee_type, - &minimal_l1_gas_amount_vector, - )); + match &account_transaction.tx { + AccountTransaction::Declare(tx) => { + use starknet_api::transaction::DeclareTransaction; + if let DeclareTransaction::V3(tx) = &tx.tx { + match &tx.resource_bounds { + ValidResourceBounds::L1Gas(_) => {} + ValidResourceBounds::AllResources(all_resource_bounds) => { + return all_resource_bounds.l2_gas.max_amount; + } + } + } + } + AccountTransaction::DeployAccount(tx) => { + use starknet_api::transaction::DeployAccountTransaction; + if let DeployAccountTransaction::V3(tx) = &tx.tx { + match &tx.resource_bounds { + ValidResourceBounds::L1Gas(_) => {} + ValidResourceBounds::AllResources(all_resource_bounds) => { + return all_resource_bounds.l2_gas.max_amount; + } + } + } } - Err(error) => { - tracing::debug!(%error, %transaction_idx, "Transaction estimation failed"); - return Err(TransactionExecutionError::new(transaction_idx, error)); + AccountTransaction::Invoke(tx) => { + use starknet_api::transaction::InvokeTransaction; + if let InvokeTransaction::V3(tx) = &tx.tx { + match &tx.resource_bounds { + ValidResourceBounds::L1Gas(_) => {} + ValidResourceBounds::AllResources(all_resource_bounds) => { + return all_resource_bounds.l2_gas.max_amount; + } + } + } } } } - Ok(fees) + + // This function should only be called with account transaction versions that + // have L2 gas. It's a pain to set it up through the type system, so we'll + // just return early in expected cases (see match above) and panic if we get + // here. + tracing::debug!(transaction=?tx, "update_l2_gas_limit() called with a transaction that doesn't have L2 gas"); + unreachable!(); +} + +fn fee_estimation_version(transaction: &Transaction) -> FeeEstimationVersion { + fn fee_estimation_from_resource_bounds( + resource_bounds: &starknet_api::transaction::fields::ValidResourceBounds, + ) -> FeeEstimationVersion { + use starknet_api::transaction::fields::ValidResourceBounds; + match resource_bounds { + ValidResourceBounds::AllResources(_) => FeeEstimationVersion::WithL2Gas, + ValidResourceBounds::L1Gas(_) => FeeEstimationVersion::WithoutL2Gas, + } + } + + match &transaction { + Transaction::Account(account_transaction) => { + use starknet_api::executable_transaction::AccountTransaction; + match &account_transaction.tx { + AccountTransaction::Declare(inner) => { + use starknet_api::transaction::DeclareTransaction; + match &inner.tx { + DeclareTransaction::V3(tx) => { + fee_estimation_from_resource_bounds(&tx.resource_bounds) + } + _ => FeeEstimationVersion::WithoutL2Gas, + } + } + AccountTransaction::DeployAccount(inner) => { + use starknet_api::transaction::DeployAccountTransaction; + match &inner.tx { + DeployAccountTransaction::V3(tx) => { + fee_estimation_from_resource_bounds(&tx.resource_bounds) + } + _ => FeeEstimationVersion::WithoutL2Gas, + } + } + AccountTransaction::Invoke(inner) => { + use starknet_api::transaction::InvokeTransaction; + match &inner.tx { + InvokeTransaction::V3(tx) => { + fee_estimation_from_resource_bounds(&tx.resource_bounds) + } + _ => FeeEstimationVersion::WithoutL2Gas, + } + } + } + } + Transaction::L1Handler(_) => FeeEstimationVersion::WithoutL2Gas, + } +} + +/// Fee estimation can currently take place in two ways - with or without L2 +/// gas. +/// +/// For the transactions before Starknet 0.13.4, the fee estimation is done +/// without L2 gas. For the ones after this version, the fee estimation is done +/// with L2 gas. +enum FeeEstimationVersion { + WithoutL2Gas, + WithL2Gas, +} + +fn failed_with_insufficient_l2_gas(tx_info: &TransactionExecutionInfo) -> bool { + let Some(revert_error) = &tx_info.revert_error else { + return false; + }; + + // TODO: Is there a type-safe way to check for this error? + revert_error.to_string().contains("Out of gas") } diff --git a/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.casm b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.casm new file mode 100644 index 0000000000..038d27b127 --- /dev/null +++ b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.casm @@ -0,0 +1,781 @@ +ap += 1; +%{ memory[ap + 0] = 8790 <= memory[fp + -4] %} +jmp rel 7 if [ap + 0] != 0, ap++; +[ap + 0] = [fp + -4] + 340282366920938463463374607431768202666, ap++; +[ap + -1] = [[fp + -5] + 0]; +jmp rel 169; +[fp + -4] = [ap + 0] + 8790, ap++; +[ap + -1] = [[fp + -5] + 0]; +[ap + 0] = 1, ap++; +[fp + -3] = [ap + 1] + [ap + -1], ap++; +%{ memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456 %} +jmp rel 7 if [ap + -1] != 0, ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[fp + -5] + 1]; +jmp rel 142; +[ap + -1] = [[fp + -5] + 1]; +[ap + 0] = [fp + -5] + 2, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -3], ap++; +call rel -27; +jmp rel 126 if [ap + -3] != 0; +[ap + 0] = 2, ap++; +[fp + 0] = [ap + -2]; +[fp + -3] = [ap + 1] + [ap + -1], ap++; +%{ memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456 %} +jmp rel 7 if [ap + -1] != 0, ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[ap + -9] + 0]; +jmp rel 101; +[ap + -1] = [[ap + -8] + 0]; +[ap + 0] = [ap + -8] + 1, ap++; +[ap + 0] = [ap + -8], ap++; +[ap + 0] = [ap + -3], ap++; +call rel -47; +jmp rel 85 if [ap + -3] != 0; +[ap + 0] = 2, ap++; +%{ (memory[ap + 0], memory[ap + 1]) = divmod(memory[ap + -1] * memory[ap + -2], 2**128) %} +ap += 2; +%{ (memory[ap + 1], memory[ap + 0]) = divmod(memory[ap + -3], 18446744073709551616) %} +[ap + 2] = [ap + 0] + 340282366920938463444927863358058659840, ap++; +[ap + 1] = [[ap + -9] + 0], ap++; +[ap + -2] = [[ap + -10] + 1], ap++; +[ap + -2] = [[ap + -11] + 2]; +[ap + 0] = [ap + -2] * 18446744073709551616, ap++; +[ap + -7] = [ap + -1] + [ap + -4]; +[ap + 0] = [ap + -4] * [ap + -8], ap++; +[ap + 0] = [ap + -4] * [ap + -9], ap++; +%{ (memory[ap + 0], memory[ap + 1]) = divmod(memory[ap + -1], 18446744073709551616) %} +[ap + 2] = [ap + 1] + 340282366920938463444927863358058659840, ap++; +[ap + 1] = [[ap + -15] + 3], ap++; +[ap + -1] = [[ap + -16] + 4], ap++; +[ap + -3] = [[ap + -17] + 5]; +[ap + 0] = [ap + -3] * 18446744073709551616, ap++; +[ap + -5] = [ap + -1] + [ap + -3]; +[ap + 0] = [ap + -3] * 18446744073709551616, ap++; +[ap + 3] = [ap + -7] + [ap + -1], ap++; +%{ (memory[ap + -1], memory[ap + -13]) = divmod(memory[ap + 2], 340282366920938463463374607431768211456) %} +[ap + 0] = [ap + -1] + 340282366920938463426481119284349108224, ap++; +[ap + -1] = [[ap + -21] + 6], ap++; +[ap + -3] = [[ap + -22] + 7], ap++; +[ap + -16] = [[ap + -23] + 8]; +[ap + -2] = [ap + -4] * 340282366920938463463374607431768211456; +[ap + -1] = [ap + -2] + [ap + -16]; +[ap + -17] = [ap + -9] + [ap + -4]; +[ap + 0] = [ap + -23] + 9, ap++; +jmp rel 34 if [ap + -18] != 0; +[ap + 1] = [fp + 0] + [ap + -17], ap++; +%{ memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456 %} +jmp rel 7 if [ap + -1] != 0, ap++; +[ap + -1] = [ap + 0] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[ap + -4] + 0]; +jmp rel 12; +[ap + -1] = [[ap + -3] + 0]; +[ap + 0] = [ap + -3] + 1, ap++; +[ap + 0] = [ap + -26], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [ap + -5], ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 39878429859757942499084499860145094553463, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -6] + 1, ap++; +[ap + 0] = [ap + -29], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -6] + 1, ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 39878429859761676908720221312622923640695, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -3], ap++; +[ap + 0] = [ap + -26], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -6] + 1, ap++; +ret; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -5], ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 39878429859763533771555484554338820190071, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -11] + 1, ap++; +[ap + 0] = [ap + -11], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -6] + 1, ap++; +ret; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -5], ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 39878429859763533771555484554338820190071, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [fp + -5] + 2, ap++; +[ap + 0] = [ap + -8], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -6] + 1, ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 375233589013918064796019, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [fp + -5] + 1, ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -6] + 1, ap++; +ret; +ret; +%{ memory[ap + 0] = 2540 <= memory[fp + -6] %} +jmp rel 7 if [ap + 0] != 0, ap++; +[ap + 0] = [fp + -6] + 340282366920938463463374607431768208916, ap++; +[ap + -1] = [[fp + -7] + 0]; +jmp rel 154; +[fp + -6] = [ap + 0] + 2540, ap++; +[ap + -1] = [[fp + -7] + 0]; +[ap + 0] = [fp + -7] + 1, ap++; +[fp + -3] = [ap + 0] + [fp + -4], ap++; +jmp rel 4 if [ap + -1] != 0; +jmp rel 10; +[ap + 0] = [fp + -4] + 1, ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [fp + -4], ap++; +jmp rel 8; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = 0, ap++; +jmp rel 111 if [ap + -2] != 0; +[ap + 0] = [[ap + -1] + 0], ap++; +%{ memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456 %} +jmp rel 22 if [ap + 0] != 0, ap++; +%{ (memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456) %} +[ap + 3] = [[ap + -8] + 0], ap++; +[ap + 3] = [[ap + -9] + 1], ap++; +[ap + -2] = [ap + 1] * 340282366920938463463374607431768211456, ap++; +[ap + -5] = [ap + -3] + [ap + 1], ap++; +[ap + -3] = [ap + -1] + -10633823966279327296825105735305134080, ap++; +jmp rel 6 if [ap + -4] != 0; +[ap + -3] = [ap + -1] + 340282366920938463463374607431768211455; +jmp rel 4; +[ap + -3] = [ap + -2] + 329648542954659136166549501696463077376; +[ap + -3] = [[ap + -13] + 2]; +jmp rel 86 if [ap + -2] != 0; +[fp + -1] = [fp + -1] + 1; +[ap + -2] = [[ap + -8] + 0]; +[ap + 0] = [ap + -8] + 1, ap++; +[ap + -6] = [ap + 0] + [ap + -7], ap++; +jmp rel 4 if [ap + -1] != 0; +jmp rel 16; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 7733229381460288120802334208475838166080759535023995805565484692595, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [ap + -14], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; +call rel 698; +[ap + 0] = [ap + -1] + 697, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +%{ memory[ap + 0] = 1680 <= memory[ap + -15] %} +jmp rel 9 if [ap + 0] != 0, ap++; +[ap + -16] = [ap + 0] + 1680, ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[ap + -9] + 0]; +jmp rel 33; +[ap + -16] = [ap + 0] + 1680, ap++; +[ap + -1] = [[ap + -8] + 0]; +[ap + 0] = [ap + -8] + 1, ap++; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [ap + -12], ap++; +call rel -290; +jmp rel 14 if [ap + -3] != 0; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + -2] = [[ap + -1] + 0]; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -6] + 1, ap++; +ret; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -6], ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 375233589013918064796019, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -11] + 1, ap++; +[ap + 0] = [ap + -21], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; +[ap + 0] = [ap + -13] + 3, ap++; +jmp rel 5; +ap += 7; +[ap + 0] = [ap + -13], ap++; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 485748461484230571791265682659113160264223489397539653310998840191492913, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -3], ap++; +[ap + 0] = [ap + -18], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 375233589013918064796019, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [fp + -7] + 1, ap++; +[ap + 0] = [fp + -6], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; +%{ memory[ap + 0] = 2540 <= memory[fp + -6] %} +jmp rel 7 if [ap + 0] != 0, ap++; +[ap + 0] = [fp + -6] + 340282366920938463463374607431768208916, ap++; +[ap + -1] = [[fp + -8] + 0]; +jmp rel 160; +[fp + -6] = [ap + 0] + 2540, ap++; +[ap + -1] = [[fp + -8] + 0]; +[ap + 0] = [fp + -8] + 1, ap++; +[fp + -3] = [ap + 0] + [fp + -4], ap++; +jmp rel 4 if [ap + -1] != 0; +jmp rel 10; +[ap + 0] = [fp + -4] + 1, ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [fp + -4], ap++; +jmp rel 8; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = 0, ap++; +jmp rel 116 if [ap + -2] != 0; +[ap + 0] = [[ap + -1] + 0], ap++; +%{ memory[ap + 0] = memory[ap + -1] < 340282366920938463463374607431768211456 %} +jmp rel 22 if [ap + 0] != 0, ap++; +%{ (memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -2], 340282366920938463463374607431768211456) %} +[ap + 3] = [[ap + -8] + 0], ap++; +[ap + 3] = [[ap + -9] + 1], ap++; +[ap + -2] = [ap + 1] * 340282366920938463463374607431768211456, ap++; +[ap + -5] = [ap + -3] + [ap + 1], ap++; +[ap + -3] = [ap + -1] + -10633823966279327296825105735305134080, ap++; +jmp rel 6 if [ap + -4] != 0; +[ap + -3] = [ap + -1] + 340282366920938463463374607431768211455; +jmp rel 4; +[ap + -3] = [ap + -2] + 329648542954659136166549501696463077376; +[ap + -3] = [[ap + -13] + 2]; +jmp rel 91 if [ap + -2] != 0; +[fp + -1] = [fp + -1] + 1; +[ap + -2] = [[ap + -8] + 0]; +[ap + 0] = [ap + -8] + 1, ap++; +[ap + -6] = [ap + 0] + [ap + -7], ap++; +jmp rel 4 if [ap + -1] != 0; +jmp rel 17; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 7733229381460288120802334208475838166080759535023995805565484692595, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -15], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [ap + -8] + 1, ap++; +ret; +call rel 523; +[ap + 0] = [ap + -1] + 522, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +%{ memory[ap + 0] = 2570 <= memory[ap + -15] %} +jmp rel 9 if [ap + 0] != 0, ap++; +[ap + -16] = [ap + 0] + 2570, ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[ap + -9] + 0]; +jmp rel 36; +[ap + -16] = [ap + 0] + 2570, ap++; +[ap + -1] = [[ap + -8] + 0]; +[ap + 0] = [ap + -8] + 1, ap++; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -13], ap++; +call rel 80; +jmp rel 15 if [ap + -3] != 0; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + -2] = [[ap + -1] + 0]; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -8], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [ap + -7], ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 375233589013918064796019, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -11] + 1, ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -22], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [ap + -8] + 1, ap++; +ret; +[ap + 0] = [ap + -13] + 3, ap++; +jmp rel 5; +ap += 7; +[ap + 0] = [ap + -13], ap++; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 485748461484230571791265682659113160264223489397539653310998840191492913, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -3], ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -19], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [ap + -8] + 1, ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 375233589013918064796019, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [fp + -8] + 1, ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [fp + -6], ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [ap + -8] + 1, ap++; +ret; +call rel 421; +[ap + 0] = [ap + -1] + 420, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [[ap + -1] + 3], ap++; +[ap + 0] = [ap + -1] * 51, ap++; +[ap + 0] = [ap + -1] + 33940, ap++; +%{ memory[ap + 0] = memory[ap + -1] <= memory[fp + -5] %} +jmp rel 8 if [ap + 0] != 0, ap++; +[fp + -5] = [ap + 0] + [ap + -2], ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[fp + -6] + 0]; +jmp rel 390; +[fp + -5] = [ap + 0] + [ap + -2], ap++; +[ap + -1] = [[fp + -6] + 0]; +[ap + 0] = [fp + -6] + 1, ap++; +jmp rel 12 if [fp + -3] != 0; +[ap + 0] = [ap + -1], ap++; +[ap + 0] = [ap + -3], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +ret; +[ap + 0] = 1, ap++; +[fp + -3] = [ap + 1] + [ap + -1], ap++; +%{ memory[ap + -1] = memory[ap + 0] < 340282366920938463463374607431768211456 %} +jmp rel 7 if [ap + -1] != 0, ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[ap + -5] + 0]; +jmp rel 349; +[ap + -1] = [[ap + -4] + 0]; +[ap + 0] = [ap + -4] + 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = [ap + -4], ap++; +call rel -50; +jmp rel 331 if [ap + -3] != 0; +jmp rel 8 if [ap + -1] != 0; +ap += 153; +[ap + 0] = [ap + -157], ap++; +[ap + 0] = [ap + -155], ap++; +jmp rel 314; +[ap + 0] = 1, ap++; +[ap + 0] = 2, ap++; +[ap + 0] = 3, ap++; +[ap + -3] = [[ap + -7] + 0]; +[ap + -2] = [[ap + -7] + 1]; +[ap + -1] = [[ap + -7] + 2]; +[ap + 0] = [[ap + -7] + 3], ap++; +[ap + 0] = [[ap + -8] + 4], ap++; +[ap + 0] = [[ap + -9] + 5], ap++; +[ap + -3] = [[ap + -10] + 6]; +[ap + -2] = [[ap + -10] + 7]; +[ap + -1] = [[ap + -10] + 8]; +[ap + 0] = [[ap + -10] + 9], ap++; +[ap + 0] = [[ap + -11] + 10], ap++; +[ap + 0] = [[ap + -12] + 11], ap++; +[ap + -3] = [[ap + -13] + 12]; +[ap + -2] = [[ap + -13] + 13]; +[ap + -1] = [[ap + -13] + 14]; +[ap + 0] = [[ap + -13] + 15], ap++; +[ap + 0] = [[ap + -14] + 16], ap++; +[ap + 0] = [[ap + -15] + 17], ap++; +[ap + -3] = [[ap + -16] + 18]; +[ap + -2] = [[ap + -16] + 19]; +[ap + -1] = [[ap + -16] + 20]; +[ap + 0] = [[ap + -16] + 21], ap++; +[ap + 0] = [[ap + -17] + 22], ap++; +[ap + 0] = [[ap + -18] + 23], ap++; +[ap + -3] = [[ap + -19] + 24]; +[ap + -2] = [[ap + -19] + 25]; +[ap + -1] = [[ap + -19] + 26]; +[ap + 0] = [[ap + -19] + 27], ap++; +[ap + 0] = [[ap + -20] + 28], ap++; +[ap + 0] = [[ap + -21] + 29], ap++; +[ap + -3] = [[ap + -22] + 30]; +[ap + -2] = [[ap + -22] + 31]; +[ap + -1] = [[ap + -22] + 32]; +[ap + 0] = [[ap + -22] + 33], ap++; +[ap + 0] = [[ap + -23] + 34], ap++; +[ap + 0] = [[ap + -24] + 35], ap++; +[ap + -3] = [[ap + -25] + 36]; +[ap + -2] = [[ap + -25] + 37]; +[ap + -1] = [[ap + -25] + 38]; +[ap + 0] = [[ap + -25] + 39], ap++; +[ap + 0] = [[ap + -26] + 40], ap++; +[ap + 0] = [[ap + -27] + 41], ap++; +[ap + -3] = [[ap + -28] + 42]; +[ap + -2] = [[ap + -28] + 43]; +[ap + -1] = [[ap + -28] + 44]; +[ap + 0] = [[ap + -28] + 45], ap++; +[ap + 0] = [[ap + -29] + 46], ap++; +[ap + 0] = [[ap + -30] + 47], ap++; +[ap + -3] = [[ap + -31] + 48]; +[ap + -2] = [[ap + -31] + 49]; +[ap + -1] = [[ap + -31] + 50]; +[ap + 0] = [[ap + -31] + 51], ap++; +[ap + 0] = [[ap + -32] + 52], ap++; +[ap + 0] = [[ap + -33] + 53], ap++; +[ap + -3] = [[ap + -34] + 54]; +[ap + -2] = [[ap + -34] + 55]; +[ap + -1] = [[ap + -34] + 56]; +[ap + 0] = [[ap + -34] + 57], ap++; +[ap + 0] = [[ap + -35] + 58], ap++; +[ap + 0] = [[ap + -36] + 59], ap++; +[ap + -3] = [[ap + -37] + 60]; +[ap + -2] = [[ap + -37] + 61]; +[ap + -1] = [[ap + -37] + 62]; +[ap + 0] = [[ap + -37] + 63], ap++; +[ap + 0] = [[ap + -38] + 64], ap++; +[ap + 0] = [[ap + -39] + 65], ap++; +[ap + -3] = [[ap + -40] + 66]; +[ap + -2] = [[ap + -40] + 67]; +[ap + -1] = [[ap + -40] + 68]; +[ap + 0] = [[ap + -40] + 69], ap++; +[ap + 0] = [[ap + -41] + 70], ap++; +[ap + 0] = [[ap + -42] + 71], ap++; +[ap + -3] = [[ap + -43] + 72]; +[ap + -2] = [[ap + -43] + 73]; +[ap + -1] = [[ap + -43] + 74]; +[ap + 0] = [[ap + -43] + 75], ap++; +[ap + 0] = [[ap + -44] + 76], ap++; +[ap + 0] = [[ap + -45] + 77], ap++; +[ap + -3] = [[ap + -46] + 78]; +[ap + -2] = [[ap + -46] + 79]; +[ap + -1] = [[ap + -46] + 80]; +[ap + 0] = [[ap + -46] + 81], ap++; +[ap + 0] = [[ap + -47] + 82], ap++; +[ap + 0] = [[ap + -48] + 83], ap++; +[ap + -3] = [[ap + -49] + 84]; +[ap + -2] = [[ap + -49] + 85]; +[ap + -1] = [[ap + -49] + 86]; +[ap + 0] = [[ap + -49] + 87], ap++; +[ap + 0] = [[ap + -50] + 88], ap++; +[ap + 0] = [[ap + -51] + 89], ap++; +[ap + -3] = [[ap + -52] + 90]; +[ap + -2] = [[ap + -52] + 91]; +[ap + -1] = [[ap + -52] + 92]; +[ap + 0] = [[ap + -52] + 93], ap++; +[ap + 0] = [[ap + -53] + 94], ap++; +[ap + 0] = [[ap + -54] + 95], ap++; +[ap + -3] = [[ap + -55] + 96]; +[ap + -2] = [[ap + -55] + 97]; +[ap + -1] = [[ap + -55] + 98]; +[ap + 0] = [[ap + -55] + 99], ap++; +[ap + 0] = [[ap + -56] + 100], ap++; +[ap + 0] = [[ap + -57] + 101], ap++; +[ap + -3] = [[ap + -58] + 102]; +[ap + -2] = [[ap + -58] + 103]; +[ap + -1] = [[ap + -58] + 104]; +[ap + 0] = [[ap + -58] + 105], ap++; +[ap + 0] = [[ap + -59] + 106], ap++; +[ap + 0] = [[ap + -60] + 107], ap++; +[ap + -3] = [[ap + -61] + 108]; +[ap + -2] = [[ap + -61] + 109]; +[ap + -1] = [[ap + -61] + 110]; +[ap + 0] = [[ap + -61] + 111], ap++; +[ap + 0] = [[ap + -62] + 112], ap++; +[ap + 0] = [[ap + -63] + 113], ap++; +[ap + -3] = [[ap + -64] + 114]; +[ap + -2] = [[ap + -64] + 115]; +[ap + -1] = [[ap + -64] + 116]; +[ap + 0] = [[ap + -64] + 117], ap++; +[ap + 0] = [[ap + -65] + 118], ap++; +[ap + 0] = [[ap + -66] + 119], ap++; +[ap + -3] = [[ap + -67] + 120]; +[ap + -2] = [[ap + -67] + 121]; +[ap + -1] = [[ap + -67] + 122]; +[ap + 0] = [[ap + -67] + 123], ap++; +[ap + 0] = [[ap + -68] + 124], ap++; +[ap + 0] = [[ap + -69] + 125], ap++; +[ap + -3] = [[ap + -70] + 126]; +[ap + -2] = [[ap + -70] + 127]; +[ap + -1] = [[ap + -70] + 128]; +[ap + 0] = [[ap + -70] + 129], ap++; +[ap + 0] = [[ap + -71] + 130], ap++; +[ap + 0] = [[ap + -72] + 131], ap++; +[ap + -3] = [[ap + -73] + 132]; +[ap + -2] = [[ap + -73] + 133]; +[ap + -1] = [[ap + -73] + 134]; +[ap + 0] = [[ap + -73] + 135], ap++; +[ap + 0] = [[ap + -74] + 136], ap++; +[ap + 0] = [[ap + -75] + 137], ap++; +[ap + -3] = [[ap + -76] + 138]; +[ap + -2] = [[ap + -76] + 139]; +[ap + -1] = [[ap + -76] + 140]; +[ap + 0] = [[ap + -76] + 141], ap++; +[ap + 0] = [[ap + -77] + 142], ap++; +[ap + 0] = [[ap + -78] + 143], ap++; +[ap + -3] = [[ap + -79] + 144]; +[ap + -2] = [[ap + -79] + 145]; +[ap + -1] = [[ap + -79] + 146]; +[ap + 0] = [[ap + -79] + 147], ap++; +[ap + 0] = [[ap + -80] + 148], ap++; +[ap + 0] = [[ap + -81] + 149], ap++; +[ap + -3] = [[ap + -82] + 150]; +[ap + -2] = [[ap + -82] + 151]; +[ap + -1] = [[ap + -82] + 152]; +[ap + 0] = [[ap + -82] + 153], ap++; +[ap + 0] = [[ap + -83] + 154], ap++; +[ap + 0] = [[ap + -84] + 155], ap++; +[ap + -3] = [[ap + -85] + 156]; +[ap + -2] = [[ap + -85] + 157]; +[ap + -1] = [[ap + -85] + 158]; +[ap + 0] = [[ap + -85] + 159], ap++; +[ap + 0] = [[ap + -86] + 160], ap++; +[ap + 0] = [[ap + -87] + 161], ap++; +[ap + -3] = [[ap + -88] + 162]; +[ap + -2] = [[ap + -88] + 163]; +[ap + -1] = [[ap + -88] + 164]; +[ap + 0] = [[ap + -88] + 165], ap++; +[ap + 0] = [[ap + -89] + 166], ap++; +[ap + 0] = [[ap + -90] + 167], ap++; +[ap + -3] = [[ap + -91] + 168]; +[ap + -2] = [[ap + -91] + 169]; +[ap + -1] = [[ap + -91] + 170]; +[ap + 0] = [[ap + -91] + 171], ap++; +[ap + 0] = [[ap + -92] + 172], ap++; +[ap + 0] = [[ap + -93] + 173], ap++; +[ap + -3] = [[ap + -94] + 174]; +[ap + -2] = [[ap + -94] + 175]; +[ap + -1] = [[ap + -94] + 176]; +[ap + 0] = [[ap + -94] + 177], ap++; +[ap + 0] = [[ap + -95] + 178], ap++; +[ap + 0] = [[ap + -96] + 179], ap++; +[ap + -3] = [[ap + -97] + 180]; +[ap + -2] = [[ap + -97] + 181]; +[ap + -1] = [[ap + -97] + 182]; +[ap + 0] = [[ap + -97] + 183], ap++; +[ap + 0] = [[ap + -98] + 184], ap++; +[ap + 0] = [[ap + -99] + 185], ap++; +[ap + -3] = [[ap + -100] + 186]; +[ap + -2] = [[ap + -100] + 187]; +[ap + -1] = [[ap + -100] + 188]; +[ap + 0] = [[ap + -100] + 189], ap++; +[ap + 0] = [[ap + -101] + 190], ap++; +[ap + 0] = [[ap + -102] + 191], ap++; +[ap + -3] = [[ap + -103] + 192]; +[ap + -2] = [[ap + -103] + 193]; +[ap + -1] = [[ap + -103] + 194]; +[ap + 0] = [[ap + -103] + 195], ap++; +[ap + 0] = [[ap + -104] + 196], ap++; +[ap + 0] = [[ap + -105] + 197], ap++; +[ap + -3] = [[ap + -106] + 198]; +[ap + -2] = [[ap + -106] + 199]; +[ap + -1] = [[ap + -106] + 200]; +[ap + 0] = [[ap + -106] + 201], ap++; +[ap + 0] = [[ap + -107] + 202], ap++; +[ap + 0] = [[ap + -108] + 203], ap++; +[ap + -3] = [[ap + -109] + 204]; +[ap + -2] = [[ap + -109] + 205]; +[ap + -1] = [[ap + -109] + 206]; +[ap + 0] = [[ap + -109] + 207], ap++; +[ap + 0] = [[ap + -110] + 208], ap++; +[ap + 0] = [[ap + -111] + 209], ap++; +[ap + -3] = [[ap + -112] + 210]; +[ap + -2] = [[ap + -112] + 211]; +[ap + -1] = [[ap + -112] + 212]; +[ap + 0] = [[ap + -112] + 213], ap++; +[ap + 0] = [[ap + -113] + 214], ap++; +[ap + 0] = [[ap + -114] + 215], ap++; +[ap + -3] = [[ap + -115] + 216]; +[ap + -2] = [[ap + -115] + 217]; +[ap + -1] = [[ap + -115] + 218]; +[ap + 0] = [[ap + -115] + 219], ap++; +[ap + 0] = [[ap + -116] + 220], ap++; +[ap + 0] = [[ap + -117] + 221], ap++; +[ap + -3] = [[ap + -118] + 222]; +[ap + -2] = [[ap + -118] + 223]; +[ap + -1] = [[ap + -118] + 224]; +[ap + 0] = [[ap + -118] + 225], ap++; +[ap + 0] = [[ap + -119] + 226], ap++; +[ap + 0] = [[ap + -120] + 227], ap++; +[ap + -3] = [[ap + -121] + 228]; +[ap + -2] = [[ap + -121] + 229]; +[ap + -1] = [[ap + -121] + 230]; +[ap + 0] = [[ap + -121] + 231], ap++; +[ap + 0] = [[ap + -122] + 232], ap++; +[ap + 0] = [[ap + -123] + 233], ap++; +[ap + -3] = [[ap + -124] + 234]; +[ap + -2] = [[ap + -124] + 235]; +[ap + -1] = [[ap + -124] + 236]; +[ap + 0] = [[ap + -124] + 237], ap++; +[ap + 0] = [[ap + -125] + 238], ap++; +[ap + 0] = [[ap + -126] + 239], ap++; +[ap + -3] = [[ap + -127] + 240]; +[ap + -2] = [[ap + -127] + 241]; +[ap + -1] = [[ap + -127] + 242]; +[ap + 0] = [[ap + -127] + 243], ap++; +[ap + 0] = [[ap + -128] + 244], ap++; +[ap + 0] = [[ap + -129] + 245], ap++; +[ap + -3] = [[ap + -130] + 246]; +[ap + -2] = [[ap + -130] + 247]; +[ap + -1] = [[ap + -130] + 248]; +[ap + 0] = [[ap + -130] + 249], ap++; +[ap + 0] = [[ap + -131] + 250], ap++; +[ap + 0] = [[ap + -132] + 251], ap++; +[ap + -3] = [[ap + -133] + 252]; +[ap + -2] = [[ap + -133] + 253]; +[ap + -1] = [[ap + -133] + 254]; +[ap + 0] = [[ap + -133] + 255], ap++; +[ap + 0] = [[ap + -134] + 256], ap++; +[ap + 0] = [[ap + -135] + 257], ap++; +[ap + -3] = [[ap + -136] + 258]; +[ap + -2] = [[ap + -136] + 259]; +[ap + -1] = [[ap + -136] + 260]; +[ap + 0] = [[ap + -136] + 261], ap++; +[ap + 0] = [[ap + -137] + 262], ap++; +[ap + 0] = [[ap + -138] + 263], ap++; +[ap + -3] = [[ap + -139] + 264]; +[ap + -2] = [[ap + -139] + 265]; +[ap + -1] = [[ap + -139] + 266]; +[ap + 0] = [[ap + -139] + 267], ap++; +[ap + 0] = [[ap + -140] + 268], ap++; +[ap + 0] = [[ap + -141] + 269], ap++; +[ap + -3] = [[ap + -142] + 270]; +[ap + -2] = [[ap + -142] + 271]; +[ap + -1] = [[ap + -142] + 272]; +[ap + 0] = [[ap + -142] + 273], ap++; +[ap + 0] = [[ap + -143] + 274], ap++; +[ap + 0] = [[ap + -144] + 275], ap++; +[ap + -3] = [[ap + -145] + 276]; +[ap + -2] = [[ap + -145] + 277]; +[ap + -1] = [[ap + -145] + 278]; +[ap + 0] = [[ap + -145] + 279], ap++; +[ap + 0] = [[ap + -146] + 280], ap++; +[ap + 0] = [[ap + -147] + 281], ap++; +[ap + -3] = [[ap + -148] + 282]; +[ap + -2] = [[ap + -148] + 283]; +[ap + -1] = [[ap + -148] + 284]; +[ap + 0] = [[ap + -148] + 285], ap++; +[ap + 0] = [[ap + -149] + 286], ap++; +[ap + 0] = [[ap + -150] + 287], ap++; +[ap + -3] = [[ap + -151] + 288]; +[ap + -2] = [[ap + -151] + 289]; +[ap + -1] = [[ap + -151] + 290]; +[ap + 0] = [[ap + -151] + 291], ap++; +[ap + 0] = [[ap + -152] + 292], ap++; +[ap + 0] = [[ap + -153] + 293], ap++; +[ap + -3] = [[ap + -154] + 294]; +[ap + -2] = [[ap + -154] + 295]; +[ap + -1] = [[ap + -154] + 296]; +[ap + 0] = [[ap + -154] + 297], ap++; +[ap + 0] = [[ap + -155] + 298], ap++; +[ap + 0] = [[ap + -156] + 299], ap++; +[ap + -3] = [[ap + -157] + 300]; +[ap + -2] = [[ap + -157] + 301]; +[ap + -1] = [[ap + -157] + 302]; +[ap + 0] = [ap + -157] + 306, ap++; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [ap + -161], ap++; +[ap + 0] = [ap + -161], ap++; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [ap + -6], ap++; +ret; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -6], ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 39878429859763533771555484554338820190071, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -7] + 1, ap++; +[ap + 0] = [ap + -9], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 375233589013918064796019, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [fp + -6] + 1, ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; diff --git a/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting_HelloStarknet.contract_class.json b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting_HelloStarknet.contract_class.json new file mode 100644 index 0000000000..4645af551e --- /dev/null +++ b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting_HelloStarknet.contract_class.json @@ -0,0 +1,611 @@ +{ + "sierra_program": [ + "0x1", + "0x6", + "0x0", + "0x2", + "0x9", + "0x2", + "0x15a", + "0xa6", + "0x26", + "0x52616e6765436865636b", + "0x800000000000000100000000000000000000000000000000", + "0x436f6e7374", + "0x800000000000000000000000000000000000000000000002", + "0x1", + "0xa", + "0x2", + "0x3", + "0x0", + "0x75313238", + "0x800000000000000700000000000000000000000000000000", + "0x4e6f6e5a65726f", + "0x800000000000000700000000000000000000000000000001", + "0x5", + "0x753132385f737562204f766572666c6f77", + "0x753132385f6d756c204f766572666c6f77", + "0x753132385f616464204f766572666c6f77", + "0x66656c74323532", + "0x553132384d756c47756172616e746565", + "0x537472756374", + "0x800000000000000700000000000000000000000000000002", + "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", + "0x556e696e697469616c697a6564", + "0x800000000000000200000000000000000000000000000001", + "0xf", + "0x800000000000000f00000000000000000000000000000001", + "0x19171cf5bff90ce740431b3a5a9c788b290fe55c0c52f1b164bf949c11d9a3", + "0x800000000000000700000000000000000000000000000003", + "0x11", + "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", + "0x4172726179", + "0x800000000000000300000000000000000000000000000001", + "0x800000000000000300000000000000000000000000000003", + "0x13", + "0x14", + "0x456e756d", + "0x6054ddb756e71bc62e1d9848753912c0094db1f243f2eba24bdd1fb894198b", + "0x12", + "0x15", + "0x506f736569646f6e", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x4f7574206f6620676173", + "0x536e617073686f74", + "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", + "0x1a", + "0x1b", + "0x2f23416cc60464d4158423619ba713070eb82b686c9d621a22c67bd37f6e0a9", + "0x4275696c74696e436f737473", + "0x53797374656d", + "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", + "0x1c", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x426f78", + "0x29d7d57c04a880978e7b3689f6218e507f3be17588744b58dc17762447ad0e7", + "0x23", + "0x22", + "0x4761734275696c74696e", + "0x58", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x7374727563745f6465636f6e737472756374", + "0x656e61626c655f61705f747261636b696e67", + "0x73746f72655f74656d70", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0x656e756d5f696e6974", + "0x24", + "0x6a756d70", + "0x7374727563745f636f6e737472756374", + "0x656e756d5f6d61746368", + "0x756e626f78", + "0x72656e616d65", + "0x75313238735f66726f6d5f66656c74323532", + "0x64697361626c655f61705f747261636b696e67", + "0x64726f70", + "0x61727261795f6e6577", + "0x636f6e73745f61735f696d6d656469617465", + "0x21", + "0x61727261795f617070656e64", + "0x20", + "0x25", + "0x1f", + "0x6765745f6275696c74696e5f636f737473", + "0x1e", + "0x77697468647261775f6761735f616c6c", + "0x66756e6374696f6e5f63616c6c", + "0x1d", + "0x753132385f746f5f66656c74323532", + "0x736e617073686f745f74616b65", + "0x19", + "0x18", + "0x17", + "0x16", + "0x616c6c6f635f6c6f63616c", + "0x66696e616c697a655f6c6f63616c73", + "0xe", + "0x647570", + "0x753132385f6f766572666c6f77696e675f737562", + "0xd", + "0x73746f72655f6c6f63616c", + "0x753132385f67756172616e7465655f6d756c", + "0x753132385f6d756c5f67756172616e7465655f766572696679", + "0x66656c743235325f69735f7a65726f", + "0x753132385f6f766572666c6f77696e675f616464", + "0x9", + "0xb", + "0x8", + "0x7", + "0x10", + "0x753132385f69735f7a65726f", + "0x4", + "0x6", + "0x68616465735f7065726d75746174696f6e", + "0x2b5", + "0xffffffffffffffff", + "0x72", + "0xc", + "0x61", + "0x5b", + "0x2b", + "0x4d", + "0x27", + "0x28", + "0x29", + "0x2a", + "0x46", + "0x2c", + "0x2d", + "0x2e", + "0x2f", + "0x30", + "0x31", + "0x32", + "0x33", + "0x34", + "0x35", + "0x36", + "0x37", + "0x38", + "0x39", + "0x3a", + "0x3b", + "0x3c", + "0x3d", + "0x65", + "0x3e", + "0x3f", + "0x40", + "0x41", + "0x42", + "0x43", + "0x44", + "0x45", + "0x47", + "0x48", + "0x49", + "0xf9", + "0x8c", + "0x91", + "0xe7", + "0xe1", + "0xac", + "0xd2", + "0xca", + "0xeb", + "0x4a", + "0x4b", + "0x4c", + "0x17d", + "0x16e", + "0x166", + "0x158", + "0x151", + "0x142", + "0x135", + "0x2a6", + "0x19b", + "0x4e", + "0x4f", + "0x50", + "0x297", + "0x290", + "0x51", + "0x1b0", + "0x288", + "0x52", + "0x53", + "0x54", + "0x55", + "0x56", + "0x57", + "0x59", + "0x5a", + "0x5c", + "0x5d", + "0x5e", + "0x5f", + "0x60", + "0x62", + "0x63", + "0x64", + "0x66", + "0x67", + "0x68", + "0x69", + "0x6a", + "0x6b", + "0x6c", + "0x6d", + "0x6e", + "0x6f", + "0x70", + "0x71", + "0x73", + "0x74", + "0x75", + "0x76", + "0x77", + "0x78", + "0x79", + "0x7a", + "0x7b", + "0x7c", + "0x7d", + "0x7e", + "0x7f", + "0x80", + "0x81", + "0x82", + "0x83", + "0x84", + "0x85", + "0x86", + "0x87", + "0x88", + "0x89", + "0x8a", + "0x8b", + "0x8d", + "0x8e", + "0x8f", + "0x90", + "0x92", + "0x93", + "0x94", + "0x95", + "0x96", + "0x97", + "0x98", + "0x99", + "0x9a", + "0x9b", + "0x9c", + "0x9d", + "0x9e", + "0x9f", + "0xa0", + "0xa1", + "0xa2", + "0xa3", + "0xa4", + "0xa5", + "0xa6", + "0xa7", + "0xa8", + "0xa9", + "0xaa", + "0xab", + "0xad", + "0xae", + "0xaf", + "0xb0", + "0xb1", + "0xb2", + "0xb3", + "0xb4", + "0xb5", + "0xb6", + "0xb7", + "0xb8", + "0xb9", + "0xba", + "0xbb", + "0xbc", + "0xbd", + "0xbe", + "0xbf", + "0xc0", + "0xc1", + "0xc2", + "0xc3", + "0xc4", + "0xc5", + "0xc6", + "0xc7", + "0xc8", + "0xc9", + "0xcb", + "0xcc", + "0xcd", + "0xce", + "0xcf", + "0xd0", + "0xd1", + "0xd3", + "0xd4", + "0xd5", + "0xd6", + "0xd7", + "0xd8", + "0xd9", + "0xda", + "0xdb", + "0xdc", + "0xdd", + "0xde", + "0xdf", + "0xe0", + "0xe2", + "0xe3", + "0xe4", + "0xe5", + "0xe6", + "0xe8", + "0xe9", + "0xea", + "0xec", + "0xed", + "0xee", + "0xef", + "0xf0", + "0xf1", + "0xf2", + "0xf3", + "0xf4", + "0xf5", + "0xf6", + "0xf7", + "0xf8", + "0xfa", + "0xfb", + "0xfc", + "0xfd", + "0x108", + "0x18b", + "0x18b7", + "0x240e06028100605038180a040181c0e06028100608038180a04018080200", + "0x3016120881c0c050200c20070301408030781c0c050200c1c0506830160a", + "0x640a180b8380a16048542805038380a040181c0e0e028100602098180a0d", + "0x1444050b024421403014401f0f0243414030143a050b02438140d8243414", + "0x8c0a0d158a80e06028100629038180a04018085027028980a25048844823", + "0x244224010c41630138143205178244224170142c090a8505a05160242a14", + "0xe00a37028d8121c120180a0d1a858121a0a0d00e06028100627028cc0a32", + "0x10c0a07210180a05208240a05200247e2e028147c091e82478091d8e80439", + "0x11c8605029180a07218140e421c0140a45049108605029005a05029001207", + "0x380a05258dc0a05258b40a05258249409248180a05200180a05240180a05", + "0x1000a07280140e42138140a45110140a45030140a4f270140a4d030140a4c", + "0x1c10052b0380a0520024aa54028148009299400a05201480a05201440a05", + "0x1086605029145c050291446050292c46050296412580c8140a3e2b8140a46", + "0x148a5c02814802e02814965b028149a3802814965a028149a09039400a07", + "0x140a4d0497c3205029783a050292c4c05028f8ba05029181008029583a05", + "0x640a0522824d00933824cc09328640a053218c0a0526824c40e02814c260", + "0x140a4b350140a4b0281cae0503908d20502934ae050290012072b8140e42", + "0x1740a07210980a05229bc0a0526824dc6d02814966c028149a6b028149a19", + "0x1340e05029341005029340c050292c0c0502984e0050292cba05029001207", + "0x1bc0e73038141207028241273028241209390140e5d0281c8409388140a05", + "0x38120939814126f049ac0a73028200a0804824e6050481c126c3801ce80e", + "0x14d809049cc0a0903824d4053a818d2073981cd60538024de0539814de05", + "0x243a05048181260029cc0a75029a41263029cc0a69029ac1275029cc0a06", + "0x1cc0a6a029ac126d029cc0a19029d41219029cc0a09350241273028240e09", + "0x24e6050481c1226029d83a053981cc00531824c00539814da0534824c605", + "0x1c3a0911814e60511814da0911814e60511014320911014e6050e814c009", + "0x244e05398144e05070241273028240e092d16cb8083b9744e073981c466f", + "0xb40a2204824e605048981209398141207048cc0a78170b40e730398c0a70", + "0x24b8092b814e60504974120939814ba05138241273028b80a2304824e605", + "0x14e605049681252029cc0a542b81cb6092a014e6052a014da092a014e605", + "0x244e05398144e05070247005398149c05170249c0539814a450038b41250", + "0x384e6f028e00a73028e00a540481c0a730281c0a57048380a73028380a33", + "0x14e605049481209398146605110241273028244c09049cc0a09038247007", + "0x240e093d0000e792890c0e73038dc1c27041381237029cc0a37029401237", + "0x1740a73029740a38049440a73029440a330490c0a730290c0a0e04824e605", + "0x141207049fc0a7e3c014e6073e81486093e9f0f60839814ba51218206e09", + "0x16c1282029cc0a81028001281029cc0a78029441280029cc0a092e8241273", + "0x2140a7c04824e60542014f60942a100e7302a0c0a7a04a0c0a7302a090007", + "0x14e6053d8141c0944014e60543814f00943814e60543014fa0943014e605", + "0x1bc0a88029cc0a88029501207029cc0a070295c127c029cc0a7c028cc127b", + "0x24f60539814f60507025120539814fe05170241273028240e094401cf87b", + "0x1f0f66f02a240a7302a240a540481c0a730281c0a57049f00a73029f00a33", + "0x1cc0a093f825140539814125d04824e6052e8144e09049cc0a09038251207", + "0x251a0539814125a04a300a7302a2d14072d8251605398151605368251605", + "0x14660900014e605000141c0947814e605470145c0947014e605462340e2d", + "0x23c0e7a001bc0a8f029cc0a8f029501207029cc0a070295c127a029cc0a7a", + "0x24e605318144409049cc0a5a0289c120939814b605138241273028240e09", + "0x24e605130150009049cc0a09038241291028240c0948014e6052e0141c09", + "0x14e60504974120939814122604a400a73029bc0a0e04824e605318144409", + "0x1681294029cc0a934901cb60949814e60549814da0949814e60504a041292", + "0x152005070252e05398152c05170252c05398152895038b41295029cc0a09", + "0x25c0a7302a5c0a540481c0a730281c0a57048380a73028380a3304a400a73", + "0x25300539814125d04824e605040150409049cc0a09038252e0707240de05", + "0x14125a049f80a7302a6530072d825320539815320536825320539814127f", + "0x14e605380141c094e014e6054d8145c094d814e6053f2680e2d04a680a73", + "0x1bc0a9c029cc0a9c029501207029cc0a070295c126c029cc0a6c028cc1270", + "0x240e09359b00e9d380380e730381c12070282412730282412094e01cd870", + "0x1c0120e029cc0a0e02838120939814126f049a40a73029bc0a0804824e605", + "0x14d60931814e60535014d809049cc0a0903824ea054f1a80c073981cd205", + "0x1a81209398141207048253e05048181219029cc0a63029a41260029cc0a06", + "0x1cc0a1d029a41260029cc0a75029ac121d029cc0a6d029d4126d029cc0a09", + "0x8c0a73028980a6004824e6050481c122202a804c053981c3205318243205", + "0x284b85d039cc0e270701c3a0913814e60513814da0913814e605118143209", + "0xcc5c073981cc00538024ba0539814ba05070241273028240e0916968b608", + "0x146605118241273028b80a2204824e6050489812093981412070495c0aa2", + "0x1480a6d049480a7302824b8092a014e60504974120939814b805138241273", + "0x1cc0a502701c5a0927014e605049681250029cc0a522a01cb60929014e605", + "0x240a05398140a0541824ba0539814ba05070246e05398147005170247005", + "0x14ba0e028dc0a73028dc0a54048200a73028200a57049c00a73029c00a33", + "0x1cc0a092902412730295c0a2204824e605048981209398141207048dc1070", + "0x1c127b3d01d46002881ce607219c0ba08270248605398148605280248605", + "0xa73028000a33049440a73029440a0e049f00a73028250809049cc0a09", + "0x1bce6052e1f00a00288390a092e014e6052e014700902814e605028150609", + "0x14e60504974120939814120704a080aa440814e607400150c09401fcf07d", + "0x250c05398150a830396c1209398150805440250a84039cc0a8102a1c1283", + "0x2240a7d04a240a7302a200a7c04824e60543814f6094421c0e7302a180a7a", + "0x14e6053f81506093e814e6053e8141c0945814e60545014f00945014e605", + "0x380a8b029cc0a8b029501208029cc0a080295c1278029cc0a78028cc127f", + "0x1f40a73029f40a0e04a300a7302a080a2e04824e6050481c128b041e0fe7d", + "0x14a80904014e60504014ae093c014e6053c01466093f814e6053f8150609", + "0x174120939814b805138241273028240e0946020f07f3e8380a8c029cc0a8c", + "0x1cc0a8e4681cb60947014e60547014da0947014e605049fc128d029cc0a09", + "0x252605398152405170252405398151e90038b41290029cc0a092d0251e05", + "0x200a57049ec0a73029ec0a33048140a73028140a83049e80a73029e80a0e", + "0x9c120939814120704a4c107b029e81c0549814e60549814a80904014e605", + "0x2500a730296c0a0e04824e605300144409049cc0a2d0289c120939814b405", + "0x241273029800a2204824e605110150009049cc0a090382412a5028240c09", + "0x2580a730282502094a814e60504974120939814122604a500a73028380a0e", + "0x1c5a094c014e605049681297029cc0a964a81cb6094b014e6054b014da09", + "0x140a0541825280539815280507024fc05398153205170253205398152e98", + "0x1f80a73029f80a54048200a73028200a57049c00a73029c00a33048140a73", + "0x2680a7302824ba09049cc0a6f02a081209398141207049f8107002a501c05", + "0x24b4094e014e6054da680e5b04a6c0a7302a6c0a6d04a6c0a7302824fe09", + "0x1cc0a6c0283812a8029cc0aa7028b812a7029cc0a9c5301c5a0953014e605", + "0x2410053981410052b824d60539814d605198240a05398140a0541824d805", + "0x24e60504a28126f029cc0a0944825500835814d80e02aa00a7302aa00a54", + "0x241273028240e09359b00ea9380380e73038141207028241273028244c09", + "0x38108d049a40a73029a40a38048180e07398140e0546024d20539814128b", + "0xcc126a029cc0a6a02838120939814120704980c607551d4d4073981cd206", + "0x243a6d0c820e6053a9c0d4081b824ea0539814ea051c024e00539814e005", + "0x880a38048880a73028251c09049cc0a09038244c05558200a73038740a43", + "0x1740eac1388c0e73038880e19042341208029cc0a083781d1e0911014e605", + "0x9c0a38049b40a73029b40a330488c0a730288c0a0e04824e6050481c125c", + "0xcc0aad17014e60716814860916968b608398144e6d118206e0913814e605", + "0x1cc0a57028e01254029cc0a2e029441257029cc0a09470241273028240e09", + "0x14a405000247005398149c5b03a48124e28148107302950ae0748024ae05", + "0x24e6050481c124302ab81273038dc0a93048e00a73028e00a0e048dc0a73", + "0x141207049f0f607579e800073981ca0511c021280928814e60504014a209", + "0x24000539814000507024f00539814fa054b024fa0539814f4054a8241273", + "0x241273028240e093c1680008029e00a73029e00a97049680a73029680a33", + "0x14e60540014da0940014e60504a60127f029cc0a092e8241273029f00a27", + "0x250605398150282038b41282029cc0a092d025020539815007f0396c1280", + "0x2100a97049680a73029680a33049ec0a73029ec0a0e04a100a7302a0c0a99", + "0x14a0051382412730290c0a7e04824e6050481c12842d1ec100542014e605", + "0x2180a6d04a180a7302825360942814e6050497412093981410054d0241273", + "0x1cc0a874401c5a0944014e605049681287029cc0a864281cb60943014e605", + "0x24b40539814b4051982470053981470050702514053981512054c8251205", + "0x26412093981410054d0241273028240e0945168700802a280a7302a280a97", + "0x1516054b824b40539814b40519824b60539814b605070251605398146605", + "0x1cc0a0802a68120939814b805138241273028240e0945968b60802a2c0a73", + "0x2300e5b04a340a7302a340a6d04a340a7302825380946014e605049741209", + "0x1cc0a9002a641290029cc0a8e4781c5a0947814e60504968128e029cc0a8d", + "0x1524053981524054b824da0539814da0519824ba0539814ba05070252405", + "0x153209049cc0a6f02a981209398140e05138241273028240e09491b4ba08", + "0x1cc0a9302a5c126d029cc0a6d028cc1219029cc0a19028381293029cc0a26", + "0x24e605038144e09049cc0a600289c120939814120704a4cda19040152605", + "0x1cc0a95029b41295029cc0a094e025280539814125d04824e605378154c09", + "0x2600a7302a592e07168252e0539814125a04a580a7302a5528072d8252a05", + "0x152e0938014e60538014660931814e605318141c094c814e6054c0153209", + "0x1bc0aa604824e605038144e09049cc0a09038253270318200a99029cc0a99", + "0x16c129a029cc0a9a029b4129a029cc0a093f824fc0539814125d04824e605", + "0x2980a9904a980a7302a6d380716825380539814125a04a6c0a7302a68fc07", + "0x14e605538152e0935814e60535814660936014e605360141c0953814e605", + "0x24d66c03ac0e00e039cc0e050481c0a09049cc0a09130254e6b360200aa7", + "0x1cd205538241c05398141c0507024d26f039cc0a6f02a301209398141207", + "0x1e4126a029cc0a09540241273029bc0a2704824e6050481c120602ac41273", + "0x1c00a33048380a73028380a0e0498c0a73029d40ab2049d40a73029a81007", + "0x24c60738038de0531814e60531815660903814e60503815060938014e605", + "0x1800a73029800a38049800a73028251609049cc0a0602ad01209398141207", + "0x1cc0a19028381209398141207048983a075a9b432073981cc06f070211a09", + "0x24da0539814da051c0240e05398140e0541824e00539814e005198243205", + "0x1c125b02ad8b8053981cba0543024ba2711888de73029b41007380641c85", + "0xb40e73028b40ab704824e605049bc122d2d01ce6052e0150e09049cc0a09", + "0x1b41257029cc0a2702a0c1209398141207048cc0ab8049cc0e2e02a4c122e", + "0x2e812093981466053f0241273028240e0904ae40a0903024a805398145a05", + "0x249c053981412bd049400a7302825780929014e60504aec1209398145a05", + "0x9cdebe049380a73029380a6d049400a73029400a6d049480a73029480a6d", + "0x248605398148605368246e05398146e0536824a2431b8e0de7302938a052", + "0x1cc0a7a029b4127c3d9e8006f39814a2431b8e0debe049440a73029440a6d", + "0x1cc0a7c3d9e8006f5f024f80539814f80536824f60539814f60536824f405", + "0x1cc0a80029b4127f029cc0a7f029b41278029cc0a78029b412803f9e0fa6f", + "0x14da0941014e60541014da094220d0481379cc0a803f9e0fa6f5f0250005", + "0x2210e86429bce6054220d048137af81284029cc0a84029b41283029cc0a83", + "0x1bd7c0944014e60544014da0943814e60543814da0943014e60543014da09", + "0x22c0a7302a2c0a6d04a280a7302a280a6d04a31168a449bce6054421d0c85", + "0x151c0536825208f47234de7302a31168a449bd7c0946014e60546014da09", + "0x15208f47234debe04a400a7302a400a6d04a3c0a7302a3c0a6d04a380a73", + "0x152a05368252805398152805368252605398152605368252a9449a48de73", + "0x1b41297029cc0a97029b412994c25d2c6f398152a9449a48debe04a540a73", + "0x26d347e379cc0a994c25d2c6f5f0253205398153205368253005398153005", + "0x2f8129c029cc0a9c029b4129b029cc0a9b029b4129a029cc0a9a029b4129c", + "0x14e60554014da0953814e60553814da093caa14ea6379cc0a9c4da68fc6f", + "0x2cc0a6d04add68b3591bce6053caa14ea637af81279029cc0a79029b412a8", + "0x2dd68b3591bd7c095b814e6055b814da095a014e6055a014da0959814e605", + "0x2f40a6d04af00a7302af00a6d04aec0a7302aec0a6d04af578bb5d1bce605", + "0x257e05398157e0536825803a5faf8de7302af578bb5d1bd7c095e814e605", + "0x1dd826f39815803a5faf8debe04b000a7302b000a6d048e80a73028e80a6d", + "0x25860539815860536825840539815840536824ee0539814ee053682586c2", + "0x1cc0ac6029b412c5029cc0ac5029b4127663315886f3981586c23bb04debe", + "0x14da0948b2590c7379cc0a7663315886f5f024ec0539814ec05368258c05", + "0x32590c737af81291029cc0a91029b412c9029cc0ac9029b412c8029cc0ac8", + "0x14da0966014e60566014da0965814e60565814da0966b3196ca379cc0a91", + "0x33c0a7302b3c0a6d04b45a0cf671bce60566b3196ca37af812cd029cc0acd", + "0x348de7302b45a0cf671bd7c0968814e60568814da0968014e60568014da09", + "0x3540a7302b540a6d04b500a7302b500a6d04b4c0a7302b4c0a6d04b55a8d3", + "0x15ae0536825ac0539815ac0536825b0d76b1d0de7302b55a8d3691bd7c09", + "0x1b412dc6db69b26f39815b0d76b1d0debe04b600a7302b600a6d04b5c0a73", + "0x369b26f5f025b80539815b80536825b60539815b60536825b40539815b405", + "0x1b412df029cc0adf029b412de029cc0ade029b412e06fb79ba6f39815b8db", + "0x14e60571014da097238dc4e1379cc0ae06fb79ba6f5f025c00539815c005", + "0x1bce6057238dc4e137af812e4029cc0ae4029b412e3029cc0ae3029b412e2", + "0x14e60574014da0973814e60573814da0973014e60573014da097439dcce5", + "0x3ac0a6d04ba80a7302ba80a6d04bb1d6ea749bce6057439dcce537af812e8", + "0x25de9e773b4de7302bb1d6ea749bd7c0976014e60576014da0975814e605", + "0x3b4debe04bbc0a7302bbc0a6d04a780a7302a780a6d04bb80a7302bb80a6d", + "0x25e40539815e40536825e20539815e205368253ef278bc0de7302bbd3cee", + "0x1cc0af4029b412f67abd1e66f398153ef278bc0debe04a7c0a7302a7c0a6d", + "0x1cc0af67abd1e66f5f025ec0539815ec0536825ea0539815ea0536825e805", + "0x1cc0afa029b412f9029cc0af9029b412f8029cc0af8029b412fa7cbe1ee6f", + "0x14da097e014e6057e014da097f3f5f8fb379cc0afa7cbe1ee6f5f025f405", + "0x40a03007f9bce6057f3f5f8fb37af812fe029cc0afe029b412fd029cc0afd", + "0x1bd7c0981014e60581014da0980814e60580814da0980014e60580014da09", + "0x4140a7302c140a6d04c100a7302c100a6d04c1a0b04819bce6058140600ff", + "0x1610053682615098441cde7302c1a0b04819bd7c0983014e60583014da09", + "0x1615098441cdebe04c280a7302c280a6d04c240a7302c240a6d04c200a73", + "0x161a05368254405398154405368261805398161805368261aa28642cde73", + "0x1b4130f029cc0b0f029b413118843e1c6f398161aa28642cdebe04c340a73", + "0x4522712379cc0b118843e1c6f5f0262205398162205368262005398162005", + "0x2f81315029cc0b15029b41314029cc0b14029b41313029cc0b13029b41315", + "0x14e6058c014da098b814e6058b814da098cc622f16379cc0b158a44e246f", + "0x46c0a6d04c76391b8d1bce6058cc622f1637af81319029cc0b19029b41318", + "0x476391b8d1bd7c098e814e6058e814da098e014e6058e014da098d814e605", + "0x4840a6d04c800a7302c800a6d04c7c0a7302c7c0a6d04c86411f8f1bce605", + "0x264605398164605368264b2491c88de7302c86411f8f1bd7c0990814e605", + "0x49e4c6f398164b2491c88debe04c940a7302c940a6d04c900a7302c900a6d", + "0x265205398165205368265005398165005368264e05398164e05368265328", + "0x1cc0b2b029b4132a029cc0b2a029b4132c95ca9486f39816532893c98debe", + "0x14da09984be5d2d379cc0b2c95ca9486f5f0265805398165805368265605", + "0x4be5d2d37af81330029cc0b30029b4132f029cc0b2f029b4132e029cc0b2e", + "0x14da0999014e60599014da0998814e60598814da0999cca62a3379cc0b30", + "0x4d40a7302cd40a6d04cde6d359a1bce60599cca62a337af81333029cc0b33", + "0x4e0de7302cde6d359a1bd7c099b814e6059b814da099b014e6059b014da09", + "0x4ec0a7302cec0a6d04ce80a7302ce80a6d04ce40a7302ce40a6d04cee7539", + "0x167c05368267a05398167a0536825433e9ecf0de7302cee75399c1bd7c09", + "0x1b41342a0d027e6f39815433e9ecf0debe04a840a7302a840a6d04cf80a73", + "0x5027e6f5f0268405398168405368268205398168205368268005398168005", + "0x268ca0039cc0aa002adc12a0029cc0aa0029b41345a2282866f398168541", + "0x51d4a6f398168b44a350cdebe04d140a7302d140a6d04d100a7302d100a6d", + "0x2940a8304824e605a48157409049cc0b4802ae81209398168e055d0269348", + "0x5280a7302950b4073c8241273028244c092a014e60550014da092b814e605", + "0x15060911814e60511814660911014e605110141c09a5814e605a50156409", + "0x2fc120939814120704d2cae23111bc0b4b029cc0b4b02acc1257029cc0a57", + "0x144e0541824460539814460519824440539814440507026980539814b605", + "0x980a2704824e6050481c134c1388c446f02d300a7302d300ab30489c0a73", + "0x14da09a7014e60504a70134d029cc0a092e8241273028200a8804824e605", + "0x169f50038b41350029cc0a092d0269e05398169d4d0396c134e029cc0b4e", + "0x1c00a73029c00a33048740a73028740a0e04d480a7302d440abf04d440a73", + "0x1cc0a0903826a40738074de05a9014e605a9015660903814e605038150609", + "0x1cc0a093f826a60539814125d04824e605040151009049cc0a6f0289c1209", + "0x26aa0539814125a04d500a7302a76a6072d8253a05398153a05368253a05", + "0x14660936014e605360141c09ab814e605ab0157e09ab014e605aa5540e2d", + "0x55c0e6b361bc0b57029cc0b5702acc1207029cc0a0702a0c126b029cc0a6b", + "0x148a25c048385c5228970120e048200e0504940a451049bc5c5228824de6f", + "0x24de0e0e970a209075600e050495ca20904038a2090438cde08038141250", + "0x159378200e0504974b851" + ], + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x1469798554697a4c50c64f933147bd163500204d4ae206eee1a9b9bf6c228de", + "function_idx": 0 + }, + { + "selector": "0x14a9a610b6c242b01e01b59a4474f46f0213139737c69cab5d3e95f1cbc00f0", + "function_idx": 1 + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + }, + "abi": "[{\"type\":\"function\",\"name\":\"test_stack_overflow\",\"inputs\":[{\"name\":\"depth\",\"type\":\"core::integer::u128\"}],\"outputs\":[{\"type\":\"core::integer::u128\"}],\"state_mutability\":\"external\"},{\"type\":\"function\",\"name\":\"test_redeposits\",\"inputs\":[{\"name\":\"depth\",\"type\":\"core::integer::u128\"}],\"outputs\":[{\"type\":\"core::felt252\"}],\"state_mutability\":\"external\"},{\"type\":\"event\",\"name\":\"l2_gas_accounting::HelloStarknet::Event\",\"kind\":\"enum\",\"variants\":[]}]" +} + diff --git a/crates/rpc/fixtures/contracts/l2_gas_accounting/lib.cairo b/crates/rpc/fixtures/contracts/l2_gas_accounting/lib.cairo new file mode 100644 index 0000000000..ad2e49ef48 --- /dev/null +++ b/crates/rpc/fixtures/contracts/l2_gas_accounting/lib.cairo @@ -0,0 +1,137 @@ +/// Simple contract for managing balance. +#[starknet::contract] +mod HelloStarknet { + + use core::poseidon::{hades_permutation}; + #[storage] + struct Storage {} + + #[abi(per_item)] + #[generate_trait] + impl SomeImpl of SomeTrait { + #[external(v0)] + fn test_stack_overflow(ref self: ContractState, depth: u128) -> u128 { + non_trivial_recursion(depth) + } + + #[external(v0)] + fn test_redeposits(ref self:ContractState, depth: u128) -> felt252 { + if(depth == 0) { + return 0; + } + let res = self.test_redeposits(depth-1); + // should be redeposited for the large if since res is never != 0 + if(res != 0) { + let mut tup = hades_permutation(1,2,3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + let (s1,s2,s3) = tup; + tup = hades_permutation(s1,s2,s3); + s1 + } + else { + res + } + } + } + + fn non_trivial_recursion(depth: u128) -> u128 { + non_trivial_recursion(depth - 1) + 2 * non_trivial_recursion(depth - 2) + } +} diff --git a/crates/rpc/src/method/estimate_fee.rs b/crates/rpc/src/method/estimate_fee.rs index e53949a5fd..75e6de73c8 100644 --- a/crates/rpc/src/method/estimate_fee.rs +++ b/crates/rpc/src/method/estimate_fee.rs @@ -201,6 +201,7 @@ mod tests { use crate::types::request::{ BroadcastedDeclareTransaction, BroadcastedDeclareTransactionV2, + BroadcastedDeclareTransactionV3, BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV0, BroadcastedInvokeTransactionV1, @@ -726,4 +727,170 @@ mod tests { ]) ); } + + fn declare_v3_transaction(account_contract_address: ContractAddress) -> BroadcastedTransaction { + let sierra_definition = include_bytes!( + "../../fixtures/contracts/l2_gas_accounting/l2_gas_accounting_HelloStarknet.\ + contract_class.json" + ); + let sierra_hash = + class_hash!("0x04468CD91AB8BD74957307632CFC13C48B7B51C741B1BD3069796F3268A5F3D1"); + // TODO: + let casm_hash = + casm_hash!("0x069032ff71f77284e1a0864a573007108ca5cc08089416af50f03260f5d6d4d8"); + + let contract_class: SierraContractClass = + ContractClass::from_definition_bytes(sierra_definition) + .unwrap() + .as_sierra() + .unwrap(); + + self::assert_eq!(contract_class.class_hash().unwrap().hash(), sierra_hash); + + BroadcastedTransaction::Declare(BroadcastedDeclareTransaction::V3( + BroadcastedDeclareTransactionV3 { + version: TransactionVersion::THREE, + signature: vec![], + nonce: transaction_nonce!("0x0"), + resource_bounds: ResourceBounds::default(), + tip: Tip(0), + paymaster_data: vec![], + account_deployment_data: vec![], + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + compiled_class_hash: casm_hash, + contract_class, + sender_address: account_contract_address, + }, + )) + } + + fn deploy_v3_transaction( + account_contract_address: ContractAddress, + universal_deployer_address: ContractAddress, + ) -> BroadcastedTransaction { + let sierra_hash = + class_hash!("0x04468CD91AB8BD74957307632CFC13C48B7B51C741B1BD3069796F3268A5F3D1"); + + BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction::V3( + BroadcastedInvokeTransactionV3 { + version: TransactionVersion::THREE, + signature: vec![], + nonce: transaction_nonce!("0x1"), + resource_bounds: ResourceBounds::default(), + tip: Tip(0), + paymaster_data: vec![], + account_deployment_data: vec![], + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + sender_address: account_contract_address, + calldata: vec![ + CallParam(*universal_deployer_address.get()), + // Entry point selector for the called contract, i.e. + // AccountCallArray::selector + CallParam(EntryPoint::hashed(b"deployContract").0), + // Length of the call data for the called contract, i.e. + // AccountCallArray::data_len + call_param!("4"), + // classHash + CallParam(sierra_hash.0), + // salt + call_param!("0x0"), + // unique + call_param!("0x0"), + // calldata_len + call_param!("0x0"), + ], + }, + )) + } + + fn invoke_v3_transaction2(account_contract_address: ContractAddress) -> BroadcastedTransaction { + BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction::V3( + BroadcastedInvokeTransactionV3 { + version: TransactionVersion::THREE, + signature: vec![], + sender_address: account_contract_address, + calldata: vec![ + // address of the deployed test contract + CallParam(felt!( + "0x0439479402A760C7368249703758241828EB7C838B536195079907F02D8CB838" + )), + // Entry point selector for the called contract, i.e. + // AccountCallArray::selector + CallParam(EntryPoint::hashed(b"test_redeposits").0), + // Length of the call data for the called contract, i.e. + // AccountCallArray::data_len + call_param!("1"), + // Depth + call_param!("100"), + ], + nonce: transaction_nonce!("0x2"), + resource_bounds: ResourceBounds::default(), + tip: Tip(0), + paymaster_data: vec![], + account_deployment_data: vec![], + nonce_data_availability_mode: DataAvailabilityMode::L1, + fee_data_availability_mode: DataAvailabilityMode::L1, + }, + )) + } + + #[tokio::test] + async fn declare_deploy_and_invoke_sierra_class_starknet_0_13_4() { + let (context, last_block_header, account_contract_address, universal_deployer_address) = + crate::test_setup::test_context_with_starknet_version(StarknetVersion::new( + 0, 13, 4, 0, + )) + .await; + + // declare test class + let declare_transaction = declare_v3_transaction(account_contract_address); + // deploy with universal deployer contract + let deploy_transaction = + deploy_v3_transaction(account_contract_address, universal_deployer_address); + // invoke deployed contract + let invoke_transaction = invoke_v3_transaction2(account_contract_address); + + let input = Input { + request: vec![declare_transaction, deploy_transaction, invoke_transaction], + simulation_flags: vec![], + block_id: BlockId::Number(last_block_header.number), + }; + let result = super::estimate_fee(context, input).await.unwrap(); + let declare_expected = FeeEstimate { + l1_gas_consumed: 1617.into(), + l1_gas_price: 2.into(), + l1_data_gas_consumed: 192.into(), + l1_data_gas_price: 2.into(), + l2_gas_consumed: 0.into(), + l2_gas_price: 1.into(), + overall_fee: 3618.into(), + unit: PriceUnit::Fri, + }; + let deploy_expected = FeeEstimate { + l1_gas_consumed: 19.into(), + l1_gas_price: 2.into(), + l1_data_gas_consumed: 224.into(), + l1_data_gas_price: 2.into(), + l2_gas_consumed: 0.into(), + l2_gas_price: 1.into(), + overall_fee: 486.into(), + unit: PriceUnit::Fri, + }; + let invoke_expected = FeeEstimate { + l1_gas_consumed: 134.into(), + l1_gas_price: 2.into(), + l1_data_gas_consumed: 128.into(), + l1_data_gas_price: 2.into(), + l2_gas_consumed: 0.into(), + l2_gas_price: 1.into(), + overall_fee: 524.into(), + unit: PriceUnit::Fri, + }; + self::assert_eq!( + result, + Output(vec![declare_expected, deploy_expected, invoke_expected,]) + ); + } } From 532f5e09e02d2102a1644764f32f8ab66225c52b Mon Sep 17 00:00:00 2001 From: sistemd Date: Mon, 3 Feb 2025 11:41:28 +0100 Subject: [PATCH 2/3] better error message --- crates/executor/src/estimate.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/executor/src/estimate.rs b/crates/executor/src/estimate.rs index cc1e931f71..c4f89ca153 100644 --- a/crates/executor/src/estimate.rs +++ b/crates/executor/src/estimate.rs @@ -134,9 +134,15 @@ where final_limit=%current_l2_gas_limit, "Initial L2 gas limit exceeded" ); - // Set the L2 gas limit to zero so that the transaction reverts. + // Set the L2 gas limit to zero so that the transaction reverts with a detailed + // `ExecutionError`. update_l2_gas_limit(tx, GasAmount::ZERO); - return execute_transaction(tx, tx_index, state, block_context); + match execute_transaction(tx, tx_index, state, block_context) { + Err(e @ TransactionExecutionError::ExecutionError { .. }) => { + return Err(e); + } + _ => unreachable!("Transaction should revert when gas limit is zero"), + } } // Finally, execute the transaction with the found L2 gas limit and set that From 705a745b52d1d01e6a2bdfc623ee96f5cdf49b6c Mon Sep 17 00:00:00 2001 From: sistemd Date: Mon, 3 Feb 2025 12:06:53 +0100 Subject: [PATCH 3/3] rebase fix: remove fee estimation version, use gas vector computation mode --- crates/executor/src/estimate.rs | 73 ++++----------------------------- 1 file changed, 8 insertions(+), 65 deletions(-) diff --git a/crates/executor/src/estimate.rs b/crates/executor/src/estimate.rs index c4f89ca153..1ce5d8e93e 100644 --- a/crates/executor/src/estimate.rs +++ b/crates/executor/src/estimate.rs @@ -4,6 +4,7 @@ use blockifier::transaction::objects::TransactionExecutionInfo; use blockifier::transaction::transaction_execution::Transaction; use blockifier::transaction::transactions::ExecutableTransaction; use starknet_api::execution_resources::GasAmount; +use starknet_api::transaction::fields::GasVectorComputationMode; use super::error::TransactionExecutionError; use super::execution_state::ExecutionState; @@ -30,11 +31,12 @@ pub fn estimate( ) .entered(); - let tx_info = match fee_estimation_version(&tx) { - FeeEstimationVersion::WithoutL2Gas => { + let gas_vector_computation_mode = super::transaction::gas_vector_computation_mode(&tx); + let tx_info = match gas_vector_computation_mode { + GasVectorComputationMode::NoL2Gas => { execute_transaction(&tx, tx_index, &mut state, &block_context) } - FeeEstimationVersion::WithL2Gas => find_l2_gas_limit_and_execute_transaction( + GasVectorComputationMode::All => find_l2_gas_limit_and_execute_transaction( &mut tx, tx_index, &mut state, @@ -51,6 +53,7 @@ pub fn estimate( Ok(FeeEstimate::from_tx_and_tx_info( &tx, &tx_info, + &gas_vector_computation_mode, &block_context, )) }) @@ -237,17 +240,16 @@ impl FeeEstimate { fn from_tx_and_tx_info( transaction: &Transaction, tx_info: &TransactionExecutionInfo, + gas_vector_computation_mode: &GasVectorComputationMode, block_context: &blockifier::context::BlockContext, ) -> Self { let fee_type = super::transaction::fee_type(transaction); - let gas_vector_computation_mode = - super::transaction::gas_vector_computation_mode(&transaction); let minimal_gas_vector = match transaction { Transaction::Account(account_transaction) => { Some(blockifier::fee::gas_usage::estimate_minimal_gas_vector( block_context, account_transaction, - &gas_vector_computation_mode, + gas_vector_computation_mode, )) } Transaction::L1Handler(_) => None, @@ -365,65 +367,6 @@ fn get_l2_gas_limit(tx: &Transaction) -> GasAmount { unreachable!(); } -fn fee_estimation_version(transaction: &Transaction) -> FeeEstimationVersion { - fn fee_estimation_from_resource_bounds( - resource_bounds: &starknet_api::transaction::fields::ValidResourceBounds, - ) -> FeeEstimationVersion { - use starknet_api::transaction::fields::ValidResourceBounds; - match resource_bounds { - ValidResourceBounds::AllResources(_) => FeeEstimationVersion::WithL2Gas, - ValidResourceBounds::L1Gas(_) => FeeEstimationVersion::WithoutL2Gas, - } - } - - match &transaction { - Transaction::Account(account_transaction) => { - use starknet_api::executable_transaction::AccountTransaction; - match &account_transaction.tx { - AccountTransaction::Declare(inner) => { - use starknet_api::transaction::DeclareTransaction; - match &inner.tx { - DeclareTransaction::V3(tx) => { - fee_estimation_from_resource_bounds(&tx.resource_bounds) - } - _ => FeeEstimationVersion::WithoutL2Gas, - } - } - AccountTransaction::DeployAccount(inner) => { - use starknet_api::transaction::DeployAccountTransaction; - match &inner.tx { - DeployAccountTransaction::V3(tx) => { - fee_estimation_from_resource_bounds(&tx.resource_bounds) - } - _ => FeeEstimationVersion::WithoutL2Gas, - } - } - AccountTransaction::Invoke(inner) => { - use starknet_api::transaction::InvokeTransaction; - match &inner.tx { - InvokeTransaction::V3(tx) => { - fee_estimation_from_resource_bounds(&tx.resource_bounds) - } - _ => FeeEstimationVersion::WithoutL2Gas, - } - } - } - } - Transaction::L1Handler(_) => FeeEstimationVersion::WithoutL2Gas, - } -} - -/// Fee estimation can currently take place in two ways - with or without L2 -/// gas. -/// -/// For the transactions before Starknet 0.13.4, the fee estimation is done -/// without L2 gas. For the ones after this version, the fee estimation is done -/// with L2 gas. -enum FeeEstimationVersion { - WithoutL2Gas, - WithL2Gas, -} - fn failed_with_insufficient_l2_gas(tx_info: &TransactionExecutionInfo) -> bool { let Some(revert_error) = &tx_info.revert_error else { return false;