diff --git a/crates/executor/src/estimate.rs b/crates/executor/src/estimate.rs index 0580a4b87e..fd070da001 100644 --- a/crates/executor/src/estimate.rs +++ b/crates/executor/src/estimate.rs @@ -1,9 +1,16 @@ +use blockifier::transaction::objects::TransactionExecutionInfo; use blockifier::transaction::transaction_execution::Transaction; -use blockifier::transaction::transactions::ExecutableTransaction; +use starknet_api::transaction::fields::GasVectorComputationMode; use super::error::TransactionExecutionError; use super::execution_state::ExecutionState; +use super::transaction::transaction_hash; use super::types::FeeEstimate; +use crate::transaction::{ + execute_transaction, + find_l2_gas_limit_and_execute_transaction, + l2_gas_accounting_enabled, +}; pub fn estimate( execution_state: ExecutionState<'_>, @@ -13,54 +20,75 @@ 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 gas_vector_computation_mode = - super::transaction::gas_vector_computation_mode(&transaction); - let minimal_l1_gas_amount_vector = match &transaction { + let gas_vector_computation_mode = super::transaction::gas_vector_computation_mode(&tx); + let tx_info = if l2_gas_accounting_enabled( + &tx, + &state, + &block_context, + &gas_vector_computation_mode, + )? { + find_l2_gas_limit_and_execute_transaction( + &mut tx, + tx_index, + &mut state, + &block_context, + )? + } else { + execute_transaction(&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, + &gas_vector_computation_mode, + &block_context, + )) + }) + .collect() +} + +impl FeeEstimate { + pub(crate) 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 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, + 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(), - }); - } - - tracing::trace!(actual_fee=%tx_info.receipt.fee.0, actual_resources=?tx_info.receipt.resources, "Transaction estimation finished"); - fees.push(FeeEstimate::from_tx_info_and_gas_price( - &tx_info, - block_context.block_info(), - fee_type, - &minimal_l1_gas_amount_vector, - )); - } - Err(error) => { - tracing::debug!(%error, %transaction_idx, "Transaction estimation failed"); - return Err(TransactionExecutionError::new(transaction_idx, error)); - } - } + FeeEstimate::from_tx_info_and_gas_price( + tx_info, + block_context.block_info(), + fee_type, + &minimal_gas_vector, + ) } - Ok(fees) } diff --git a/crates/executor/src/simulate.rs b/crates/executor/src/simulate.rs index 935a8a31a5..fed70a18ed 100644 --- a/crates/executor/src/simulate.rs +++ b/crates/executor/src/simulate.rs @@ -25,7 +25,12 @@ use super::error::TransactionExecutionError; use super::execution_state::ExecutionState; use super::types::{FeeEstimate, TransactionSimulation, TransactionTrace}; use crate::error_stack::ErrorStack; -use crate::transaction::transaction_hash; +use crate::transaction::{ + execute_transaction, + find_l2_gas_limit_and_execute_transaction, + l2_gas_accounting_enabled, + transaction_hash, +}; use crate::types::{ DataAvailabilityResources, DeclareTransactionTrace, @@ -86,66 +91,58 @@ pub fn simulate( let (mut state, block_context) = execution_state.starknet_state()?; - let mut simulations = Vec::with_capacity(transactions.len()); - for (transaction_idx, transaction) in transactions.into_iter().enumerate() { - let _span = tracing::debug_span!("simulate", 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!( + "simulate", + block_number = %block_number, + transaction_hash = %transaction_hash(&tx), + transaction_index = %tx_index + ) + .entered(); + + let gas_vector_computation_mode = super::transaction::gas_vector_computation_mode(&tx); + let mut tx_state = CachedState::<_>::create_transactional(&mut state); + let tx_info = if l2_gas_accounting_enabled( + &tx, + &tx_state, + &block_context, + &gas_vector_computation_mode, + )? { + find_l2_gas_limit_and_execute_transaction( + &mut tx, + tx_index, + &mut tx_state, + &block_context, + )? + } else { + execute_transaction(&tx, tx_index, &mut tx_state, &block_context)? + }; + let state_diff = to_state_diff(&mut tx_state, transaction_declared_deprecated_class(&tx))?; + tx_state.commit(); - let transaction_type = transaction_type(&transaction); - let transaction_declared_deprecated_class_hash = - transaction_declared_deprecated_class(&transaction); - let fee_type = super::transaction::fee_type(&transaction); - let gas_vector_computation_mode = - super::transaction::gas_vector_computation_mode(&transaction); + tracing::trace!(actual_fee=%tx_info.receipt.fee.0, actual_resources=?tx_info.receipt.resources, "Transaction simulation finished"); - let minimal_l1_gas_amount_vector = match &transaction { - Transaction::Account(account_transaction) => { - Some(blockifier::fee::gas_usage::estimate_minimal_gas_vector( + Ok(TransactionSimulation { + fee_estimation: FeeEstimate::from_tx_and_tx_info( + &tx, + &tx_info, + &gas_vector_computation_mode, &block_context, - account_transaction, + ), + trace: to_trace( + transaction_type(&tx), + tx_info, + state_diff, + block_context.versioned_constants(), &gas_vector_computation_mode, - )) - } - Transaction::L1Handler(_) => None, - }; - - let mut tx_state = CachedState::<_>::create_transactional(&mut state); - let tx_info = transaction.execute(&mut tx_state, &block_context); - let state_diff = to_state_diff(&mut tx_state, transaction_declared_deprecated_class_hash)?; - tx_state.commit(); - - match tx_info { - Ok(tx_info) => { - if let Some(revert_error) = &tx_info.revert_error { - let revert_string = revert_error.to_string(); - tracing::trace!(revert_error=%revert_string, "Transaction reverted"); - } - - tracing::trace!(actual_fee=%tx_info.receipt.fee.0, actual_resources=?tx_info.receipt.resources, "Transaction simulation finished"); - - simulations.push(TransactionSimulation { - fee_estimation: FeeEstimate::from_tx_info_and_gas_price( - &tx_info, - block_context.block_info(), - fee_type, - &minimal_l1_gas_amount_vector, - ), - trace: to_trace( - transaction_type, - tx_info, - state_diff, - block_context.versioned_constants(), - &gas_vector_computation_mode, - block_context.block_info().use_kzg_da, - ), - }); - } - Err(error) => { - tracing::debug!(%error, %transaction_idx, "Transaction simulation failed"); - return Err(TransactionExecutionError::new(transaction_idx, error)); - } - } - } - Ok(simulations) + block_context.block_info().use_kzg_da, + ), + }) + }) + .collect() } pub fn trace( diff --git a/crates/executor/src/transaction.rs b/crates/executor/src/transaction.rs index 86fbd3e139..178dece433 100644 --- a/crates/executor/src/transaction.rs +++ b/crates/executor/src/transaction.rs @@ -1,10 +1,17 @@ -use blockifier::transaction::objects::HasRelatedFeeType; +use blockifier::execution::contract_class::TrackedResource; +use blockifier::state::cached_state::{CachedState, MutRefState}; +use blockifier::state::state_api::UpdatableState; +use blockifier::transaction::objects::{HasRelatedFeeType, TransactionExecutionInfo}; use blockifier::transaction::transaction_execution::Transaction; +use blockifier::transaction::transactions::ExecutableTransaction; use pathfinder_common::TransactionHash; use starknet_api::block::FeeType; +use starknet_api::core::ClassHash; +use starknet_api::execution_resources::GasAmount; use starknet_api::transaction::fields::GasVectorComputationMode; use super::felt::IntoFelt; +use crate::TransactionExecutionError; // This workaround will not be necessary after the PR: // https://github.com/starkware-libs/blockifier/pull/927 @@ -73,3 +80,372 @@ pub fn gas_vector_computation_mode(transaction: &Transaction) -> GasVectorComput Transaction::L1Handler(_) => GasVectorComputationMode::NoL2Gas, } } + +/// Starknet 0.13.4 introduced runtime L2 gas accounting but due to how +/// `blockifier` handles execution resources, it is only enabled if both the +/// caller and the "callee" contract classes were compiled as Seirra 1.7. +/// +/// This function determines if the fee estimation should consider L2 gas +/// accounting or not. +pub(crate) fn l2_gas_accounting_enabled( + tx: &Transaction, + state: &S, + block_context: &blockifier::context::BlockContext, + gas_vector_computation_mode: &GasVectorComputationMode, +) -> blockifier::state::state_api::StateResult +where + S: UpdatableState, +{ + let sender_class_hash = state.get_class_hash_at(tx.sender_address())?; + // Uninitialized class. + if sender_class_hash == ClassHash::default() { + return Ok(false); + } + + let tracked_resource = state + .get_compiled_class(sender_class_hash)? + .tracked_resource( + &block_context + .versioned_constants() + .min_sierra_version_for_sierra_gas, + None, + ); + + // This is _not quite_ correct because only the sender contract class is + // checked, but it is close enough. The default fee estimation with L2 gas + // accounting (`l2_gas_consumed * 1.1`) will cover the case when the sender + // contract class Seirra version is >= 1.7 but the called contract class + // version is < 1.7. + Ok( + gas_vector_computation_mode == &GasVectorComputationMode::All + && tracked_resource == TrackedResource::SierraGas, + ) +} + +/// The margin for the binary search for the minimal L2 gas limit. +const L2_GAS_SEARCH_MARGIN: GasAmount = GasAmount(1_000_000); + +/// 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). +pub(crate) 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. + set_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) => { + return Err( + anyhow::anyhow!("Fee estimation failed, maximum gas limit exceeded").into(), + ); + } + }; + + let GasAmount(l2_gas_consumed) = tx_info.receipt.gas.l2_gas; + + // Add a 10% buffer to the actual L2 gas fee. + let l2_gas_adjusted = GasAmount(l2_gas_consumed.saturating_add(l2_gas_consumed / 10)); + set_l2_gas_limit(tx, l2_gas_adjusted); + + let (l2_gas_limit, mut tx_info, tx_state) = + match simulate_transaction(tx, tx_index, state, block_context) { + Ok((tx_info, tx_state)) => { + // If 110% of the actual transaction gas fee is enough, we use that + // as the estimate and skip the binary search. + (l2_gas_adjusted, tx_info, tx_state) + } + Err(TransactionSimulationError::OutOfGas) => { + let mut lower_bound = GasAmount(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. + let (tx_info, tx_state) = loop { + tracing::debug!( + lower_bound=%lower_bound, + upper_bound=%upper_bound, + current=%current_l2_gas_limit, + "Searching for minimal L2 gas limit" + ); + set_l2_gas_limit(tx, current_l2_gas_limit); + + // Special case where the search would get stuck if `current_l2_gas_limit == + // lower_bound` but the required amount is equal to the upper bound. + let bounds_diff = upper_bound + .checked_sub(lower_bound) + .expect("Upper bound >= lower bound"); + if bounds_diff == GasAmount(1) && current_l2_gas_limit == lower_bound { + lower_bound = upper_bound; + current_l2_gas_limit = upper_bound; + } + + match simulate_transaction(tx, tx_index, state, block_context) { + Ok((tx_info, tx_state)) => { + if search_done(lower_bound, upper_bound, L2_GAS_SEARCH_MARGIN) { + break (tx_info, tx_state); + } + + 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); + } + } + }; + + (current_l2_gas_limit, tx_info, tx_state) + } + Err(TransactionSimulationError::ExecutionError(error)) => { + return Err(error); + } + }; + + if l2_gas_limit > initial_l2_gas_limit { + tracing::debug!( + initial_limit=%initial_l2_gas_limit, + final_limit=%l2_gas_limit, + "Initial L2 gas limit exceeded" + ); + tx_state.abort(); + // Set the L2 gas limit to zero so that the transaction reverts with a detailed + // `ExecutionError`. + set_l2_gas_limit(tx, GasAmount::ZERO); + 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"), + } + } + + // State changes must be committed once the search is done. + tx_state.commit(); + tx_info.receipt.gas.l2_gas = l2_gas_limit; + + Ok(tx_info) +} + +/// Execute the transaction and handle common errors. +pub(crate) 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)) + } + } +} + +/// Calculates the midpoint between two gas amounts without overflowing. +fn midpoint(a: GasAmount, b: GasAmount) -> GasAmount { + let GasAmount(a) = a; + let GasAmount(b) = b; + let distance = b.checked_sub(a).expect("b >= a"); + + GasAmount(a + distance / 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 transaction without updating the execution state directly. Instead, +/// the function returns the transactional state handle to the caller to decide +/// whether to commit the state update or not. +fn simulate_transaction<'state, S>( + tx: &Transaction, + tx_index: usize, + state: &'state mut S, + block_context: &blockifier::context::BlockContext, +) -> Result< + ( + TransactionExecutionInfo, + CachedState>, + ), + TransactionSimulationError, +> +where + S: UpdatableState, +{ + 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, tx_state)), + 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), +} + +fn set_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!(); +} + +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; + + 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; + } + } + } + } + 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; + } + } + } + } + } + } + + // 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 failed_with_insufficient_l2_gas(tx_info: &TransactionExecutionInfo) -> bool { + let Some(revert_error) = &tx_info.revert_error else { + return false; + }; + + revert_error.to_string().contains("Out of gas") +} diff --git a/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.cairo b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.cairo new file mode 100644 index 0000000000..ad2e49ef48 --- /dev/null +++ b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.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/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..c95aad69ac --- /dev/null +++ b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.casm @@ -0,0 +1,828 @@ +ap += 1; +%{ memory[ap + 0] = 9190 <= memory[fp + -4] %} +jmp rel 7 if [ap + 0] != 0, ap++; +[ap + 0] = [fp + -4] + 340282366920938463463374607431768202266, ap++; +[ap + -1] = [[fp + -5] + 0]; +jmp rel 179; +[fp + -4] = [ap + 0] + 9190, ap++; +[ap + -1] = [[fp + -5] + 0]; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -2], ap++; +[fp + -3] = [ap + 1] + [ap + -2], 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 150; +[ap + -1] = [[fp + -5] + 1]; +[ap + 0] = [fp + -5] + 2, ap++; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [ap + -3], ap++; +call rel -28; +jmp rel 133 if [ap + -3] != 0; +[ap + 0] = 2, ap++; +[fp + 0] = [ap + -2]; +[ap + 0] = [ap + -5], ap++; +[fp + -3] = [ap + 1] + [ap + -2], 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 + -10] + 0]; +jmp rel 106; +[ap + -1] = [[ap + -9] + 0]; +[ap + 0] = [ap + -9] + 1, ap++; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [ap + -3], ap++; +call rel -49; +jmp rel 89 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 + -22], ap++; +[ap + 0] = [ap + -24] + 9, ap++; +jmp rel 36 if [ap + -19] != 0; +[ap + 0] = [ap + -2], ap++; +[ap + 1] = [fp + 0] + [ap + -19], 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 + -5] + 0]; +jmp rel 13; +[ap + -1] = [[ap + -4] + 0]; +[ap + 0] = [ap + -4] + 1, ap++; +[ap + 0] = [ap + -4] + 500, 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 + -7] + 1, ap++; +[ap + 0] = [ap + -7], 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 + -5] + 670, 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] + 4400, 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 + -12] + 1, ap++; +[ap + 0] = [ap + -7] + 5880, 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] + 7040, 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 + -7] + 8520, 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] = 3040 <= memory[fp + -6] %} +jmp rel 7 if [ap + 0] != 0, ap++; +[ap + 0] = [fp + -6] + 340282366920938463463374607431768208416, ap++; +[ap + -1] = [[fp + -7] + 0]; +jmp rel 164; +[fp + -6] = [ap + 0] + 3040, ap++; +[ap + -1] = [[fp + -7] + 0]; +[ap + 0] = [fp + -7] + 1, ap++; +[ap + 0] = [ap + -2], ap++; +[fp + -3] = [ap + 0] + [fp + -4], ap++; +jmp rel 4 if [ap + -1] != 0; +jmp rel 11; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [fp + -4] + 1, ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [fp + -4], ap++; +jmp rel 9; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = 0, ap++; +jmp rel 118 if [ap + -2] != 0; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [ap + -6], ap++; +%{ memory[ap + 0] = memory[ap + -2] < 340282366920938463463374607431768211456 %} +jmp rel 22 if [ap + 0] != 0, ap++; +%{ (memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -3], 340282366920938463463374607431768211456) %} +[ap + 3] = [[ap + -11] + 0], ap++; +[ap + 3] = [[ap + -12] + 1], ap++; +[ap + -2] = [ap + 1] * 340282366920938463463374607431768211456, ap++; +[ap + -6] = [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 + -16] + 2]; +jmp rel 90 if [ap + -2] != 0; +[fp + -1] = [fp + -1] + 1; +[ap + -3] = [[ap + -11] + 0]; +[ap + 0] = [ap + -11] + 1, ap++; +[ap + 0] = [ap + -3], ap++; +[ap + -8] = [ap + 0] + [ap + -9], 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 + -5], ap++; +[ap + 0] = [ap + -5] + 1170, ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -6], ap++; +[ap + 0] = [ap + -7] + 1, ap++; +ret; +call rel 757; +[ap + 0] = [ap + -1] + 756, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [[ap + -2] + 0], ap++; +%{ memory[ap + 0] = 1680 <= memory[ap + -2] %} +jmp rel 9 if [ap + 0] != 0, ap++; +[ap + -3] = [ap + 0] + 1680, ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[ap + -11] + 0]; +jmp rel 34; +[ap + -3] = [ap + 0] + 1680, ap++; +[ap + -1] = [[ap + -10] + 0]; +[ap + 0] = [ap + -10] + 1, ap++; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [ap + -15], ap++; +call rel -307; +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] + 200, 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 + -13] + 1, ap++; +[ap + 0] = [ap + -8], 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 + -16] + 3, ap++; +[ap + 0] = [ap + -8] + 230, ap++; +jmp rel 5; +[ap + 0] = [ap + -8], ap++; +[ap + 0] = [ap + -6] + 1840, ap++; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 485748461484230571791265682659113160264223489397539653310998840191492913, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [ap + -4], 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] = 3040 <= memory[fp + -6] %} +jmp rel 7 if [ap + 0] != 0, ap++; +[ap + 0] = [fp + -6] + 340282366920938463463374607431768208416, ap++; +[ap + -1] = [[fp + -8] + 0]; +jmp rel 170; +[fp + -6] = [ap + 0] + 3040, ap++; +[ap + -1] = [[fp + -8] + 0]; +[ap + 0] = [fp + -8] + 1, ap++; +[ap + 0] = [ap + -2], ap++; +[fp + -3] = [ap + 0] + [fp + -4], ap++; +jmp rel 4 if [ap + -1] != 0; +jmp rel 11; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [fp + -4] + 1, ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [fp + -4], ap++; +jmp rel 9; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = [fp + -3], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = 0, ap++; +jmp rel 123 if [ap + -2] != 0; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [ap + -6], ap++; +%{ memory[ap + 0] = memory[ap + -2] < 340282366920938463463374607431768211456 %} +jmp rel 22 if [ap + 0] != 0, ap++; +%{ (memory[ap + 3], memory[ap + 4]) = divmod(memory[ap + -3], 340282366920938463463374607431768211456) %} +[ap + 3] = [[ap + -11] + 0], ap++; +[ap + 3] = [[ap + -12] + 1], ap++; +[ap + -2] = [ap + 1] * 340282366920938463463374607431768211456, ap++; +[ap + -6] = [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 + -16] + 2]; +jmp rel 95 if [ap + -2] != 0; +[fp + -1] = [fp + -1] + 1; +[ap + -3] = [[ap + -11] + 0]; +[ap + 0] = [ap + -11] + 1, ap++; +[ap + 0] = [ap + -3], ap++; +[ap + -8] = [ap + 0] + [ap + -9], ap++; +jmp rel 4 if [ap + -1] != 0; +jmp rel 18; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 7733229381460288120802334208475838166080759535023995805565484692595, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -6] + 1170, ap++; +[ap + 0] = [fp + -5], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -7], ap++; +[ap + 0] = [ap + -8] + 1, ap++; +ret; +call rel 572; +[ap + 0] = [ap + -1] + 571, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [[ap + -2] + 0], ap++; +%{ memory[ap + 0] = 2570 <= memory[ap + -2] %} +jmp rel 9 if [ap + 0] != 0, ap++; +[ap + -3] = [ap + 0] + 2570, ap++; +[ap + 0] = [ap + -1] + 340282366920938463463374607431768211456, ap++; +[ap + -1] = [[ap + -11] + 0]; +jmp rel 37; +[ap + -3] = [ap + 0] + 2570, ap++; +[ap + -1] = [[ap + -10] + 0]; +[ap + 0] = [ap + -10] + 1, ap++; +[ap + 0] = [ap + -2], ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -16], ap++; +call rel 83; +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] + 200, 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 + -13] + 1, ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -9], 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 + -16] + 3, ap++; +[ap + 0] = [ap + -8] + 230, ap++; +jmp rel 5; +[ap + 0] = [ap + -8], ap++; +[ap + 0] = [ap + -6] + 1840, ap++; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 485748461484230571791265682659113160264223489397539653310998840191492913, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [fp + -7], ap++; +[ap + 0] = [ap + -5], 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 466; +[ap + 0] = [ap + -1] + 465, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [[ap + -1] + 3], ap++; +[ap + 0] = [ap + -1] * 51, ap++; +[ap + 0] = [ap + -1] + 34340, 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 435; +[fp + -5] = [ap + 0] + [ap + -2], ap++; +[ap + -1] = [[fp + -6] + 0]; +[ap + 0] = [fp + -6] + 1, ap++; +[ap + 0] = [ap + -2], ap++; +jmp rel 22 if [fp + -3] != 0; +call rel 441; +[ap + 0] = [ap + -1] + 440, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [[ap + -1] + 3], ap++; +[ap + 0] = [ap + -1] * 51, ap++; +[ap + 0] = [ap + -1] + 33840, ap++; +[ap + 0] = [ap + -9], ap++; +[ap + 0] = [ap + -9] + [ap + -2], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +ret; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -2], ap++; +[fp + -3] = [ap + 1] + [ap + -2], 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 + -7] + 0]; +jmp rel 372; +[ap + -1] = [[ap + -6] + 0]; +[ap + 0] = [ap + -6] + 1, ap++; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [fp + -4], ap++; +[ap + 0] = [ap + -4], ap++; +call rel -62; +jmp rel 344 if [ap + -3] != 0; +[ap + 0] = [ap + -5], ap++; +jmp rel 19 if [ap + -2] != 0; +ap += 146; +call rel 395; +[ap + 0] = [ap + -1] + 394, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [[ap + -1] + 3], ap++; +[ap + 0] = [ap + -1] * 51, ap++; +[ap + 0] = [ap + -1] + 28240, ap++; +[ap + 0] = [ap + -154] + [ap + -1], ap++; +[ap + 0] = [ap + -159], ap++; +[ap + 0] = [ap + -157], ap++; +jmp rel 315; +[ap + 0] = 1, ap++; +[ap + 0] = 2, ap++; +[ap + 0] = 3, ap++; +[ap + -3] = [[ap + -8] + 0]; +[ap + -2] = [[ap + -8] + 1]; +[ap + -1] = [[ap + -8] + 2]; +[ap + 0] = [[ap + -8] + 3], ap++; +[ap + 0] = [[ap + -9] + 4], ap++; +[ap + 0] = [[ap + -10] + 5], ap++; +[ap + -3] = [[ap + -11] + 6]; +[ap + -2] = [[ap + -11] + 7]; +[ap + -1] = [[ap + -11] + 8]; +[ap + 0] = [[ap + -11] + 9], ap++; +[ap + 0] = [[ap + -12] + 10], ap++; +[ap + 0] = [[ap + -13] + 11], ap++; +[ap + -3] = [[ap + -14] + 12]; +[ap + -2] = [[ap + -14] + 13]; +[ap + -1] = [[ap + -14] + 14]; +[ap + 0] = [[ap + -14] + 15], ap++; +[ap + 0] = [[ap + -15] + 16], ap++; +[ap + 0] = [[ap + -16] + 17], ap++; +[ap + -3] = [[ap + -17] + 18]; +[ap + -2] = [[ap + -17] + 19]; +[ap + -1] = [[ap + -17] + 20]; +[ap + 0] = [[ap + -17] + 21], ap++; +[ap + 0] = [[ap + -18] + 22], ap++; +[ap + 0] = [[ap + -19] + 23], ap++; +[ap + -3] = [[ap + -20] + 24]; +[ap + -2] = [[ap + -20] + 25]; +[ap + -1] = [[ap + -20] + 26]; +[ap + 0] = [[ap + -20] + 27], ap++; +[ap + 0] = [[ap + -21] + 28], ap++; +[ap + 0] = [[ap + -22] + 29], ap++; +[ap + -3] = [[ap + -23] + 30]; +[ap + -2] = [[ap + -23] + 31]; +[ap + -1] = [[ap + -23] + 32]; +[ap + 0] = [[ap + -23] + 33], ap++; +[ap + 0] = [[ap + -24] + 34], ap++; +[ap + 0] = [[ap + -25] + 35], ap++; +[ap + -3] = [[ap + -26] + 36]; +[ap + -2] = [[ap + -26] + 37]; +[ap + -1] = [[ap + -26] + 38]; +[ap + 0] = [[ap + -26] + 39], ap++; +[ap + 0] = [[ap + -27] + 40], ap++; +[ap + 0] = [[ap + -28] + 41], ap++; +[ap + -3] = [[ap + -29] + 42]; +[ap + -2] = [[ap + -29] + 43]; +[ap + -1] = [[ap + -29] + 44]; +[ap + 0] = [[ap + -29] + 45], ap++; +[ap + 0] = [[ap + -30] + 46], ap++; +[ap + 0] = [[ap + -31] + 47], ap++; +[ap + -3] = [[ap + -32] + 48]; +[ap + -2] = [[ap + -32] + 49]; +[ap + -1] = [[ap + -32] + 50]; +[ap + 0] = [[ap + -32] + 51], ap++; +[ap + 0] = [[ap + -33] + 52], ap++; +[ap + 0] = [[ap + -34] + 53], ap++; +[ap + -3] = [[ap + -35] + 54]; +[ap + -2] = [[ap + -35] + 55]; +[ap + -1] = [[ap + -35] + 56]; +[ap + 0] = [[ap + -35] + 57], ap++; +[ap + 0] = [[ap + -36] + 58], ap++; +[ap + 0] = [[ap + -37] + 59], ap++; +[ap + -3] = [[ap + -38] + 60]; +[ap + -2] = [[ap + -38] + 61]; +[ap + -1] = [[ap + -38] + 62]; +[ap + 0] = [[ap + -38] + 63], ap++; +[ap + 0] = [[ap + -39] + 64], ap++; +[ap + 0] = [[ap + -40] + 65], ap++; +[ap + -3] = [[ap + -41] + 66]; +[ap + -2] = [[ap + -41] + 67]; +[ap + -1] = [[ap + -41] + 68]; +[ap + 0] = [[ap + -41] + 69], ap++; +[ap + 0] = [[ap + -42] + 70], ap++; +[ap + 0] = [[ap + -43] + 71], ap++; +[ap + -3] = [[ap + -44] + 72]; +[ap + -2] = [[ap + -44] + 73]; +[ap + -1] = [[ap + -44] + 74]; +[ap + 0] = [[ap + -44] + 75], ap++; +[ap + 0] = [[ap + -45] + 76], ap++; +[ap + 0] = [[ap + -46] + 77], ap++; +[ap + -3] = [[ap + -47] + 78]; +[ap + -2] = [[ap + -47] + 79]; +[ap + -1] = [[ap + -47] + 80]; +[ap + 0] = [[ap + -47] + 81], ap++; +[ap + 0] = [[ap + -48] + 82], ap++; +[ap + 0] = [[ap + -49] + 83], ap++; +[ap + -3] = [[ap + -50] + 84]; +[ap + -2] = [[ap + -50] + 85]; +[ap + -1] = [[ap + -50] + 86]; +[ap + 0] = [[ap + -50] + 87], ap++; +[ap + 0] = [[ap + -51] + 88], ap++; +[ap + 0] = [[ap + -52] + 89], ap++; +[ap + -3] = [[ap + -53] + 90]; +[ap + -2] = [[ap + -53] + 91]; +[ap + -1] = [[ap + -53] + 92]; +[ap + 0] = [[ap + -53] + 93], ap++; +[ap + 0] = [[ap + -54] + 94], ap++; +[ap + 0] = [[ap + -55] + 95], ap++; +[ap + -3] = [[ap + -56] + 96]; +[ap + -2] = [[ap + -56] + 97]; +[ap + -1] = [[ap + -56] + 98]; +[ap + 0] = [[ap + -56] + 99], ap++; +[ap + 0] = [[ap + -57] + 100], ap++; +[ap + 0] = [[ap + -58] + 101], ap++; +[ap + -3] = [[ap + -59] + 102]; +[ap + -2] = [[ap + -59] + 103]; +[ap + -1] = [[ap + -59] + 104]; +[ap + 0] = [[ap + -59] + 105], ap++; +[ap + 0] = [[ap + -60] + 106], ap++; +[ap + 0] = [[ap + -61] + 107], ap++; +[ap + -3] = [[ap + -62] + 108]; +[ap + -2] = [[ap + -62] + 109]; +[ap + -1] = [[ap + -62] + 110]; +[ap + 0] = [[ap + -62] + 111], ap++; +[ap + 0] = [[ap + -63] + 112], ap++; +[ap + 0] = [[ap + -64] + 113], ap++; +[ap + -3] = [[ap + -65] + 114]; +[ap + -2] = [[ap + -65] + 115]; +[ap + -1] = [[ap + -65] + 116]; +[ap + 0] = [[ap + -65] + 117], ap++; +[ap + 0] = [[ap + -66] + 118], ap++; +[ap + 0] = [[ap + -67] + 119], ap++; +[ap + -3] = [[ap + -68] + 120]; +[ap + -2] = [[ap + -68] + 121]; +[ap + -1] = [[ap + -68] + 122]; +[ap + 0] = [[ap + -68] + 123], ap++; +[ap + 0] = [[ap + -69] + 124], ap++; +[ap + 0] = [[ap + -70] + 125], ap++; +[ap + -3] = [[ap + -71] + 126]; +[ap + -2] = [[ap + -71] + 127]; +[ap + -1] = [[ap + -71] + 128]; +[ap + 0] = [[ap + -71] + 129], ap++; +[ap + 0] = [[ap + -72] + 130], ap++; +[ap + 0] = [[ap + -73] + 131], ap++; +[ap + -3] = [[ap + -74] + 132]; +[ap + -2] = [[ap + -74] + 133]; +[ap + -1] = [[ap + -74] + 134]; +[ap + 0] = [[ap + -74] + 135], ap++; +[ap + 0] = [[ap + -75] + 136], ap++; +[ap + 0] = [[ap + -76] + 137], ap++; +[ap + -3] = [[ap + -77] + 138]; +[ap + -2] = [[ap + -77] + 139]; +[ap + -1] = [[ap + -77] + 140]; +[ap + 0] = [[ap + -77] + 141], ap++; +[ap + 0] = [[ap + -78] + 142], ap++; +[ap + 0] = [[ap + -79] + 143], ap++; +[ap + -3] = [[ap + -80] + 144]; +[ap + -2] = [[ap + -80] + 145]; +[ap + -1] = [[ap + -80] + 146]; +[ap + 0] = [[ap + -80] + 147], ap++; +[ap + 0] = [[ap + -81] + 148], ap++; +[ap + 0] = [[ap + -82] + 149], ap++; +[ap + -3] = [[ap + -83] + 150]; +[ap + -2] = [[ap + -83] + 151]; +[ap + -1] = [[ap + -83] + 152]; +[ap + 0] = [[ap + -83] + 153], ap++; +[ap + 0] = [[ap + -84] + 154], ap++; +[ap + 0] = [[ap + -85] + 155], ap++; +[ap + -3] = [[ap + -86] + 156]; +[ap + -2] = [[ap + -86] + 157]; +[ap + -1] = [[ap + -86] + 158]; +[ap + 0] = [[ap + -86] + 159], ap++; +[ap + 0] = [[ap + -87] + 160], ap++; +[ap + 0] = [[ap + -88] + 161], ap++; +[ap + -3] = [[ap + -89] + 162]; +[ap + -2] = [[ap + -89] + 163]; +[ap + -1] = [[ap + -89] + 164]; +[ap + 0] = [[ap + -89] + 165], ap++; +[ap + 0] = [[ap + -90] + 166], ap++; +[ap + 0] = [[ap + -91] + 167], ap++; +[ap + -3] = [[ap + -92] + 168]; +[ap + -2] = [[ap + -92] + 169]; +[ap + -1] = [[ap + -92] + 170]; +[ap + 0] = [[ap + -92] + 171], ap++; +[ap + 0] = [[ap + -93] + 172], ap++; +[ap + 0] = [[ap + -94] + 173], ap++; +[ap + -3] = [[ap + -95] + 174]; +[ap + -2] = [[ap + -95] + 175]; +[ap + -1] = [[ap + -95] + 176]; +[ap + 0] = [[ap + -95] + 177], ap++; +[ap + 0] = [[ap + -96] + 178], ap++; +[ap + 0] = [[ap + -97] + 179], ap++; +[ap + -3] = [[ap + -98] + 180]; +[ap + -2] = [[ap + -98] + 181]; +[ap + -1] = [[ap + -98] + 182]; +[ap + 0] = [[ap + -98] + 183], ap++; +[ap + 0] = [[ap + -99] + 184], ap++; +[ap + 0] = [[ap + -100] + 185], ap++; +[ap + -3] = [[ap + -101] + 186]; +[ap + -2] = [[ap + -101] + 187]; +[ap + -1] = [[ap + -101] + 188]; +[ap + 0] = [[ap + -101] + 189], ap++; +[ap + 0] = [[ap + -102] + 190], ap++; +[ap + 0] = [[ap + -103] + 191], ap++; +[ap + -3] = [[ap + -104] + 192]; +[ap + -2] = [[ap + -104] + 193]; +[ap + -1] = [[ap + -104] + 194]; +[ap + 0] = [[ap + -104] + 195], ap++; +[ap + 0] = [[ap + -105] + 196], ap++; +[ap + 0] = [[ap + -106] + 197], ap++; +[ap + -3] = [[ap + -107] + 198]; +[ap + -2] = [[ap + -107] + 199]; +[ap + -1] = [[ap + -107] + 200]; +[ap + 0] = [[ap + -107] + 201], ap++; +[ap + 0] = [[ap + -108] + 202], ap++; +[ap + 0] = [[ap + -109] + 203], ap++; +[ap + -3] = [[ap + -110] + 204]; +[ap + -2] = [[ap + -110] + 205]; +[ap + -1] = [[ap + -110] + 206]; +[ap + 0] = [[ap + -110] + 207], ap++; +[ap + 0] = [[ap + -111] + 208], ap++; +[ap + 0] = [[ap + -112] + 209], ap++; +[ap + -3] = [[ap + -113] + 210]; +[ap + -2] = [[ap + -113] + 211]; +[ap + -1] = [[ap + -113] + 212]; +[ap + 0] = [[ap + -113] + 213], ap++; +[ap + 0] = [[ap + -114] + 214], ap++; +[ap + 0] = [[ap + -115] + 215], ap++; +[ap + -3] = [[ap + -116] + 216]; +[ap + -2] = [[ap + -116] + 217]; +[ap + -1] = [[ap + -116] + 218]; +[ap + 0] = [[ap + -116] + 219], ap++; +[ap + 0] = [[ap + -117] + 220], ap++; +[ap + 0] = [[ap + -118] + 221], ap++; +[ap + -3] = [[ap + -119] + 222]; +[ap + -2] = [[ap + -119] + 223]; +[ap + -1] = [[ap + -119] + 224]; +[ap + 0] = [[ap + -119] + 225], ap++; +[ap + 0] = [[ap + -120] + 226], ap++; +[ap + 0] = [[ap + -121] + 227], ap++; +[ap + -3] = [[ap + -122] + 228]; +[ap + -2] = [[ap + -122] + 229]; +[ap + -1] = [[ap + -122] + 230]; +[ap + 0] = [[ap + -122] + 231], ap++; +[ap + 0] = [[ap + -123] + 232], ap++; +[ap + 0] = [[ap + -124] + 233], ap++; +[ap + -3] = [[ap + -125] + 234]; +[ap + -2] = [[ap + -125] + 235]; +[ap + -1] = [[ap + -125] + 236]; +[ap + 0] = [[ap + -125] + 237], ap++; +[ap + 0] = [[ap + -126] + 238], ap++; +[ap + 0] = [[ap + -127] + 239], ap++; +[ap + -3] = [[ap + -128] + 240]; +[ap + -2] = [[ap + -128] + 241]; +[ap + -1] = [[ap + -128] + 242]; +[ap + 0] = [[ap + -128] + 243], ap++; +[ap + 0] = [[ap + -129] + 244], ap++; +[ap + 0] = [[ap + -130] + 245], ap++; +[ap + -3] = [[ap + -131] + 246]; +[ap + -2] = [[ap + -131] + 247]; +[ap + -1] = [[ap + -131] + 248]; +[ap + 0] = [[ap + -131] + 249], ap++; +[ap + 0] = [[ap + -132] + 250], ap++; +[ap + 0] = [[ap + -133] + 251], ap++; +[ap + -3] = [[ap + -134] + 252]; +[ap + -2] = [[ap + -134] + 253]; +[ap + -1] = [[ap + -134] + 254]; +[ap + 0] = [[ap + -134] + 255], ap++; +[ap + 0] = [[ap + -135] + 256], ap++; +[ap + 0] = [[ap + -136] + 257], ap++; +[ap + -3] = [[ap + -137] + 258]; +[ap + -2] = [[ap + -137] + 259]; +[ap + -1] = [[ap + -137] + 260]; +[ap + 0] = [[ap + -137] + 261], ap++; +[ap + 0] = [[ap + -138] + 262], ap++; +[ap + 0] = [[ap + -139] + 263], ap++; +[ap + -3] = [[ap + -140] + 264]; +[ap + -2] = [[ap + -140] + 265]; +[ap + -1] = [[ap + -140] + 266]; +[ap + 0] = [[ap + -140] + 267], ap++; +[ap + 0] = [[ap + -141] + 268], ap++; +[ap + 0] = [[ap + -142] + 269], ap++; +[ap + -3] = [[ap + -143] + 270]; +[ap + -2] = [[ap + -143] + 271]; +[ap + -1] = [[ap + -143] + 272]; +[ap + 0] = [[ap + -143] + 273], ap++; +[ap + 0] = [[ap + -144] + 274], ap++; +[ap + 0] = [[ap + -145] + 275], ap++; +[ap + -3] = [[ap + -146] + 276]; +[ap + -2] = [[ap + -146] + 277]; +[ap + -1] = [[ap + -146] + 278]; +[ap + 0] = [[ap + -146] + 279], ap++; +[ap + 0] = [[ap + -147] + 280], ap++; +[ap + 0] = [[ap + -148] + 281], ap++; +[ap + -3] = [[ap + -149] + 282]; +[ap + -2] = [[ap + -149] + 283]; +[ap + -1] = [[ap + -149] + 284]; +[ap + 0] = [[ap + -149] + 285], ap++; +[ap + 0] = [[ap + -150] + 286], ap++; +[ap + 0] = [[ap + -151] + 287], ap++; +[ap + -3] = [[ap + -152] + 288]; +[ap + -2] = [[ap + -152] + 289]; +[ap + -1] = [[ap + -152] + 290]; +[ap + 0] = [[ap + -152] + 291], ap++; +[ap + 0] = [[ap + -153] + 292], ap++; +[ap + 0] = [[ap + -154] + 293], ap++; +[ap + -3] = [[ap + -155] + 294]; +[ap + -2] = [[ap + -155] + 295]; +[ap + -1] = [[ap + -155] + 296]; +[ap + 0] = [[ap + -155] + 297], ap++; +[ap + 0] = [[ap + -156] + 298], ap++; +[ap + 0] = [[ap + -157] + 299], ap++; +[ap + -3] = [[ap + -158] + 300]; +[ap + -2] = [[ap + -158] + 301]; +[ap + -1] = [[ap + -158] + 302]; +[ap + 0] = [ap + -154], ap++; +[ap + 0] = [ap + -159] + 306, ap++; +[ap + 0] = [ap + -5], ap++; +[ap + 0] = [ap + -163], ap++; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = [ap + -4], ap++; +[ap + 0] = 0, ap++; +[ap + 0] = 0, ap++; +[ap + 0] = [ap + -6], ap++; +ret; +call rel 58; +[ap + 0] = [ap + -1] + 57, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [[ap + -1] + 3], ap++; +[ap + 0] = [ap + -1] * 51, ap++; +[ap + 0] = [ap + -1] + 30400, ap++; +[ap + 0] = [ap + -13], ap++; +[ap + 0] = [ap + -13] + [ap + -2], ap++; +[ap + 0] = [ap + -13], ap++; +[ap + 0] = 1, ap++; +[ap + 0] = [ap + -13], ap++; +[ap + 0] = [ap + -13], ap++; +ret; +call rel 40; +[ap + 0] = [ap + -1] + 39, ap++; +[ap + 0] = [[ap + -1] + 0], ap++; +[ap + 0] = [[ap + -1] + 3], ap++; +[ap + 0] = [ap + -1] * 51, ap++; +[ap + 0] = [ap + -1] + 32770, ap++; +%{ memory[ap + 0] = segments.add() %} +ap += 1; +[ap + 0] = 39878429859763533771555484554338820190071, ap++; +[ap + -1] = [[ap + -2] + 0]; +[ap + 0] = [ap + -16] + 1, ap++; +[ap + 0] = [ap + -14] + [ap + -4], 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.json b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.json new file mode 100644 index 0000000000..8a1fbcfcc6 --- /dev/null +++ b/crates/rpc/fixtures/contracts/l2_gas_accounting/l2_gas_accounting.json @@ -0,0 +1,647 @@ +{ + "sierra_program": [ + "0x1", + "0x7", + "0x0", + "0x2", + "0xa", + "0x0", + "0x169", + "0x97", + "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", + "0x59", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x72656465706f7369745f676173", + "0x7374727563745f6465636f6e737472756374", + "0x656e61626c655f61705f747261636b696e67", + "0x73746f72655f74656d70", + "0x25", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0x656e756d5f696e6974", + "0x24", + "0x6a756d70", + "0x7374727563745f636f6e737472756374", + "0x656e756d5f6d61746368", + "0x64697361626c655f61705f747261636b696e67", + "0x756e626f78", + "0x72656e616d65", + "0x75313238735f66726f6d5f66656c74323532", + "0x64726f70", + "0x61727261795f6e6577", + "0x636f6e73745f61735f696d6d656469617465", + "0x21", + "0x61727261795f617070656e64", + "0x20", + "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", + "0x300", + "0xffffffffffffffff", + "0x86", + "0xc", + "0x73", + "0x6b", + "0x36", + "0x27", + "0x28", + "0x29", + "0x2a", + "0x2b", + "0x2c", + "0x2d", + "0x5c", + "0x2e", + "0x2f", + "0x30", + "0x31", + "0x32", + "0x33", + "0x34", + "0x54", + "0x35", + "0x37", + "0x38", + "0x39", + "0x3a", + "0x3b", + "0x3c", + "0x3d", + "0x3e", + "0x3f", + "0x40", + "0x41", + "0x42", + "0x43", + "0x44", + "0x45", + "0x46", + "0x47", + "0x48", + "0x49", + "0x4a", + "0x4b", + "0x7a", + "0x4c", + "0x4d", + "0x4e", + "0x4f", + "0x50", + "0x51", + "0x52", + "0x53", + "0x55", + "0x56", + "0x57", + "0x58", + "0x122", + "0xa5", + "0xac", + "0x10e", + "0x106", + "0xcc", + "0xf6", + "0xed", + "0x115", + "0x5a", + "0x5b", + "0x1b8", + "0x1a8", + "0x19f", + "0x190", + "0x188", + "0x178", + "0x16a", + "0x2f0", + "0x1da", + "0x2e0", + "0x2d8", + "0x1f6", + "0x2d0", + "0x5d", + "0x5e", + "0x5f", + "0x60", + "0x61", + "0x62", + "0x63", + "0x64", + "0x65", + "0x66", + "0x67", + "0x68", + "0x69", + "0x6a", + "0x6c", + "0x6d", + "0x6e", + "0x6f", + "0x70", + "0x71", + "0x72", + "0x74", + "0x75", + "0x76", + "0x77", + "0x78", + "0x79", + "0x7b", + "0x7c", + "0x7d", + "0x7e", + "0x7f", + "0x80", + "0x81", + "0x82", + "0x83", + "0x84", + "0x85", + "0x87", + "0x88", + "0x89", + "0x8a", + "0x8b", + "0x8c", + "0x8d", + "0x8e", + "0x8f", + "0x90", + "0x91", + "0x92", + "0x93", + "0x94", + "0x95", + "0x96", + "0x97", + "0x98", + "0x99", + "0x9a", + "0x9b", + "0x9c", + "0x9d", + "0x9e", + "0x9f", + "0xa0", + "0xa1", + "0xa2", + "0xa3", + "0xa4", + "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", + "0xca", + "0xcb", + "0xcd", + "0xce", + "0xcf", + "0xd0", + "0xd1", + "0xd2", + "0xd3", + "0xd4", + "0xd5", + "0xd6", + "0xd7", + "0xd8", + "0xd9", + "0xda", + "0xdb", + "0xdc", + "0xdd", + "0xde", + "0xdf", + "0xe0", + "0xe1", + "0xe2", + "0xe3", + "0xe4", + "0xe5", + "0xe6", + "0xe7", + "0xe8", + "0xe9", + "0xea", + "0xeb", + "0xec", + "0xee", + "0xef", + "0xf0", + "0xf1", + "0xf2", + "0xf3", + "0xf4", + "0xf5", + "0xf7", + "0xf8", + "0xf9", + "0xfa", + "0xfb", + "0xfc", + "0xfd", + "0xfe", + "0xff", + "0x100", + "0x101", + "0x102", + "0x103", + "0x104", + "0x105", + "0x107", + "0x108", + "0x132", + "0x1c7", + "0x1b15", + "0x240e06028100605038180a040181c0e06028100608038180a04018080200", + "0x3016120881c0c050200c20070301408030781c0c050200c1c0506830160a", + "0x640a180b8380a16048542805038380a040181c0e0e028100602098180a0d", + "0x1444050b024421403014401f0f0243414030143a050b02438140d8243414", + "0x8c0a0d158a80e06028100629038180a04018085027028980a25048844823", + "0x244224010c41630138143205178244224170142c090a8505a05160242a14", + "0xe00a37028d8121c120180a0d1a858121a0a0d00e06028100627028cc0a32", + "0x148642028148209028148209200b80a051f8247c091e82478091d8e80439", + "0x1c8a050391070050291c1246228140a41168140a410481c8a05039100c05", + "0x149a2d028149a09260180a05208180a05258180a05250249245028149005", + "0x1104e050291c44050291c0c0502944a0050293c0c05029381c05029346e05", + "0x14ae0e0281482092b1540a0520824a852028148253028148205039480a07", + "0x140a47170140a47118140a4d118140a5a049643205028fcb005029200e08", + "0x1740a05208b80a05269700a05278e00a052696c0a05278240e520281c8833", + "0x13c12600c8140a5f0e8140a4d130140a3f2f0140a48040200a570e8140a47", + "0x148e0934824d00933824cc1902814ca64028149e09318380a05311840a05", + "0x134d605029340a072c0140e44350140a4f2c0140a410481cb005039103205", + "0x1c8826028148e70028149e09379b80a05269b40a05279b00a05278640a05", + "0x140a4f040140a4f030140a4d030140a62388140a4d2f0140a410481cbc05", + "0x1d00e050481c0a09049d00a0904824e605039780a0722024e405028149e07", + "0x1d00a08029c0126c029d00a0e0282012093a0141207049b4e2073a838e007", + "0x14d80936014e80536014da0938014e80538014e209049d00a0907024d405", + "0x1ac0a6a049900a74029b00a0804824e8050481c1276029b8d606039d00e6a", + "0x14e80530814d60937014e805030140c090c814e80532014da0930814e805", + "0x14e805049901226029d00a6c0282012093a014120704824ba05049d8121d", + "0x1ac126e029d00a76028181219029d00a26029b41223029d00a22029841222", + "0x14126e04824e8050481c125e029dc4e053a01c3a050c8243a053a0144605", + "0x24b6053a014b80513024b8053a0144e050e824ba053a0143205040241274", + "0x20f02e1681ce8072d9c00e23049740a74029740a6d0496c0a740296c0a22", + "0x1b4122d029d00a2d029c41253029d00a5d0282012093a014120704954b033", + "0x144e09049d00a090382470053c940a4073a01cdc0536024a6053a014a605", + "0x246e053a014a605040241274028b80a5d04824e80528014bc09049d00a52", + "0x148445038b41242029d00a42028881242029d00a092d8248a053a014125c", + "0x1f00a74029ec0a58049ec0a7402800f40719824f4053a014122e048000a74", + "0x14a60903814e80503814aa091b814e8051b814da0916814e80516814e209", + "0x141009049d00a380289c12093a0141207049f00e37169c00a7c029d00a7c", + "0x14e8053f014a0093e814e8053e814da093f014e80504948127d029d00a53", + "0x150005040241274028240e0941a080e81401fc0e74039f8fa2d040e0127e", + "0xb80a74028b80a3704a100a7402a100a6d049fc0a74029fc0a7104a100a74", + "0x14120704a280a8944014e80743814840943a190a083a0145c843f8208a09", + "0x1e8128c029d00a8802800128b029d00a092e024f2053a0150c05040241274", + "0x14f8094823c0e7402a380a7b04a380a7402a351607168251a053a0151805", + "0x14e80549014fe0949014e80548814fc0948814e80548014fa09049d00a8f", + "0x14c1207029d00a07029541279029d00a79029b41285029d00a85029c41293", + "0x2528053a0150c05040241274028240e094981cf2853801526053a0152605", + "0x1c0a5504a500a7402a500a6d04a140a7402a140a7104a540a7402a280a58", + "0x14ba09049d00a09038252a074a214e0054a814e8054a814a60903814e805", + "0x2530053a014128004a5c0a7402824b8094b014e805418141009049d00a2e", + "0x2680e3304a680a74028245c094c814e8054c25c0e2d04a600a7402a600a22", + "0x1d00a96029b41282029d00a82029c4129c029d00a9b02960129b029d00a99", + "0x240e094e01d2c823801538053a0153805298240e053a0140e052a8252c05", + "0x141009049d00a6e0289c12093a014aa052e8241274029600a5d04824e805", + "0x254005049d8129f029d00a9d029b4129e029d00a33029c4129d029d00a5d", + "0x241274029b80a2704824e8052f0150409049d00a09370241274028240e09", + "0x14125c04a7c0a7402a840a6d04a780a74029c00a7104a840a74028640a08", + "0x2900a7402a8d44071682546053a01546051102546053a014128304a880a74", + "0x14e20953814e80553014b00953014e805522940e3304a940a74028245c09", + "0x1d00aa70294c1207029d00a0702954129f029d00a9f029b4129e029d00a9e", + "0x1d00a6d0282012093a0141005420241274028240e095381d3e9e380154e05", + "0x1c5a0954814e80554814440954814e80504a001289029d00a092e0255005", + "0x1558052c02558053a01554ab038cc12ab029d00a091702554053a0155289", + "0x1c0a740281c0a5504aa00a7402aa00a6d049c40a74029c40a71048e80a74", + "0x1d00e070481c0a09049d00a09048247407541c4e0051d014e8051d014a609", + "0x1d00a70029c0126a029d00a710282012093a0141207049b0da07569c41c07", + "0x14d80935014e80535014da0907014e80507014e209049d00a09070240c05", + "0x1d80a6a049840a74029a80a0804824e8050481c126402ab8ec6b039d00e06", + "0x14e8050c814d6090e814e805358140c0937014e80530814da090c814e805", + "0x14e805049901222029d00a6a0282012093a0141207048255e05049d81226", + "0x1ac121d029d00a6402818126e029d00a22029b41227029d00a23029841223", + "0x14126e04824e8050481c125d02ac0bc053a01c4c050c8244c053a0144e05", + "0x245a053a014b60513024b6053a014bc050e824b8053a014dc05040241274", + "0x2162331701ce807168380e23049700a74029700a6d048b40a74028b40a22", + "0x1b4122e029d00a2e029c41252029d00a5c0282012093a01412070494caa58", + "0x144e09049d00a09038246e05590e0a0073a01c3a0536024a4053a014a405", + "0x248a053a014a405040241274028cc0a5d04824e8051c014bc09049d00a50", + "0x140042038b41200029d00a00028881200029d00a092d82484053a014125c", + "0x1f40a74029f00a58049f00a74029e8f60719824f6053a014122e049e80a74", + "0x14aa0922814e80522814da0902814e805028150a0917014e80517014e209", + "0x241274028240e093e8208a05170380a7d029d00a7d0294c1208029d00a08", + "0x1d00a7e029b4127f029d00a0929024fc053a014a405040241274028dc0a27", + "0x1c12844181d66824001ce8073f9f85c081c024fe053a014fe0528024fc05", + "0x2000a7402a000a7104a180a74028250c0942814e805410141009049d00a09", + "0x390e0919814e805198146e0902814e805028150a0942814e80542814da09", + "0x14120704a300ab445814e8073c81510093ca291087381d00a33430150a80", + "0x25208f039d00a8b02a28128e029d00a092e0251a053a0151005040241274", + "0x14f80949a480e7402a440a7b04a440a7402a411c0716824127402a3c0a79", + "0x14e8054a814fe094a814e8054a014fc094a014e80549814fa09049d00a92", + "0x154128d029d00a8d029b4128a029d00a8a02a141287029d00a87029c41296", + "0x24e8050481c1296042351487070152c053a0152c052982410053a0141005", + "0x150a0943814e80543814e2094c014e80546014b0094b814e805440141009", + "0x1d00a980294c1208029d00a08029541297029d00a97029b4128a029d00a8a", + "0x150805040241274028cc0a5d04824e8050481c12980425d1487070153005", + "0xb4129b029d00a9b02888129b029d00a094002534053a014125c04a640a74", + "0x2780a5804a780a7402a713a07198253a053a014122e04a700a7402a6d3407", + "0x14e8054c814da0902814e805028150a0941814e80541814e2094f814e805", + "0x240e094f8213205418380a9f029d00a9f0294c1208029d00a08029541299", + "0x141009049d00a1d0289c12093a014a6052e8241274029540a5d04824e805", + "0x256a05049d812a3029d00aa1029b412a2029d00a58029c412a1029d00a5c", + "0x241274028740a2704824e8052e8150409049d00a09370241274028240e09", + "0x14125c04a8c0a7402a900a6d04a880a74028380a7104a900a74029b80a08", + "0x29c0a7402a994a07168254c053a0154c05110254c053a014128304a940a74", + "0x14e20954814e80544814b00944814e80553aa00e3304aa00a74028245c09", + "0x1d00a080295412a3029d00aa3029b41205029d00a0502a1412a2029d00aa2", + "0x1c00a8404824e8050481c12a90428c0aa20701552053a0155205298241005", + "0x8812ac029d00a094002556053a014125c04aa80a74029b00a0804824e805", + "0xe96c07198256c053a014122e048e80a7402ab156071682558053a0155805", + "0x14e805028150a0936814e80536814e20940814e8055b814b0095b814e805", + "0x380a81029d00a810294c1208029d00a080295412aa029d00aaa029b41205", + "0x1c0a09049d00a0937024127402825180938014e80504a2c1281042a80a6d", + "0x234126a029d00a710282012093a0141207049b0da075c1c41c073a01c0a09", + "0x14d405368240c053a0140c051b824d607039d00a0702a381206029d00a09", + "0x141009049d00a0903824326103ae4c876039d00e0635838108f049a80a74", + "0x1d00a64028dc126e029d00a6e029b41276029d00a76029c4126e029d00a6a", + "0x1c122302ae810053a01c44052102444260e820e805321b8ec0822824c805", + "0x1780a74029780a37049780a7402825200913814e805130141009049d00a09", + "0x1740e74039780e1d0423c1227029d00a27029b41208029d00a083801d2209", + "0x1740a74029740a71048b80a740289c0a0804824e8050481c122d2d81d765c", + "0x16066083a014b82e2e8208a092e014e8052e0146e0917014e80517014da09", + "0x24a0053a014b005040241274028240e09290157853029d00e55029081255", + "0xdc70074902470053a01470051b8246e053a014a6050002470053a0141290", + "0x1400a6d049ec0a74029140a7a049e80a7402800660749824004222820e805", + "0x1d00a0903824f8055e824e8073d81528093d014e8053d014e20928014e805", + "0x254127d029d00a7d029b4127e029d00a0802800127d029d00a50028201209", + "0x2100a74029f40a0804824e8050481c12834101d7c803f81ce807211f8f408", + "0x14da093f814e8053f814e20943014e805428152e0942814e805400152c09", + "0x14ba09049d00a09038250c843f8200a86029d00a8602a601284029d00a84", + "0x2514053a014129904a200a7402824b80943814e8053e8141009049d00a83", + "0x22c0e3304a2c0a74028245c093c814e805452200e2d04a280a7402a280a22", + "0x1d00a87029b41282029d00a82029c4128d029d00a8c02a68128c029d00a79", + "0x1d00a7c02a6c12093a014120704a350e82040151a053a0151a054c0250e05", + "0x14125c04a380a74029400a0804824e80521014ba09049d00a0802a701209", + "0x2440a7402a411e071682520053a01520051102520053a014129d04a3c0a74", + "0x14e2094a014e80549815340949814e80548a480e3304a480a74028245c09", + "0x25288e3d0200a94029d00a9402a60128e029d00a8e029b4127a029d00a7a", + "0x14e8052901534094a814e8052c0141009049d00a0802a7012093a0141207", + "0x200a96029d00a9602a601295029d00a95029b41233029d00a33029c41296", + "0x9c0a0804824e805040153809049d00a2d0297412093a014120704a592a33", + "0x2532053a01532051102532053a014129e04a600a7402824b8094b814e805", + "0x1534094e014e8054d26c0e3304a6c0a74028245c094d014e8054ca600e2d", + "0x1d00a9d02a601297029d00a97029b4125b029d00a5b029c4129d029d00a9c", + "0x24e805380153e09049d00a070297412093a014120704a752e5b040153a05", + "0x14da090e814e8050e814e2094f814e8051181534094f014e805130141009", + "0x14ba09049d00a09038253e9e0e8200a9f029d00a9f02a60129e029d00a9e", + "0x2542053a014d4050402412740281c0a5d04824e805380153e09049d00a19", + "0x1546a2038b412a3029d00aa30288812a3029d00a094f02544053a014125c", + "0x29c0a7402a980a9a04a980a7402a914a07198254a053a014122e04a900a74", + "0x184100553814e80553815300950814e80550814da0930814e80530814e209", + "0x14d8050402412740281c0a5d04824e805380153e09049d00a09038254ea1", + "0xb412a9029d00aa90288812a9029d00a094002512053a014125c04aa00a74", + "0x2b00a9a04ab00a7402aa956071982556053a014122e04aa80a7402aa51207", + "0x14e8051d015300954014e80554014da0936814e80536814e2091d014e805", + "0x24d86d03afce20e039d00e050481c0a09049d00a093702474a8368200a3a", + "0x141c05388240c70039d00a7002a38126a029d00a710282012093a0141207", + "0x24e8050481c126b02b001274038180aa1049a80a74029a80a6d048380a74", + "0x190100751824c8053a01412a2049d80a74029a80a0804824e80538014ba09", + "0x14e8053b014da0907014e80507014e2090c814e80530815480930814e805", + "0x141207048640e76071c00a19029d00a1902a941207029d00a0702a141276", + "0x146e090e814e80504a34126e029d00a6a0282012093a014d605530241274", + "0x8c0ec1110980e7403874e00e0423c126e029d00a6e029b4121d029d00a1d", + "0x1780a6d048980a74028980a71049780a74029b80a0804824e8050481c1227", + "0x200e5e130390e0911014e805110146e0903814e805038150a092f014e805", + "0x2012093a0141207048cc0ac217014e8071681510091696cb85d381d00a22", + "0x1d00a5302a9c12093a014120e0494caa073a0145c0545024b0053a014b805", + "0x24e8050481c125002b0c1274039480a94049600a74029600a6d04948a607", + "0x14440922814e8052d8150a091b814e8051c014da091c014e8052c0141009", + "0x155009049d00a5002a6c12093a0141207048258805049d81242029d00a53", + "0x24f6053a01412a9049e80a7402825120900014e8052c0141009049d00a53", + "0x14f80511024f6053a014f60511024f4053a014f40511024f8053a01412aa", + "0x88127e029d00a7e0288812803f9f8fa703a014f87b3d16ce0ab049f00a74", + "0x2110682381d00a803f9f8fa705582500053a015000511024fe053a014fe05", + "0x2ac1285029d00a85028881284029d00a84028881283029d00a83028881285", + "0x14e80544014440943814e805438144409452210e86381d00a854220d0470", + "0x22c0a2204a35188b3c9c0e805452210e86382ac128a029d00a8a028881288", + "0x235188b3c9c1560946814e80546814440946014e80546014440945814e805", + "0x2440a2204a400a7402a400a2204a3c0a7402a3c0a2204a45208f471c0e805", + "0x2526053a0152605110252a9449a48e07402a45208f471c1560948814e805", + "0x25d2c703a0152a9449a48e0ab04a540a7402a540a2204a500a7402a500a22", + "0x2532053a01532051102530053a0153005110252e053a0152e05110253298", + "0x1d00a9c02888129b029d00a9b02888129d4e26d34703a01532984ba58e0ab", + "0x144409512853e9e381d00a9d4e26d3470558253a053a0153a05110253805", + "0x2853e9e382ac12a2029d00aa20288812a1029d00aa102888129f029d00a9f", + "0x14440952814e80552814440952014e8055201444095329548a3381d00aa2", + "0x2a00a7402aa00a2204aa512a8539c0e8055329548a3382ac12a6029d00aa6", + "0x2a8e07402aa512a8539c1560954814e80554814440944814e805448144409", + "0xe80a74028e80a2204ab00a7402ab00a2204aac0a7402aac0a22048e958ab", + "0x150205110256e053a0156e05110258a815bad8e074028e958ab551c15609", + "0x8812c96431d8c703a0158a815bad8e0ab04b140a7402b140a2204a040a74", + "0x31d8c705582592053a01592051102590053a0159005110258e053a0158e05", + "0x8812cc029d00acc0288812cb029d00acb0288812cd6632d94703a01592c8", + "0x14e80567814440968b419ece381d00acd6632d9470558259a053a0159a05", + "0x1c0e80568b419ece382ac12d1029d00ad10288812d0029d00ad00288812cf", + "0x14e8056a014440969814e8056981444093c014e8053c01444096a34cf0d2", + "0x35c0a2204b580a7402b580a2204b61aed66a9c0e8056a34cf0d2382ac12d4", + "0x25b6da3bb64e07402b61aed66a9c156096c014e8056c01444096b814e805", + "0x364e0ab04b6c0a7402b6c0a2204b680a7402b680a22049dc0a74029dc0a22", + "0x25bc053a015bc0511025ba053a015ba0511025bede6eb70e07402b6db477", + "0x1d00ae00288812e270b8140703a015bede6eb70e0ab04b7c0a7402b7c0a22", + "0x1d00ae270b81407055825c4053a015c40511025c2053a015c20511025c005", + "0x1d00ae60288812e5029d00ae50288812e4029d00ae40288812e672b91c670", + "0x14440974014e805740144409753a5d0e7381d00ae672b91c67055825cc05", + "0x3b5d8eb3a9c0e805753a5d0e7382ac12ea029d00aea0288812e9029d00ae9", + "0x1c1560976814e80576814440976014e80576014440975814e805758144409", + "0x3c00a7402bc00a2204bbc0a7402bbc0a2204bc5e0ef771c0e80576bb1d675", + "0x15e60511025eaf479bc8e07402bc5e0ef771c1560978814e805788144409", + "0x15eaf479bc8e0ab04bd40a7402bd40a2204bd00a7402bd00a2204bcc0a74", + "0x15f20511025f0053a015f00511025ee053a015ee0511025f2f87bbd8e074", + "0x8812fb029d00afb0288812fd7e3edf4703a015f2f87bbd8e0ab04be40a74", + "0x401fefe381d00afd7e3edf47055825fa053a015fa0511025f8053a015f805", + "0x2ac1301029d00b01028881300029d00b000288812ff029d00aff028881301", + "0x14e80582014440981814e80581814440982c120702381d00b01803fdfc70", + "0x41c0a2204aba1107831c0e80582c120702382ac1305029d00b05028881304", + "0x2ba1107831c1560957014e80557014440984014e80584014440983814e805", + "0x4300a2204c2c0a7402c2c0a2204c280a7402c280a2204c32170a849c0e805", + "0x261c053a0161c05110261eaf87434e07402c32170a849c1560986014e805", + "0x44620703a0161eaf87434e0ab04c3c0a7402c3c0a2204abc0a7402abc0a22", + "0x2626053a01626051102624053a01624051102622053a0162205110262712", + "0x1d00b16028881315029d00b150288813178b45628703a016271288c40e0ab", + "0x1444098dc6a3318381d00b178b4562870558262e053a0162e05110262c05", + "0x46a3318382ac131b029d00b1b02888131a029d00b1a028881319029d00b19", + "0x1444098f014e8058f01444098e814e8058e81444098fc7a3b1c381d00b1b", + "0x4840a7402c840a2204c8e4521901c0e8058fc7a3b1c382ac131f029d00b1f", + "0x490e07402c8e4521901c1560991814e80591814440991014e805910144409", + "0x49c0a7402c9c0a2204c980a7402c980a2204c940a7402c940a2204c9e4d25", + "0x1654051102652053a016520511026572a94ca0e07402c9e4d25921c15609", + "0x88132e594b658703a016572a94ca0e0ab04cac0a7402cac0a2204ca80a74", + "0x4b65870558265c053a0165c051102564053a0156405110265a053a0165a05", + "0x881331029d00b31028881330029d00b3002888133298cc25e703a0165cb2", + "0x14e8059a01444099b4d66933381d00b3298cc25e705582664053a0166405", + "0x1c0e8059b4d66933382ac1336029d00b36028881335029d00b35028881334", + "0x14e8059d01444099c814e8059c81444099c014e8059c01444099d4e67137", + "0x4f40a2204cf00a7402cf00a2204cfa7b3c9d9c0e8059d4e67137382ac133a", + "0x268541a04fce07402cfa7b3c9d9c156099f014e8059f01444099e814e805", + "0x4fce0ab04d080a7402d080a2204d040a7402d040a2204d000a7402d000a22", + "0x268a053a0168a051102688053a0168805110268d45a250ce07402d0a8340", + "0x1d00b4802888134aa4d228e703a0168d45a250ce0ab04d180a7402d180a22", + "0x1d00b4aa4d228e705582694053a01694051102692053a0169205110269005", + "0x1d00ab402888134d029d00b4d02888134c029d00b4c0288812b4a6d329670", + "0x154e09a7814e805a78144409a8d429f4e381d00ab4a6d329670558256805", + "0x54a9c7055826a2053a016a20511026a0053a016a00511026a54f039d00b4f", + "0x2cc0aa804824e805aa8155009049d00b5402aa012b3aad52a6703a016a350", + "0x1080a7402d3c0a22049140a7402d4c0a85048dc0a74028000a6d04824e805", + "0x1740a7104d5c0a7402d580aa404d580a7402908aa0751824127402824dc09", + "0x14e805ab8154a0922814e805228150a091b814e8051b814da092e814e805", + "0x1d00a3302ab01358029d00a5c0282012093a014120704d5c8a372e9c00b57", + "0x24b6053a014b60542826b0053a016b00536824ba053a014ba0538826b205", + "0x2412740289c0a5d04824e8050481c13592dd60ba7002d640a7402d640aa5", + "0x14e80504a78135b029d00a092e026b4053a014dc05040241274028200a79", + "0xcc135e029d00a0917026ba053a016b95b038b4135c029d00b5c02888135c", + "0x5680a6d0488c0a740288c0a7104d800a7402d7c0aac04d7c0a7402d76bc07", + "0x26c007ad08ce005b0014e805b00154a0903814e805038150a09ad014e805", + "0x5840a74029b00a0804824e80504014f209049d00a700297412093a0141207", + "0x58ec40716826c6053a016c60511026c6053a014128004d880a7402824b809", + "0x14e805b28155809b2814e805b22c40e3304ac40a74028245c09b2014e805", + "0x2941207029d00a0702a141361029d00b61029b4126d029d00a6d029c41366", + "0x200e0504948a642049c05c5321024e070b301ec26d38016cc053a016cc05", + "0x1608409040388409043e4e00803814125229908ba09070b8a6422e8241c09", + "0x168380200e0504978ba42049c01c1d2e908120eb381c0a09" + ], + "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/src/method/estimate_fee.rs b/crates/rpc/src/method/estimate_fee.rs index b088803661..53c9ce2f1f 100644 --- a/crates/rpc/src/method/estimate_fee.rs +++ b/crates/rpc/src/method/estimate_fee.rs @@ -193,8 +193,8 @@ impl crate::dto::SerializeForVersion for Output { mod tests { use pathfinder_common::macro_prelude::*; use pathfinder_common::prelude::*; - use pathfinder_common::transaction::{DataAvailabilityMode, ResourceBounds}; - use pathfinder_common::{felt, BlockId, Tip}; + use pathfinder_common::transaction::{DataAvailabilityMode, ResourceBound, ResourceBounds}; + use pathfinder_common::{felt, BlockId, ResourceAmount, ResourcePricePerUnit, Tip}; use pathfinder_executor::types::{FeeEstimate, PriceUnit}; use pretty_assertions_sorted::assert_eq; @@ -202,6 +202,7 @@ mod tests { use crate::types::request::{ BroadcastedDeclareTransaction, BroadcastedDeclareTransactionV2, + BroadcastedDeclareTransactionV3, BroadcastedInvokeTransaction, BroadcastedInvokeTransactionV0, BroadcastedInvokeTransactionV1, @@ -733,4 +734,277 @@ mod tests { ]) ); } + + fn declare_v3_transaction(sender_address: ContractAddress) -> BroadcastedTransaction { + let sierra_definition = + include_bytes!("../../fixtures/contracts/l2_gas_accounting/l2_gas_accounting.json"); + let sierra_hash = + class_hash!("0x01A48FD3F75D0A7C2288AC23FB6ABA26CD375607BA63E4A3B3ED47FC8E99DC21"); + let casm_hash = + casm_hash!("0x02F58B23F7D98FF076AE59C08125AAFFD6DECCF1A7E97378D1A303B1A4223989"); + + 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, + }, + )) + } + + fn deploy_v3_transaction( + account_contract_address: ContractAddress, + universal_deployer_address: ContractAddress, + ) -> BroadcastedTransaction { + let sierra_hash = + class_hash!("0x01A48FD3F75D0A7C2288AC23FB6ABA26CD375607BA63E4A3B3ED47FC8E99DC21"); + + 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![ + // Number of calls + call_param!("0x1"), + 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"), + ], + }, + )) + } + + /// Invokes a contract that calls a recursive function. Recursion depth can + /// be set with the `depth` parameter. + fn invoke_v3_transaction_with_data_gas( + sender_address: ContractAddress, + nonce: TransactionNonce, + depth: CallParam, + ) -> BroadcastedTransaction { + BroadcastedTransaction::Invoke(BroadcastedInvokeTransaction::V3( + BroadcastedInvokeTransactionV3 { + version: TransactionVersion::THREE, + signature: vec![], + sender_address, + calldata: vec![ + // Number of calls + call_param!("0x1"), + // Address of the deployed test contract + CallParam(felt!( + "0x17c54b787c2eccfb057cf6aa2f941d612249549fff74140adc20bb949eab74b" + )), + // Entry point selector for the called contract, i.e. + CallParam(EntryPoint::hashed(b"test_redeposits").0), + // Length of the call data for the called contract, i.e. + call_param!("1"), + depth, + ], + nonce, + resource_bounds: ResourceBounds { + l1_gas: ResourceBound { + max_amount: ResourceAmount(50), + max_price_per_unit: ResourcePricePerUnit(1000), + }, + l1_data_gas: Some(ResourceBound { + max_amount: ResourceAmount(100), + max_price_per_unit: ResourcePricePerUnit(1000), + }), + l2_gas: ResourceBound { + max_amount: ResourceAmount(800_000), + max_price_per_unit: ResourcePricePerUnit(1000), + }, + }, + tip: Tip(0), + paymaster_data: vec![], + account_deployment_data: vec![], + nonce_data_availability_mode: DataAvailabilityMode::L2, + fee_data_availability_mode: DataAvailabilityMode::L2, + }, + )) + } + + #[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_transaction_with_data_gas( + account_contract_address, + transaction_nonce!("0x2"), + call_param!("7"), + ); + // Invoke once more to test that the execution state updates properly with L2 + // gas accounting aware code. + let invoke_transaction2 = invoke_v3_transaction_with_data_gas( + account_contract_address, + transaction_nonce!("0x3"), + call_param!("7"), + ); + + let input = Input { + request: vec![ + declare_transaction, + deploy_transaction, + invoke_transaction, + invoke_transaction2, + ], + simulation_flags: vec![SimulationFlag::SkipValidate], + block_id: BlockId::Number(last_block_header.number), + }; + let result = super::estimate_fee(context, input).await.unwrap(); + let declare_expected = FeeEstimate { + l1_gas_consumed: 1736.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: 3856.into(), + unit: PriceUnit::Fri, + }; + let deploy_expected = FeeEstimate { + l1_gas_consumed: 22.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: 492.into(), + unit: PriceUnit::Fri, + }; + let invoke_expected = FeeEstimate { + l1_gas_consumed: 0.into(), + l1_gas_price: 2.into(), + l1_data_gas_consumed: 128.into(), + l1_data_gas_price: 2.into(), + l2_gas_consumed: 778635.into(), + l2_gas_price: 1.into(), + overall_fee: 778891.into(), + unit: PriceUnit::Fri, + }; + self::assert_eq!( + result, + Output(vec![ + declare_expected, + deploy_expected, + invoke_expected, + invoke_expected, + ]) + ); + } + + #[tokio::test] + async fn starknet_0_13_4_max_gas_exceeded() { + 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_transaction_with_data_gas( + account_contract_address, + transaction_nonce!("0x2"), + call_param!("100000"), + ); + + let input = Input { + request: vec![declare_transaction, deploy_transaction, invoke_transaction], + simulation_flags: vec![SimulationFlag::SkipValidate], + block_id: BlockId::Number(last_block_header.number), + }; + let result = super::estimate_fee(context, input).await; + let expected_err = anyhow::anyhow!("Fee estimation failed, maximum gas limit exceeded"); + assert_matches::assert_matches!(result, Err(EstimateFeeError::Internal(err)) if err.to_string() == expected_err.to_string()); + } + + #[tokio::test] + async fn starknet_0_13_4_user_provided_gas_limit_exceeded() { + 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 with large depth (it is a recursive function) such + // that the L2 gas required exceeds the user provided limit. + let invoke_transaction = invoke_v3_transaction_with_data_gas( + account_contract_address, + transaction_nonce!("0x2"), + call_param!("1000"), + ); + + let input = Input { + request: vec![declare_transaction, deploy_transaction, invoke_transaction], + simulation_flags: vec![SimulationFlag::SkipValidate], + block_id: BlockId::Number(last_block_header.number), + }; + let EstimateFeeError::TransactionExecutionError { error, .. } = + super::estimate_fee(context, input).await.unwrap_err() + else { + panic!("Expected TransactionExecutionError"); + }; + + // This is currently the best way to check that the transaction was reverted due + // to insufficient gas. Leaving this test and the assert below to detect if + // anything in `blockifier` changes in the future. + assert!(error.contains("Out of gas")); + } } diff --git a/crates/rpc/src/method/simulate_transactions.rs b/crates/rpc/src/method/simulate_transactions.rs index f8424fdcf5..1e92813090 100644 --- a/crates/rpc/src/method/simulate_transactions.rs +++ b/crates/rpc/src/method/simulate_transactions.rs @@ -2632,8 +2632,8 @@ pub(crate) mod tests { } } - const INVOKE_V3_OVERALL_FEE: u64 = 692846; - const INVOKE_V3_GAS_CONSUMED: u64 = 692590; + const INVOKE_V3_WITH_DATA_GAS_BOUNDS_OVERALL_FEE: u64 = 762105; + const INVOKE_V3_WITH_DATA_GAS_BOUNDS_GAS_CONSUMED: u64 = 761849; const INVOKE_V3_DATA_GAS_CONSUMED: u64 = 128; pub fn invoke_v3_with_data_gas_bounds( @@ -2647,9 +2647,9 @@ pub(crate) mod tests { l1_gas_price: 2.into(), l1_data_gas_consumed: INVOKE_V3_DATA_GAS_CONSUMED.into(), l1_data_gas_price: 2.into(), - l2_gas_consumed: INVOKE_V3_GAS_CONSUMED.into(), + l2_gas_consumed: INVOKE_V3_WITH_DATA_GAS_BOUNDS_GAS_CONSUMED.into(), l2_gas_price: 1.into(), - overall_fee: INVOKE_V3_OVERALL_FEE.into(), + overall_fee: INVOKE_V3_WITH_DATA_GAS_BOUNDS_OVERALL_FEE.into(), unit: pathfinder_executor::types::PriceUnit::Fri, }, trace: pathfinder_executor::types::TransactionTrace::Invoke( @@ -2682,7 +2682,7 @@ pub(crate) mod tests { }, l1_gas: 0, l1_data_gas: 128, - l2_gas: 692590, + l2_gas: INVOKE_V3_WITH_DATA_GAS_BOUNDS_GAS_CONSUMED.into(), }, }, ), @@ -2804,6 +2804,8 @@ pub(crate) mod tests { } } + const INVOKE_V3_OVERALL_FEE: u64 = 692846; + fn invoke_v3_fee_transfer( account_contract_address: ContractAddress, last_block_header: &BlockHeader,