Skip to content

Commit 7bd69b5

Browse files
starknet_os: os resources test - add keccak
1 parent 818a408 commit 7bd69b5

5 files changed

Lines changed: 58 additions & 24 deletions

File tree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ const SYSCALL_BASE_GAS_COST = 10000;
105105

106106
// Syscall gas costs.
107107
const CALL_CONTRACT_GAS_COST = 91160;
108-
const DEPLOY_GAS_COST = 151870;
109-
const DEPLOY_CALLDATA_FACTOR_GAS_COST = 4650;
108+
const DEPLOY_GAS_COST = 151670;
109+
const DEPLOY_CALLDATA_FACTOR_GAS_COST = 4850;
110110
const GET_BLOCK_HASH_GAS_COST = 10810;
111111
const GET_CLASS_HASH_AT_GAS_COST = 10000;
112112
const GET_EXECUTION_INFO_GAS_COST = 11240;
@@ -133,7 +133,7 @@ const SECP256R1_MUL_GAS_COST = 13511870;
133133
const SECP256R1_NEW_GAS_COST = 61630;
134134

135135
const KECCAK_GAS_COST = 10000;
136-
const KECCAK_ROUND_COST_GAS_COST = 171707;
136+
const KECCAK_ROUND_COST_GAS_COST = 175107;
137137
const SHA256_PROCESS_BLOCK_GAS_COST = 841295;
138138

139139
// Cairo 1.0 error codes.

crates/apollo_starknet_os_program/src/program_hash.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"os": "0x769d28e62bb261f8b7a535c9007361344abd5458f559bcbaee8f9b4897864f6",
2+
"os": "0x4993a6c01cd33ffab71977f6a6a89835cd3bc4861f81734f45ad749df041cca",
33
"virtual_os": "0x4ccaaed5759efad1372b08a0719839fcf22c28f1ae8b0744a4ad95a20a628ff",
44
"aggregator": "0x700786d51b3854af43d8e12180380bda3029be6c1767e007858de6ca2edac40",
55
"aggregator_with_prefix": "0xe08d300e3f5996e43d6d7cc5a20068e0e58cf1309089f2348317ac580f6c1f"

