|
| 1 | +# W3F Grant Proposal |
| 2 | + |
| 3 | +- **Project Name:** `wasm-opt` for Rust |
| 4 | +- **Team Name:** Common Orbit LLC |
| 5 | +- **Payment Address:** (Polkadot aUSD) 143W7CfR2R1dbATX3RVtrYfDXUMju1ua9pQh9B3DpLsuuB5M |
| 6 | +- **[Level](https://github.com/w3f/Grants-Program/tree/master#level_slider-levels):** 2 |
| 7 | + |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +## Project Overview :page_facing_up: |
| 12 | + |
| 13 | +### Overview |
| 14 | + |
| 15 | +This project makes the [`wasm-opt`] tool more accessible to Rust programmers. |
| 16 | +`wasm-opt` is a [WebAssembly] optimizer and is required by most software toolchains that |
| 17 | +produce WebAssembly binaries. |
| 18 | + |
| 19 | +[`wasm-opt`]: https://rustwasm.github.io/book/reference/tools.html#wasm-opt--a-hrefhttpsgithubcomwebassemblybinaryenrepositorya |
| 20 | +[WebAssembly]: https://webassembly.org/ |
| 21 | + |
| 22 | +This project is to package `wasm-opt` as a cargo crate, |
| 23 | +so that it can be installed by typing |
| 24 | + |
| 25 | +> `cargo install wasm-opt` |
| 26 | +
|
| 27 | +Additionally, it will provide a Rust API so that toolchain developers may, |
| 28 | +if they desire, call `wasm-opt` programmatically, |
| 29 | +so that their users are not required to manually install the tool. |
| 30 | + |
| 31 | +`wasm-opt` is a part of the [binaryen] toolset, written in C++. |
| 32 | +It is almost universally required by all toolchains that compile to WebAssembly. |
| 33 | +It is required by Parity's [`cargo-contract`] tool for [ink!] development. |
| 34 | + |
| 35 | +[binaryen]: https://github.com/WebAssembly/binaryen |
| 36 | +[`cargo-contract`]: https://github.com/paritytech/cargo-contract |
| 37 | +[ink!]: https://github.com/paritytech/ink |
| 38 | + |
| 39 | +**This tool can not be aquired in the way Rust programmers expect — with `cargo install`.** |
| 40 | +Installation of the tool is system-dependent. |
| 41 | +Many system package managers have some version of it, |
| 42 | +in some cases an old version; |
| 43 | +or it can be downloaded in binary form for most platforms, from GitHub, |
| 44 | +in which case it has to be extracted and added to the environment `PATH` variable in an ad-hoc way. |
| 45 | + |
| 46 | +In [our personal experience][wasmexp], aquiring this tool was a minor, but needless, barrier, to programming with [ink!]. |
| 47 | + |
| 48 | +[wasmexp]: #appendix-the-wasm-opt-installation-experience |
| 49 | + |
| 50 | +In the course of this grant `cargo-contract` will receive pull requests |
| 51 | +to optionally enable both the following: |
| 52 | + |
| 53 | +1) recommend installation via `cargo install wasm-opt` |
| 54 | +2) use `wasm-opt` via API and not require installation. |
| 55 | + |
| 56 | + |
| 57 | + |
| 58 | + |
| 59 | +### Project Details |
| 60 | + |
| 61 | +Note that although `wasm-opt` comes from the binaryen suite of tools, |
| 62 | +this project is only focused on `wasm-opt`. |
| 63 | +All other binaryen tools are out of scope. |
| 64 | +If this project is successful and there is demand, |
| 65 | +future work can extend the technique to the rest of binaryen. |
| 66 | + |
| 67 | +This project is technically straightforward. |
| 68 | +The main complication is that within `cargo` it is not possible to install binaries that were not produced |
| 69 | +directly by the Rust compiler. |
| 70 | +This means that it is not possible to simply build `wasm-opt` in a build script, then have `cargo` install it. |
| 71 | + |
| 72 | +This is the basic approach we will take, for the executable: |
| 73 | + |
| 74 | +- a `wasm-opt-sys` crate builds the C++ code for `wasm-opt` |
| 75 | +- the C++ source is built with only the C++ compiler all Rust users will have installed, |
| 76 | + no CMake or other build-system dependency |
| 77 | +- the C++ `wasm-opt` source is minimally-patched to export its `main` function with C ABI to be called from Rust |
| 78 | +- a `wasm-opt` crate contains a tiny Rust module that calls the C `wasm-opt` main function |
| 79 | + |
| 80 | +We have prototyped the project sufficiently to believe the described approach will succeed. |
| 81 | + |
| 82 | +For the library bindings: |
| 83 | + |
| 84 | +- `wasm-opt-sys` will export low-level Rust bindings with the help of one |
| 85 | + of the common C++-integration crates, likely `cxx` |
| 86 | +- `wasm-opt` will provide an idiomatic Rust wrapper that exposes the necessary `wasm-opt` options programmatically |
| 87 | + |
| 88 | +We will also deliver the following: |
| 89 | + |
| 90 | +- Full README and API documentation |
| 91 | +- Basic regression tests for the binary and library |
| 92 | +- CI for the platforms |
| 93 | + - `aarch64-apple-darwin` |
| 94 | + - `aarch64-unknown-linux-gnu` |
| 95 | + - `i686-pc-windows-msvc` |
| 96 | + - `i686-unknown-linux-gnu` |
| 97 | + - `x86_64-apple-darwin` |
| 98 | + - `x86_64-pc-windows-msvc` |
| 99 | + - `x86_64-unknown-linux-gnu` |
| 100 | +- Pull requests adding optional support for the `wasm-opt` crate to |
| 101 | + - `cargo-contract`, the ink! build tool |
| 102 | +- One blog post about the tool and its development, at https://brson.github.io |
| 103 | + |
| 104 | + |
| 105 | + |
| 106 | + |
| 107 | +### Ecosystem Fit |
| 108 | + |
| 109 | +This project is immediately useful to all Rust developers that build for wasm. |
| 110 | + |
| 111 | +It is more specifically useful to developers of Rust-based toolchains that target wasm, |
| 112 | +and most specifically the `cargo-contract` tool used to compile ink! programs. |
| 113 | +It is probably relevant to authors of Substrate runtimes as well, |
| 114 | +though we do not have that experience yet. |
| 115 | + |
| 116 | + |
| 117 | +#### Prior Work and Alternatives |
| 118 | + |
| 119 | +There are existing [Rust bindings for binaryen][brs]. |
| 120 | +As-is they don't provide a route to installing `wasm-opt` via cargo. |
| 121 | +It is unclear if they provide the APIs needed to expose `wasm-opt` programmatically, |
| 122 | +though they probably do. |
| 123 | +These bindings appear to rely on CMake to build. |
| 124 | +We do not expect to use them directly, but may reference them during development. |
| 125 | + |
| 126 | +[brs]: https://github.com/pepyakin/binaryen-rs |
| 127 | + |
| 128 | +The [`cargo-wasi`] tool takes a [different strategy][cws] to acquiring `wasm-opt`. |
| 129 | +It automatically downloads the `wasm-opt` binary, presumably from the official releases. |
| 130 | +Other wasm toolchains like `cargo-contract` could follow a similar strategy, |
| 131 | +possibly by extracting the existing logic from `cargo-wasi`. |
| 132 | + |
| 133 | +[`cargo-wasi`]: https://github.com/bytecodealliance/cargo-wasi |
| 134 | +[cws]: https://bytecodealliance.github.io/cargo-wasi/wasm-opt.html#which-wasm-opt-executed |
| 135 | + |
| 136 | + |
| 137 | + |
| 138 | + |
| 139 | + |
| 140 | +## Team :busts_in_silhouette: |
| 141 | + |
| 142 | +### Team members |
| 143 | + |
| 144 | +- **Team lead:** [Brian Anderson](https://github.com/brson) |
| 145 | +- **Team member:** [Aimee Zhu](https://github.com/aimeedeer) |
| 146 | + |
| 147 | +### Contact |
| 148 | + |
| 149 | +- **Contact Name:** Brian Anderson |
| 150 | +- **Contact Email: ** [email protected] |
| 151 | +- **Website:** https://brson.github.io |
| 152 | + |
| 153 | +### Legal Structure |
| 154 | + |
| 155 | +- **Registered Address:** 16192 Coastal Highway, Lewes, Delaware 19958 |
| 156 | +- **Registered Legal Entity:** Common Orbit LLC |
| 157 | + |
| 158 | +### Team's experience |
| 159 | + |
| 160 | +The team lead is one of the original authors of the Rust programming language, |
| 161 | +with 12 years of Rust experience. |
| 162 | +They have performed Rust work for Mozilla, Reddit, PingCAP, Solana, MobileCoin, Parity, and Nervos. |
| 163 | +Both team members are maintainers of the [Rust in Blockchain](https://rustinblockchain.org/) newsletter. |
| 164 | + |
| 165 | +### Team Code Repos |
| 166 | + |
| 167 | +- https://github.com/brson/wasm-opt-rs |
| 168 | +- https://github.com/brson |
| 169 | +- https://github.com/aimeedeer |
| 170 | + |
| 171 | +### Team LinkedIn Profiles (if available) |
| 172 | + |
| 173 | +N/A |
| 174 | + |
| 175 | + |
| 176 | + |
| 177 | + |
| 178 | +## Development Status :open_book: |
| 179 | + |
| 180 | +https://github.com/brson/wasm-opt-rs |
| 181 | + |
| 182 | +We have created the initial project layout and investigated the feasibility of building the binaryen codebase using only the [`cc`] crate, |
| 183 | +as well as the feasibility of trivially calling the `wasm-opt` `main` function from Rust as described. |
| 184 | + |
| 185 | +[`cc`]: https://docs.rs/cc/latest/cc/ |
| 186 | + |
| 187 | +We have reserved the `wasm-opt` and `wasm-opt-sys` crate names on crates.io. |
| 188 | + |
| 189 | + |
| 190 | + |
| 191 | + |
| 192 | +## Development Roadmap :nut_and_bolt: |
| 193 | + |
| 194 | +### Overview |
| 195 | + |
| 196 | +- **Total Estimated Duration:** 3-4 months |
| 197 | +- **Full-Time Equivalent (FTE):** 0.4 |
| 198 | +- **Total Costs:** 30,000 USD |
| 199 | + |
| 200 | +This will be a part time effort. |
| 201 | +I have divided this into two logical milestones, |
| 202 | +though in reality the work will overlap. |
| 203 | + |
| 204 | + |
| 205 | +### Milestone 1 — Proof of Concept |
| 206 | + |
| 207 | +- **Estimated duration:** 1-2 month |
| 208 | +- **FTE:** 0.4 |
| 209 | +- **Costs:** 15,000 USD |
| 210 | + |
| 211 | +During this phase we will prove the concept and produce a `wasm-opt` Rust binary and API. |
| 212 | + |
| 213 | +| Number | Deliverable | Specification | |
| 214 | +| -----: | ----------- | ------------- | |
| 215 | +| 0a. | License | MIT / Apache-2.0 | |
| 216 | +| 0b. | Documentation | Basic README. | |
| 217 | +| 0c. | Testing Guide | Manual smoke testing on Linux, Windows, and MacOS, x86_64 and ARM. | |
| 218 | +| 0d. | Docker | Docker is not required for this project. | |
| 219 | +| 1. | `wasm-opt` binary | Produce a `wasm-opt` binary that can be built by cargo but is otherwise identical to stock `wasm-opt`. | |
| 220 | +| 2. | APIs | Write an idiomatic, but possibly incomplete, Rust API for loading wasm, optimizing it, and writing it again. | |
| 221 | + |
| 222 | + |
| 223 | +### Milestone 2 — Integration |
| 224 | + |
| 225 | +- **Estimated duration:** 1-2 month |
| 226 | +- **FTE:** 0.4 |
| 227 | +- **Costs:** 15,000 USD |
| 228 | + |
| 229 | +During this phase we will prepare the project for production and integrate it with `cargo-contract`. |
| 230 | + |
| 231 | +| Number | Deliverable | Specification | |
| 232 | +| -----: | ----------- | ------------- | |
| 233 | +| 0a. | License | MIT / Apache-2.0 | |
| 234 | +| 0b. | Documentation | Full README and API docs. | |
| 235 | +| 0c. | Testing Guide | Basic integration tests for both binary and library. | |
| 236 | +| 0d. | Docker | Docker is not required for this project. | |
| 237 | +| 0e. | Article | Publish a technical blog post about how the project was developed and indicating it is available for use. | |
| 238 | +| 1. | APIs | Ensure the APIs expose all the `wasm-opt` options, and can be easily integrated into tools like `cargo-contract`. | |
| 239 | +| 2. | `cargo-contract` integration | Submit a PR to `cargo-contract` that integrates the `wasm-opt` crate. | |
| 240 | +| 3. | CI | Set up CI for all indicated platforms. | |
| 241 | + |
| 242 | + |
| 243 | + |
| 244 | + |
| 245 | +## Future Plans |
| 246 | + |
| 247 | +Upon completion of this project we will pursue a maintainence grant |
| 248 | +to supply hourly funds for maintenance of this project. |
| 249 | +We expect maintenance to be minimal, |
| 250 | +primarily updating the code and making new releases to match upstream binaryen releases, |
| 251 | +and responding to issue reports. |
| 252 | + |
| 253 | +We are interested in pursuing a pure-Rust alternative to `wasm-opt` with a limited |
| 254 | +focus of quickly shrinking wasm binaries. |
| 255 | + |
| 256 | +We expect to pursue additional projects related to ink! and Substrate. |
| 257 | + |
| 258 | + |
| 259 | + |
| 260 | + |
| 261 | +## Appendix: The `wasm-opt` installation experience |
| 262 | + |
| 263 | +Upon calling `cargo-contract build` without `wasm-opt` installed |
| 264 | +the build errors with this long explanation: |
| 265 | + |
| 266 | +``` |
| 267 | +ERROR: wasm-opt not found! Make sure the binary is in your PATH environment. |
| 268 | +
|
| 269 | +We use this tool to optimize the size of your contract's Wasm binary. |
| 270 | +
|
| 271 | +wasm-opt is part of the binaryen package. You can find detailed |
| 272 | +installation instructions on https://github.com/WebAssembly/binaryen#tools. |
| 273 | +
|
| 274 | +There are ready-to-install packages for many platforms: |
| 275 | +* Debian/Ubuntu: apt-get install binaryen |
| 276 | +* Homebrew: brew install binaryen |
| 277 | +* Arch Linux: pacman -S binaryen |
| 278 | +* Windows: binary releases at https://github.com/WebAssembly/binaryen/releases |
| 279 | +``` |
| 280 | + |
| 281 | +Despite the effort to explain how to install this tool, |
| 282 | +following the instructions on our system resulted in an old version of `wasm-opt` |
| 283 | +and `cargo-contract` produced a new error: |
| 284 | + |
| 285 | +``` |
| 286 | +ERROR: Your wasm-opt version is 91, but we require a version >= 99. |
| 287 | +
|
| 288 | +If you tried installing from your system package manager the best |
| 289 | +way forward is to download a recent binary release directly: |
| 290 | +
|
| 291 | +https://github.com/WebAssembly/binaryen/releases |
| 292 | +
|
| 293 | +Make sure that the `wasm-opt` file from that release is in your `PATH`. |
| 294 | +``` |
| 295 | + |
| 296 | +This actually did about the best that could be expected to help us |
| 297 | +get set up, and we did end up downloading the binary tarball, |
| 298 | +extracting it, and modifying our path. |
| 299 | +But the experience could be better. |
0 commit comments