Skip to content

Commit

Permalink
fix(extrinsics): remove printing from estimate_gas methods
Browse files Browse the repository at this point in the history
Signed-off-by: Tarek <[email protected]>
  • Loading branch information
tareknaser committed Aug 19, 2023
1 parent d6a705d commit 24eb4d7
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 37 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/cargo-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ url = { version = "2.4.0", features = ["serde"] }
# dependencies for extrinsics (deploying and calling a contract)
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
subxt = "0.31.0"
sp-weights = "20.0.0"
hex = "0.4.3"

[build-dependencies]
Expand Down
111 changes: 108 additions & 3 deletions crates/cargo-contract/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,20 @@ use contract_extrinsics::{
display_contract_exec_result,
display_contract_exec_result_debug,
display_dry_run_result_warning,
print_dry_running_status,
print_gas_required_success,
prompt_confirm_tx,
CallDryRunResult,
CallExec,
Code,
CodeHashResult,
InstantiateExec,
StorageDeposit,
TokenMetadata,
UploadDryRunResult,
MAX_KEY_COL_WIDTH,
};
use sp_weights::Weight;

// These crates are only used when we run integration tests `--features
// integration-tests`. However since we can't have optional `dev-dependencies` we pretend
Expand Down Expand Up @@ -307,7 +312,8 @@ fn handle_instantiate(
}
} else {
tracing::debug!("instantiate data {:?}", instantiate_exec.args().data());
let gas_limit = instantiate_exec.estimate_gas(true).await?;
let gas_limit =
pre_submit_dry_run_gas_estimate_instantiate(&instantiate_exec).await?;
if !instantiate_exec.opts().skip_confirm() {
prompt_confirm_tx(|| {
instantiate_exec.print_default_instantiate_preview(gas_limit);
Expand Down Expand Up @@ -376,8 +382,7 @@ fn handle_call(call_command: &CallCommand) -> Result<(), ErrorVariant> {
}
}
} else {
let gas_limit = call_exec.estimate_gas(true).await?;

let gas_limit = pre_submit_dry_run_gas_estimate_call(&call_exec).await?;
if !call_exec.opts().skip_confirm() {
prompt_confirm_tx(|| {
name_value_println!(
Expand Down Expand Up @@ -463,3 +468,103 @@ fn format_err<E: Debug>(err: E) -> Error {
format!("{err:?}").bright_red()
)
}

/// A helper function to estimate the gas required for a contract instantiation.
pub async fn pre_submit_dry_run_gas_estimate_instantiate(
instantiate_exec: &InstantiateExec,
) -> Result<Weight> {
if instantiate_exec.opts().skip_dry_run() {
return match (instantiate_exec.args().gas_limit(), instantiate_exec.args().proof_size()) {
(Some(ref_time), Some(proof_size)) => Ok(Weight::from_parts(ref_time, proof_size)),
_ => {
Err(anyhow!(
"Weight args `--gas` and `--proof-size` required if `--skip-dry-run` specified"
))
}
};
}
if !instantiate_exec.output_json() {
print_dry_running_status(instantiate_exec.args().constructor());
}
let instantiate_result = instantiate_exec.instantiate_dry_run().await?;
match instantiate_result.result {
Ok(_) => {
if !instantiate_exec.output_json() {
print_gas_required_success(instantiate_result.gas_required);
}
// use user specified values where provided, otherwise use the estimates
let ref_time = instantiate_exec
.args()
.gas_limit()
.unwrap_or_else(|| instantiate_result.gas_required.ref_time());
let proof_size = instantiate_exec
.args()
.proof_size()
.unwrap_or_else(|| instantiate_result.gas_required.proof_size());
Ok(Weight::from_parts(ref_time, proof_size))
}
Err(ref err) => {
let object = ErrorVariant::from_dispatch_error(
err,
&instantiate_exec.client().metadata(),
)?;
if instantiate_exec.output_json() {
Err(anyhow!("{}", serde_json::to_string_pretty(&object)?))
} else {
name_value_println!("Result", object, MAX_KEY_COL_WIDTH);
display_contract_exec_result::<_, MAX_KEY_COL_WIDTH>(
&instantiate_result,
)?;

Err(anyhow!("Pre-submission dry-run failed. Use --skip-dry-run to skip this step."))
}
}
}
}

/// A helper function to estimate the gas required for a contract call.
pub async fn pre_submit_dry_run_gas_estimate_call(
call_exec: &CallExec,
) -> Result<Weight> {
if call_exec.opts().skip_dry_run() {
return match (call_exec.gas_limit(), call_exec.proof_size()) {
(Some(ref_time), Some(proof_size)) => Ok(Weight::from_parts(ref_time, proof_size)),
_ => {
Err(anyhow!(
"Weight args `--gas` and `--proof-size` required if `--skip-dry-run` specified"
))
}
};
}
if !call_exec.output_json() {
print_dry_running_status(call_exec.message());
}
let call_result = call_exec.call_dry_run().await?;
match call_result.result {
Ok(_) => {
if !call_exec.output_json() {
print_gas_required_success(call_result.gas_required);
}
// use user specified values where provided, otherwise use the estimates
let ref_time = call_exec
.gas_limit()
.unwrap_or_else(|| call_result.gas_required.ref_time());
let proof_size = call_exec
.proof_size()
.unwrap_or_else(|| call_result.gas_required.proof_size());
Ok(Weight::from_parts(ref_time, proof_size))
}
Err(ref err) => {
let object =
ErrorVariant::from_dispatch_error(err, &call_exec.client().metadata())?;
if call_exec.output_json() {
Err(anyhow!("{}", serde_json::to_string_pretty(&object)?))
} else {
name_value_println!("Result", object, MAX_KEY_COL_WIDTH);
display_contract_exec_result::<_, MAX_KEY_COL_WIDTH>(&call_result)?;

Err(anyhow!("Pre-submission dry-run failed. Use --skip-dry-run to skip this step."))
}
}
}
}
18 changes: 2 additions & 16 deletions crates/extrinsics/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

use super::{
account_id,
display_contract_exec_result,
events::DisplayEvents,
runtime_api::api,
state,
Expand All @@ -34,7 +33,6 @@ use super::{
StorageDeposit,
TokenMetadata,
DEFAULT_KEY_COL_WIDTH,
MAX_KEY_COL_WIDTH,
};

use anyhow::{
Expand Down Expand Up @@ -299,7 +297,7 @@ impl CallExec {
// use user specified values where provided, otherwise estimate
let gas_limit = match gas_limit {
Some(gas_limit) => gas_limit,
None => self.estimate_gas(false).await?,
None => self.estimate_gas().await?,
};
tracing::debug!("calling contract {:?}", self.contract);
let token_metadata = TokenMetadata::query(&self.client).await?;
Expand Down Expand Up @@ -331,7 +329,7 @@ impl CallExec {
///
/// Returns the estimated gas weight of type [`Weight`] for contract calls, or an
/// error.
pub async fn estimate_gas(&self, print_to_terminal: bool) -> Result<Weight> {
pub async fn estimate_gas(&self) -> Result<Weight> {
if self.opts.skip_dry_run {
return match (self.gas_limit, self.proof_size) {
(Some(ref_time), Some(proof_size)) => Ok(Weight::from_parts(ref_time, proof_size)),
Expand All @@ -342,15 +340,9 @@ impl CallExec {
}
};
}
if !self.output_json && print_to_terminal {
super::print_dry_running_status(&self.message);
}
let call_result = self.call_dry_run().await?;
match call_result.result {
Ok(_) => {
if !self.output_json && print_to_terminal {
super::print_gas_required_success(call_result.gas_required);
}
// use user specified values where provided, otherwise use the estimates
let ref_time = self
.gas_limit
Expand All @@ -366,12 +358,6 @@ impl CallExec {
if self.output_json {
Err(anyhow!("{}", serde_json::to_string_pretty(&object)?))
} else {
if print_to_terminal {
name_value_println!("Result", object, MAX_KEY_COL_WIDTH);
display_contract_exec_result::<_, MAX_KEY_COL_WIDTH>(
&call_result,
)?;
}
Err(anyhow!("Pre-submission dry-run failed. Use --skip-dry-run to skip this step."))
}
}
Expand Down
30 changes: 14 additions & 16 deletions crates/extrinsics/src/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

use super::{
account_id,
display_contract_exec_result,
events::DisplayEvents,
runtime_api::api,
state,
Expand All @@ -34,7 +33,6 @@ use super::{
StorageDeposit,
TokenMetadata,
DEFAULT_KEY_COL_WIDTH,
MAX_KEY_COL_WIDTH,
};
use anyhow::{
anyhow,
Expand Down Expand Up @@ -277,13 +275,25 @@ impl InstantiateArgs {
self.storage_deposit_limit.map(Into::into)
}

pub fn constructor(&self) -> &str {
&self.constructor
}

pub fn code(&self) -> &Code {
&self.code
}

pub fn data(&self) -> &[u8] {
&self.data
}

pub fn gas_limit(&self) -> Option<u64> {
self.gas_limit
}

pub fn proof_size(&self) -> Option<u64> {
self.proof_size
}
}

pub struct InstantiateExec {
Expand Down Expand Up @@ -418,7 +428,7 @@ impl InstantiateExec {
// use user specified values where provided, otherwise estimate
let gas_limit = match gas_limit {
Some(gas_limit) => gas_limit,
None => self.estimate_gas(false).await?,
None => self.estimate_gas().await?,
};
match self.args.code.clone() {
Code::Upload(code) => self.instantiate_with_code(code, gas_limit).await,
Expand Down Expand Up @@ -499,7 +509,7 @@ impl InstantiateExec {
///
/// Returns the estimated gas weight of type [`Weight`] for contract instantiation, or
/// an error.
pub async fn estimate_gas(&self, print_to_terminal: bool) -> Result<Weight> {
pub async fn estimate_gas(&self) -> Result<Weight> {
if self.opts.skip_dry_run {
return match (self.args.gas_limit, self.args.proof_size) {
(Some(ref_time), Some(proof_size)) => Ok(Weight::from_parts(ref_time, proof_size)),
Expand All @@ -510,15 +520,9 @@ impl InstantiateExec {
}
};
}
if !self.output_json && print_to_terminal {
super::print_dry_running_status(&self.args.constructor);
}
let instantiate_result = self.instantiate_dry_run().await?;
match instantiate_result.result {
Ok(_) => {
if !self.output_json && print_to_terminal {
super::print_gas_required_success(instantiate_result.gas_required);
}
// use user specified values where provided, otherwise use the estimates
let ref_time = self
.args
Expand All @@ -536,12 +540,6 @@ impl InstantiateExec {
if self.output_json {
Err(anyhow!("{}", serde_json::to_string_pretty(&object)?))
} else {
if print_to_terminal {
name_value_println!("Result", object, MAX_KEY_COL_WIDTH);
display_contract_exec_result::<_, MAX_KEY_COL_WIDTH>(
&instantiate_result,
)?;
}
Err(anyhow!("Pre-submission dry-run failed. Use --skip-dry-run to skip this step."))
}
}
Expand Down
9 changes: 7 additions & 2 deletions crates/extrinsics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub use balance::{
pub use call::{
CallCommand,
CallDryRunResult,
CallExec,
CallRequest,
};
use contract_metadata::ContractMetadata;
Expand Down Expand Up @@ -336,6 +337,10 @@ impl ExtrinsicOpts {
pub fn skip_confirm(&self) -> bool {
self.skip_confirm
}

pub fn skip_dry_run(&self) -> bool {
self.skip_dry_run
}
}

impl Default for ExtrinsicOpts {
Expand Down Expand Up @@ -597,7 +602,7 @@ pub fn prompt_confirm_tx<F: FnOnce()>(show_details: F) -> Result<()> {
}
}

fn print_dry_running_status(msg: &str) {
pub fn print_dry_running_status(msg: &str) {
println!(
"{:>width$} {} (skip with --skip-dry-run)",
"Dry-running".green().bold(),
Expand All @@ -606,7 +611,7 @@ fn print_dry_running_status(msg: &str) {
);
}

fn print_gas_required_success(gas: Weight) {
pub fn print_gas_required_success(gas: Weight) {
println!(
"{:>width$} Gas required estimated at {}",
"Success!".green().bold(),
Expand Down

0 comments on commit 24eb4d7

Please sign in to comment.