-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce WASM size to fit into production chainspec #143
Conversation
i had experimented with this and had not had much luck. If you can get it to pass the contract tests I'm all for it. |
Make sure you use the code when judging the size, only code paths you use and ones that could be called by dyn trait make it into the optimized binary. Our contract also has std from risc0 transitive dependencies linked in. |
Looks good, any idea why we are running out of gas in the tests? |
Previously it was using 2500 (default), but it seems to be more costly after code-space optimization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Nice optimization.
@Avi-D-coder @marijanp Contract calls in test engine are using the default payment, which is 2500 CSPR. Since we optimized code for size, it might be more expensive to execute. I just measured it and previously the cost was 1043 CSPR, and after full size optimization it is 2756 CSPR 😨. For example just by setting Rust We should find a good balance between WASM size and cost of execution, but I think compatibility with the production chainspec is a priority here. Code used for testing: let cost = self
.builder
.get_last_exec_results()
.unwrap()
.get(0)
.unwrap()
.cost();
panic!("Cost of execution: {:?}", cost); |
Yup, I made unsuccessful verification trigger panic, so Risc0 code was definitely used there.
On the one hand Risc0 has a bug, where |
Hmm, that seems odd. |
I don't like |
Try borsh we could not get bincode working in the wasm contract, float related issue. |
Context
In Casper v1.5.6 maximum contract size is 1 MiB (1,048,576 bytes), which we fairly exceed with demo contract (1.4 MiB), therefore making Kairos incompatible with production network.
Can we reduce it?
I was suspecting that Risc0 verifier might be the biggest part of final WASM, so I did some tests on bare minimum contract. However, bare Risc0 verifier (+ bincode2 deserialization for receipt) is less than 20 KB 👾. Casper API calls are also quite small (few kilobytes), so it means we should be able to get way less than 1 MiB.
First easy optimization
Simple idea: we can enable more aggressive optimization in Rust complier and WASM optimizer.
I run benchmark for WASM produced by
nix build -L --no-link --show-trace .#packages.x86_64-linux.kairos-contracts
:o='s'
: 1004KiB (1,025,823 bytes)o='z'
: 904KiB (921,813 bytes)o='s'
: 1.3MiB (1,322,590 bytes)o='z'
: 1.3MiB (1,320,589 bytes)o='s'
and WASMo='s'
: 964KiB (985,116 bytes)o='s'
and WASMo='z'
: 964KiB (983,713 bytes)o='z'
and WASMo='s'
: 868KiB (886,560 bytes)o='z'
and WASMo='z'
: 868KiB (884,798 bytes) ⬅️ This PR.After those optimizations we are using 84.77% of production WASM limit 😌. Still much, but it was low hanging fruit.