Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
chore(fee, concurrency): move add_fee_to_sequencer_balance to fee_uti…
Browse files Browse the repository at this point in the history
…ls (#2003)
  • Loading branch information
Yoni-Starkware authored Jun 25, 2024
1 parent 001940a commit b581558
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 102 deletions.
44 changes: 44 additions & 0 deletions crates/blockifier/src/concurrency/fee_utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
use std::collections::HashMap;

use num_traits::ToPrimitive;
use starknet_api::core::ContractAddress;
use starknet_api::hash::StarkFelt;
use starknet_api::stark_felt;
use starknet_api::transaction::Fee;

use crate::context::BlockContext;
use crate::execution::call_info::CallInfo;
use crate::execution::execution_utils::stark_felt_to_felt;
use crate::fee::fee_utils::get_sequencer_balance_keys;
use crate::state::cached_state::{ContractClassMapping, StateMaps};
use crate::state::state_api::UpdatableState;

#[cfg(test)]
#[path = "fee_utils_test.rs"]
mod test;
Expand Down Expand Up @@ -28,3 +40,35 @@ pub fn fill_sequencer_balance_reads(
storage_read_values[low_index] = sequencer_balance_low;
storage_read_values[high_index] = sequencer_balance_high;
}

pub fn add_fee_to_sequencer_balance(
fee_token_address: ContractAddress,
state: &mut impl UpdatableState,
actual_fee: Fee,
block_context: &BlockContext,
sequencer_balance_value_low: StarkFelt,
sequencer_balance_value_high: StarkFelt,
) {
let sequencer_balance_low_as_u128 = stark_felt_to_felt(sequencer_balance_value_low)
.to_u128()
.expect("sequencer balance low should be u128");
let sequencer_balance_high_as_u128 = stark_felt_to_felt(sequencer_balance_value_high)
.to_u128()
.expect("sequencer balance high should be u128");
let (new_value_low, carry) = sequencer_balance_low_as_u128.overflowing_add(actual_fee.0);
let (new_value_high, carry) = sequencer_balance_high_as_u128.overflowing_add(carry.into());
assert!(
!carry,
"The sequencer balance overflowed when adding the fee. This should not happen."
);
let (sequencer_balance_key_low, sequencer_balance_key_high) =
get_sequencer_balance_keys(block_context);
let writes = StateMaps {
storage: HashMap::from([
((fee_token_address, sequencer_balance_key_low), stark_felt!(new_value_low)),
((fee_token_address, sequencer_balance_key_high), stark_felt!(new_value_high)),
]),
..StateMaps::default()
};
state.apply_writes(&writes, &ContractClassMapping::default(), &HashMap::default());
}
61 changes: 58 additions & 3 deletions crates/blockifier/src/concurrency/fee_utils_test.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
use cairo_felt::Felt252;
use num_bigint::BigUint;
use rstest::rstest;
use starknet_api::hash::StarkFelt;
use starknet_api::transaction::TransactionVersion;
use starknet_api::stark_felt;
use starknet_api::transaction::{Fee, TransactionVersion};

use crate::concurrency::fee_utils::fill_sequencer_balance_reads;
use crate::concurrency::fee_utils::{add_fee_to_sequencer_balance, fill_sequencer_balance_reads};
use crate::concurrency::test_utils::create_fee_transfer_call_info;
use crate::context::BlockContext;
use crate::execution::execution_utils::{felt_to_stark_felt, stark_felt_to_felt};
use crate::fee::fee_utils::get_sequencer_balance_keys;
use crate::invoke_tx_args;
use crate::state::state_api::StateReader;
use crate::test_utils::contracts::FeatureContract;
use crate::test_utils::initial_test_state::{fund_account, test_state_inner};
use crate::test_utils::initial_test_state::{fund_account, test_state, test_state_inner};
use crate::test_utils::{
create_trivial_calldata, CairoVersion, BALANCE, MAX_L1_GAS_AMOUNT, MAX_L1_GAS_PRICE,
};
use crate::transaction::objects::FeeType;
use crate::transaction::test_utils::{account_invoke_tx, block_context, l1_resource_bounds};

#[rstest]
Expand Down Expand Up @@ -45,3 +52,51 @@ pub fn test_fill_sequencer_balance_reads(

assert_eq!(concurrency_call_info, call_info);
}

#[rstest]
#[case::no_overflow(Fee(50_u128), stark_felt!(100_u128), StarkFelt::ZERO)]
#[case::overflow(Fee(150_u128), stark_felt!(u128::MAX), stark_felt!(5_u128))]
#[case::overflow_edge_case(Fee(500_u128), stark_felt!(u128::MAX), stark_felt!(u128::MAX-1))]
pub fn test_add_fee_to_sequencer_balance(
#[case] actual_fee: Fee,
#[case] sequencer_balance_low: StarkFelt,
#[case] sequencer_balance_high: StarkFelt,
) {
let block_context = BlockContext::create_for_account_testing_with_concurrency_mode(true);
let account = FeatureContract::Empty(CairoVersion::Cairo1);
let mut state = test_state(&block_context.chain_info, 0, &[(account, 1)]);
let (sequencer_balance_key_low, sequencer_balance_key_high) =
get_sequencer_balance_keys(&block_context);

let fee_token_address = block_context.chain_info.fee_token_address(&FeeType::Strk);

add_fee_to_sequencer_balance(
fee_token_address,
&mut state,
actual_fee,
&block_context,
sequencer_balance_low,
sequencer_balance_high,
);

let new_sequencer_balance_value_low =
state.get_storage_at(fee_token_address, sequencer_balance_key_low).unwrap();
let new_sequencer_balance_value_high =
state.get_storage_at(fee_token_address, sequencer_balance_key_high).unwrap();
let expected_balance =
(stark_felt_to_felt(sequencer_balance_low) + Felt252::from(actual_fee.0)).to_biguint();

let mask_128_bit = (BigUint::from(1_u8) << 128) - 1_u8;
let expected_sequencer_balance_value_low = Felt252::from(&expected_balance & mask_128_bit);
let expected_sequencer_balance_value_high =
stark_felt_to_felt(sequencer_balance_high) + Felt252::from(&expected_balance >> 128);

assert_eq!(
new_sequencer_balance_value_low,
felt_to_stark_felt(&expected_sequencer_balance_value_low)
);
assert_eq!(
new_sequencer_balance_value_high,
felt_to_stark_felt(&expected_sequencer_balance_value_high)
);
}
45 changes: 3 additions & 42 deletions crates/blockifier/src/concurrency/worker_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,18 @@ use std::sync::Mutex;
use std::thread;
use std::time::Duration;

use num_traits::ToPrimitive;
use starknet_api::core::{ClassHash, ContractAddress};
use starknet_api::hash::StarkFelt;
use starknet_api::stark_felt;
use starknet_api::core::ClassHash;
use starknet_api::transaction::Fee;

use super::versioned_state::{VersionedState, VersionedStateProxy};
use super::versioned_state::VersionedState;
use crate::blockifier::transaction_executor::TransactionExecutorError;
use crate::bouncer::Bouncer;
use crate::concurrency::fee_utils::fill_sequencer_balance_reads;
use crate::concurrency::fee_utils::{add_fee_to_sequencer_balance, fill_sequencer_balance_reads};
use crate::concurrency::scheduler::{Scheduler, Task};
use crate::concurrency::utils::lock_mutex_in_array;
use crate::concurrency::versioned_state::ThreadSafeVersionedState;
use crate::concurrency::TxIndex;
use crate::context::BlockContext;
use crate::execution::execution_utils::stark_felt_to_felt;
use crate::fee::fee_utils::get_sequencer_balance_keys;
use crate::state::cached_state::{
ContractClassMapping, StateChanges, StateMaps, TransactionalState,
};
Expand Down Expand Up @@ -313,37 +308,3 @@ impl<'a, U: UpdatableState> WorkerExecutor<'a, U> {
.commit_chunk_and_recover_block_state(n_committed_txs, visited_pcs)
}
}

