-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sierra gas resource tracking #3049
base: master
Are you sure you want to change the base?
Conversation
56e4694
to
6169638
Compare
...heatnet/src/runtime_extensions/call_to_blockifier_runtime_extension/execution/entry_point.rs
Show resolved
Hide resolved
crates/cheatnet/src/runtime_extensions/forge_runtime_extension/mod.rs
Outdated
Show resolved
Hide resolved
fn n_steps_to_sierra_gas(n_steps: usize, versioned_constants: &VersionedConstants) -> GasAmount { | ||
let n_steps_u64 = u64_from_usize(n_steps); | ||
let gas_per_step = versioned_constants | ||
.os_constants | ||
.gas_costs | ||
.base | ||
.step_gas_cost; | ||
let n_steps_gas_cost = n_steps_u64.checked_mul(gas_per_step).unwrap_or_else(|| { | ||
panic!( | ||
"Multiplication overflow while converting steps to gas. steps: {n_steps}, gas per step: {gas_per_step}." | ||
) | ||
}); | ||
GasAmount(n_steps_gas_cost) | ||
} | ||
|
||
#[must_use] | ||
pub fn vm_resources_to_sierra_gas( | ||
resources: &ExecutionResources, | ||
versioned_constants: &VersionedConstants, | ||
) -> GasAmount { | ||
let builtins_gas_cost = | ||
builtins_to_sierra_gas(&resources.prover_builtins(), versioned_constants); | ||
let n_steps_gas_cost = n_steps_to_sierra_gas(resources.total_n_steps(), versioned_constants); | ||
n_steps_gas_cost.checked_add(builtins_gas_cost).unwrap_or_else(|| { | ||
panic!( | ||
"Addition overflow while converting vm resources to gas. steps gas: {n_steps_gas_cost}, \ | ||
builtins gas: {builtins_gas_cost}." | ||
) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is Sierra gas calculated this way exactly the same as real Sierra gas calculated when executing with Cairo-native?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My question was not related to the conversion logic. I was wondering because what we generally do is not exactly tracking Sierra resources, but rather tracking VM resources and then converting them to Sierra resources. So my question is, are we sure that executing the same transaction with cairo-native
will result in exactly the same Sierra gas as calculated in snforge
with the current logic? According to the starknet documentation, it seems that this may not necessarily be the case. Please correct me if I am wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not really true - we are tracking sierra resources, but the execution comes through the vm (because at the moment, we do not support cairo native execution in forge; I believe it is not even yet planned). We are converting things here, because vm has some pre-defined "spin-up" cost that is given in steps and builtins - which are not the way to describe execution cost when tracking sierra gas; when going through native the same cost would be described in sierra gas.
Regarding the docs you've linked (and answering the question) - we are as sure as we can be running thrugh vm. The cost when tracking sierra gas should not differ regardless of the environment, but we'll never be 100% sure as long as we do not support native, I guess. To reiterate my point from the previous paragraph - we are not tracking cairo steps and converting them; we are tracking sierra gas, and take them as they are reported by the vm, no conversion there. The docs state that there will be some mismatch because of the cost of the resources and max vs sum approach - which is true and you can actually observe it in the tests I added in #3055, where identical tests yield different costs depending on the tracked resource.
Hope that answers your question, but if something still seems off please let me know 🙏
match &context | ||
.tracked_resource_stack | ||
.last() | ||
.expect("Unexpected empty tracked resource.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit, but maybe these should be passed as an argument to this function instead of taking them of the stack? For me it's like a post execution callback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite the contrast from this comment by Darek #3049 (comment) :D
My rationale for doing this here was that we already have a context, so there was really no need to do it this way, but I'm fine with either one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't have a strong opinion on this, we can keep this as is
resources -= &versioned_constants.get_additional_os_syscall_resources(syscall_counter); | ||
} | ||
TrackedResource::SierraGas => { | ||
let syscalls_consumed_gas: u64 = syscall_counter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should already rebase ourselves to new changes to main-0.13.4
branch in blockifier (rebase my fork).
They've removed the syscall_counter
and replaced it with a similar structure with different name and layout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any changes on our side regarding this? if not I'd rather not, as this is out od scope of what this PR is supposed to do. If yes, I can add a PR to this stack with required changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just this but didn't verify in details. They actually already have main-0.13.5
branch now.
l1_handler_payload_lengths, | ||
l2_to_l1_payload_lengths, | ||
} | ||
} | ||
|
||
fn n_steps_to_sierra_gas(n_steps: usize, versioned_constants: &VersionedConstants) -> GasAmount { | ||
let n_steps_u64 = u64_from_usize(n_steps); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What it does exactly? Why not just unwrap/expect here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does exactly what you said it should. But hey have a helper for this in blockifier (and use it), so I figured - what the heck I'll use it too. If you rather not, I can change it to regular expect(). 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean maybe there is a reason they do that. I'm fine with either.
let syscalls_consumed_gas: u64 = top_call_syscalls | ||
.iter() | ||
.map(|(name, count)| { | ||
versioned_constants.get_syscall_gas_cost(name) * (*count as u64) | ||
}) | ||
.sum(); | ||
sierra_gas_consumed += syscalls_consumed_gas; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar code is used in remove_syscall_resources_and_exit_success_call
. Maybe it'd make sense to reuse it as a function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be sure - You only mean the part of fetching consumed gas by syscalls, right?
I can do it if you think this will bring us some gains, but personaly I find it too trivial and not really worth it to make a separate function out of 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole logic. It's not necessary, but we are kind of repeating ourselves with this.
let syscalls_consumed_gas: u64 = top_call_syscalls | |
.iter() | |
.map(|(name, count)| { | |
versioned_constants.get_syscall_gas_cost(name) * (*count as u64) | |
}) | |
.sum(); | |
sierra_gas_consumed += syscalls_consumed_gas; | |
let syscalls_consumed_gas: u64 = top_call_syscalls | |
.iter() | |
.map(|(name, count)| { | |
versioned_constants.get_syscall_gas_cost(name) * (*count as u64) | |
}) | |
.sum(); | |
sierra_gas_consumed += syscalls_consumed_gas; |
@@ -83,7 +87,7 @@ pub fn run_config_pass( | |||
let string_to_hint = hints_by_representation(&assembled_program); | |||
let hints_dict = hints_to_params(&assembled_program); | |||
|
|||
let mut context = build_context(&block_info, None); | |||
let mut context = build_context(&block_info, None, &TrackedResource::from(tracked_resource)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it matters for config pass anyway. But if you already added the logic to provide correct resource here, we can keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I'm not sure I follow :( Can you rephrase or specify please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This part is specifically for the so called 'configuration run' which doesn't execute any tests and only collect configuration from attributes. Tracking resources here does not matter as they are not counted for anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is true 👍 But I still don't know if any/what action is needed from me here :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant is that you probably didn't need to provide correct tracked_resource
here and could just hardcode some value. But no need to change that.
crates/cheatnet/src/runtime_extensions/forge_runtime_extension/mod.rs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just please address the comments if needed
match &context | ||
.tracked_resource_stack | ||
.last() | ||
.expect("Unexpected empty tracked resource.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't have a strong opinion on this, we can keep this as is
resources -= &versioned_constants.get_additional_os_syscall_resources(syscall_counter); | ||
} | ||
TrackedResource::SierraGas => { | ||
let syscalls_consumed_gas: u64 = syscall_counter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just this but didn't verify in details. They actually already have main-0.13.5
branch now.
let syscalls_consumed_gas: u64 = top_call_syscalls | ||
.iter() | ||
.map(|(name, count)| { | ||
versioned_constants.get_syscall_gas_cost(name) * (*count as u64) | ||
}) | ||
.sum(); | ||
sierra_gas_consumed += syscalls_consumed_gas; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole logic. It's not necessary, but we are kind of repeating ourselves with this.
let syscalls_consumed_gas: u64 = top_call_syscalls | |
.iter() | |
.map(|(name, count)| { | |
versioned_constants.get_syscall_gas_cost(name) * (*count as u64) | |
}) | |
.sum(); | |
sierra_gas_consumed += syscalls_consumed_gas; | |
let syscalls_consumed_gas: u64 = top_call_syscalls | |
.iter() | |
.map(|(name, count)| { | |
versioned_constants.get_syscall_gas_cost(name) * (*count as u64) | |
}) | |
.sum(); | |
sierra_gas_consumed += syscalls_consumed_gas; |
l1_handler_payload_lengths, | ||
l2_to_l1_payload_lengths, | ||
} | ||
} | ||
|
||
fn n_steps_to_sierra_gas(n_steps: usize, versioned_constants: &VersionedConstants) -> GasAmount { | ||
let n_steps_u64 = u64_from_usize(n_steps); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean maybe there is a reason they do that. I'm fine with either.
// region: Modified blockifier code | ||
// https://github.com/starkware-libs/sequencer/blob/main-v0.13.4/crates/blockifier/src/bouncer.rs#L320 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit but maybe we can just do that
// region: Modified blockifier code | |
// https://github.com/starkware-libs/sequencer/blob/main-v0.13.4/crates/blockifier/src/bouncer.rs#L320 | |
// Based on https://github.com/starkware-libs/sequencer/blob/main-v0.13.4/crates/blockifier/src/bouncer.rs#L320 |
if we aren't marking specific modified parts anyway. Or you can mark the modified parts in code
@@ -83,7 +87,7 @@ pub fn run_config_pass( | |||
let string_to_hint = hints_by_representation(&assembled_program); | |||
let hints_dict = hints_to_params(&assembled_program); | |||
|
|||
let mut context = build_context(&block_info, None); | |||
let mut context = build_context(&block_info, None, &TrackedResource::from(tracked_resource)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant is that you probably didn't need to provide correct tracked_resource
here and could just hardcode some value. But no need to change that.
Related to #2977
This PR stack aims to add support for new resource tracking (sierra-gas) and new gas representation (GasVector triplet instead of single l1 gas value).
--> (This PR) Add sierra gas tracking
-- (#3050) Run already existing tests with CairoSteps set explicitly
-- (#3051) Add support for sierra gas in
--detailed-resources
-- (#3052) Add support for sierra gas in
--save-trace-data
-- (#3053) Add sierra version assertion
-- (#3054) Introduce new gas representation
-- (#3055) Add gas tests for sierra-gas tracking
-- (#3056) Update docs with sierra-gas related changes