Skip to content

Commit 4cdb254

Browse files
authored
Deprecate stellar contract optimize in favor of stellar contract build --optimize. (#2241)
1 parent 4198835 commit 4cdb254

6 files changed

Lines changed: 157 additions & 71 deletions

File tree

FULL_HELP_DOCS.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,11 @@ Tools for smart contract developers
8989
- `id` — Generate the contract id for a given contract or asset
9090
- `info` — Access info about contracts
9191
- `init` — Initialize a Soroban contract project
92-
- `inspect` — (Deprecated in favor of `contract info` subcommand) Inspect a WASM file listing contract functions, meta, etc
92+
- `inspect` — (Deprecated, use `contract info`) Inspect a WASM file listing contract functions, meta, etc
9393
- `upload` — Install a WASM file to the ledger without creating a contract instance
94-
- `install` — (Deprecated in favor of `contract upload` subcommand) Install a WASM file to the ledger without creating a contract instance
94+
- `install` — (Deprecated, use `contract upload`) Install a WASM file to the ledger without creating a contract instance
9595
- `invoke` — Invoke a contract function
96-
- `optimize` — Optimize a WASM file
96+
- `optimize`(Deprecated, use `build --optimize`) Optimize a WASM file
9797
- `read` — Print the current value of a contract-data ledger entry
9898
- `restore` — Restore an evicted value for a contract-data legder entry
9999

@@ -357,6 +357,7 @@ To view the commands that will be executed, without executing them, use the --pr
357357

358358
- `--print-commands-only` — Print commands to build without executing them
359359
- `--meta <META>` — Add key-value to contract meta (adds the meta to the `contractmetav0` custom section)
360+
- `--optimize` — Optimize the generated wasm
360361

361362
## `stellar contract extend`
362363

@@ -661,7 +662,7 @@ This command will create a Cargo workspace project and add a sample Stellar cont
661662

662663
## `stellar contract inspect`
663664

664-
(Deprecated in favor of `contract info` subcommand) Inspect a WASM file listing contract functions, meta, etc
665+
(Deprecated, use `contract info`) Inspect a WASM file listing contract functions, meta, etc
665666

666667
**Usage:** `stellar contract inspect [OPTIONS] --wasm <WASM>`
667668

@@ -713,7 +714,7 @@ Install a WASM file to the ledger without creating a contract instance
713714

714715
## `stellar contract install`
715716

716-
(Deprecated in favor of `contract upload` subcommand) Install a WASM file to the ledger without creating a contract instance
717+
(Deprecated, use `contract upload`) Install a WASM file to the ledger without creating a contract instance
717718

718719
**Usage:** `stellar contract install [OPTIONS] --source-account <SOURCE_ACCOUNT> --wasm <WASM>`
719720

@@ -789,7 +790,7 @@ stellar contract invoke ... -- --help
789790

790791
## `stellar contract optimize`
791792

792-
Optimize a WASM file
793+
(Deprecated, use `build --optimize`) Optimize a WASM file
793794

794795
**Usage:** `stellar contract optimize [OPTIONS] --wasm <WASM>...`
795796

cmd/soroban-cli/src/commands/contract/build.rs

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ use std::{
1717
};
1818
use stellar_xdr::curr::{Limited, Limits, ScMetaEntry, ScMetaV0, StringM, WriteXdr};
1919

20-
use crate::{commands::global, print::Print};
20+
use crate::{
21+
commands::{contract::optimize, global},
22+
print::Print,
23+
wasm,
24+
};
2125

2226
/// Build a contract from source
2327
///
@@ -32,6 +36,7 @@ use crate::{commands::global, print::Print};
3236
/// To view the commands that will be executed, without executing them, use the
3337
/// --print-commands-only option.
3438
#[derive(Parser, Debug, Clone)]
39+
#[allow(clippy::struct_excessive_bools)]
3540
pub struct Cmd {
3641
/// Path to Cargo.toml
3742
#[arg(long)]
@@ -41,12 +46,15 @@ pub struct Cmd {
4146
/// If omitted, all packages that build for crate-type cdylib are built.
4247
#[arg(long)]
4348
pub package: Option<String>,
49+
4450
/// Build with the specified profile
4551
#[arg(long, default_value = "release")]
4652
pub profile: String,
53+
4754
/// Build with the list of features activated, space or comma separated
4855
#[arg(long, help_heading = "Features")]
4956
pub features: Option<String>,
57+
5058
/// Build with the all features activated
5159
#[arg(
5260
long,
@@ -55,9 +63,11 @@ pub struct Cmd {
5563
help_heading = "Features"
5664
)]
5765
pub all_features: bool,
66+
5867
/// Build with the default feature not activated
5968
#[arg(long, help_heading = "Features")]
6069
pub no_default_features: bool,
70+
6171
/// Directory to copy wasm files to
6272
///
6373
/// If provided, wasm files can be found in the cargo target directory, and
@@ -66,12 +76,18 @@ pub struct Cmd {
6676
/// If ommitted, wasm files are written only to the cargo target directory.
6777
#[arg(long)]
6878
pub out_dir: Option<std::path::PathBuf>,
79+
6980
/// Print commands to build without executing them
7081
#[arg(long, conflicts_with = "out_dir", help_heading = "Other")]
7182
pub print_commands_only: bool,
83+
7284
/// Add key-value to contract meta (adds the meta to the `contractmetav0` custom section)
7385
#[arg(long, num_args=1, value_parser=parse_meta_arg, action=clap::ArgAction::Append, help_heading = "Metadata")]
7486
pub meta: Vec<(String, String)>,
87+
88+
/// Optimize the generated wasm.
89+
#[arg(long)]
90+
pub optimize: bool,
7591
}
7692

7793
fn parse_meta_arg(s: &str) -> Result<(String, String), Error> {
@@ -89,34 +105,54 @@ fn parse_meta_arg(s: &str) -> Result<(String, String), Error> {
89105
pub enum Error {
90106
#[error(transparent)]
91107
Metadata(#[from] cargo_metadata::Error),
108+
92109
#[error(transparent)]
93110
CargoCmd(io::Error),
111+
94112
#[error("exit status {0}")]
95113
Exit(ExitStatus),
114+
96115
#[error("package {package} not found")]
97116
PackageNotFound { package: String },
117+
98118
#[error("finding absolute path of Cargo.toml: {0}")]
99119
AbsolutePath(io::Error),
120+
100121
#[error("creating out directory: {0}")]
101122
CreatingOutDir(io::Error),
123+
102124
#[error("deleting existing artifact: {0}")]
103125
DeletingArtifact(io::Error),
126+
104127
#[error("copying wasm file: {0}")]
105128
CopyingWasmFile(io::Error),
129+
106130
#[error("getting the current directory: {0}")]
107131
GettingCurrentDir(io::Error),
132+
108133
#[error("retreiving CARGO_HOME: {0}")]
109134
CargoHome(io::Error),
135+
110136
#[error("reading wasm file: {0}")]
111137
ReadingWasmFile(io::Error),
138+
112139
#[error("writing wasm file: {0}")]
113140
WritingWasmFile(io::Error),
141+
114142
#[error("invalid meta entry: {0}")]
115143
MetaArg(String),
144+
116145
#[error("use rust 1.81 or 1.84+ to build contracts (got {0})")]
117146
RustVersion(String),
147+
118148
#[error(transparent)]
119149
Xdr(#[from] stellar_xdr::curr::Error),
150+
151+
#[error(transparent)]
152+
Optimize(#[from] optimize::Error),
153+
154+
#[error(transparent)]
155+
Wasm(#[from] wasm::Error),
120156
}
121157

122158
const WASM_TARGET: &str = "wasm32v1-none";
@@ -202,7 +238,8 @@ impl Cmd {
202238
return Err(Error::Exit(status));
203239
}
204240

205-
let file = format!("{}.wasm", p.name.replace('-', "_"));
241+
let wasm_name = p.name.replace('-', "_");
242+
let file = format!("{wasm_name}.wasm");
206243
let target_file_path = Path::new(target_dir)
207244
.join(&wasm_target)
208245
.join(&self.profile)
@@ -219,7 +256,20 @@ impl Cmd {
219256
target_file_path
220257
};
221258

222-
Self::print_build_summary(&print, &final_path)?;
259+
let wasm_bytes = fs::read(&final_path).map_err(Error::ReadingWasmFile)?;
260+
let mut optimized_wasm_bytes: Vec<u8> = Vec::new();
261+
262+
if self.optimize {
263+
let mut path = final_path.clone();
264+
path.set_extension("optimized.wasm");
265+
optimize::optimize(true, vec![final_path.clone()], Some(path.clone()))?;
266+
optimized_wasm_bytes = fs::read(&path).map_err(Error::ReadingWasmFile)?;
267+
268+
fs::remove_file(&final_path).map_err(Error::DeletingArtifact)?;
269+
fs::rename(&path, &final_path).map_err(Error::CopyingWasmFile)?;
270+
}
271+
272+
Self::print_build_summary(&print, &final_path, wasm_bytes, optimized_wasm_bytes);
223273
}
224274
}
225275

@@ -332,20 +382,41 @@ impl Cmd {
332382
Ok(buffer)
333383
}
334384

335-
fn print_build_summary(print: &Print, target_file_path: &PathBuf) -> Result<(), Error> {
385+
fn print_build_summary(
386+
print: &Print,
387+
path: &Path,
388+
wasm_bytes: Vec<u8>,
389+
optimized_wasm_bytes: Vec<u8>,
390+
) {
336391
print.infoln("Build Summary:");
337-
let rel_target_file_path = target_file_path
392+
393+
let rel_path = path
338394
.strip_prefix(env::current_dir().unwrap())
339-
.unwrap_or(target_file_path);
340-
print.blankln(format!("Wasm File: {}", rel_target_file_path.display()));
395+
.unwrap_or(path);
396+
397+
let size = wasm_bytes.len();
398+
let optimized_size = optimized_wasm_bytes.len();
399+
400+
let size_description = if optimized_size > 0 {
401+
format!("{optimized_size} bytes optimized (original size was {size} bytes)")
402+
} else {
403+
format!("{size} bytes")
404+
};
341405

342-
let wasm_bytes = fs::read(target_file_path).map_err(Error::ReadingWasmFile)?;
406+
let bytes = if optimized_size > 0 {
407+
&optimized_wasm_bytes
408+
} else {
409+
&wasm_bytes
410+
};
343411

344412
print.blankln(format!(
345-
"Wasm Hash: {}",
346-
hex::encode(Sha256::digest(&wasm_bytes))
413+
"Wasm File: {path} ({size_description})",
414+
path = rel_path.display()
347415
));
348416

417+
print.blankln(format!("Wasm Hash: {}", hex::encode(Sha256::digest(bytes))));
418+
print.blankln(format!("Wasm Size: {size_description}"));
419+
349420
let parser = wasmparser::Parser::new(0);
350421
let export_names: Vec<&str> = parser
351422
.parse_all(&wasm_bytes)
@@ -363,6 +434,7 @@ impl Cmd {
363434
.map(|export| export.name)
364435
.sorted()
365436
.collect();
437+
366438
if export_names.is_empty() {
367439
print.blankln("Exported Functions: None found");
368440
} else {
@@ -371,9 +443,8 @@ impl Cmd {
371443
print.blankln(format!(" • {name}"));
372444
}
373445
}
374-
print.checkln("Build Complete");
375446

376-
Ok(())
447+
print.checkln("Build Complete\n");
377448
}
378449
}
379450

cmd/soroban-cli/src/commands/contract/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ pub enum Cmd {
6161
/// be overwritten unless `--overwrite` is passed.
6262
Init(init::Cmd),
6363

64-
/// (Deprecated in favor of `contract info` subcommand) Inspect a WASM file listing contract functions, meta, etc
64+
/// (Deprecated, use `contract info`) Inspect a WASM file listing contract functions, meta, etc
6565
#[command(display_order = 100)]
6666
Inspect(inspect::Cmd),
6767

6868
/// Install a WASM file to the ledger without creating a contract instance
6969
Upload(upload::Cmd),
7070

71-
/// (Deprecated in favor of `contract upload` subcommand) Install a WASM file to the ledger without creating a contract instance
71+
/// (Deprecated, use `contract upload`) Install a WASM file to the ledger without creating a contract instance
7272
Install(upload::Cmd),
7373

7474
/// Invoke a contract function
@@ -81,7 +81,7 @@ pub enum Cmd {
8181
/// stellar contract invoke ... -- --help
8282
Invoke(invoke::Cmd),
8383

84-
/// Optimize a WASM file
84+
/// (Deprecated, use `build --optimize`) Optimize a WASM file
8585
Optimize(optimize::Cmd),
8686

8787
/// Print the current value of a contract-data ledger entry
@@ -165,7 +165,7 @@ impl Cmd {
165165
}
166166
Cmd::Upload(upload) => upload.run(global_args).await?,
167167
Cmd::Invoke(invoke) => invoke.run(global_args).await?,
168-
Cmd::Optimize(optimize) => optimize.run()?,
168+
Cmd::Optimize(optimize) => optimize.run(global_args)?,
169169
Cmd::Fetch(fetch) => fetch.run().await?,
170170
Cmd::Read(read) => read.run().await?,
171171
Cmd::Restore(restore) => restore.run().await?,

0 commit comments

Comments
 (0)