Description
Reproducible builds
This is a little investigation into "do we have reproducible builds in geth?".
A reproducible build means that one can replicate locally a build made on e.g. a build-server.
That is, produce an exact matching binary. This is very useful to verify the integrity
of the build-servers: any remote machine can be used to watch over the builds.
The Go compiler is, supposedly, reproducible. However, go-ethereum is not pure go
- It uses a
c
compiler, thus we need to ensure the same compiler is used - It bundles some version-system artefacts at build-time,
- Maybe other things. To be discovered.
Testing
First, I downloaded the latest build from our downloads-page. The downloads-page
lists the checksum as 8d5e138dc3eb7b08cde48966aee0ea79
(note: md5
is not a secure
cryptographic hash, but we also provide detached signatures, which offers much
better security in verifying integrity).
[user@work go-ethereum]$ md5sum geth-linux-amd64-1.13.13-unstable-fe91d476.tar.gz
8d5e138dc3eb7b08cde48966aee0ea79 geth-linux-amd64-1.13.13-unstable-fe91d476.tar.gz
[user@work go-ethereum]$ md5sum geth-linux-amd64-1.13.13-unstable-fe91d476/geth
1a372833c2a63c95a2f855524eb5fcd9 geth-linux-amd64-1.13.13-unstable-fe91d476/geth
I then tried to create a docker container replicating the enviromment used. Details gleaned from the downloaded file:
$ ./geth-linux-amd64-1.13.13-unstable-fe91d476/geth version
Geth
Version: 1.13.13-unstable
Git Commit: fe91d476ba3e29316b6dc99b6efd4a571481d888
Git Commit Date: 20240213
Architecture: amd64
Go Version: go1.21.6
Operating System: linux
GOPATH=/home/user/go
GOROOT=/usr/local/go
The .travis.yml
also gives us some hints:
dist: bionic
go: 1.21.x
Dockerfile attempt
Using a dockerfile like this:
from ubuntu:bionic
RUN apt-get update && apt-get install gcc-multilib git ca-certificates wget -yq --no-install-recommends
RUN git clone --branch master https://github.com/ethereum/go-ethereum.git
RUN wget https://go.dev/dl/go1.21.6.linux-amd64.tar.gz && \
rm -rf /usr/local/go && \
tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz && \
export PATH=$PATH:/usr/local/go/bin
RUN cd go-ethereum && git checkout fe91d476ba3e29316b6dc99b6efd4a571481d888 && \
CI=true TRAVIS=true TRAVIS_COMMIT="fe91d476ba3e29316b6dc99b6efd4a571481d888" go run ./build/ci.go install ./cmd/geth/
RUN md5sum ./build/bin/geth
In order to make the docker-version bundle the git data, we set the TRAVIS
,CI
env variables. See internal/build/env.go
for reasons.
The two builds are not exactly alike in size:
root@208cb9fcfa68:/go-ethereum# ls -l ./build/bin/geth
-rwxr-xr-x 1 root root 58129760 Feb 14 09:53 ./build/bin/geth
$ ls -la ./geth-linux-amd64-1.13.13-unstable-fe91d476/geth
-rwxr-xr-x 1 user user 58129968 Feb 13 14:55 ./geth-linux-amd64-1.13.13-unstable-fe91d476/geth
Content-wise:
root@208cb9fcfa68:/go-ethereum# strings ./build/bin/geth | head
/lib64/ld-linux-x86-64.so.2
RAMLiBUAnrbn5zHLQ2v2/WlYmiboMK5ddsyu5qL-z/zajlwZgTLCfStG3HorG6/Utx6Jmui4qlzsokyGBwE
D %$
DD@
#@ $
@@ j
k(dB0
0 b
ljI^
q6-p
VS
$ strings ./geth-linux-amd64-1.13.13-unstable-fe91d476/geth | head
/lib64/ld-linux-x86-64.so.2
JHKPXlVR27nUe4y9sY68/WlYmiboMK5ddsyu5qL-z/zajlwZgTLCfStG3HorG6/QrO6sKmnFVHR7U-WHF3U
x3vo
D %$
DD@
#@ $
@@ j
k(dB0
0 b
ljI^