// Utilities.

fn add_fee_to_sequencer_balance(
fee_token_address: ContractAddress,
tx_versioned_state: &mut VersionedStateProxy<impl StateReader>,
actual_fee: Fee,
block_context: &BlockContext,
sequencer_balance_value_low: StarkFelt,
sequencer_balance_value_high: StarkFelt,
) {
let sequencer_balance_low_as_u128 = stark_felt_to_felt(sequencer_balance_value_low)
.to_u128()
.expect("sequencer balance low should be u128");
let sequencer_balance_high_as_u128 = stark_felt_to_felt(sequencer_balance_value_high)
.to_u128()
.expect("sequencer balance high should be u128");
let (new_value_low, carry) = sequencer_balance_low_as_u128.overflowing_add(actual_fee.0);
let (new_value_high, carry) = sequencer_balance_high_as_u128.overflowing_add(carry.into());
assert!(
!carry,
"The sequencer balance overflowed when adding the fee. This should not happen."
);
let (sequencer_balance_key_low, sequencer_balance_key_high) =
get_sequencer_balance_keys(block_context);
let writes = StateMaps {
storage: HashMap::from([
((fee_token_address, sequencer_balance_key_low), stark_felt!(new_value_low)),
((fee_token_address, sequencer_balance_key_high), stark_felt!(new_value_high)),
]),
..StateMaps::default()
};
tx_versioned_state.apply_writes(&writes, &ContractClassMapping::default(), &HashMap::default());
}
60 changes: 3 additions & 57 deletions crates/blockifier/src/concurrency/worker_logic_test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use std::sync::Mutex;

