It seems that builds of Monero are non deterministic. Since this is a difficult goal and there is many way to achieve it, I want first to open the discussion here before opening a new PR
I've checked how Bitcoin and Tor is doing it, they use Gitian. I would recommend doing something similar...
Gitian is a thin wrapper around the Ubuntu virtualization tools written in a combination of Ruby and bash. It was originally developed by Bitcoin developers to ensure the build security and integrity of the Bitcoin software.
Gitian uses Ubuntu's python-vmbuilder to create a qcow2 base image for an Ubuntu version and architecture combination and a set of git and tarball inputs that you specify in a 'descriptor', and then proceeds to run a shell script that you provide to build a component inside that controlled environment. This build process produces an output set that includes the compiled result and another "output descriptor" that captures the versions and hashes of all packages present on the machine during compilation.
Gitian requires either Intel VT support (for qemu-kvm), or LXC support, and currently only supports launching Ubuntu build environments from Ubuntu itself.
I want through the source code and checked already that Non-determinism is not originating from the code base itself:
I'm open to any ideas or solutions, lets have a good discussion!
Why is __LINE__ non deterministic ?
Anyway, pigeons was looking at that, and will find his old notes about it so it can be done. Or at least some more work done towards it.
i could help if needed pigeons, he should just PM me
__LINE__ is not deterministic according to the chromium project (https://www.chromium.org/developers/testing/isolated-testing/deterministic-builds), all these macro are implemented differently on each platform (windows, linux, macos) and each compiler. Example for __FILE__ see http://blog.mindfab.net/2013/12/on-way-to-deterministic-binariy-gcc.html
it is a huge topic that will need more than one person to complete: it took debian lots of time but we should be able to profit from their experience https://wiki.debian.org/ReproducibleBuilds
Thanks @cedricwalter are you on freenode?
@danrmiller not yet, but on which channel monero-dev?
The link doesn't give any info, but OK. We can cross that bridge if and when we end up needing to.
@TheCharlatan Also mentioned an interest in helping out with deterministic builds.
The version control metadata should not be a problem, if the build is done similar to bitcoin's gitian. Gitian checks out the source tree for every build for every platform in the same way.
The following is required for a clean Gitian build:
For the record, I tried compiling simplewallet.cpp twice, and I got identical object files (after stripping debug info), so it's looking like we're in a good starting position :)
+proposal
This issue should be moved to the meta repo as it will affect all applicable monero umbrella projects.
Some updates: I managed to static compile a linux binary with all important dependencies linked from a modified version of bitcoin's depends system and an additional cmake toolchain file. It might be a good idea to break this into smaller pieces, since I cannot really estimate the time required to get it running on all platforms. It would be nice to get a minimal set of requirements (e.g. which platforms should be supported, what manual interaction is acceptable) in order to open a pull request for this so more people can start working on it.
Edit:
To give a taste on how it works in Bitcoin:
A local script calls the gitian builder who creates a container in which the following is run:
make HOST=PLATFORM_TRIPLET , where platform triplet is for example x86_64-apple-darwin, or x86_64-w64-mingw32CONFIG.SITE=/path/to/depends/PLATFORM_TRIPLET/share/config.site prepended (in monero this would be something like cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/depends/toolchain_file)Are you still working on this (or planning to) ?
Still working on it. The cross compilation is a bit problematic, since the current build system expects vendored sources from external/ to be built. Not quite sure how to properly ship around this while keeping native compilation intact. This is why I will probably focus on getting the deterministic build done now on Linux, and think about the cross compilation again at a later stage.
Getting there in steps is certainly fine. Thanks for doing this.
I now opened #3430 to get depends on monero. This should at least take care of deterministically getting dependencies for all platforms.
Any status updates on the progress? Need any support with something?
The pr is still open, I will continue work on it once it is merged. If you want to move ahead, checkout my depends branch and try to setup a gitian descriptor, probably for a 64bit linux to start out, like here in bitcoin.
actually, monero can be (re-)build in a deterministic way, if the same build path is used. see https://tests.reproducible-builds.org/monero (the sun icons on the left...) :-)
@h01ger yes, it can and I have achieved reproducibility in the past on linux amd64. The hard thing is to make an easy as possible recipe for all architectures and target hosts (including mac and windows).
right. I guess it would be very nice to have some generic way/toolchain for that, maybe even a tool. and documentation...
Now that the builds are more or less stable https://travis-ci.org/TheCharlatan/monero/builds/433563684 (hooray!) , I'll post a list of issues that still remain and need to be dealt with. Support/input on any of the items is welcome.
Optional, once the above is taken care of:
--enable-deterministic-archives for the archiver.make dist for cmake might be useful as well to ensure that no git metadata leaks into the source during compile time. This should be taken care of though, when building in a seperate build director. Just something to keep in mind.Progress on the gitian build script (gitian-build.py) can be tracked here: https://github.com/TheCharlatan/monero/tree/gitian/contrib/gitian . if you want to participate, checkout that branch and submit improvements there.
I now opened #4526 to add a gitian build script to monero.
The gitian builds are running stable now and seem to produced reproducible outputs. I also opened https://github.com/monero-project/unbound/pull/12 and https://github.com/monero-project/monero/pull/4929 to ensure that binaries compiled by gitian are portable across linux distributions.
Now that docker support has been merged, building has become quite easy. Just run a docker daemon on ubuntu pass an additional --docker to the build script.
Currently there is a compilation problem with macOS (though there is also a runtime problem when initialising openSSL that requires further inspection).
Next to this, all windows builds and all linux builds safe x86_64-linux-gnu are reproducible. I'm investigating the source of non-determinism on the native 64 bit toolchain, my current suspects are some time calling functions and the JIT compilation of the mining code.
Thanks to hyc's https://github.com/monero-project/monero/pull/5633 we now have full reproducibility for all compiled binaries. The pull request also seems to have fixed the crashes on macOS. I will close the issue once reproducible builds are used to build a monero release and at least two other participants achieve the same hashes.
Awesome - thank you for your hard work! I鈥檒l tag today or tomorrow, and then we can build:)
@fluffypony - Please don't forget to merge #5633 and #5631 for the release-v0.14 branch.
@fluffypony - Those PRs have been merged. When would you be able to create a "prep for v0.14.1" PR (similar to #5170) + tag?
Already on it, will let you know when it鈥檚 done and then we can do some reproducible builds :)
Thanks!
+resolved
+resolved
Most helpful comment
Now that docker support has been merged, building has become quite easy. Just run a docker daemon on ubuntu pass an additional
--dockerto the build script.Currently there is a compilation problem with macOS (though there is also a runtime problem when initialising openSSL that requires further inspection).
Next to this, all windows builds and all linux builds safe
x86_64-linux-gnuare reproducible. I'm investigating the source of non-determinism on the native 64 bit toolchain, my current suspects are some time calling functions and the JIT compilation of the mining code.