Skip to content

Commit

Permalink
feat(blockifier): add struct StateChangesCountForFee
Browse files Browse the repository at this point in the history
  • Loading branch information
yoavGrs committed Nov 25, 2024
1 parent aa0115b commit 3cf36e7
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 68 deletions.
19 changes: 11 additions & 8 deletions crates/blockifier/src/fee/gas_usage_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,17 @@ fn starknet_resources() -> StarknetResources {
.map(|call_info| call_info.with_some_class_hash())
.collect();
let execution_summary =
CallInfo::summarize_many(call_infos.iter(), VersionedConstants::latest_constants());
let state_resources = StateResources::new_for_testing(StateChangesCount {
n_storage_updates: 7,
n_class_hash_updates: 11,
n_compiled_class_hash_updates: 13,
n_modified_contracts: 17,
});
StarknetResources::new(2_usize, 3_usize, 4_usize, state_resources, 6.into(), execution_summary)
CallInfo::summarize_many(call_infos.iter(), VersionedConstants::latest_constants());
let state_resources = StateResources::new_for_testing(
StateChangesCount {
n_storage_updates: 7,
n_class_hash_updates: 11,
n_compiled_class_hash_updates: 13,
n_modified_contracts: 17,
},
19,
);
>>>>>>> b5f69e82c (feat(blockifier): add struct StateChangesCountForFee)
}