use num_bigint::BigUint;
use rstest::rstest;
use starknet_api::core::{ContractAddress, Nonce, PatriciaKey};
use starknet_api::hash::{StarkFelt, StarkHash};
use starknet_api::transaction::{ContractAddressSalt, Fee, TransactionVersion};
Expand All @@ -15,9 +15,8 @@ use crate::concurrency::fee_utils::STORAGE_READ_SEQUENCER_BALANCE_INDICES;
use crate::concurrency::scheduler::{Task, TransactionStatus};
use crate::concurrency::test_utils::safe_versioned_state_for_testing;
use crate::concurrency::versioned_state::ThreadSafeVersionedState;
use crate::concurrency::worker_logic::{add_fee_to_sequencer_balance, lock_mutex_in_array};
use crate::concurrency::worker_logic::lock_mutex_in_array;
use crate::context::{BlockContext, TransactionContext};
use crate::execution::execution_utils::{felt_to_stark_felt, stark_felt_to_felt};
use crate::fee::fee_utils::get_sequencer_balance_keys;
use crate::state::cached_state::StateMaps;
use crate::state::state_api::StateReader;
Expand All @@ -30,7 +29,7 @@ use crate::test_utils::{
};
use crate::transaction::account_transaction::AccountTransaction;
use crate::transaction::constants::DEPLOY_CONTRACT_FUNCTION_ENTRY_POINT_NAME;
use crate::transaction::objects::{FeeType, HasRelatedFeeType};
use crate::transaction::objects::HasRelatedFeeType;
use crate::transaction::test_utils::{
account_invoke_tx, calculate_class_info_for_testing, l1_resource_bounds,
};
Expand Down Expand Up @@ -533,59 +532,6 @@ fn test_worker_validate() {
let next_task2 = worker_executor.validate(tx_index);
assert_eq!(next_task2, Task::AskForTask);
}
use cairo_felt::Felt252;
use rstest::rstest;

#[rstest]
#[case::no_overflow(Fee(50_u128), stark_felt!(100_u128), StarkFelt::ZERO)]
#[case::overflow(Fee(150_u128), stark_felt!(u128::MAX), stark_felt!(5_u128))]
#[case::overflow_edge_case(Fee(500_u128), stark_felt!(u128::MAX), stark_felt!(u128::MAX-1))]
pub fn test_add_fee_to_sequencer_balance(
#[case] actual_fee: Fee,
#[case] sequencer_balance_low: StarkFelt,
#[case] sequencer_balance_high: StarkFelt,
) {
let tx_index = 0;
let block_context = BlockContext::create_for_account_testing_with_concurrency_mode(true);
let account = FeatureContract::Empty(CairoVersion::Cairo1);
let safe_versioned_state =
safe_versioned_state_for_testing(test_state(&block_context.chain_info, 0, &[(account, 1)]));
let mut tx_versioned_state = safe_versioned_state.pin_version(tx_index);
let (sequencer_balance_key_low, sequencer_balance_key_high) =
get_sequencer_balance_keys(&block_context);

let fee_token_address = block_context.chain_info.fee_token_address(&FeeType::Strk);

add_fee_to_sequencer_balance(
fee_token_address,
&mut tx_versioned_state,
actual_fee,
&block_context,
sequencer_balance_low,
sequencer_balance_high,
);

let new_sequencer_balance_value_low =
tx_versioned_state.get_storage_at(fee_token_address, sequencer_balance_key_low).unwrap();
let new_sequencer_balance_value_high =
tx_versioned_state.get_storage_at(fee_token_address, sequencer_balance_key_high).unwrap();
let expected_balance =
(stark_felt_to_felt(sequencer_balance_low) + Felt252::from(actual_fee.0)).to_biguint();

let mask_128_bit = (BigUint::from(1_u8) << 128) - 1_u8;
let expected_sequencer_balance_value_low = Felt252::from(&expected_balance & mask_128_bit);
let expected_sequencer_balance_value_high =
stark_felt_to_felt(sequencer_balance_high) + Felt252::from(&expected_balance >> 128);

assert_eq!(
new_sequencer_balance_value_low,
felt_to_stark_felt(&expected_sequencer_balance_value_low)
);
assert_eq!(
new_sequencer_balance_value_high,
felt_to_stark_felt(&expected_sequencer_balance_value_high)
);
}

#[test]
fn test_deploy_before_declare() {
Expand Down

0 comments on commit b581558

Please sign in to comment.