crates/blockifier/resources/blockifier_versioned_constants_0_14_3.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,15 +247,15 @@
247247
},
248248
"Deploy": {
249249
"constant": {
250-
"n_steps": 1180,
250+
"n_steps": 1178,
251251
"n_memory_holes": 0,
252252
"builtin_instance_counter": {
253253
"range_check_builtin": 21,
254254
"pedersen_builtin": 8
255255
}
256256
},
257257
"calldata_factor": {
258-
"n_steps": 6,
258+
"n_steps": 8,
259259
"n_memory_holes": 0,
260260
"builtin_instance_counter": {
261261
"pedersen_builtin": 1
@@ -337,7 +337,7 @@
337337
"builtin_instance_counter": {}
338338
},
339339
"KeccakRound": {
340-
"n_steps": 281,
340+
"n_steps": 315,
341341
"n_memory_holes": 0,
342342
"builtin_instance_counter": {
343343
"range_check_builtin": 56,

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod OsResourcesTestContract {
88
deploy_syscall,
99
emit_event_syscall,
1010
get_execution_info_v2_syscall,
11+
keccak_syscall,
1112
library_call_syscall,
1213
};
1314
use starknet::{ClassHash, ContractAddress, get_block_hash_syscall, get_class_hash_at_syscall};
@@ -99,6 +100,15 @@ mod OsResourcesTestContract {
99100

100101
// get execution info syscall.
101102
get_execution_info_v2_syscall().unwrap_syscall();
103+
104+
// keccak syscall. Second call is to measure the keccak round syscall.
105+
keccak_syscall(array![].span()).unwrap_syscall();
106+
// Exactly 17 input u64s are required to measure a single round.
107+
let mut input = array![];
108+
for _ in 0_u8..17 {
109+
input.append(1_u64);
110+
}
111+
keccak_syscall(input.span()).unwrap_syscall();
102112
}
103113

104114
// Target for call_contract and library_call — accepts no arguments.

crates/starknet_os_flow_tests/src/os_resources_test.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::collections::HashSet;
22

33
use blockifier::blockifier_versioned_constants::{
4+
RawStepGasCost,
45
RawVersionedConstants,
56
ResourcesParams,
67
VariableCallDataFactor,
@@ -31,7 +32,7 @@ use crate::tests::NON_TRIVIAL_RESOURCE_BOUNDS;
3132
use crate::utils::get_class_hash_of_feature_contract;
3233

3334
// TODO(Dori): Delete this, or at least reduce it to a minimal set of unmeasurable syscalls.
34-
const UNMEASURABLE_SYSCALLS: [Selector; 27] = [
35+
const UNMEASURABLE_SYSCALLS: [Selector; 25] = [
3536
Selector::DelegateCall,
3637
Selector::DelegateL1Handler,
3738
Selector::GetBlockNumber,
@@ -41,8 +42,6 @@ const UNMEASURABLE_SYSCALLS: [Selector; 27] = [
4142
Selector::GetSequencerAddress,
4243
Selector::GetTxInfo,
4344
Selector::GetTxSignature,
44-
Selector::Keccak,
45-
Selector::KeccakRound,
4645
Selector::Sha256ProcessBlock,
4746
Selector::LibraryCallL1Handler,
4847
Selector::ReplaceClass,
@@ -61,7 +60,10 @@ const UNMEASURABLE_SYSCALLS: [Selector; 27] = [
6160
Selector::StorageWrite,
6261
];
6362

64-
const SYSCALLS_WITH_LINEAR_FACTOR: [Selector; 2] = [Selector::Deploy, Selector::MetaTxV0];
63+
/// Keccak does not store the linear factor in the same entry in the versioned constants, but it
64+
/// does have a measurable linear factor stored under [Selector::KeccakRound].
65+
const SYSCALLS_WITH_LINEAR_FACTOR: [Selector; 3] =
66+
[Selector::Deploy, Selector::Keccak, Selector::MetaTxV0];
6567

6668
/// Expected syscalls in the fee transfer call. Should be removed from the list of syscalls during
6769
/// measurement iteration - only the syscalls called during __execute__ should be measured.
@@ -122,6 +124,9 @@ async fn test_fee_transfer_syscalls() {
122124
async fn test_os_resources_regression() {
123125
let os_resources_contract = FeatureContract::OsResourcesTest(RunnableCairo1::Casm);
124126
let os_resources_class_hash = get_class_hash_of_feature_contract(os_resources_contract);
127+
let version = StarknetVersion::LATEST;
128+
let mut raw_vc: RawVersionedConstants =
129+
serde_json::from_str(VersionedConstants::json_str(&version).unwrap()).unwrap();
125130

126131
// Setup the test initial state and test builder.
127132
// Need to explicitly set up the state to be able to override the minimal sierra version for gas
@@ -253,7 +258,7 @@ async fn test_os_resources_regression() {
253258

254259
// If this if a syscall with a linear factor, the next syscall should be the linear cost.
255260
// Otherwise, this syscall has a constant cost.
256-
let syscall_cost = if SYSCALLS_WITH_LINEAR_FACTOR.contains(&selector) {
261+
if SYSCALLS_WITH_LINEAR_FACTOR.contains(&selector) {
257262
let next_syscall_trace = syscalls_iter.next().unwrap();
258263
assert_eq!(
259264
selector,
@@ -267,16 +272,38 @@ async fn test_os_resources_regression() {
267272
- &next_inner_overhead)
268273
.filter_unused_builtins();
269274
let linear_factor_resources = (&next_resources - &resources).filter_unused_builtins();
270-
VariableResourceParams::WithFactor(ResourcesParams {
271-
constant: resources,
272-
// Syscalls with a linear factor have an unscaled linear factor cost.
273-
calldata_factor: VariableCallDataFactor::Unscaled(linear_factor_resources),
274-
})
275+
// Keccak is a special case - we store the linear cost as a separate syscall.
276+
if selector == Selector::Keccak {
277+
// TODO(Dori): Currently, the Keccak base cost is enforced in the OS to equal the
278+
// syscall base cost. If and when this is no longer the case, no need to replace
279+
// `resources` (measured keccak base cost) with the syscall base cost, and no need
280+
// to recompute the linear factor.
281+
let RawStepGasCost { step_gas_cost: n_steps } =
282+
raw_vc.os_constants.syscall_base_gas_cost.clone();
283+
let resources = ExecutionResources {
284+
n_steps: n_steps.0.try_into().unwrap(),
285+
..Default::default()
286+
};
287+
let linear_factor_resources =
288+
(&next_resources - &resources).filter_unused_builtins();
289+
measurements.insert(Selector::Keccak, VariableResourceParams::Constant(resources));
290+
measurements.insert(
291+
Selector::KeccakRound,
292+
VariableResourceParams::Constant(linear_factor_resources),
293+
);
294+
} else {
295+
measurements.insert(
296+
selector,
297+
VariableResourceParams::WithFactor(ResourcesParams {
298+
constant: resources,
299+
// Syscalls with a linear factor have an unscaled linear factor cost.
300+
calldata_factor: VariableCallDataFactor::Unscaled(linear_factor_resources),
301+
}),
302+
);
303+
}
275304
} else {
276-
VariableResourceParams::Constant(resources)
277-
};
278-
279-
measurements.insert(selector, syscall_cost);
305+
measurements.insert(selector, VariableResourceParams::Constant(resources));
306+
}
280307
}
281308

282309
// Make sure we covered all syscalls we expect to.
@@ -297,9 +324,6 @@ async fn test_os_resources_regression() {
297324
);
298325

299326
// Compare the measurements with the expected values on the latest VC.
300-
let version = StarknetVersion::LATEST;
301-
let mut raw_vc: RawVersionedConstants =
302-
serde_json::from_str(VersionedConstants::json_str(&version).unwrap()).unwrap();
303327
for (syscall, resources) in measurements {
304328
raw_vc.os_resources.execute_syscalls.insert(syscall, resources);
305329
}

0 commit comments

Comments
 (0)