Skip to content

Commit 56419e6

Browse files
blockifier: move logic inside felt_size_count
1 parent f8bd57a commit 56419e6

File tree

3 files changed

+32
-43
lines changed

3 files changed

+32
-43
lines changed

crates/blockifier/src/execution/contract_class.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,30 @@ pub struct FeltSizeCount {
7171
}
7272

7373
impl FeltSizeCount {
74+
// Constants that define how felts are encoded into u32s for BLAKE hashing.
75+
// Number of `u32` words in a single BLAKE input message block.
76+
pub(crate) const U32_WORDS_PER_MESSAGE: usize = 16;
77+
// Number of `u32` words a large felt expands into.
78+
pub(crate) const U32_WORDS_PER_LARGE_FELT: usize = 8;
79+
// Number of `u32` words a small felt expands into.
80+
pub(crate) const U32_WORDS_PER_SMALL_FELT: usize = 2;
81+
7482
pub fn n_felts(&self) -> usize {
7583
self.small + self.large
7684
}
85+
86+
/// Returns the total number of `u32` words required to encode all felts
87+
/// according to the small/large felt encoding scheme.
88+
pub(crate) fn encoded_u32_len(&self) -> usize {
89+
self.large * Self::U32_WORDS_PER_LARGE_FELT + self.small * Self::U32_WORDS_PER_SMALL_FELT
90+
}
91+
92+
/// Returns the number of BLAKE opcodes required to hash the felts.
93+
/// Each BLAKE opcode processes one message block of [`U32_WORDS_PER_MESSAGE`] `u32`s
94+
/// (partial messages are padded).
95+
pub(crate) fn blake_opcode_count(&self) -> usize {
96+
self.encoded_u32_len().div_ceil(Self::U32_WORDS_PER_MESSAGE)
97+
}
7798
}
7899

79100
/// Counts felts in bytecode by size (small < 2^63, large >= 2^63).

crates/blockifier/src/execution/execution_utils.rs

Lines changed: 6 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -373,16 +373,6 @@ pub fn poseidon_hash_many_cost(data_length: usize) -> ExecutionResources {
373373
}
374374
}
375375

376-
// Constants that define how felts are encoded into u32s for BLAKE hashing.
377-
mod blake_encoding {
378-
/// Number of u32s in a Blake input message.
379-
pub const N_U32S_MESSAGE: usize = 16;
380-
381-
/// Number of u32s a felt is encoded into.
382-
pub const N_U32S_BIG_FELT: usize = 8;
383-
pub const N_U32S_SMALL_FELT: usize = 2;
384-
}
385-
386376
// Constants used for estimating the cost of BLAKE hashing inside Starknet OS.
387377
// These values are based on empirical measurement by running
388378
// `encode_felt252_data_and_calc_blake_hash` on various combinations of big and small felts.
@@ -404,20 +394,8 @@ mod blake_estimation {
404394
pub const STEPS_EMPTY_INPUT: usize = 170;
405395
}
406396

