Skip to content

Commit 5a100c2

Browse files
blockifier: move logic inside casm_v2hash_resource_estimate
1 parent 8715ec2 commit 5a100c2

File tree

3 files changed

+72
-82
lines changed

3 files changed

+72
-82
lines changed

crates/blockifier/src/execution/casm_hash_estimation.rs

Lines changed: 54 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,6 @@ impl From<(ExecutionResources, HashVersion)> for EstimatedExecutionResources {
147147
/// `compiled_class_hash`.
148148
///
149149
/// This provides resource estimates rather than exact values.
150-
// TODO(AvivG): Remove allow once used.
151-
#[allow(unused)]
152150
pub trait EstimateCasmHashResources {
153151
/// Specifies the hash function variant that the estimate is for.
154152
fn hash_version(&self) -> HashVersion;
@@ -173,7 +171,7 @@ pub trait EstimateCasmHashResources {
173171

174172
// TODO(AvivG): Remove allow once used.
175173
#[allow(unused)]
176-
struct CasmV1HashResourceEstimate {}
174+
pub(crate) struct CasmV1HashResourceEstimate {}
177175

178176
impl EstimateCasmHashResources for CasmV1HashResourceEstimate {
179177
fn hash_version(&self) -> HashVersion {
@@ -210,7 +208,8 @@ impl EstimateCasmHashResources for CasmV2HashResourceEstimate {
210208
fn estimated_resources_of_hash_function(
211209
felt_size_groups: &FeltSizeCount,
212210
) -> EstimatedExecutionResources {
213-
let n_steps = estimate_steps_of_encode_felt252_data_and_calc_blake_hash(felt_size_groups);
211+
let n_steps =
212+
Self::estimate_steps_of_encode_felt252_data_and_calc_blake_hash(felt_size_groups);
214213
let builtin_instance_counter = match felt_size_groups.n_felts() {
215214
// The empty case does not use builtins at all.
216215
0 => HashMap::new(),
@@ -230,7 +229,6 @@ impl EstimateCasmHashResources for CasmV2HashResourceEstimate {
230229
}
231230
}
232231
}
233-
234232
// Constants used for estimating the cost of BLAKE hashing inside Starknet OS.
235233
// These values are based on empirical measurement by running
236234
// `encode_felt252_data_and_calc_blake_hash` on various combinations of big and small felts.
@@ -252,71 +250,59 @@ mod blake_estimation {
252250
pub const STEPS_EMPTY_INPUT: usize = 170;
253251
}
254252

255-
fn base_steps_for_blake_hash(n_u32s: usize) -> usize {
256-
let rem_u32s = n_u32s % FeltSizeCount::U32_WORDS_PER_MESSAGE;
257-
if rem_u32s == 0 {
258-
blake_estimation::BASE_STEPS_FULL_MSG
259-
} else {
260-
// This computation is based on running blake2s with different inputs.
261-
// Note: all inputs expand to an even number of u32s --> `rem_u32s` is always even.
262-
blake_estimation::BASE_STEPS_PARTIAL_MSG
263-
+ (rem_u32s / 2) * blake_estimation::STEPS_PER_2_U32_REMINDER
264-
}
265-
}
253+
impl CasmV2HashResourceEstimate {
254+
/// Estimates the total number of VM steps needed to hash the given felts with Blake in the
255+
/// Starknet OS.
256+
fn estimate_steps_of_encode_felt252_data_and_calc_blake_hash(
257+
felt_size_groups: &FeltSizeCount,
258+
) -> usize {
259+
let encoded_u32_len = felt_size_groups.encoded_u32_len();
260+
if encoded_u32_len == 0 {
261+
// The empty input case is a special case.
262+
return blake_estimation::STEPS_EMPTY_INPUT;
263+
}
266264

267-
fn felts_steps(n_big_felts: usize, n_small_felts: usize) -> usize {
268-
let big_steps = n_big_felts
269-
.checked_mul(blake_estimation::STEPS_BIG_FELT)
270-
.expect("Overflow computing big felt steps");
271-
let small_steps = n_small_felts
272-
.checked_mul(blake_estimation::STEPS_SMALL_FELT)
273-
.expect("Overflow computing small felt steps");
274-
big_steps.checked_add(small_steps).expect("Overflow computing total felt steps")
275-
}
265+
// Adds a base cost depending on whether the total fits exactly into full 16-u32 messages.
266+
let base_steps = if encoded_u32_len % FeltSizeCount::U32_WORDS_PER_MESSAGE == 0 {
267+
blake_estimation::BASE_STEPS_FULL_MSG
268+
} else {
269+
// This computation is based on running blake2s with different inputs.
270+
// Note: all inputs expand to an even number of u32s --> `rem_u32s` is always even.
271+
blake_estimation::BASE_STEPS_PARTIAL_MSG
272+
+ (encoded_u32_len % FeltSizeCount::U32_WORDS_PER_MESSAGE / 2)
273+
* blake_estimation::STEPS_PER_2_U32_REMINDER
274+
};
276275

277-
/// Estimates the number of VM steps needed to hash the given felts with Blake in Starknet OS.
278-
/// Each small felt unpacks into 2 u32s, and each big felt into 8 u32s.
279-
/// Adds a base cost depending on whether the total fits exactly into full 16-u32 messages.
280-
fn estimate_steps_of_encode_felt252_data_and_calc_blake_hash(
281-
felt_size_groups: &FeltSizeCount,
282-
) -> usize {
283-
let total_u32s = felt_size_groups.encoded_u32_len();
284-
if total_u32s == 0 {
285-
// The empty input case is a special case.
286-
return blake_estimation::STEPS_EMPTY_INPUT;
276+
base_steps
277+
+ felt_size_groups.large * blake_estimation::STEPS_BIG_FELT
278+
+ felt_size_groups.small * blake_estimation::STEPS_SMALL_FELT
287279
}
288280

289-
let base_steps = base_steps_for_blake_hash(total_u32s);
290-
let felt_steps = felts_steps(felt_size_groups.large, felt_size_groups.small);
291-
292-
base_steps.checked_add(felt_steps).expect("Overflow computing total Blake hash steps")
293-
}
294-
295-
/// Converts the execution resources and blake opcode count to L2 gas.
296-
///
297-
/// Used for both Stwo ("proving_gas") and Stone ("sierra_gas") estimations, which differ in
298-
/// builtin costs. This unified logic is valid because only the `range_check` builtin is used,
299-
/// and its cost is identical across provers (see `bouncer.get_tx_weights`).
300-
// TODO(AvivG): Move inside blake estimation struct.
301-
pub fn blake_execution_resources_estimation_to_gas(
302-
resources: EstimatedExecutionResources,
303-
versioned_constants: &VersionedConstants,
304-
blake_opcode_gas: usize,
305-
) -> GasAmount {
306-
// TODO(AvivG): Remove this once gas computation is separated from resource estimation.
307-
assert!(
308-
resources
309-
.resources()
310-
.builtin_instance_counter
311-
.keys()
312-
.all(|&k| k == BuiltinName::range_check),
313-
"Expected either empty builtins or only `range_check` builtin, got: {:?}. This breaks the \
314-
assumption that builtin costs are identical between provers.",
315-
resources.resources().builtin_instance_counter.keys().collect::<Vec<_>>()
316-
);
317-
318-
resources.to_sierra_gas(
319-
|resources| vm_resources_to_sierra_gas(resources, versioned_constants),
320-
Some(blake_opcode_gas),
321-
)
281+
/// Converts the execution resources and blake opcode count to L2 gas.
282+
///
283+
/// Used for both Stwo ("proving_gas") and Stone ("sierra_gas") estimations, which differ in
284+
/// builtin costs. This unified logic is valid because only the `range_check` builtin is used,
285+
/// and its cost is identical across provers (see `bouncer.get_tx_weights`).
286+
pub(crate) fn blake_execution_resources_estimation_to_gas(
287+
resources: EstimatedExecutionResources,
288+
versioned_constants: &VersionedConstants,
289+
blake_opcode_gas: usize,
290+
) -> GasAmount {
291+
// TODO(AvivG): Remove this once gas computation is separated from resource estimation.
292+
assert!(
293+
resources
294+
.resources()
295+
.builtin_instance_counter
296+
.keys()
297+
.all(|&k| k == BuiltinName::range_check),
298+
"Expected either empty builtins or only `range_check` builtin, got: {:?}. This breaks \
299+
the assumption that builtin costs are identical between provers.",
300+
resources.resources().builtin_instance_counter.keys().collect::<Vec<_>>()
301+
);
302+
303+
resources.to_sierra_gas(
304+
|resources| vm_resources_to_sierra_gas(resources, versioned_constants),
305+
Some(blake_opcode_gas),
306+
)
307+
}
322308
}

crates/blockifier/src/execution/casm_hash_estimation_test.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ use pretty_assertions::assert_eq;
77
use rstest::rstest;
88
use starknet_types_core::felt::Felt;
99

10-
use crate::execution::casm_hash_estimation::blake_estimation::STEPS_EMPTY_INPUT;
1110
use crate::execution::casm_hash_estimation::{
12-
estimate_steps_of_encode_felt252_data_and_calc_blake_hash,
11+
blake_estimation,
1312
CasmV2HashResourceEstimate,
1413
EstimateCasmHashResources,
1514
EstimatedExecutionResources,
@@ -123,11 +122,15 @@ fn test_u32_constants() {
123122
#[test]
124123
fn test_zero_inputs() {
125124
// logic was written.
126-
let steps = estimate_steps_of_encode_felt252_data_and_calc_blake_hash(&FeltSizeCount {
127-
large: 0,
128-
small: 0,
129-
});
130-
assert_eq!(steps, STEPS_EMPTY_INPUT, "Unexpected base step cost for zero inputs");
125+
let steps =
126+
CasmV2HashResourceEstimate::estimate_steps_of_encode_felt252_data_and_calc_blake_hash(
127+
&FeltSizeCount::default(),
128+
);
129+
assert_eq!(
130+
steps,
131+
blake_estimation::STEPS_EMPTY_INPUT,
132+
"Unexpected base step cost for zero inputs"
133+
);
131134

132135
// No opcodes should be emitted.
133136
let opcodes = FeltSizeCount::default().blake_opcode_count();
@@ -136,7 +139,8 @@ fn test_zero_inputs() {
136139
// Should result in base cost only (no opcode cost).
137140
let resources =
138141
CasmV2HashResourceEstimate::estimated_resources_of_hash_function(&FeltSizeCount::default());
139-
let expected = ExecutionResources { n_steps: STEPS_EMPTY_INPUT, ..Default::default() };
142+
let expected =
143+
ExecutionResources { n_steps: blake_estimation::STEPS_EMPTY_INPUT, ..Default::default() };
140144
assert_eq!(resources.resources(), &expected, "Unexpected resources values for zero-input hash");
141145
assert_eq!(resources.blake_count(), 0, "Expected zero BLAKE opcodes for zero inputs");
142146
}

crates/blockifier/src/execution/contract_class.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ use crate::blockifier_versioned_constants::VersionedConstants;
4444
use crate::bouncer::vm_resources_to_sierra_gas;
4545
use crate::execution::call_info::BuiltinCounterMap;
4646
use crate::execution::casm_hash_estimation::{
47-
blake_execution_resources_estimation_to_gas,
4847
CasmV2HashResourceEstimate,
4948
EstimateCasmHashResources,
5049
EstimatedExecutionResources,
@@ -476,11 +475,12 @@ impl CompiledClassV1 {
476475
) -> (GasAmount, BuiltinCounterMap) {
477476
let blake_hash_resources =
478477
estimate_casm_blake_hash_computation_resources(&self.bytecode_segment_felt_sizes);
479-
let blake_hash_gas = blake_execution_resources_estimation_to_gas(
480-
blake_hash_resources,
481-
versioned_constants,
482-
blake_weight,
483-
);
478+
let blake_hash_gas =
479+
CasmV2HashResourceEstimate::blake_execution_resources_estimation_to_gas(
480+
blake_hash_resources,
481+
versioned_constants,
482+
blake_weight,
483+
);
484484

485485
let poseidon_hash_resources =
486486
estimate_casm_poseidon_hash_computation_resources(&self.bytecode_segment_felt_sizes);

0 commit comments

Comments
 (0)