#[rstest]
Expand Down
7 changes: 6 additions & 1 deletion crates/blockifier/src/fee/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ impl TransactionReceipt {
calldata_length,
signature_length,
code_size,
StateResources::new(state_changes, sender_address, tx_context.fee_token_address()),
StateResources::new(
state_changes,
sender_address,
tx_context.fee_token_address(),
tx_context.block_context.versioned_constants.enable_stateful_compression,
),
l1_handler_payload_size,
execution_summary_without_fee_transfer,
);
Expand Down
17 changes: 10 additions & 7 deletions crates/blockifier/src/fee/receipt_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
calldata_length,
signature_length,
0,
StateResources::new_for_testing(deploy_account_state_changes_count),
StateResources::new_for_testing(deploy_account_state_changes_count, 0),
None,
ExecutionSummary::default(),
);
Expand Down Expand Up @@ -228,7 +228,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
0,
0,
0,
StateResources::new_for_testing(l2_to_l1_state_changes_count),
StateResources::new_for_testing(l2_to_l1_state_changes_count, 0),
None,
execution_summary.clone(),
);
Expand Down Expand Up @@ -261,7 +261,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(

assert_eq!(l2_to_l1_messages_gas_usage_vector, manual_gas_computation);

// Any calculation with storage writings.t
// Any calculation with storage writings.

let n_modified_contracts = 7;
let n_storage_updates = 11;
Expand All @@ -275,7 +275,7 @@ fn test_calculate_tx_gas_usage_basic<'a>(
0,
0,
0,
StateResources::new_for_testing(storage_writes_state_changes_count),
StateResources::new_for_testing(storage_writes_state_changes_count, n_storage_updates / 2),
None,
ExecutionSummary::default(),
);
Expand Down Expand Up @@ -304,7 +304,10 @@ fn test_calculate_tx_gas_usage_basic<'a>(
l1_handler_payload_size,
signature_length,
0,
StateResources::new_for_testing(combined_state_changes_count),
StateResources::new_for_testing(
combined_state_changes_count,
storage_writes_state_changes_count.n_storage_updates / 2,
),
Some(l1_handler_payload_size),
execution_summary.clone(),
);
Expand Down Expand Up @@ -379,7 +382,7 @@ fn test_calculate_tx_gas_usage(
calldata_length,
signature_length,
0,
StateResources::new_for_testing(state_changes_count),
StateResources::new_for_testing(state_changes_count, 0),
None,
ExecutionSummary::default(),
);
Expand Down Expand Up @@ -437,7 +440,7 @@ fn test_calculate_tx_gas_usage(
calldata_length,
signature_length,
0,
StateResources::new_for_testing(state_changes_count),
StateResources::new_for_testing(state_changes_count, 0),
None,
// The transfer entrypoint emits an event - pass the call info to count its resources.
execution_summary,
Expand Down
29 changes: 21 additions & 8 deletions crates/blockifier/src/fee/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::fee::gas_usage::{
get_message_segment_length,
get_onchain_data_segment_length,
};
use crate::state::cached_state::{StateChanges, StateChangesCount};
use crate::state::cached_state::{StateChanges, StateChangesCount, StateChangesCountForFee};
use crate::transaction::errors::TransactionFeeError;
use crate::utils::u64_from_usize;
use crate::versioned_constants::{ArchivalDataGasCosts, VersionedConstants};
Expand Down Expand Up @@ -157,34 +157,47 @@ impl StarknetResources {
#[cfg_attr(feature = "transaction_serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct StateResources {
state_changes_for_fee: StateChangesCount,
pub state_changes_for_fee: StateChangesCountForFee,
}

impl StateResources {
pub fn new(
state_changes: &StateChanges,
sender_address: Option<ContractAddress>,
fee_token_address: ContractAddress,
enable_stateful_compression: bool,
) -> Self {
Self {
state_changes_for_fee: state_changes
.count_for_fee_charge(sender_address, fee_token_address),
state_changes_for_fee: state_changes.count_for_fee_charge(
sender_address,
fee_token_address,
enable_stateful_compression,
),
}
}

#[cfg(any(test, feature = "testing"))]
pub fn new_for_testing(state_changes_for_fee: StateChangesCount) -> Self {
Self { state_changes_for_fee }
pub fn new_for_testing(
state_changes_count: StateChangesCount,
n_allocated_keys: usize,
) -> Self {
Self {
state_changes_for_fee: StateChangesCountForFee {
state_changes_count,
n_allocated_keys,
},
}
}

/// Returns the gas cost of the transaction's state changes.
pub fn to_gas_vector(&self, use_kzg_da: bool) -> GasVector {
// TODO(Nimrod, 29/3/2024): delete `get_da_gas_cost` and move it's logic here.
get_da_gas_cost(&self.state_changes_for_fee, use_kzg_da)
// TODO(Yoav): Add the cost of allocating keys.
get_da_gas_cost(&self.state_changes_for_fee.state_changes_count, use_kzg_da)
}

pub fn get_onchain_data_segment_length(&self) -> usize {
get_onchain_data_segment_length(&self.state_changes_for_fee)
get_onchain_data_segment_length(&self.state_changes_for_fee.state_changes_count)
}
}

Expand Down
29 changes: 23 additions & 6 deletions crates/blockifier/src/state/cached_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,8 @@ impl StateChanges {
&self,
sender_address: Option<ContractAddress>,
fee_token_address: ContractAddress,
) -> StateChangesCount {
enable_stateful_compression: bool,
) -> StateChangesCountForFee {
let mut modified_contracts = self.state_maps.get_modified_contracts();

// For account transactions, we need to compute the transaction fee before we can execute
Expand All @@ -720,11 +721,19 @@ impl StateChanges {
// block.
modified_contracts.remove(&fee_token_address);

StateChangesCount {
n_storage_updates,
n_class_hash_updates: self.state_maps.class_hashes.len(),
n_compiled_class_hash_updates: self.state_maps.compiled_class_hashes.len(),
n_modified_contracts: modified_contracts.len(),
StateChangesCountForFee {
state_changes_count: StateChangesCount {
n_storage_updates,
n_class_hash_updates: self.state_maps.class_hashes.len(),
n_compiled_class_hash_updates: self.state_maps.compiled_class_hashes.len(),
n_modified_contracts: modified_contracts.len(),
},
n_allocated_keys: if enable_stateful_compression {
// TODO: Set number of allocated keys.
0
} else {
0
},
}
}
}
Expand All @@ -738,3 +747,11 @@ pub struct StateChangesCount {
pub n_compiled_class_hash_updates: usize,
pub n_modified_contracts: usize,
}

/// Holds the number of state changes for fee.
#[cfg_attr(feature = "transaction_serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct StateChangesCountForFee {
pub state_changes_count: StateChangesCount,
pub n_allocated_keys: usize,
}
21 changes: 14 additions & 7 deletions crates/blockifier/src/state/cached_state_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,25 +323,32 @@ fn create_state_changes_for_test<S: StateReader>(
let sender_balance_key = get_fee_token_var_address(sender_address);
state.set_storage_at(fee_token_address, sender_balance_key, felt!("0x1999")).unwrap();
}

state.get_actual_state_changes().unwrap()
}

#[rstest]
fn test_from_state_changes_for_fee_charge(
#[values(Some(contract_address!("0x102")), None)] sender_address: Option<ContractAddress>,
#[values(true, false)] enable_stateful_compression: bool,
) {
let mut state: CachedState<DictStateReader> = CachedState::default();
let fee_token_address = contract_address!("0x17");
let state_changes =
create_state_changes_for_test(&mut state, sender_address, fee_token_address);
let state_changes_count = state_changes.count_for_fee_charge(sender_address, fee_token_address);
let expected_state_changes_count = StateChangesCount {
let state_changes_count = state_changes.count_for_fee_charge(
sender_address,
fee_token_address,
enable_stateful_compression,
);
let expected_state_changes_count = StateChangesCountForFee {
// 1 for storage update + 1 for sender balance update if sender is defined.
n_storage_updates: 1 + usize::from(sender_address.is_some()),
n_class_hash_updates: 1,
n_compiled_class_hash_updates: 1,
n_modified_contracts: 2,
state_changes_count: StateChangesCount {
n_storage_updates: 1 + usize::from(sender_address.is_some()),
n_class_hash_updates: 1,
n_compiled_class_hash_updates: 1,
n_modified_contracts: 2,
},
n_allocated_keys: 0,
};
assert_eq!(state_changes_count, expected_state_changes_count);
}
Expand Down
75 changes: 46 additions & 29 deletions crates/blockifier/src/transaction/account_transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use crate::execution::entry_point::EntryPointExecutionContext;
use crate::execution::syscalls::SyscallSelector;
use crate::fee::fee_utils::{get_fee_by_gas_vector, get_sequencer_balance_keys};
use crate::fee::gas_usage::estimate_minimal_gas_vector;
use crate::state::cached_state::{StateChangesCount, TransactionalState};
use crate::state::cached_state::{StateChangesCount, StateChangesCountForFee, TransactionalState};
use crate::state::state_api::{State, StateReader};
use crate::test_utils::contracts::FeatureContract;
use crate::test_utils::declare::declare_tx;
Expand Down Expand Up @@ -1384,15 +1384,21 @@ fn test_count_actual_storage_changes(
expected_sequencer_fee_update,
]);

let state_changes_count_1 =
state_changes_1.clone().count_for_fee_charge(Some(account_address), fee_token_address);
let expected_state_changes_count_1 = StateChangesCount {
// See expected storage updates.
n_storage_updates: 3,
// The contract address (storage update) and the account address (nonce update). Does not
// include the fee token address as a modified contract.
n_modified_contracts: 2,
..Default::default()
let state_changes_count_1 = state_changes_1.clone().count_for_fee_charge(
Some(account_address),
fee_token_address,
block_context.versioned_constants.enable_stateful_compression,
);
let expected_state_changes_count_1 = StateChangesCountForFee {
state_changes_count: StateChangesCount {
// See expected storage updates.
n_storage_updates: 3,
// The contract address (storage update) and the account address (nonce update). Does
// not include the fee token address as a modified contract.
n_modified_contracts: 2,
..Default::default()
},
n_allocated_keys: 0,
};

assert_eq!(expected_modified_contracts, state_changes_1.state_maps.get_modified_contracts());
Expand Down Expand Up @@ -1421,15 +1427,21 @@ fn test_count_actual_storage_changes(
let expected_storage_updates_2 =
HashMap::from([account_balance_storage_change, expected_sequencer_fee_update]);

let state_changes_count_2 =
state_changes_2.clone().count_for_fee_charge(Some(account_address), fee_token_address);
let expected_state_changes_count_2 = StateChangesCount {
// See expected storage updates.
n_storage_updates: 2,
// The account address (nonce update). Does not include the fee token address as a modified
// contract.
n_modified_contracts: 1,
..Default::default()
let state_changes_count_2 = state_changes_2.clone().count_for_fee_charge(
Some(account_address),
fee_token_address,
block_context.versioned_constants.enable_stateful_compression,
);
let expected_state_changes_count_2 = StateChangesCountForFee {
state_changes_count: StateChangesCount {
// See expected storage updates.
n_storage_updates: 2,
// The account address (nonce update). Does not include the fee token address as a
// modified contract.
n_modified_contracts: 1,
..Default::default()
},
n_allocated_keys: 0,
};

assert_eq!(expected_modified_contracts_2, state_changes_2.state_maps.get_modified_contracts());
Expand Down Expand Up @@ -1466,16 +1478,21 @@ fn test_count_actual_storage_changes(
expected_sequencer_fee_update,
]);

let state_changes_count_3 = state_changes_transfer
.clone()
.count_for_fee_charge(Some(account_address), fee_token_address);
let expected_state_changes_count_3 = StateChangesCount {
// See expected storage updates.
n_storage_updates: 3,
// The account address (nonce update). Does not include the fee token address as a modified
// contract.
n_modified_contracts: 1,
..Default::default()
let state_changes_count_3 = state_changes_transfer.clone().count_for_fee_charge(
Some(account_address),
fee_token_address,
block_context.versioned_constants.enable_stateful_compression,
);
let expected_state_changes_count_3 = StateChangesCountForFee {
state_changes_count: StateChangesCount {
// See expected storage updates.
n_storage_updates: 3,
// The account address (nonce update). Does not include the fee token address as a
// modified contract.
n_modified_contracts: 1,
..Default::default()
},
n_allocated_keys: 0,
};

assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions crates/blockifier/src/transaction/transactions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ fn test_invoke_tx(
calldata_length,
signature_length,
0,
StateResources::new_for_testing(state_changes_for_fee),
StateResources::new_for_testing(state_changes_for_fee, 0),
None,
ExecutionSummary::default(),
);
Expand Down Expand Up @@ -1506,7 +1506,7 @@ fn test_declare_tx(
0,
0,
class_info.code_size(),
StateResources::new_for_testing(state_changes_for_fee),
StateResources::new_for_testing(state_changes_for_fee, 0),
None,
ExecutionSummary::default(),
);
Expand Down
1 change: 1 addition & 0 deletions target_vscode/.rustc_info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"rustc_fingerprint":2888093778743971573,"outputs":{"2713324566792342441":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n","stderr":""},"3223659835760633936":{"success":true,"status":"","code":0,"stdout":"___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/yoav/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\noff\npacked\nunpacked\n___\nclippy\ndebug_assertions\nfeature=\"cargo-clippy\"\npanic=\"unwind\"\nproc_macro\ntarget_abi=\"\"\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n","stderr":""},"865200126862334810":{"success":true,"status":"","code":0,"stdout":"rustc 1.81.0 (eeb90cda1 2024-09-04)\nbinary: rustc\ncommit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c\ncommit-date: 2024-09-04\nhost: x86_64-unknown-linux-gnu\nrelease: 1.81.0\nLLVM version: 18.1.7\n","stderr":""}},"successes":{}}

0 comments on commit 3cf36e7

Please sign in to comment.