Skip to content

Commit

Permalink
fix(forge): reset gas to original after pauseGasMetering (#8717)
Browse files Browse the repository at this point in the history
  • Loading branch information
grandizzy authored Aug 22, 2024
1 parent 5c52be6 commit 70ef94a
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
8 changes: 7 additions & 1 deletion crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,13 @@ impl Cheatcodes {
// inside it.
self.gas_metering_create = Some(None)
}
opcode::STOP | opcode::RETURN | opcode::SELFDESTRUCT | opcode::REVERT => {
opcode::STOP => {
// Reset gas to value recorded when paused.
interpreter.gas = *gas;
self.gas_metering = None;
self.gas_metering_create = None;
}
opcode::RETURN | opcode::SELFDESTRUCT | opcode::REVERT => {
match &self.gas_metering_create {
None | Some(None) => {
// If we are ending current execution frame, we want to reset
Expand Down
48 changes: 48 additions & 0 deletions crates/forge/tests/cli/test_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1238,3 +1238,51 @@ contract DeterministicRandomnessTest is Test {
assert_ne!(res4, res1);
assert_ne!(res4, res3);
});

// tests that `pauseGasMetering` used at the end of test does not produce meaningless values
// see https://github.com/foundry-rs/foundry/issues/5491
forgetest_init!(repro_5491, |prj, cmd| {
prj.wipe_contracts();

prj.add_test(
"ATest.t.sol",
r#"
import {Test} from "forge-std/Test.sol";
contract ATest is Test {
function testWeirdGas1() public {
vm.pauseGasMetering();
}
function testWeirdGas2() public {
uint256 a = 1;
uint256 b = a + 1;
require(b == 2, "b is not 2");
vm.pauseGasMetering();
}
function testNormalGas() public {
vm.pauseGasMetering();
vm.resumeGasMetering();
}
function testWithAssembly() public {
vm.pauseGasMetering();
assembly {
return(0, 0)
}
}
}
"#,
)
.unwrap();

cmd.args(["test"]).with_no_redact().assert_success().stdout_eq(str![[r#"
...
[PASS] testNormalGas() (gas: 3202)
[PASS] testWeirdGas1() (gas: 3040)
[PASS] testWeirdGas2() (gas: 3148)
[PASS] testWithAssembly() (gas: 3083)
...
"#]]);
});
16 changes: 15 additions & 1 deletion crates/test-utils/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ impl TestProject {
current_dir_lock: None,
saved_cwd: pretty_err("<current dir>", std::env::current_dir()),
stdin_fun: None,
redact_output: true,
}
}

Expand All @@ -638,6 +639,7 @@ impl TestProject {
current_dir_lock: None,
saved_cwd: pretty_err("<current dir>", std::env::current_dir()),
stdin_fun: None,
redact_output: true,
}
}

Expand Down Expand Up @@ -735,6 +737,8 @@ pub struct TestCommand {
// initial: Command,
current_dir_lock: Option<parking_lot::lock_api::MutexGuard<'static, parking_lot::RawMutex, ()>>,
stdin_fun: Option<Box<dyn FnOnce(ChildStdin)>>,
/// If true, command output is redacted.
redact_output: bool,
}

impl TestCommand {
Expand Down Expand Up @@ -825,6 +829,12 @@ impl TestCommand {
self
}

/// Does not apply [`snapbox`] redactions to the command output.
pub fn with_no_redact(&mut self) -> &mut Self {
self.redact_output = false;
self
}

/// Returns the `Config` as spit out by `forge config`
#[track_caller]
pub fn config(&mut self) -> Config {
Expand Down Expand Up @@ -1053,7 +1063,11 @@ stderr:
/// Runs the command, returning a [`snapbox`] object to assert the command output.
#[track_caller]
pub fn assert(&mut self) -> OutputAssert {
OutputAssert::new(self.execute()).with_assert(test_assert())
let assert = OutputAssert::new(self.execute());
if self.redact_output {
return assert.with_assert(test_assert());
};
assert
}

/// Runs the command and asserts that it resulted in success.
Expand Down

0 comments on commit 70ef94a

Please sign in to comment.