CosmWasm / wasmvm

Go bindings to the running cosmwasm contracts with wasmer
Apache License 2.0
173 stars 99 forks source link

Make a deterministic build system #136

Open ethanfrey opened 4 years ago

ethanfrey commented 4 years ago

See https://github.com/CosmWasm/wasmd/issues/268

Multiple compiles of the same code should give us the same dlls.

I think this requires removing all concurrency from compilation and a few other tricks... definitely increasing build times a lot, so it should be an option, not default. But we should do this for tagged releases, so we can get deterministic (and signable) go binaries

webmaster128 commented 3 years ago

We have build containers now for the .dylib, .so and .a builds. Rust strives towards reproducible builds in general and is doing pretty good. I think the only thing that is really missing here is that we should not mount the host's target folder into the guest, which happens as part of -v $(shell pwd):/code. Instead we should have a guest-only target folder, as in

docker run --rm -v "$(pwd)":/code \
  --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \
  --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
  cosmwasm/rust-optimizer:0.10.5
yihuang commented 3 years ago

https://github.com/yihuang/cosmwasm-plus-plus/blob/integration-tests/nix/default.nix How about nix? I managed to build wasmd and wasmvm together with nix.

ethanfrey commented 3 years ago

I think the main issue is the compilation step of wasmvm returns a different dll each time. Maybe if we limit it to one compiler thread (and 4-8x slower), it will produce deterministic output, as with the smart contracts.

Nix is a good idea if we have dependency issues (like linking native C libs causing issues). It may also be a more efficient solution to the Docker files we use now.

maurolacy commented 3 years ago

I think the main issue is the compilation step of wasmvm returns a different dll each time.

Interesting. My take is that it should be possible to instruct the compiler / linker to produce deterministic output. Maybe with some compiler flags, disabling some optimizations, or something like that.

I can take a look at this at some point if you want.

yihuang commented 3 years ago

Is there an issue in the rust side? I was only aware of un-deterministic caused by working path, which should be fixed with option --remap-path-prefix.

webmaster128 commented 3 years ago

My take is that it should be possible to instruct the compiler / linker to produce deterministic output.

I second that. For Rust, deterministic builds are considered standard and when builds are not deterministic, we can file this as a bug. It is well possible that this does not work here for the shared libs that are a bit exotic for Rust, but we should have all the community support to get this fixed.

ethanfrey commented 3 years ago

I believe it is due to multiple compiler threads and varying linking order.

I know I set codegen-units = 1 to get deterministic builds for the CosmWasm contracts (over a year ago) https://github.com/CosmWasm/cosmwasm/blob/main/contracts/hackatom/Cargo.toml#L19

I have not tried building the wasmvm with that option and checking the sha256sum of the resultant DLLs. I would be interested in the results if anyone wants to try.

maurolacy commented 3 years ago

Some relevant links, after a quick search for "rustc deterministic":

Some info may be outdated. According to the last link, and particularly if we keep the same build system, deterministic builds are very likely.

beatriz-web3 commented 2 years ago

what about now? If i compile multiple times on a same cosmwasm contact code. Is its output same from binary level?

webmaster128 commented 2 years ago

@siulee2 this discussion is about the wasmvm library (the host part), not contracts (the guest part). If you use rust-optimizer or workspace-optimizer to build your contracts, the build is always deterministic. Feel free to follow up in https://github.com/CosmWasm/rust-optimizer.

webmaster128 commented 1 year ago

This seems to work well for the .so and .dylib builds. But the .dll on Windows changes even without changes to the libwasmvm source code (https://github.com/CosmWasm/wasmvm/commit/ba3ecc0619ac730cc0836d762452360ec6041045).