Skip to content

Commit a43e687

Browse files
starknet_os: os resources test - add keccak
1 parent 5762c7a commit a43e687

6 files changed

Lines changed: 68 additions & 34 deletions

File tree

crates/apollo_starknet_os_program/src/cairo/starkware/starknet/core/os/constants.cairo

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_1 = (
7272
0x06ecb73d21c7d98ddd4148f5bcd91cc2747c65364245fbf32a63b05cca1685c2
7373
);
7474
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_2 = (
75-
0x06e0e4653c9bf533daba4c89a969a78f082fd2b7ebd38912ca8138441a897bea
75+
0x050a1cd46f1a35628c7569f85218b7b8b01510cb33834c3bd00885183c5770a5
7676
);
7777
const ALLOWED_VIRTUAL_OS_PROGRAM_HASHES_LEN = 3;
7878

@@ -136,7 +136,7 @@ const SECP256R1_MUL_GAS_COST = 13511870;
136136
const SECP256R1_NEW_GAS_COST = 61630;
137137

138138
const KECCAK_GAS_COST = 10000;
139-
const KECCAK_ROUND_COST_GAS_COST = 171707;
139+
const KECCAK_ROUND_COST_GAS_COST = 175207;
140140
const SHA256_PROCESS_BLOCK_GAS_COST = 841295;
141141
const SHA512_PROCESS_BLOCK_GAS_COST = 2413810;
142142

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"os": "0x6953c7279f84f553ce738d580de5df707feef830c3ca1840829b6bbdf79db4e",
3-
"virtual_os": "0x6e0e4653c9bf533daba4c89a969a78f082fd2b7ebd38912ca8138441a897bea",
2+
"os": "0x195ad0b42c896cb80d029d349cc1b7fe182acb20c540c3dcb68256ab87ea41",
3+
"virtual_os": "0x50a1cd46f1a35628c7569f85218b7b8b01510cb33834c3bd00885183c5770a5",
44
"aggregator": "0x700786d51b3854af43d8e12180380bda3029be6c1767e007858de6ca2edac40",
55
"aggregator_with_prefix": "0xe08d300e3f5996e43d6d7cc5a20068e0e58cf1309089f2348317ac580f6c1f"
66
}

