Skip to content

Commit 08a6409

Browse files
zerosnacksklkvr
andauthored
feat: gas snapshots over arbitrary sections (foundry-rs#8952)
* update internal naming * further internals * deprecate cheats * update Solidity tests and add dedicated test for testing deprecated cheatcodes * clarify gas snapshots * fix build * final fixes * fix build * fix repro 6355 rename * add gas snapshot setup from foundry-rs#8755 * fix build + clippy warnings * fix cheatcodes * account for fixed CREATE / CALL gas cost * remove import * add stipend * recalculate after a - b setup * clear call_stipend, update tests * avoid double counting external calls * update cheatcodes, remove debug prints * enable assertions * clean up tests * clean up test names * remove snapshot directory on `forge clean` * do not remove all snapshots by default due to multiple test suites being able to be ran concurrently or sequentially + optimize gas snapshots check - skip if none were captured * handle edge case where we ask to compare but file does not exist, remove snapshot directory at a top level before test suites are ran * fix path issue when attempting removal * Update crates/cheatcodes/src/evm.rs Co-authored-by: Arsenii Kulikov <[email protected]> * Update crates/cheatcodes/src/inspector.rs Co-authored-by: Arsenii Kulikov <[email protected]> * refactor, apply recommended changes for last_snapshot_group, last_snapshot_name * remove gas snapshots from fuzz tests for now: this is largely due to it conflicting with the FORGE_SNAPSHOT_CHECK where it is highly likely that with different fuzzed input the gas measurement differs as well. In the future it would be an idea to capture the average gas * fix clippy * avoid setting to 0 unnecessarily * use if let Some * improve comments, clarify use of last_gas_used != 0 * fix merge conflict issue * fix arg ordering to address group naming regression * fix import * move snapshot name derivation to helper * only skip initial call w/ overhead, no special handling for call frames * add flare test * style nits + use helper method --------- Co-authored-by: Arsenii Kulikov <[email protected]>
1 parent 4469a65 commit 08a6409

File tree

17 files changed

+947
-5
lines changed

17 files changed

+947
-5
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
.DS_STORE
22
/target
33
out/
4+
snapshots/
45
out.json
56
.idea
67
.vscode

crates/cheatcodes/assets/cheatcodes.json

+181-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cheatcodes/spec/src/vm.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,49 @@ interface Vm {
509509
#[cheatcode(group = Evm, safety = Unsafe)]
510510
function readCallers() external returns (CallerMode callerMode, address msgSender, address txOrigin);
511511

512+
// ----- Arbitrary Snapshots -----
513+
514+
/// Snapshot capture an arbitrary numerical value by name.
515+
/// The group name is derived from the contract name.
516+
#[cheatcode(group = Evm, safety = Unsafe)]
517+
function snapshotValue(string calldata name, uint256 value) external;
518+
519+
/// Snapshot capture an arbitrary numerical value by name in a group.
520+
#[cheatcode(group = Evm, safety = Unsafe)]
521+
function snapshotValue(string calldata group, string calldata name, uint256 value) external;
522+
523+
// -------- Gas Snapshots --------
524+
525+
/// Snapshot capture the gas usage of the last call by name from the callee perspective.
526+
#[cheatcode(group = Evm, safety = Unsafe)]
527+
function snapshotGasLastCall(string calldata name) external returns (uint256 gasUsed);
528+
529+
/// Snapshot capture the gas usage of the last call by name in a group from the callee perspective.
530+
#[cheatcode(group = Evm, safety = Unsafe)]
531+
function snapshotGasLastCall(string calldata group, string calldata name) external returns (uint256 gasUsed);
532+
533+
/// Start a snapshot capture of the current gas usage by name.
534+
/// The group name is derived from the contract name.
535+
#[cheatcode(group = Evm, safety = Unsafe)]
536+
function startSnapshotGas(string calldata name) external;
537+
538+
/// Start a snapshot capture of the current gas usage by name in a group.
539+
#[cheatcode(group = Evm, safety = Unsafe)]
540+
function startSnapshotGas(string calldata group, string calldata name) external;
541+
542+
/// Stop the snapshot capture of the current gas by latest snapshot name, capturing the gas used since the start.
543+
#[cheatcode(group = Evm, safety = Unsafe)]
544+
function stopSnapshotGas() external returns (uint256 gasUsed);
545+
546+
/// Stop the snapshot capture of the current gas usage by name, capturing the gas used since the start.
547+
/// The group name is derived from the contract name.
548+
#[cheatcode(group = Evm, safety = Unsafe)]
549+
function stopSnapshotGas(string calldata name) external returns (uint256 gasUsed);
550+
551+
/// Stop the snapshot capture of the current gas usage by name in a group, capturing the gas used since the start.
552+
#[cheatcode(group = Evm, safety = Unsafe)]
553+
function stopSnapshotGas(string calldata group, string calldata name) external returns (uint256 gasUsed);
554+
512555
// -------- State Snapshots --------
513556

514557
/// `snapshot` is being deprecated in favor of `snapshotState`. It will be removed in future versions.
@@ -698,7 +741,7 @@ interface Vm {
698741

699742
// -------- Gas Measurement --------
700743

701-
/// Gets the gas used in the last call.
744+
/// Gets the gas used in the last call from the callee perspective.
702745
#[cheatcode(group = Evm, safety = Safe)]
703746
function lastCallGas() external view returns (Gas memory gas);
704747

crates/cheatcodes/src/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ pub struct CheatsConfig {
4949
/// If Some, `vm.getDeployedCode` invocations are validated to be in scope of this list.
5050
/// If None, no validation is performed.
5151
pub available_artifacts: Option<ContractsByArtifact>,
52+
/// Name of the script/test contract which is currently running.
53+
pub running_contract: Option<String>,
5254
/// Version of the script/test contract which is currently running.
5355
pub running_version: Option<Version>,
5456
/// Whether to enable legacy (non-reverting) assertions.
@@ -64,6 +66,7 @@ impl CheatsConfig {
6466
evm_opts: EvmOpts,
6567
available_artifacts: Option<ContractsByArtifact>,
6668
script_wallets: Option<ScriptWallets>,
69+
running_contract: Option<String>,
6770
running_version: Option<Version>,
6871
) -> Self {
6972
let mut allowed_paths = vec![config.root.0.clone()];
@@ -92,6 +95,7 @@ impl CheatsConfig {
9295
labels: config.labels.clone(),
9396
script_wallets,
9497
available_artifacts,
98+
running_contract,
9599
running_version,
96100
assertions_revert: config.assertions_revert,
97101
seed: config.fuzz.seed,
@@ -221,6 +225,7 @@ impl Default for CheatsConfig {
221225
labels: Default::default(),
222226
script_wallets: None,
223227
available_artifacts: Default::default(),
228+
running_contract: Default::default(),
224229
running_version: Default::default(),
225230
assertions_revert: true,
226231
seed: None,
@@ -240,6 +245,7 @@ mod tests {
240245
None,
241246
None,
242247
None,
248+
None,
243249
)
244250
}
245251

0 commit comments

Comments
 (0)