Skip to content

Commit ff9fda4

Browse files
authored
Add gas component to debugging trace (#3796)
<!-- Reference any GitHub issues resolved by this PR --> Closes #3624
1 parent 9434744 commit ff9fda4

File tree

11 files changed

+91
-29
lines changed

11 files changed

+91
-29
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
- `Fuzzable` trait implementations for `bool` and `ContractAddress`
1515
- Type aliases for `StarkCurveKeyPair`, `Secp256k1CurveKeyPair`, `Secp256r1CurveKeyPair`
16+
- Option to display L2 gas for each call in the debugging trace
1617

1718
#### Changed
1819

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ license-file = "LICENSE"
3434

3535
[workspace.dependencies]
3636
# TODO(#3770) Use blockifier directly
37-
blockifier = { git = "https://github.com/software-mansion-labs/sequencer.git", branch = "main-v0.14.0", features = ["testing", "tracing"] }
37+
blockifier = { git = "https://github.com/software-mansion-labs/sequencer.git", branch = "main-v0.14.0", features = ["testing", "tracing", "node_api"] }
3838
bigdecimal = "0.4.8"
3939
# TODO(#3770) Use starknet_api directly
4040
starknet_api = { git = "https://github.com/software-mansion-labs/sequencer.git", branch = "main-v0.14.0" }

crates/cheatnet/src/state.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::runtime_extensions::forge_runtime_extension::cheatcodes::cheat_execut
1010
};
1111
use crate::runtime_extensions::forge_runtime_extension::cheatcodes::spy_events::Event;
1212
use crate::runtime_extensions::forge_runtime_extension::cheatcodes::spy_messages_to_l1::MessageToL1;
13+
use blockifier::blockifier_versioned_constants::VersionedConstants;
1314
use blockifier::execution::call_info::{ExecutionSummary, OrderedEvent, OrderedL2ToL1Message};
1415
use blockifier::execution::contract_class::RunnableCompiledClass;
1516
use blockifier::execution::entry_point::CallEntryPoint;
@@ -29,13 +30,15 @@ use runtime::starknet::context::SerializableBlockInfo;
2930
use runtime::starknet::state::DictStateReader;
3031
use starknet_api::block::BlockInfo;
3132
use starknet_api::core::{ChainId, EntryPointSelector};
33+
use starknet_api::execution_resources::GasVector;
3234
use starknet_api::transaction::fields::ContractAddressSalt;
35+
use starknet_api::transaction::fields::GasVectorComputationMode;
3336
use starknet_api::{
3437
core::{ClassHash, CompiledClassHash, ContractAddress, Nonce},
3538
state::StorageKey,
3639
};
3740
use starknet_types_core::felt::Felt;
38-
use std::cell::{Ref, RefCell};
41+
use std::cell::{OnceCell, Ref, RefCell};
3942
use std::collections::HashMap;
4043
use std::num::NonZeroUsize;
4144
use std::rc::Rc;
@@ -203,15 +206,28 @@ impl<T> CheatStatus<T> {
203206
}
204207
}
205208

206-
#[derive(Debug)]
209+
#[derive(Clone, Debug)]
207210
pub struct GasReportData {
208211
pub execution_summary: ExecutionSummary,
212+
partial_gas_usage: OnceCell<GasVector>,
209213
}
210214

211215
impl GasReportData {
212216
#[must_use]
213217
pub fn new(execution_summary: ExecutionSummary) -> Self {
214-
Self { execution_summary }
218+
Self {
219+
execution_summary,
220+
partial_gas_usage: OnceCell::new(),
221+
}
222+
}
223+
224+
pub fn get_gas(&self) -> &GasVector {
225+
self.partial_gas_usage.get_or_init(|| {
226+
self.execution_summary.clone().to_partial_gas_vector(
227+
VersionedConstants::latest_constants(),
228+
&GasVectorComputationMode::All,
229+
)
230+
})
215231
}
216232
}
217233