crates/blockifier/resources/blockifier_versioned_constants_0_14_4.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@
128128
"allowed_virtual_os_program_hashes": [
129129
"0x3e98c2d7703b03a7edb73ed7f075f97f1dcbaa8f717cdf6e1a57bf058265473",
130130
"0x6ecb73d21c7d98ddd4148f5bcd91cc2747c65364245fbf32a63b05cca1685c2",
131-
"0x6e0e4653c9bf533daba4c89a969a78f082fd2b7ebd38912ca8138441a897bea"
131+
"0x50a1cd46f1a35628c7569f85218b7b8b01510cb33834c3bd00885183c5770a5"
132132
],
133133
"constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194",
134134
"default_entry_point_selector": "0x0",
@@ -337,7 +337,7 @@
337337
"builtin_instance_counter": {}
338338
},
339339
"KeccakRound": {
340-
"n_steps": 281,
340+
"n_steps": 316,
341341
"n_memory_holes": 0,
342342
"builtin_instance_counter": {
343343
"range_check_builtin": 56,

crates/blockifier/resources/versioned_constants_diff_regression/0.14.3_0.14.4.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
+ /os_constants/allowed_virtual_os_program_hashes/2: "0x6e0e4653c9bf533daba4c89a969a78f082fd2b7ebd38912ca8138441a897bea"
1+
+ /os_constants/allowed_virtual_os_program_hashes/2: "0x50a1cd46f1a35628c7569f85218b7b8b01510cb33834c3bd00885183c5770a5"
22
~ /os_resources/execute_syscalls/CallContract/n_steps: 901
33
~ /os_resources/execute_syscalls/LibraryCall/n_steps: 874
44
~ /os_resources/execute_syscalls/MetaTxV0/constant/builtin_instance_counter/pedersen_builtin: 13

crates/blockifier_test_utils/resources/feature_contracts/cairo1/os_resources_test_contract.cairo

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod OsResourcesTestContract {
44
use starknet::info::SyscallResultTrait;
55
use starknet::syscalls::{
66
call_contract_syscall, deploy_syscall, emit_event_syscall, get_execution_info_v3_syscall,
7-
library_call_syscall,
7+
keccak_syscall, library_call_syscall,
88
};
99
use starknet::{ClassHash, ContractAddress, get_block_hash_syscall, get_class_hash_at_syscall};
1010

@@ -92,5 +92,14 @@ mod OsResourcesTestContract {
9292

9393
// get execution info syscall.
9494
get_execution_info_v3_syscall().unwrap_syscall();
95+
96+
// keccak syscall. Second call is to measure the keccak round syscall.
97+
keccak_syscall(array![].span()).unwrap_syscall();
98+
// Exactly 17 input u64s are required to measure a single round.
99+
let mut input = array![];
100+
for _ in 0_u8..17 {
101+
input.append(1_u64);
102+
}
103+
keccak_syscall(input.span()).unwrap_syscall();
95104
}
96105
}

crates/starknet_os_flow_tests/src/os_resources_test.rs

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet};
22
use std::sync::LazyLock;
33

44
use blockifier::blockifier_versioned_constants::{
5+
RawStepGasCost,
56
RawVersionedConstants,
67
ResourcesParams,
78
VariableCallDataFactor,
@@ -44,7 +45,7 @@ use crate::test_manager::{
4445
use crate::tests::NON_TRIVIAL_RESOURCE_BOUNDS;
4546

4647
// TODO(Dori): Delete this, or at least reduce it to a minimal set of unmeasurable syscalls.
47-
const UNMEASURABLE_SYSCALLS: [Selector; 28] = [
48+
const UNMEASURABLE_SYSCALLS: [Selector; 26] = [
4849
Selector::DelegateCall,
4950
Selector::DelegateL1Handler,
5051
Selector::GetBlockNumber,
@@ -54,8 +55,6 @@ const UNMEASURABLE_SYSCALLS: [Selector; 28] = [
5455
Selector::GetSequencerAddress,
5556
Selector::GetTxInfo,
5657
Selector::GetTxSignature,
57-
Selector::Keccak,
58-
Selector::KeccakRound,
5958
Selector::Sha256ProcessBlock,
6059
Selector::Sha512ProcessBlock,
6160
Selector::LibraryCallL1Handler,
@@ -90,8 +89,9 @@ const UNMEASURABLE_SYSCALLS: [Selector; 28] = [
9089
/// The second call will always have one more linear element than the first call.
9190
/// Note: Keccak does not store the linear factor in the same entry in the versioned constants, but
9291
/// it does have a measurable linear factor stored under [Selector::KeccakRound].
93-
static SYSCALLS_WITH_LINEAR_FACTOR: LazyLock<HashMap<Selector, usize>> =
94-
LazyLock::new(|| HashMap::from([(Selector::Deploy, 1), (Selector::MetaTxV0, 1)]));
92+
static SYSCALLS_WITH_LINEAR_FACTOR: LazyLock<HashMap<Selector, usize>> = LazyLock::new(|| {
93+
HashMap::from([(Selector::Deploy, 1), (Selector::Keccak, 0), (Selector::MetaTxV0, 1)])
94+
});
9595

9696
/// Expected syscalls in the fee transfer call. Should be removed from the list of syscalls during
9797
/// measurement iteration - only the syscalls called during __execute__ should be measured.
@@ -177,6 +177,9 @@ async fn test_fee_transfer_syscalls() {
177177
#[tokio::test]
178178
async fn test_os_resources_regression() {
179179
let os_resources_contract = FeatureContract::OsResourcesTest(RunnableCairo1::Casm);
180+
let version = StarknetVersion::LATEST;
181+
let mut raw_vc: RawVersionedConstants =
182+
serde_json::from_str(VersionedConstants::json_str(&version).unwrap()).unwrap();
180183

181184
// Setup the test initial state and test builder.
182185
// Need to explicitly set up the state to be able to override the minimal sierra version for gas
@@ -190,6 +193,7 @@ async fn test_os_resources_regression() {
190193
initial_state_data.initial_state.block_context = {
191194
let block_context = &initial_state_data.initial_state.block_context;
192195
let mut vc = block_context.versioned_constants().clone();
196+
assert_eq!(vc, raw_vc.clone().into());
193197
vc.min_sierra_version_for_sierra_gas = SierraVersion::new(99, 99, 99);
194198
BlockContext::new(
195199
block_context.block_info().clone(),
@@ -335,9 +339,7 @@ async fn test_os_resources_regression() {
335339

336340
// If this if a syscall with a linear factor, the next syscall should be an invocation of
337341
// the same syscall with +1 linear element.
338-
let syscall_cost = if let Some(linear_count_in_base) =
339-
SYSCALLS_WITH_LINEAR_FACTOR.get(&selector)
340-
{
342+
if let Some(linear_count_in_base) = SYSCALLS_WITH_LINEAR_FACTOR.get(&selector) {
341343
let next_syscall_trace = syscalls_iter.next().unwrap();
342344
assert_eq!(
343345
selector,
@@ -348,24 +350,50 @@ async fn test_os_resources_regression() {
348350
);
349351
let next_resources =
350352
maybe_deduct_inner(next_syscall_trace.get_resources().unwrap(), selector);
351-
let linear_factor_resources = (&next_resources - &resources).filter_unused_builtins();
352353

353-
// Linear factor is computed; deduct the linear overhead from the base cost to get the
354-
// real base cost.
355-
let constant_resources = (&resources
356-
- &(&linear_factor_resources * *linear_count_in_base))
357-
.filter_unused_builtins();
354+
// Keccak is a special case:
355+
// 1. We store the linear cost as a separate syscall.
356+
// 2. Currently, the Keccak base cost is enforced in the OS to equal the syscall base
357+
// cost (`static_assert KECCAK_GAS_COST == SYSCALL_BASE_GAS_COST`).
358+
// TODO(Dori): If and when (2) is no longer the case, no need to replace `resources`
359+
// (measured keccak base cost) with the syscall base cost, and no need to recompute
360+
// the linear factor.
361+
if selector == Selector::Keccak {
362+
let RawStepGasCost { step_gas_cost: n_steps } =
363+
raw_vc.os_constants.syscall_base_gas_cost.clone();
364+
let constant_resources = ExecutionResources {
365+
n_steps: n_steps.0.try_into().unwrap(),
366+
..Default::default()
367+
};
368+
let linear_factor_resources =
369+
(&next_resources - &constant_resources).filter_unused_builtins();
370+
measurements
371+
.insert(Selector::Keccak, VariableResourceParams::Constant(constant_resources));
372+
measurements.insert(
373+
Selector::KeccakRound,
374+
VariableResourceParams::Constant(linear_factor_resources),
375+
);
376+
} else {
377+
let linear_factor_resources =
378+
(&next_resources - &resources).filter_unused_builtins();
379+
// Linear factor is computed; deduct the linear overhead from the base cost to get
380+
// the real base cost.
381+
let constant_resources = (&resources
382+
- &(&linear_factor_resources * *linear_count_in_base))
383+
.filter_unused_builtins();
358384

359-
VariableResourceParams::WithFactor(ResourcesParams {
360-
constant: constant_resources,
361-
// Syscalls with a linear factor have an unscaled linear factor cost.
362-
calldata_factor: VariableCallDataFactor::Unscaled(linear_factor_resources),
363-
})
385+
measurements.insert(
386+
selector,
387+
VariableResourceParams::WithFactor(ResourcesParams {
388+
constant: constant_resources,
389+
// Syscalls with a linear factor have an unscaled linear factor cost.
390+
calldata_factor: VariableCallDataFactor::Unscaled(linear_factor_resources),
391+
}),
392+
);
393+
}
364394
} else {
365-
VariableResourceParams::Constant(resources)
366-
};
367-
368-
measurements.insert(selector, syscall_cost);
395+
measurements.insert(selector, VariableResourceParams::Constant(resources));
396+
}
369397
}
370398

371399
// Make sure we covered all syscalls we expect to.
@@ -379,9 +407,6 @@ async fn test_os_resources_regression() {
379407
);
380408

381409
// Compare the measurements with the expected values on the latest VC.
382-
let version = StarknetVersion::LATEST;
383-
let mut raw_vc: RawVersionedConstants =
384-
serde_json::from_str(VersionedConstants::json_str(&version).unwrap()).unwrap();
385410
for (syscall, resources) in measurements {
386411
raw_vc.os_resources.execute_syscalls.insert(syscall, resources);
387412
}

0 commit comments

Comments
 (0)