Skip to content

Commit 5a44121

Browse files
Merge pull request #92 from Didi-vi/automate_wasm
feat: Implement automated WASM compression for reduced deployment fees
2 parents 6c4fbdf + 2d449b4 commit 5a44121

File tree

5 files changed

+458
-4
lines changed

5 files changed

+458
-4
lines changed

.github/workflows/test.yml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ name: SubStream Contract Tests
22

33
on:
44
push:
5-
branches: [ "main" ]
5+
branches: ["main"]
66
pull_request:
7-
branches: [ "main" ]
7+
branches: ["main"]
88

99
env:
1010
CARGO_TERM_COLOR: always
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- uses: actions/checkout@v3
17-
17+
1818
- name: Install Rust
1919
uses: dtolnay/rust-toolchain@stable
2020
with:
@@ -29,9 +29,19 @@ jobs:
2929
find . -maxdepth 2 -name stellar -type f -exec sudo mv {} /usr/local/bin/ \;
3030
stellar --version
3131
32+
- name: Install Binaryen for WASM optimization
33+
run: |
34+
sudo apt-get update
35+
sudo apt-get install -y binaryen
36+
3237
- name: Build Contract
3338
run: cargo build --target wasm32-unknown-unknown --release
3439

40+
- name: Build and Compress WASM
41+
run: |
42+
cd contracts/substream_contracts
43+
make build-compressed
44+
3545
- name: Run Unit Tests
3646
run: cargo test
3747

@@ -41,9 +51,15 @@ jobs:
4151
- name: Run Code Coverage
4252
run: |
4353
cargo tarpaulin --out Lcov --output-dir coverage
44-
54+
4555
- name: Upload Coverage report
4656
uses: actions/upload-artifact@v3
4757
with:
4858
name: code-coverage-report
4959
path: coverage/lcov.info
60+
61+
- name: Upload Compressed WASM files
62+
uses: actions/upload-artifact@v3
63+
with:
64+
name: compressed-wasm
65+
path: contracts/substream_contracts/target/compressed/

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ If the fan dislikes the content, they can cancel instantly and get their remaini
1717
## Sybil Protection
1818

1919
To prevent users from rapidly starting/stopping streams to "scrape" content, the protocol enforces a **minimum flow duration of 24 hours**. Once a stream is initiated, it cannot be canceled until the minimum duration has elapsed. This protects creators from abuse and ensures meaningful engagement.
20+
2021
- **cancel**: Subscriber stops the stream and refunds unspent tokens.
2122
- **subscribe_group**: User streams to a group channel with exactly 5 creators and percentage splits that sum to 100.
2223
- **collect_group**: Contract automatically splits each collected amount to all 5 creators based on configured percentages.
@@ -63,3 +64,22 @@ To build the contract for Wasm:
6364
```bash
6465
cargo build --target wasm32-unknown-unknown --release
6566
```
67+
68+
### WASM Compression (Recommended for Deployment)
69+
70+
To reduce deployment fees, use the automated WASM compression:
71+
72+
```bash
73+
cd contracts/substream_contracts
74+
make build-compressed
75+
```
76+
77+
Or use the compression script:
78+
79+
```bash
80+
./scripts/compress_wasm.sh
81+
```
82+
83+
The compression system uses `wasm-opt` to optimize WASM binaries, typically reducing file sizes by 10-30%, which directly lowers deployment costs on Stellar.
84+
85+
See [WASM_COMPRESSION.md](./WASM_COMPRESSION.md) for detailed documentation.

WASM_COMPRESSION.md

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
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.

contracts/substream_contracts/Makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,27 @@ build:
99
stellar contract build
1010
@ls -l target/wasm32v1-none/release/*.wasm
1111

12+
build-compressed: build
13+
@echo "Compressing WASM files..."
14+
@mkdir -p target/compressed
15+
@for wasm_file in target/wasm32v1-none/release/*.wasm; do \
16+
if [ -f "$$wasm_file" ]; then \
17+
basename=$$(basename "$$wasm_file" .wasm); \
18+
echo "Optimizing $$basename.wasm..."; \
19+
wasm-opt -Oz --vacuum --dae --remove-unused-names --remove-unused-types --merge-blocks "$$wasm_file" -o "target/compressed/$$basename.optimized.wasm"; \
20+
original_size=$$(wc -c < "$$wasm_file"); \
21+
compressed_size=$$(wc -c < "target/compressed/$$basename.optimized.wasm"); \
22+
reduction=$$((($$original_size - $$compressed_size) * 100 / $$original_size)); \
23+
echo "Original: $$original_size bytes, Compressed: $$compressed_size bytes, Reduction: $$reduction%"; \
24+
fi; \
25+
done
26+
@ls -l target/compressed/*.optimized.wasm
27+
1228
fmt:
1329
cargo fmt --all
1430

1531
clean:
1632
cargo clean
33+
rm -rf target/compressed
34+
35+
.PHONY: build-compressed

0 commit comments

Comments
 (0)