407-
/// Calculates the total number of u32s required to encode the given number of big and small felts.
408-
/// Big felts encode to 8 u32s each, small felts encode to 2 u32s each.
409-
fn total_u32s_from_felts(n_big_felts: usize, n_small_felts: usize) -> usize {
410-
let big_u32s = n_big_felts
411-
.checked_mul(blake_encoding::N_U32S_BIG_FELT)
412-
.expect("Overflow computing big felts u32s");
413-
let small_u32s = n_small_felts
414-
.checked_mul(blake_encoding::N_U32S_SMALL_FELT)
415-
.expect("Overflow computing small felts u32s");
416-
big_u32s.checked_add(small_u32s).expect("Overflow computing total u32s")
417-
}
418-
419397
fn base_steps_for_blake_hash(n_u32s: usize) -> usize {
420-
let rem_u32s = n_u32s % blake_encoding::N_U32S_MESSAGE;
398+
let rem_u32s = n_u32s % FeltSizeCount::U32_WORDS_PER_MESSAGE;
421399
if rem_u32s == 0 {
422400
blake_estimation::BASE_STEPS_FULL_MSG
423401
} else {
@@ -441,27 +419,19 @@ fn felts_steps(n_big_felts: usize, n_small_felts: usize) -> usize {
441419
/// Estimates the number of VM steps needed to hash the given felts with Blake in Starknet OS.
442420
/// Each small felt unpacks into 2 u32s, and each big felt into 8 u32s.
443421
/// Adds a base cost depending on whether the total fits exactly into full 16-u32 messages.
444-
fn compute_blake_hash_steps(n_big_felts: usize, n_small_felts: usize) -> usize {
445-
let total_u32s = total_u32s_from_felts(n_big_felts, n_small_felts);
422+
fn compute_blake_hash_steps(felt_size_groups: &FeltSizeCount) -> usize {
423+
let total_u32s = felt_size_groups.encoded_u32_len();
446424
if total_u32s == 0 {
447425
// The empty input case is a special case.
448426
return blake_estimation::STEPS_EMPTY_INPUT;
449427
}
450428

451429
let base_steps = base_steps_for_blake_hash(total_u32s);
452-
let felt_steps = felts_steps(n_big_felts, n_small_felts);
430+
let felt_steps = felts_steps(felt_size_groups.large, felt_size_groups.small);
453431

454432
base_steps.checked_add(felt_steps).expect("Overflow computing total Blake hash steps")
455433
}
456434

457-
/// Returns the number of BLAKE opcodes needed to hash the given felts.
458-
/// Each BLAKE opcode processes 16 u32s (partial messages are padded).
459-
fn count_blake_opcode(n_big_felts: usize, n_small_felts: usize) -> usize {
460-
// Count the total number of u32s to be hashed.
461-
let total_u32s = total_u32s_from_felts(n_big_felts, n_small_felts);
462-
total_u32s.div_ceil(blake_encoding::N_U32S_MESSAGE)
463-
}
464-
465435
/// Estimates resource usage for `encode_felt252_data_and_calc_blake_hash` in the Starknet OS.
466436
///
467437
/// # Encoding Details
@@ -475,7 +445,7 @@ fn count_blake_opcode(n_big_felts: usize, n_small_felts: usize) -> usize {
475445
pub fn encode_and_blake_hash_resources(
476446
felt_size_groups: &FeltSizeCount,
477447
) -> EstimatedExecutionResources {
478-
let n_steps = compute_blake_hash_steps(felt_size_groups.large, felt_size_groups.small);
448+
let n_steps = compute_blake_hash_steps(felt_size_groups);
479449
let builtin_instance_counter = match felt_size_groups.n_felts() {
480450
// The empty case does not use builtins at all.
481451
0 => HashMap::new(),
@@ -490,7 +460,7 @@ pub fn encode_and_blake_hash_resources(
490460

491461
EstimatedExecutionResources::V2Hash {
492462
resources,
493-
blake_count: count_blake_opcode(felt_size_groups.large, felt_size_groups.small),
463+
blake_count: felt_size_groups.blake_opcode_count(),
494464
}
495465
}
496466

crates/blockifier/src/execution/execution_utils_test.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@ use pretty_assertions::assert_eq;
44
use starknet_types_core::felt::Felt;
55

66
use crate::execution::contract_class::FeltSizeCount;
7-
use crate::execution::execution_utils::blake_encoding::{N_U32S_BIG_FELT, N_U32S_SMALL_FELT};
87
use crate::execution::execution_utils::blake_estimation::STEPS_EMPTY_INPUT;
98
use crate::execution::execution_utils::{
109
compute_blake_hash_steps,
11-
count_blake_opcode,
1210
encode_and_blake_hash_resources,
1311
};
1412

@@ -23,19 +21,19 @@ fn test_u32_constants() {
2321
let big_u32s = encode_felts_to_u32s(vec![big_felt]);
2422

2523
// Blake estimation constants should match the actual encoding.
26-
assert_eq!(small_u32s.len(), N_U32S_SMALL_FELT);
27-
assert_eq!(big_u32s.len(), N_U32S_BIG_FELT);
24+
assert_eq!(small_u32s.len(), FeltSizeCount::U32_WORDS_PER_SMALL_FELT);
25+
assert_eq!(big_u32s.len(), FeltSizeCount::U32_WORDS_PER_LARGE_FELT);
2826
}
2927

3028
/// Test the edge case of hashing an empty array of felt values.
3129
#[test]
3230
fn test_zero_inputs() {
3331
// logic was written.
34-
let steps = compute_blake_hash_steps(0, 0);
32+
let steps = compute_blake_hash_steps(&FeltSizeCount { large: 0, small: 0 });
3533
assert_eq!(steps, STEPS_EMPTY_INPUT, "Unexpected base step cost for zero inputs");
3634

3735
// No opcodes should be emitted.
38-
let opcodes = count_blake_opcode(0, 0);
36+
let opcodes = FeltSizeCount { large: 0, small: 0 }.blake_opcode_count();
3937
assert_eq!(opcodes, 0, "Expected zero BLAKE opcodes for zero inputs");
4038

4139
// Should result in base cost only (no opcode cost).
@@ -47,7 +45,7 @@ fn test_zero_inputs() {
4745

4846
// TODO(AvivG): Add tests for:
4947
// - `compute_blake_hash_steps` simple cases (felts input).
50-
// - `count_blake_opcode` simple cases (felts input).
48+
// - `blake_opcode_count` simple cases (felts input).
5149
// - `cost_of_encode_felt252_data_and_calc_blake_hash` simple cases (felts input) (including partial
5250
// remainder).
5351
// - `cost_of_encode_felt252_data_and_calc_blake_hash` compare against actual execution resources

0 commit comments

Comments
 (0)