Skip to content

Commit

Permalink
feat(blockifier): gas_for_fee computation (#1804)
Browse files Browse the repository at this point in the history
  • Loading branch information
TzahiTaub authored Nov 7, 2024
1 parent 0dd72ad commit 93dd596
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
30 changes: 30 additions & 0 deletions crates/blockifier/src/execution/entry_point_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ use crate::execution::syscalls::hint_processor::SyscallHintProcessor;
use crate::state::state_api::State;
use crate::versioned_constants::GasCosts;

#[cfg(test)]
#[path = "entry_point_execution_test.rs"]
mod test;

// TODO(spapini): Try to refactor this file into a StarknetRunner struct.

pub struct VmExecutionContext<'a> {
Expand Down Expand Up @@ -363,6 +367,32 @@ fn maybe_fill_holes(
Ok(())
}

/// Calculates the total gas for fee in the current call + subtree.
#[allow(dead_code)]
fn to_gas_for_fee(
tracked_resource: &TrackedResource,
gas_consumed: u64,
inner_calls: &[CallInfo],
) -> GasAmount {
// The Sierra gas consumed in this specific call is `gas_consumed`
// (= total gas of self + subtree), minus the sum of all inner calls Sierra gas consumed.
// To compute the total Sierra gas to charge (of self + subtree), if the tracked resource is
// Sierra gas, we add this amount to the total gas to charge for in the subtree:
// gas_for_fee = gas_consumed - subtree_gas_consumed + subtree_gas_to_fee.
GasAmount(match tracked_resource {
// If the tracked resource is CairoSteps, then all tracked resources of all calls in
// the subtree are also CairoSteps. Thus, the total gas to charge in this subtree is zero.
TrackedResource::CairoSteps => 0,
TrackedResource::SierraGas => gas_consumed
.checked_sub(
inner_calls
.iter()
.map(|call| call.execution.gas_consumed - call.charged_resources.gas_for_fee.0)
.sum::<u64>(),
)
.expect("gas_for_fee unexpectedly underflowed."),
})
}
pub fn finalize_execution(
mut runner: CairoRunner,
mut syscall_handler: SyscallHintProcessor<'_>,
Expand Down
55 changes: 55 additions & 0 deletions crates/blockifier/src/execution/entry_point_execution_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use starknet_api::execution_resources::GasAmount;

use crate::execution::call_info::{CallExecution, CallInfo, ChargedResources};
use crate::execution::contract_class::TrackedResource;
use crate::execution::entry_point_execution::to_gas_for_fee;

#[test]
/// Verifies that every call from the inner most to the outer has the expected gas_for_fee for the
/// following topology (marked as TrackedResource(gas_consumed)):
// Gas(8) -> Gas(3) -> VM(2) -> VM(1)
// \ -> VM(4)
// Expected values are 2 -> 1 -> 0 -> 0.
// \-> 0.
fn test_gas_for_fee() {
// First branch - 3 nested calls.
let mut inner_calls = vec![];
for (tracked_resource, gas_consumed, expected_gas_for_fee) in [
(TrackedResource::CairoSteps, 1, 0),
(TrackedResource::CairoSteps, 2, 0),
(TrackedResource::SierraGas, 3, 1),
] {
assert_eq!(
to_gas_for_fee(&tracked_resource, gas_consumed, &inner_calls).0,
expected_gas_for_fee
);
inner_calls = vec![CallInfo {
execution: CallExecution { gas_consumed, ..Default::default() },
tracked_resource,
inner_calls,
charged_resources: ChargedResources {
gas_for_fee: GasAmount(expected_gas_for_fee),
..Default::default()
},
..Default::default()
}];
}

// Second branch - 1 call.
let (tracked_resource, gas_consumed, expected_gas_for_fee) =
(TrackedResource::CairoSteps, 4, 0);
assert_eq!(to_gas_for_fee(&tracked_resource, gas_consumed, &[]).0, expected_gas_for_fee);

inner_calls.push(CallInfo {
execution: CallExecution { gas_consumed, ..Default::default() },
tracked_resource,
charged_resources: ChargedResources {
gas_for_fee: GasAmount(expected_gas_for_fee),
..Default::default()
},
..Default::default()
});

// Outer call.
assert_eq!(to_gas_for_fee(&TrackedResource::SierraGas, 8, &inner_calls).0, 2);
}

0 comments on commit 93dd596

Please sign in to comment.