Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(forge): export gas reports #887

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions cli/src/cmd/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ pub struct TestArgs {
#[clap(help = "print a gas report", long = "gas-report")]
gas_report: bool,

#[clap(help = "export a gas report to .gas_report", alias = "gre", long = "gas-report-export")]
gas_report_export: bool,

#[clap(flatten)]
evm_opts: EvmArgs,

Expand Down Expand Up @@ -201,7 +204,7 @@ impl Cmd for TestArgs {
filter,
json,
allow_failure,
(self.gas_report, config.gas_reports),
(self.gas_report, self.gas_report_export, config.gas_reports),
)
}
}
Expand Down Expand Up @@ -319,10 +322,11 @@ fn test<A: ArtifactOutput + 'static>(
filter: Filter,
json: bool,
allow_failure: bool,
gas_reports: (bool, Vec<String>),
gas_reports: (bool, bool, Vec<String>),
) -> eyre::Result<TestOutcome> {
let verbosity = evm_opts.verbosity;
let gas_reporting = gas_reports.0;
let gas_reporting_export = gas_reports.1;
if gas_reporting && evm_opts.verbosity < 3 {
// force evm to do tracing, but dont hit the verbosity print path
evm_opts.verbosity = 3;
Expand All @@ -336,7 +340,7 @@ fn test<A: ArtifactOutput + 'static>(
Ok(TestOutcome::new(results, allow_failure))
} else {
// Dapptools-style printing of test results
let mut gas_report = GasReport::new(gas_reports.1);
let mut gas_report = GasReport::new(gas_reports.2, gas_reporting_export);
let (tx, rx) = channel::<(String, BTreeMap<String, TestResult>)>();
let known_contracts = runner.known_contracts.clone();
let execution_info = runner.execution_info.clone();
Expand Down Expand Up @@ -438,7 +442,17 @@ fn test<A: ArtifactOutput + 'static>(
}
}
gas_report.finalize();
println!("{}", gas_report);
if gas_reporting_export {
let table_view = format!("{}", gas_report);
if let Err(e) = std::fs::write(".gas-report", table_view) {
println!(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
println!(
eprintln!(

"error writing to .gas-report: {:?}.\noutputting to stdout instead\n{}",
e, gas_report
);
}
} else {
println!("{}", gas_report);
}
}
Ok(TestOutcome::new(results, allow_failure))
}
Expand Down
81 changes: 54 additions & 27 deletions evm-adapters/src/gas_report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use comfy_table::{modifiers::UTF8_ROUND_CORNERS, presets::UTF8_FULL, *};
pub struct GasReport {
pub report_for: Vec<String>,
pub contracts: BTreeMap<String, ContractInfo>,
pub stdout: bool,
}

#[derive(Debug, Serialize, Deserialize, Default)]
Expand All @@ -34,8 +35,8 @@ pub struct GasInfo {
}

impl GasReport {
pub fn new(report_for: Vec<String>) -> Self {
Self { report_for, ..Default::default() }
pub fn new(report_for: Vec<String>, export: bool) -> Self {
Self { report_for, stdout: !export, ..Default::default() }
Comment on lines +38 to +39
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this rather be colors?

}

pub fn analyze(
Expand Down Expand Up @@ -133,33 +134,59 @@ impl Display for GasReport {
for (name, contract) in self.contracts.iter() {
let mut table = Table::new();
table.load_preset(UTF8_FULL).apply_modifier(UTF8_ROUND_CORNERS);
table.set_header(vec![Cell::new(format!("{} contract", name))
.add_attribute(Attribute::Bold)
.fg(Color::Green)]);
table.add_row(vec![
Cell::new("Deployment Cost").add_attribute(Attribute::Bold).fg(Color::Cyan),
Cell::new("Deployment Size").add_attribute(Attribute::Bold).fg(Color::Cyan),
]);
table.add_row(vec![contract.gas.to_string(), contract.size.to_string()]);

table.add_row(vec![
Cell::new("Function Name").add_attribute(Attribute::Bold).fg(Color::Magenta),
Cell::new("min").add_attribute(Attribute::Bold).fg(Color::Green),
Cell::new("avg").add_attribute(Attribute::Bold).fg(Color::Yellow),
Cell::new("median").add_attribute(Attribute::Bold).fg(Color::Yellow),
Cell::new("max").add_attribute(Attribute::Bold).fg(Color::Red),
Cell::new("# calls").add_attribute(Attribute::Bold),
]);
contract.functions.iter().for_each(|(fname, function)| {
if self.stdout {
// include coloring
table.set_header(vec![Cell::new(format!("{} contract", name))
.add_attribute(Attribute::Bold)
.fg(Color::Green)]);
table.add_row(vec![
Cell::new(fname.to_string()).add_attribute(Attribute::Bold),
Cell::new(function.min.to_string()).fg(Color::Green),
Cell::new(function.mean.to_string()).fg(Color::Yellow),
Cell::new(function.median.to_string()).fg(Color::Yellow),
Cell::new(function.max.to_string()).fg(Color::Red),
Cell::new(function.calls.len().to_string()),
Cell::new("Deployment Cost").add_attribute(Attribute::Bold).fg(Color::Cyan),
Cell::new("Deployment Size").add_attribute(Attribute::Bold).fg(Color::Cyan),
]);
});
table.add_row(vec![contract.gas.to_string(), contract.size.to_string()]);

table.add_row(vec![
Cell::new("Function Name").add_attribute(Attribute::Bold).fg(Color::Magenta),
Cell::new("min").add_attribute(Attribute::Bold).fg(Color::Green),
Cell::new("avg").add_attribute(Attribute::Bold).fg(Color::Yellow),
Cell::new("median").add_attribute(Attribute::Bold).fg(Color::Yellow),
Cell::new("max").add_attribute(Attribute::Bold).fg(Color::Red),
Cell::new("# calls").add_attribute(Attribute::Bold),
]);
contract.functions.iter().for_each(|(fname, function)| {
table.add_row(vec![
Cell::new(fname.to_string()).add_attribute(Attribute::Bold),
Cell::new(function.min.to_string()).fg(Color::Green),
Cell::new(function.mean.to_string()).fg(Color::Yellow),
Cell::new(function.median.to_string()).fg(Color::Yellow),
Cell::new(function.max.to_string()).fg(Color::Red),
Cell::new(function.calls.len().to_string()),
]);
});
} else {
table.set_header(vec![Cell::new(format!("{} contract", name))]);
table.add_row(vec![Cell::new("Deployment Cost"), Cell::new("Deployment Size")]);
table.add_row(vec![contract.gas.to_string(), contract.size.to_string()]);

table.add_row(vec![
Cell::new("Function Name"),
Cell::new("min"),
Cell::new("avg"),
Cell::new("median"),
Cell::new("max"),
Cell::new("# calls"),
]);
contract.functions.iter().for_each(|(fname, function)| {
table.add_row(vec![
Cell::new(fname.to_string()),
Cell::new(function.min.to_string()),
Cell::new(function.mean.to_string()),
Cell::new(function.median.to_string()),
Cell::new(function.max.to_string()),
Cell::new(function.calls.len().to_string()),
]);
});
}
writeln!(f, "{}", table)?
}
Ok(())
Expand Down