crates/debugging/src/trace/collect.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::contracts_data_store::ContractsDataStore;
22
use crate::trace::types::{
3-
CallerAddress, ContractAddress, ContractName, ContractTrace, Selector, TestName, TraceInfo,
4-
TransformedCallResult, TransformedCalldata,
3+
CallerAddress, ContractAddress, ContractName, ContractTrace, Gas, Selector, TestName,
4+
TraceInfo, TransformedCallResult, TransformedCalldata,
55
};
66
use crate::{Context, Trace};
77
use cheatnet::runtime_extensions::call_to_blockifier_runtime_extension::rpc::{
@@ -52,6 +52,7 @@ impl<'a> Collector<'a> {
5252
call_type: components.call_type(entry_point.call_type),
5353
nested_calls,
5454
call_result: components.call_result_lazy(|| self.collect_transformed_call_result(abi)),
55+
gas: components.gas_lazy(|| self.collect_gas()),
5556
};
5657

5758
ContractTrace {
@@ -125,6 +126,16 @@ impl<'a> Collector<'a> {
125126
})
126127
}
127128

129+
fn collect_gas(&self) -> Gas {
130+
Gas(self
131+
.call_trace
132+
.gas_report_data
133+
.as_ref()
134+
.expect("Gas report data must be updated after test execution")
135+
.get_gas()
136+
.l2_gas)
137+
}
138+
128139
fn class_hash(&self) -> &ClassHash {
129140
self.call_trace
130141
.entry_point

crates/debugging/src/trace/components.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::trace::types::{
2-
CallerAddress, ContractAddress, ContractName, TransformedCallResult, TransformedCalldata,
2+
CallerAddress, ContractAddress, ContractName, Gas, TransformedCallResult, TransformedCalldata,
33
};
44
use blockifier::execution::entry_point::CallType;
55
use paste::paste;
@@ -42,6 +42,8 @@ pub enum Component {
4242
CallType,
4343
/// The result of the call, transformed for display.
4444
CallResult,
45+
/// The L2 gas used by the call.
46+
Gas,
4547
}
4648

4749
macro_rules! impl_component_container {
@@ -122,3 +124,4 @@ impl_component_container!(ContractAddress);
122124
impl_component_container!(CallerAddress);
123125
impl_component_container!(CallType);
124126
impl_component_container!(CallResult, TransformedCallResult);
127+
impl_component_container!(Gas);

crates/debugging/src/trace/types.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ use crate::Context;
22
use crate::trace::collect::Collector;
33
use crate::trace::components::{
44
CallResultContainer, CallTypeContainer, CalldataContainer, CallerAddressContainer,
5-
ContractAddressContainer, ContractNameContainer, EntryPointTypeContainer,
5+
ContractAddressContainer, ContractNameContainer, EntryPointTypeContainer, GasContainer,
66
};
77
use crate::tree::TreeSerialize;
88
use cheatnet::state::CallTrace;
99
use starknet_api::core::ContractAddress as ApiContractAddress;
10+
use starknet_api::execution_resources::GasAmount as ApiGasAmount;
1011
use std::fmt;
1112
use std::fmt::Display;
1213

@@ -32,6 +33,7 @@ pub struct TraceInfo {
3233
pub call_type: CallTypeContainer,
3334
pub nested_calls: Vec<ContractTrace>,
3435
pub call_result: CallResultContainer,
36+
pub gas: GasContainer,
3537
}
3638

3739
#[derive(Debug, Clone)]
@@ -55,6 +57,9 @@ pub struct ContractAddress(pub ApiContractAddress);
5557
#[derive(Debug, Clone)]
5658
pub struct CallerAddress(pub ApiContractAddress);
5759

60+
#[derive(Debug, Clone)]
61+
pub struct Gas(pub ApiGasAmount);
62+
5863
impl Trace {
5964
/// Creates a new [`Trace`] from a given [`Context`] and a test name.
6065
#[must_use]

crates/debugging/src/tree/ui/as_tree_node.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ impl AsTreeNode for TraceInfo {
3434
parent.leaf_optional(self.caller_address.as_option());
3535
parent.leaf_optional(self.call_type.as_option());
3636
parent.leaf_optional(self.call_result.as_option());
37+
parent.leaf_optional(self.gas.as_option());
3738
for nested_call in &self.nested_calls {
3839
parent.as_tree_node(nested_call);
3940
}

crates/debugging/src/tree/ui/display.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::trace::types::{
2-
CallerAddress, ContractAddress, ContractName, Selector, TestName, TransformedCallResult,
2+
CallerAddress, ContractAddress, ContractName, Gas, Selector, TestName, TransformedCallResult,
33
TransformedCalldata,
44
};
55
use blockifier::execution::entry_point::CallType;
@@ -84,6 +84,13 @@ impl NodeDisplay for TransformedCallResult {
8484
}
8585
}
8686

87+
impl NodeDisplay for Gas {
88+
const TAG: &'static str = "L2 gas";
89+
fn string_pretty(&self) -> String {
90+
self.0.to_string()
91+
}
92+
}
93+
8794
/// Helper function to get hex representation
8895
/// of a type that can be converted to a [`Felt`].
8996
fn string_hex(data: impl Into<Felt>) -> String {

crates/forge-runner/src/debugging/component.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ pub enum Component {
1919
CallType,
2020
/// The result of the call, transformed for display.
2121
CallResult,
22+
/// The L2 gas used by the call.
23+
Gas,
2224
}
2325
impl Component {
2426
/// Returns minimal [`TraceVerbosity`] for the component.
@@ -30,7 +32,8 @@ impl Component {
3032
Component::ContractAddress
3133
| Component::CallerAddress
3234
| Component::EntryPointType
33-
| Component::CallType => TraceVerbosity::Detailed,
35+
| Component::CallType
36+
| Component::Gas => TraceVerbosity::Detailed,
3437
}
3538
}
3639
}
@@ -45,6 +48,7 @@ impl From<&Component> for debugging::Component {
4548
Component::CallerAddress => debugging::Component::CallerAddress,
4649
Component::CallType => debugging::Component::CallType,
4750
Component::CallResult => debugging::Component::CallResult,
51+
Component::Gas => debugging::Component::Gas,
4852
}
4953
}
5054
}

crates/forge/tests/e2e/debugging.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ fn detailed_debugging_trace_message(test_name: &str, package_name: &str) -> Stri
175175
│ ├─ [caller address] [..]
176176
│ ├─ [call type] Call
177177
│ ├─ [call result] success: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}]
178+
│ ├─ [L2 gas] [..]
178179
│ ├─ [selector] execute_calls
179180
│ │ ├─ [contract name] SimpleContract
180181
│ │ ├─ [entry point type] External
@@ -183,38 +184,43 @@ fn detailed_debugging_trace_message(test_name: &str, package_name: &str) -> Stri
183184
│ │ ├─ [caller address] [..]
184185
│ │ ├─ [call type] Call
185186
│ │ ├─ [call result] success: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}]
187+
│ │ ├─ [L2 gas] [..]
186188
│ │ ├─ [selector] execute_calls
187189
│ │ │ ├─ [contract name] SimpleContract
188190
│ │ │ ├─ [entry point type] External
189191
│ │ │ ├─ [calldata] array![]
190192
│ │ │ ├─ [contract address] [..]
191193
│ │ │ ├─ [caller address] [..]
192194
│ │ │ ├─ [call type] Call
193-
│ │ │ └─ [call result] success: array![]
195+
│ │ │ ├─ [call result] success: array![]
196+
│ │ │ └─ [L2 gas] [..]
194197
│ │ └─ [selector] execute_calls
195198
│ │ ├─ [contract name] SimpleContract
196199
│ │ ├─ [entry point type] External
197200
│ │ ├─ [calldata] array![]
198201
│ │ ├─ [contract address] [..]
199202
│ │ ├─ [caller address] [..]
200203
│ │ ├─ [call type] Call
201-
│ │ └─ [call result] success: array![]
204+
│ │ ├─ [call result] success: array![]
205+
│ │ └─ [L2 gas] [..]
202206
│ └─ [selector] execute_calls
203207
│ ├─ [contract name] SimpleContract
204208
│ ├─ [entry point type] External
205209
│ ├─ [calldata] array![]
206210
│ ├─ [contract address] [..]
207211
│ ├─ [caller address] [..]
208212
│ ├─ [call type] Call
209-
│ └─ [call result] success: array![]
213+
│ ├─ [call result] success: array![]
214+
│ └─ [L2 gas] [..]
210215
└─ [selector] fail
211216
├─ [contract name] SimpleContract
212217
├─ [entry point type] External
213218
├─ [calldata] array![0x1, 0x2, 0x3, 0x4, 0x5]
214219
├─ [contract address] [..]
215220
├─ [caller address] [..]
216221
├─ [call type] Call
217-
└─ [call result] panic: (0x1, 0x2, 0x3, 0x4, 0x5)
222+
├─ [call result] panic: (0x1, 0x2, 0x3, 0x4, 0x5)
223+
└─ [L2 gas] [..]
218224
"}
219225
}
220226

