Skip to content

Reproducible Build With Nix

yihuang edited this page Dec 1, 2022 · 10 revisions

It's possible to reproducibly build cronosd binaries locally using nix.

Prerequisite

  • Install nix, follow the instructions here: https://nixos.org/download.html
  • Install cachix and enable cronos binary cache:
    $ nix-env -iA cachix -f https://cachix.org/api/v1/install
    $ cachix use cronos
    

Build Type Matrix

  • network type
    • mainnet (default)
    • testnet
  • build type
    • normal nix package (default)
    • bundle: re-distributable bundle
    • tarball: the tarball of the above bundle.
    • image: docker image of the bundle

The binary support both rocksdb and goleveldb backends.

The package name is constructed by joining the above properties with separator -, omitting the default values, for example:

  • cronosd means mainnet rocksdb nix package.
  • cronosd-tarball means mainnet re-distributable tarball.
  • cronosd-testnet-tarball means testnet re-distributable tarball.

The nix flake url is like: github:crypto-org-chain/cronos/$TAG_NAME#$PACKAGE_NAME, replace the $TAG_NAME and $PACKAGE_NAME to the one you needed, for example, the full command to build a v1.0.0 mainnet re-distributable tarball is:

$ nix build github:crypto-org-chain/cronos/v1.0.0#cronosd-tarball

The result is reside at ./result by default, then you can copy the tarball to other machines with the same OS and arch. The re-distributable bundle/tarball has dynamic libraries included, no extra runtime dependency is needed.

Tarball Content

To keep the tarball redistributable, it has all the runtime dependencies included, the dynamic linker, and the shared libraries, and they are founded with a relative path, so it's important that the whole package is moved together.

  • bin/cronosd, the entry point, it's a wrapper script that executes the binary using the included dynamic linker.
  • exe/cronosd, the executable.
  • lib/, all the shared libraries.

Build Linux Binary on Mac

Remote Building Setup

Run the builder in docker:

docker run --restart always --name nix-docker -d -p 3022:22 lnl7/nix:ssh

Prepare ssh client credentials:

$ cat > ~/.ssh/docker_rsa << EOF
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAxYsCrKrZZ7g8hfnPQCTvpK0EJr1kbXbxDN3dhTMGDlNLFVNY
Bh1x6XW/0Lb2cmVfm70q6PlH3nSVvhWizHfrcLp+JZaf5pThMyl+ps9cWOjrRiFX
NWucG9jGNhG+mqbZSVDc1uOvR6nbyShpRDhHDrdW++FgREa8ubzcxpUvDFl9anYy
pbJ7kIOl3m9FyyzO4IukvMfh+GbhbZI3WkwuiXvhoutTtZ/OOS++u7TkxyWVA4Qi
z28HYNc6cA/pTCNdEIJD5IHPbmrV5I7wnF/DudVsQdlE6eMODcD/y6eQWVf0oHGz
FI4SjVbUQ6h9QnUYEDIOQaOViMmGrcf5wHW+DwIDAQABAoIBAQCzwxo98oNAZWF+
MaOtpW8GFgPvFO3sxw34PXW2HoZmRtnOoDc76VOdtW9GCRkfZKyqVmxT8XS7NLCH
d7zcAEyaGrtsjTMZa2W7XwlH1u8cYWioOvLXRAOdO5iz31Xp+edFVnaAflUlC6db
2JBiaiwPcjuPnroxp4VaKEln1J4pxzQVN3w9Me+CMGejuIrUzsoAfs62UZ6oHCBN
NhEgeduKUYri3yVf2qNcJkOjsRi+YuLzU86jqXswHoal1jH5Dl/O+eYB8VYAgsXi
XgCz9YDnoiakOq4aR1Tebl2tusMD3GXAgOTO8OIZDAFVyzEriOhOoubq3K9qADTx
jfJl1SzxAoGBAOxeMFzIlpgZaIj8OK/Tyuj6UQimd72V5WpbP5g31M07VvgeJesY
du18fOKnSrze6huZUmi7bGwY6i5HmCtu0GQVth+yy694vQdWNXni184hjzK0oeU+
em7WV5yEcnefgCOfvvdWmtp/J8VITMEvqSuuIfIH2LQ5jEaQHjrcviJTAoGBANXz
TO3WzFGLE0Z8lOiD4TQWUcI1ecRpq8MlsqLiTjBGWlLdcC7ZTpq0bsw0vjyd4Mra
Ohj2mwgq+mcU5gtSo2/yVXBsF9dN7BK3k2RCHp/rPrzGEegienCTD6w3jgkL/PLi
ZgLRqbEC+KCNXQbhkbDspcJzuga83UpXf00NODXVAoGAPyx9aI8EEOrZkaM302ab
2ODuP42ee0FQ67gvqxNhAOlXOUF1iPwk7RxUlI953jkGARJdgDh3pfySuoPQG+um
LtnOr3IuFlwCya8047rJSwKVL0wv6QFl37HSALc1kNtEeED93UV8ZeGOU6AbQ5bl
dBM6Z2HJfYHUCBgEvF67QpkCgYBVauaayjgWkjTm3lRBJG3j8sk/hUQRM7McnU9d
koZu5ZeoH7prKd0lDMZzhtcwskOOGWQ6lTI+J5KDVyek+6A+0Hxl/vHhxr1ql5oj
2/YIGM6aZWW+zQ0fJseKFUACwqOBgPwDQhvCjRIgX2/1kFcvULu5D6UEjaC3zokH
hTCc5QKBgEfwW+fUNv/+p4lJcmf8+gBx+0eda7zUnUS0N5DyLKSLoOBoWkiHoDcN
91KDFGxAbIWNnQ7k8gOhnVMtHELpu3U3kBQG+Q/EWTNXsEq/8C5uMnzIzar6NrDn
UE5XM5vZex7NQTH+cus4zckdNwHUv0rGx0diYWFRfEe/uR7fm8rs
-----END RSA PRIVATE KEY-----
EOF
$ chmod 600 ~/.ssh/docker_rsa
$ sudo cat >> ~/.ssh/config << EOF
Host nix-docker
  User root
  HostName localhost
  Port 3022
  IdentityFile ~/.ssh/docker_rsa
EOF

Make sure you can do ssh nix-docker without input password for ssh.

Building

  • Raw binary:

    $ nix build --builders "ssh://nix-docker x86_64-linux" .#legacyPackages.x86_64-linux.cronos-matrix.cronosd
    
  • Docker image:

    $ nix build --builders "ssh://nix-docker x86_64-linux" .#legacyPackages.x86_64-linux.cronos-matrix.cronosd-image 
    

    The result file can be import with docker import.