Skip to content

Commit 5218dce

Browse files
feat(starknet_os): os_logger: implement ResourceCounter::sub_counter
1 parent 8514c7d commit 5218dce

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

crates/starknet_os/src/hint_processor.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod constants;
12
pub mod execution_helper;
23
pub mod os_logger;
34
pub mod panicking_state_reader;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use std::collections::HashMap;
2+
use std::sync::LazyLock;
3+
4+
use cairo_vm::types::builtin_name::BuiltinName;
5+
6+
pub(crate) static BUILTIN_INSTANCE_SIZES: LazyLock<HashMap<BuiltinName, usize>> =
7+
LazyLock::new(|| {
8+
HashMap::from([
9+
(BuiltinName::pedersen, 3),
10+
(BuiltinName::range_check, 1),
11+
(BuiltinName::ecdsa, 2),
12+
(BuiltinName::bitwise, 5),
13+
(BuiltinName::ec_op, 7),
14+
(BuiltinName::poseidon, 6),
15+
(BuiltinName::segment_arena, 3),
16+
(BuiltinName::range_check96, 1),
17+
(BuiltinName::add_mod, 7),
18+
(BuiltinName::mul_mod, 7),
19+
(BuiltinName::keccak, 16),
20+
])
21+
});

crates/starknet_os/src/hint_processor/os_logger.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,39 @@ use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
1111
use cairo_vm::vm::vm_core::VirtualMachine;
1212
use starknet_api::transaction::TransactionHash;
1313

14+
use crate::hint_processor::constants::BUILTIN_INSTANCE_SIZES;
1415
use crate::hints::error::OsHintError;
1516
use crate::hints::vars::{CairoStruct, Ids};
1617
use crate::vm_utils::get_address_of_nested_fields;
1718

1819
#[derive(Debug, thiserror::Error)]
1920
pub enum OsLoggerError {
21+
#[error(
22+
"Builtin {builtin} in self and in the enter call counter are not in the same segment: \
23+
{self_ptr}, {enter_ptr}."
24+
)]
25+
BuiltinsNotInSameSegment { builtin: BuiltinName, self_ptr: Relocatable, enter_ptr: Relocatable },
2026
#[error("Failed to build builtin pointer map: {0}.")]
2127
BuiltinPtrs(OsHintError),
2228
#[error("SyscallTrace should be finalized only once.")]
2329
DoubleFinalize,
2430
#[error("Failed to fetch identifier data for struct {0}.")]
2531
InnerBuiltinPtrsIdentifierMissing(String),
32+
#[error("{0}")]
33+
MissingBuiltinPtr(String),
2634
#[error("The `members` field is None in identifier data for struct {0}.")]
2735
MissingMembers(String),
36+
#[error(
37+
"Range check in self and in the enter call counter are not in the same segment: \
38+
{self_ptr}, {enter_ptr}."
39+
)]
40+
RangeCheckNotInSameSegment { self_ptr: Relocatable, enter_ptr: Relocatable },
2841
#[error("SyscallTrace should be finalized before accessing resources.")]
2942
ResourceAccessBeforeFinalize,
3043
#[error("{0}")]
3144
UnknownBuiltin(String),
45+
#[error("Builtin {0} is not in the known sizes mapping {:?}.", BUILTIN_INSTANCE_SIZES)]
46+
UnknownBuiltinSize(String),
3247
}
3348

3449
pub type OsLoggerResult<T> = Result<T, OsLoggerError>;
@@ -177,6 +192,49 @@ impl ResourceCounter {
177192
})
178193
}
179194

195+
pub fn sub_counter(&self, enter_counter: &Self) -> OsLoggerResult<ExecutionResources> {
196+
// Subtract pointers to count usage.
197+
let mut builtins_count_ptr: HashMap<BuiltinName, usize> = HashMap::new();
198+
for (builtin_name, builtin_ptr) in self.builtin_ptrs_dict.iter() {
199+
let enter_counter_ptr = enter_counter
200+
.builtin_ptrs_dict
201+
.get(builtin_name)
202+
.ok_or(OsLoggerError::MissingBuiltinPtr(builtin_name.to_str().to_string()))?;
203+
let mut builtin_count = (*builtin_ptr - *enter_counter_ptr).map_err(|_error| {
204+
OsLoggerError::BuiltinsNotInSameSegment {
205+
builtin: *builtin_name,
206+
self_ptr: *builtin_ptr,
207+
enter_ptr: *enter_counter_ptr,
208+
}
209+
})?;
210+
211+
// Adds the OS range_check resources of the current entry point.
212+
if builtin_name == &BuiltinName::range_check {
213+
builtin_count +=
214+
(self.range_check_ptr - enter_counter.range_check_ptr).map_err(|_error| {
215+
OsLoggerError::RangeCheckNotInSameSegment {
216+
self_ptr: self.range_check_ptr,
217+
enter_ptr: enter_counter.range_check_ptr,
218+
}
219+
})?;
220+
}
221+
222+
// Divide by the builtin size to get the actual usage count.
223+
let builtin_size = BUILTIN_INSTANCE_SIZES
224+
.get(builtin_name)
225+
.ok_or(OsLoggerError::UnknownBuiltinSize(builtin_name.to_str().to_string()))?;
226+
builtin_count /= *builtin_size;
227+
228+
builtins_count_ptr.insert(*builtin_name, builtin_count);
229+
}
230+
231+
Ok(ExecutionResources {
232+
n_steps: self.n_steps - enter_counter.n_steps,
233+
builtin_instance_counter: builtins_count_ptr,
234+
n_memory_holes: 0,
235+
})
236+
}
237+
180238
fn build_builtin_ptrs_dict(
181239
ids_data: &HashMap<String, HintReference>,
182240
vm: &VirtualMachine,

0 commit comments

Comments
 (0)