@@ -229,6 +235,7 @@ fn detailed_debugging_trace_message_fork(test_name: &str, package_name: &str) ->
229235
│ ├─ [caller address] [..]
230236
│ ├─ [call type] Call
231237
│ ├─ [call result] success: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}]
238+
│ ├─ [L2 gas] [..]
232239
│ ├─ [selector] execute_calls
233240
│ │ ├─ [contract name] forked contract
234241
│ │ ├─ [entry point type] External
@@ -237,38 +244,43 @@ fn detailed_debugging_trace_message_fork(test_name: &str, package_name: &str) ->
237244
│ │ ├─ [caller address] [..]
238245
│ │ ├─ [call type] Call
239246
│ │ ├─ [call result] success: array![RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}, RecursiveCall {{ contract_address: ContractAddress([..]), payload: array![] }}]
247+
│ │ ├─ [L2 gas] [..]
240248
│ │ ├─ [selector] execute_calls
241249
│ │ │ ├─ [contract name] forked contract
242250
│ │ │ ├─ [entry point type] External
243251
│ │ │ ├─ [calldata] array![]
244252
│ │ │ ├─ [contract address] [..]
245253
│ │ │ ├─ [caller address] [..]
246254
│ │ │ ├─ [call type] Call
247-
│ │ │ └─ [call result] success: array![]
255+
│ │ │ ├─ [call result] success: array![]
256+
│ │ │ └─ [L2 gas] [..]
248257
│ │ └─ [selector] execute_calls
249258
│ │ ├─ [contract name] forked contract
250259
│ │ ├─ [entry point type] External
251260
│ │ ├─ [calldata] array![]
252261
│ │ ├─ [contract address] [..]
253262
│ │ ├─ [caller address] [..]
254263
│ │ ├─ [call type] Call
255-
│ │ └─ [call result] success: array![]
264+
│ │ ├─ [call result] success: array![]
265+
│ │ └─ [L2 gas] [..]
256266
│ └─ [selector] execute_calls
257267
│ ├─ [contract name] forked contract
258268
│ ├─ [entry point type] External
259269
│ ├─ [calldata] array![]
260270
│ ├─ [contract address] [..]
261271
│ ├─ [caller address] [..]
262272
│ ├─ [call type] Call
263-
│ └─ [call result] success: array![]
273+
│ ├─ [call result] success: array![]
274+
│ └─ [L2 gas] [..]
264275
└─ [selector] fail
265276
├─ [contract name] forked contract
266277
├─ [entry point type] External
267278
├─ [calldata] array![0x1, 0x2, 0x3, 0x4, 0x5]
268279
├─ [contract address] [..]
269280
├─ [caller address] [..]
270281
├─ [call type] Call
271-
└─ [call result] panic: (0x1, 0x2, 0x3, 0x4, 0x5)
282+
├─ [call result] panic: (0x1, 0x2, 0x3, 0x4, 0x5)
283+
└─ [L2 gas] [..]
272284
"}
273285
}
274286

0 commit comments

Comments
 (0)