|
| 1 | +# WASM Compression for SubStream Protocol Contracts |
| 2 | + |
| 3 | +This document describes the WASM compression implementation for SubStream Protocol Contracts, designed to reduce deployment fees on the Stellar network by optimizing contract binary sizes. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The WASM compression system uses `wasm-opt` from the Binaryen toolkit to apply aggressive optimizations to contract binaries, resulting in smaller WASM files that cost less to deploy on Stellar. |
| 8 | + |
| 9 | +## Features |
| 10 | + |
| 11 | +- **Aggressive Optimization**: Uses `wasm-opt -Oz` with additional optimization flags |
| 12 | +- **Size Reporting**: Shows before/after file sizes and compression percentages |
| 13 | +- **CI/CD Integration**: Automated compression in GitHub Actions |
| 14 | +- **Flexible Configuration**: Customizable optimization levels and output directories |
| 15 | +- **Multiple Contracts**: Handles all WASM files in the target directory |
| 16 | + |
| 17 | +## Tools Used |
| 18 | + |
| 19 | +- **Binaryen**: Provides `wasm-opt` for WASM optimization |
| 20 | +- **Stellar CLI**: Builds the contracts to WASM |
| 21 | +- **Make**: Automation of build and compression steps |
| 22 | + |
| 23 | +## Installation |
| 24 | + |
| 25 | +### Local Development |
| 26 | + |
| 27 | +1. Install Binaryen: |
| 28 | + ```bash |
| 29 | + # macOS |
| 30 | + brew install binaryen |
| 31 | + |
| 32 | + # Ubuntu/Debian |
| 33 | + sudo apt-get install binaryen |
| 34 | + |
| 35 | + # Other platforms |
| 36 | + # Download from https://github.com/WebAssembly/binaryen/releases |
| 37 | + ``` |
| 38 | + |
| 39 | +2. Verify installation: |
| 40 | + ```bash |
| 41 | + wasm-opt --version |
| 42 | + ``` |
| 43 | + |
| 44 | +### CI/CD |
| 45 | + |
| 46 | +The GitHub Actions workflow automatically installs Binaryen for WASM optimization. |
| 47 | + |
| 48 | +## Usage |
| 49 | + |
| 50 | +### Command Line |
| 51 | + |
| 52 | +#### Using the Makefile (Recommended) |
| 53 | + |
| 54 | +```bash |
| 55 | +# Build and compress in one step |
| 56 | +cd contracts/substream_contracts |
| 57 | +make build-compressed |
| 58 | + |
| 59 | +# Or build first, then compress |
| 60 | +make build |
| 61 | +make build-compressed |
| 62 | +``` |
| 63 | + |
| 64 | +#### Using the Compression Script |
| 65 | + |
| 66 | +```bash |
| 67 | +# Basic usage |
| 68 | +./scripts/compress_wasm.sh |
| 69 | + |
| 70 | +# With custom options |
| 71 | +./scripts/compress_wasm.sh \ |
| 72 | + --contract-dir contracts/substream_contracts \ |
| 73 | + --output-dir target/compressed \ |
| 74 | + --optimization-level Oz |
| 75 | + |
| 76 | +# Show help |
| 77 | +./scripts/compress_wasm.sh --help |
| 78 | +``` |
| 79 | + |
| 80 | +### Optimization Levels |
| 81 | + |
| 82 | +Available optimization levels for `wasm-opt`: |
| 83 | + |
| 84 | +- `O0`: No optimization (fastest compilation) |
| 85 | +- `O1`: Basic optimization |
| 86 | +- `O2`: More optimization |
| 87 | +- `O3`: Aggressive optimization |
| 88 | +- `Os`: Optimize for size |
| 89 | +- `Oz`: Optimize for size aggressively (recommended for deployment) |
| 90 | + |
| 91 | +### Optimization Flags Used |
| 92 | + |
| 93 | +The compression applies these optimization flags: |
| 94 | + |
| 95 | +- `-Oz`: Aggressive size optimization |
| 96 | +- `--vacuum`: Remove redundant items |
| 97 | +- `--dae`: Dead code elimination |
| 98 | +- `--remove-unused-names`: Remove unused names |
| 99 | +- `--remove-unused-types`: Remove unused types |
| 100 | +- `--merge-blocks`: Merge blocks |
| 101 | +- `--simplify-locals`: Simplify local variables |
| 102 | +- `--coalesce-locals`: Coalesce local variables |
| 103 | + |
| 104 | +## File Structure |
| 105 | + |
| 106 | +``` |
| 107 | +contracts/substream_contracts/ |
| 108 | +├── target/ |
| 109 | +│ ├── wasm32v1-none/release/ |
| 110 | +│ │ └── substream_contracts.wasm # Original WASM |
| 111 | +│ └── compressed/ |
| 112 | +│ └── substream_contracts.optimized.wasm # Compressed WASM |
| 113 | +├── Makefile # Build automation |
| 114 | +└── src/ |
| 115 | + └── lib.rs # Contract source |
| 116 | +``` |
| 117 | + |
| 118 | +## CI/CD Integration |
| 119 | + |
| 120 | +The GitHub Actions workflow (`.github/workflows/test.yml`) includes: |
| 121 | + |
| 122 | +1. **Binaryen Installation**: Installs `wasm-opt` and related tools |
| 123 | +2. **Contract Building**: Builds the contract using Stellar CLI |
| 124 | +3. **WASM Compression**: Runs the compression process |
| 125 | +4. **Artifact Upload**: Saves compressed WASM files as workflow artifacts |
| 126 | + |
| 127 | +### Workflow Steps |
| 128 | + |
| 129 | +```yaml |
| 130 | +- name: Install Binaryen for WASM optimization |
| 131 | + run: | |
| 132 | + sudo apt-get update |
| 133 | + sudo apt-get install -y binaryen |
| 134 | +
|
| 135 | +- name: Build and Compress WASM |
| 136 | + run: | |
| 137 | + cd contracts/substream_contracts |
| 138 | + make build-compressed |
| 139 | +
|
| 140 | +- name: Upload Compressed WASM files |
| 141 | + uses: actions/upload-artifact@v3 |
| 142 | + with: |
| 143 | + name: compressed-wasm |
| 144 | + path: contracts/substream_contracts/target/compressed/ |
| 145 | +``` |
| 146 | +
|
| 147 | +## Performance Impact |
| 148 | +
|
| 149 | +### Typical Compression Results |
| 150 | +
|
| 151 | +Based on similar Stellar contracts, you can expect: |
| 152 | +
|
| 153 | +- **Size Reduction**: 10-30% smaller WASM files |
| 154 | +- **Deployment Cost**: Proportional reduction in deployment fees |
| 155 | +- **Runtime Performance**: Minimal to no impact on execution speed |
| 156 | +- **Gas Costs**: No increase in transaction gas costs |
| 157 | +
|
| 158 | +### Example Output |
| 159 | +
|
| 160 | +``` |
| 161 | +🚀 SubStream Protocol WASM Compression Script |
| 162 | +============================================= |
| 163 | +🔨 Building contract... |
| 164 | +📦 Compressing WASM files with optimization level: Oz |
| 165 | + Optimizing substream_contracts.wasm... |
| 166 | + ✅ Original: 45678 bytes, Compressed: 34234 bytes, Reduction: 25% |
| 167 | +🎉 Compression complete! |
| 168 | +📊 Summary: |
| 169 | + Total original size: 45678 bytes |
| 170 | + Total compressed size: 34234 bytes |
| 171 | + Total reduction: 25% |
| 172 | + Compressed files saved to: target/compressed |
| 173 | +✨ Done! Your optimized WASM files are ready for deployment. |
| 174 | +``` |
| 175 | + |
| 176 | +## Best Practices |
| 177 | + |
| 178 | +### Development Workflow |
| 179 | + |
| 180 | +1. **Regular Builds**: Use `make build` during development |
| 181 | +2. **Pre-deployment**: Always use `make build-compressed` before deployment |
| 182 | +3. **Size Monitoring**: Track compression ratios over time |
| 183 | +4. **Testing**: Deploy compressed WASM to testnet first |
| 184 | + |
| 185 | +### Optimization Tips |
| 186 | + |
| 187 | +1. **Code Review**: Smaller source code often results in smaller WASM |
| 188 | +2. **Dependencies**: Minimize external dependencies |
| 189 | +3. **Feature Flags**: Use conditional compilation for unused features |
| 190 | +4. **Profile**: Use `cargo bloat` to identify large dependencies |
| 191 | + |
| 192 | +## Troubleshooting |
| 193 | + |
| 194 | +### Common Issues |
| 195 | + |
| 196 | +#### wasm-opt not found |
| 197 | +```bash |
| 198 | +# Install Binaryen |
| 199 | +brew install binaryen # macOS |
| 200 | +sudo apt-get install binaryen # Ubuntu |
| 201 | +``` |
| 202 | + |
| 203 | +#### Build fails |
| 204 | +```bash |
| 205 | +# Check Rust targets |
| 206 | +rustup target add wasm32v1-none |
| 207 | +rustup target add wasm32-unknown-unknown |
| 208 | +``` |
| 209 | + |
| 210 | +#### Permission denied |
| 211 | +```bash |
| 212 | +# Make script executable |
| 213 | +chmod +x scripts/compress_wasm.sh |
| 214 | +``` |
| 215 | + |
| 216 | +### Debug Mode |
| 217 | + |
| 218 | +For debugging, use lower optimization levels: |
| 219 | + |
| 220 | +```bash |
| 221 | +./scripts/compress_wasm.sh --optimization-level O1 |
| 222 | +``` |
| 223 | + |
| 224 | +## Integration with Deployment |
| 225 | + |
| 226 | +### Manual Deployment |
| 227 | + |
| 228 | +```bash |
| 229 | +# Build compressed WASM |
| 230 | +make build-compressed |
| 231 | + |
| 232 | +# Deploy using compressed file |
| 233 | +stellar contract deploy \ |
| 234 | + --wasm-file target/compressed/substream_contracts.optimized.wasm \ |
| 235 | + --source-account your_account \ |
| 236 | + --network testnet |
| 237 | +``` |
| 238 | + |
| 239 | +### Automated Deployment |
| 240 | + |
| 241 | +The compressed WASM files can be automatically deployed using the workflow artifacts: |
| 242 | + |
| 243 | +1. Download `compressed-wasm` artifact from GitHub Actions |
| 244 | +2. Extract the optimized WASM files |
| 245 | +3. Deploy using your preferred deployment tool |
| 246 | + |
| 247 | +## Contributing |
| 248 | + |
| 249 | +When contributing to the compression system: |
| 250 | + |
| 251 | +1. Test compression ratios with your changes |
| 252 | +2. Verify that compressed contracts still function correctly |
| 253 | +3. Update documentation for any new optimization flags |
| 254 | +4. Consider the impact on deployment costs |
| 255 | + |
| 256 | +## License |
| 257 | + |
| 258 | +This WASM compression implementation is part of the SubStream Protocol Contracts project and follows the same license terms. |
0 commit comments