Skip to content

Commit

Permalink
fix(forge): always report deployment size in gas reports (foundry-rs#…
Browse files Browse the repository at this point in the history
  • Loading branch information
grandizzy authored and rplusq committed Nov 29, 2024
1 parent d090d39 commit bf8044b
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 14 deletions.
29 changes: 15 additions & 14 deletions crates/forge/src/gas_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,31 +94,32 @@ impl GasReport {
return;
}

// Only include top-level calls which account for calldata and base (21.000) cost.
// Only include Calls and Creates as only these calls are isolated in inspector.
if trace.depth > 1 &&
(trace.kind == CallKind::Call ||
trace.kind == CallKind::Create ||
trace.kind == CallKind::Create2 ||
trace.kind == CallKind::EOFCreate)
{
return;
}

let Some(name) = decoder.contracts.get(&node.trace.address) else { return };
let contract_name = name.rsplit(':').next().unwrap_or(name);

if !self.should_report(contract_name) {
return;
}
let contract_info = self.contracts.entry(name.to_string()).or_default();
let is_create_call = trace.kind.is_any_create();

// Record contract deployment size.
if is_create_call {
trace!(contract_name, "adding create size info");
contract_info.size = trace.data.len();
}

// Only include top-level calls which account for calldata and base (21.000) cost.
// Only include Calls and Creates as only these calls are isolated in inspector.
if trace.depth > 1 && (trace.kind == CallKind::Call || is_create_call) {
return;
}

let decoded = || decoder.decode_function(&node.trace);

let contract_info = self.contracts.entry(name.to_string()).or_default();
if trace.kind.is_any_create() {
if is_create_call {
trace!(contract_name, "adding create gas info");
contract_info.gas = trace.gas_used;
contract_info.size = trace.data.len();
} else if let Some(DecodedCallData { signature, .. }) = decoded().await.call_data {
let name = signature.split('(').next().unwrap();
// ignore any test/setup functions
Expand Down
126 changes: 126 additions & 0 deletions crates/forge/tests/cli/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2544,6 +2544,132 @@ Suite result: ok. 1 passed; 0 failed; 0 skipped; [ELAPSED]
);
});

// <https://github.com/foundry-rs/foundry/issues/9300>
forgetest_init!(gas_report_size_for_nested_create, |prj, cmd| {
prj.add_test(
"NestedDeployTest.sol",
r#"
import {Test} from "forge-std/Test.sol";
contract Child {
AnotherChild public child;
constructor() {
child = new AnotherChild();
}
function w() external {
child.w();
}
}
contract AnotherChild {
function w() external {}
}
contract Parent {
Child public immutable child;
constructor() {
child = new Child();
}
}
contract NestedDeploy is Test {
function test_nested_create_gas_report() external {
Parent p = new Parent();
p.child().child().w();
}
}
"#,
)
.unwrap();

cmd.args(["test", "--mt", "test_nested_create_gas_report", "--gas-report"])
.assert_success()
.stdout_eq(str![[r#"
...
Ran 1 test for test/NestedDeployTest.sol:NestedDeploy
[PASS] test_nested_create_gas_report() ([GAS])
Suite result: ok. 1 passed; 0 failed; 0 skipped; [ELAPSED]
| test/NestedDeployTest.sol:AnotherChild contract | | | | | |
|-------------------------------------------------|-----------------|-------|--------|-------|---------|
| Deployment Cost | Deployment Size | | | | |
| 0 | 130 | | | | |
| Function Name | min | avg | median | max | # calls |
| w | 21162 | 21162 | 21162 | 21162 | 1 |
| test/NestedDeployTest.sol:Child contract | | | | | |
|------------------------------------------|-----------------|-----|--------|-----|---------|
| Deployment Cost | Deployment Size | | | | |
| 0 | 498 | | | | |
| Function Name | min | avg | median | max | # calls |
| child | 325 | 325 | 325 | 325 | 1 |
| test/NestedDeployTest.sol:Parent contract | | | | | |
|-------------------------------------------|-----------------|-----|--------|-----|---------|
| Deployment Cost | Deployment Size | | | | |
| 254857 | 770 | | | | |
| Function Name | min | avg | median | max | # calls |
| child | 182 | 182 | 182 | 182 | 1 |
...
"#]]);

cmd.forge_fuse()
.args(["test", "--mt", "test_nested_create_gas_report", "--gas-report", "--json"])
.assert_success()
.stdout_eq(
str![[r#"
[
{
"contract": "test/NestedDeployTest.sol:AnotherChild",
"deployment": {
"gas": 0,
"size": 130
},
"functions": {
"w()": {
"calls": 1,
"min": 21162,
"mean": 21162,
"median": 21162,
"max": 21162
}
}
},
{
"contract": "test/NestedDeployTest.sol:Child",
"deployment": {
"gas": 0,
"size": 498
},
"functions": {
"child()": {
"calls": 1,
"min": 325,
"mean": 325,
"median": 325,
"max": 325
}
}
},
{
"contract": "test/NestedDeployTest.sol:Parent",
"deployment": {
"gas": 254857,
"size": 770
},
"functions": {
"child()": {
"calls": 1,
"min": 182,
"mean": 182,
"median": 182,
"max": 182
}
}
}
]
"#]]
.is_json(),
);
});

forgetest_init!(can_use_absolute_imports, |prj, cmd| {
let remapping = prj.paths().libraries[0].join("myDependency");
let config = Config {
Expand Down

0 comments on commit bf8044b

Please sign in to comment.