This post is kept updated as this project progresses. Use this latest update link to see what’s new.
Please read the README.md
.
Guix Introduction
This PR enables building bitcoin in Guix containers. Guix is a transactional package manager much like Nix, but unlike Nix, it has more of a focus on bootstrappability and reproducibility which are attractive for security-sensitive projects like bitcoin.
Guix Build Walkthrough
Please read the README.md
.
We can then invoke
0guix environment --manifest=contrib/guix/manifest.scm --container --pure --no-grafts --no-substitutes
To have Guix:
- Build an environment containing the packages we defined in our
contrib/guix/manifest.scm
manifest from the Guix bootstrap binaries (see bootstrappability for more details). - Start a container with that environment that has no network access, and no access to the host’s filesystem except to the
pwd
that it was started in. - Drop you into a shell in that container.
Note: if you don’t want to wait hours for Guix to build the entire world from scratch, you can eliminate the
--no-substitutes
option to have Guix download from available binary sources. Note that this convenience doesn’t necessarily compromise your security, as you can check that a package was built correctly after the fact usingguix build --check <packagename>
Therefore, we can perform a build of bitcoin much like in Gitian by invoking the following:
0make -C depends -j"$(nproc)" download && \
1 cat contrib/guix/build.sh | guix environment --manifest=contrib/guix/manifest.scm --container --pure --no-grafts --no-substitutes
We don’t include make -C depends -j"$(nproc)" download
inside contrib/guix/build.sh
because contrib/guix/build.sh
is run inside the container, which has no network access (which is a good thing).
Rationale
I believe that this represents a substantial improvement for the “supply chain security” of bitcoin because:
- We no longer have to rely on Ubuntu for our build environment for our releases (oh the horror), because Guix builds everything about the container, we can perform this on almost any Linux distro/system.
- It is now much easier to determine what trusted binaries are in our supply chain, and even make a nice visualization! (see bootstrappability).
- There is active effort among Guix folks to minimize the number of trusted binaries even further. OriansJ’s stage0, and janneke’s Mes all aim to achieve reduced binary boostrap for Guix. In fact, I believe if OriansJ gets his way, we will end up some day with only a single trusted binary: hex0 (a ~500 byte self-hosting hex assembler).
Steps to Completion
- Successfully build bitcoin inside the Guix environment
- Make
check-symbols
pass - Do the above but without nasty hacks
- Solve some of the more innocuous hacks
- Make it cross-compile (HELP WANTED HERE)
- Linux
- x86_64-linux-gnu
- i686-linux-gnu
- aarch64-linux-gnu
- arm-linux-gnueabihf
- riscv64-linux-gnu
- OS X
- x86_64-apple-darwin14
- Windows
- x86_64-w64-mingw32
- Linux
- Maybe make importer for depends syntax
- Document build process for future releases
- Extra: Pin the revision of Guix that we build with with Guix inferiors
Help Wanted
Here’s what ldd src/bitcoind
looks like when built in a Guix container:
0 linux-vdso.so.1 (0x00007ffcc2d90000)
1 libdl.so.2 => /gnu/store/h90vnqw0nwd0hhm1l5dgxsdrigddfmq4-glibc-2.28/lib/libdl.so.2 (0x00007fb7eda09000)
2 librt.so.1 => /gnu/store/h90vnqw0nwd0hhm1l5dgxsdrigddfmq4-glibc-2.28/lib/librt.so.1 (0x00007fb7ed9ff000)
3 libstdc++.so.6 => /gnu/store/4sqps8dczv3g7rwbdibfz6rf5jlk7w90-gcc-5.5.0-lib/lib/libstdc++.so.6 (0x00007fb7ed87c000)
4 libpthread.so.0 => /gnu/store/h90vnqw0nwd0hhm1l5dgxsdrigddfmq4-glibc-2.28/lib/libpthread.so.0 (0x00007fb7ed85b000)
5 libm.so.6 => /gnu/store/h90vnqw0nwd0hhm1l5dgxsdrigddfmq4-glibc-2.28/lib/libm.so.6 (0x00007fb7ed6da000)
6 libgcc_s.so.1 => /gnu/store/4sqps8dczv3g7rwbdibfz6rf5jlk7w90-gcc-5.5.0-lib/lib/libgcc_s.so.1 (0x00007fb7ed6bf000)
7 libc.so.6 => /gnu/store/h90vnqw0nwd0hhm1l5dgxsdrigddfmq4-glibc-2.28/lib/libc.so.6 (0x00007fb7ed506000)
8 /gnu/store/h90vnqw0nwd0hhm1l5dgxsdrigddfmq4-glibc-2.28/lib/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fb7ee3a0000)
And here’s what it looks in one of our releases:
0 linux-vdso.so.1 (0x00007ffff52cd000)
1 libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f87726b4000)
2 librt.so.1 => /usr/lib/librt.so.1 (0x00007f87726aa000)
3 libm.so.6 => /usr/lib/libm.so.6 (0x00007f8772525000)
4 libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f877250b000)
5 libc.so.6 => /usr/lib/libc.so.6 (0x00007f8772347000)
6 /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f8773392000)
I suspect it is because my script does not apply the gitian-input patches described in the release process but there is no description as to how these patches are applied. It might also be something else entirely.
Edit: It is something else. It appears that the gitian inputs are only used by gitian-win-signer.yml
How to Help
- Install Guix on your distro either from source or perform a binary installation
- Try out my branch and the command described above!