From 2ba90545d44f656ff3026c093f53a460f725f508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kayvan=20=20=E2=89=85=20=DA=A9=DB=8C=D9=88=D8=A7=D9=86?= Date: Thu, 31 Oct 2024 13:26:03 -0700 Subject: [PATCH] nixify (#86) * nixify Add nix related artifacts to make project build in nixos * nixfy Add Nix related documentation --- .gitignore | 7 +- README.md | 13 ++++ docs/nix-setup-guide.md | 145 +++++++++++++++++++++++++++++++++++++++ flake.lock | 146 ++++++++++++++++++++++++++++++++++++++++ flake.nix | 65 ++++++++++++++++++ rust-toolchain.toml | 13 ++++ 6 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 docs/nix-setup-guide.md create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 rust-toolchain.toml diff --git a/.gitignore b/.gitignore index 47cc9e32..980c8f84 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,11 @@ dist/ # Ignore environment-specific files .env +# Ignore nixos related environment-specific files +.envrc +.cargo/ +.direnv/ + # Ignore editor-specific files .vscode/ .idea/ @@ -25,4 +30,4 @@ target/ debug/ yarn.lock -contracts/deployments/ \ No newline at end of file +contracts/deployments/ diff --git a/README.md b/README.md index 0679e54c..c8790ff1 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ That's it. This simple flow highlights some of the core mechanics of how AVSs wo The following instructions explain how to manually deploy the AVS from scratch including EigenLayer and AVS specific contracts using Foundry (forge) to a local anvil chain, and start Typescript Operator application and tasks. +## Development Environment +This section describes the tooling required for local development. + +### Non-Nix Environment Install dependencies: - [Node](https://nodejs.org/en/download/) @@ -30,6 +34,15 @@ Install dependencies: - [Foundry](https://getfoundry.sh/) - [ethers](https://www.npmjs.com/package/ethers) +### Nix Environment +On [Nix](https://nixos.org/) platforms, if you already have the proper Nix configuration, you can build the project’s artifacts inside a `nix develop` shell +``` sh +nix develop +``` +Otherwise, please refer to [installed and configured](./docs/nix-setup-guide.md) section. + +## Quick start + ### Start Anvil Chain In terminal window #1, execute the following commands: diff --git a/docs/nix-setup-guide.md b/docs/nix-setup-guide.md new file mode 100644 index 00000000..29fb470b --- /dev/null +++ b/docs/nix-setup-guide.md @@ -0,0 +1,145 @@ +# Nix Setup Guide + +Here you will find instructions on how to install and configure [nix package manager](https://nixos.wiki/wiki/Nix_package_manager) to work with +projects. + +## Installing / Upgrading + +If you don't have nix installed, follow the instructions on the +[official website](https://nixos.org/download), or simply use one of following +commands in a terminal: + +- For multi-user installation (i.e., system-wide setup, **recommended**) +```bash +sh <(curl -L https://nixos.org/nix/install) --daemon +``` +- For single-user installation (i.e., local setup) +```bash +sh <(curl -L https://nixos.org/nix/install) --no-daemon +``` + +We use nix `flakes` which require nix version `>= 2.4`, therefore if you already +have nix installed, make sure to +[upgrade](https://nixos.org/manual/nix/stable/installation/upgrading) to a +recent version. + +## Becoming a Truster User + +If you are on NixOS or have installed nix in multi-user mode, you **must** be +a [trusted user](https://nixos.org/nix/manual/#ssec-multi-user), which is +necessary to enable access to our binary cache. + +On non-NixOS systems, append the following line to the system-wide configuration +`/etc/nix/nix.conf`: +```txt +trusted-users = USER root +``` +**Where `USER` is the result of running `whoami` in a terminal.** + +You can also use a group name by prefixing it with `@`. For instance, to add all +members of the `wheel` group: +```txt +trusted-users = @wheel root +``` + +On NixOS, add the user/group name to the list under +[`nix.settings.trusted-users`](https://search.nixos.org/options?show=nix.settings.trusted-users). + +## Setting Up for Flakes + +We use [Nix flakes](https://nixos.wiki/wiki/Flakes). To configure for flakes, follow the instruction on the [Nixos Wiki](https://nixos.wiki/wiki/Flakes) or simply do one of the following depending on your system: + +- On non-NixOS systems, edit one of the following two files (create them if they don't exist): + - `/etc/nix/nix.conf` for system-wide settings on a multi-user installation + - `~/.config/nix/nix.conf` for user-wide settings on a single-user installation + +By appending the following lines: +```txt +experimental-features = nix-command flakes +``` + +On NixOS systems, set the following NixOS options: +```nix + nix.settings.experimental-features = [ "nix-command" "flakes" ]; +``` + +## Notes for Apple Users + +Apple Silicon users can run any Intel binary out-of-the-box thanks to Rosetta +emulation, but when working with nix flakes, the `aarch64-darwin` system will be +selected by default. + +However, some projects at cannot be built natively on `aarch64-darwin`. + +Therefore you must specify the `--system` explicitly to target `x86_64-darwin`. +```bash +nix (develop|build|run|check) --system x86_64-darwin # Will use the x86_64-darwin derivation +nix (develop|build|run|check) # Will use the aarch64-darwin derivation, if available +``` + +To enable this, you must append the following lines to your `/etc/nix/nix.conf` +or `~/.config/nix/nix.conf`: +```txt +extra-platforms = x86_64-darwin aarch64-darwin +extra-sandbox-paths = /System/Library/Frameworks /System/Library/PrivateFrameworks /usr/lib /private/tmp /private/var/tmp /usr/bin/env +``` + +You may need to reload the nix daemon for changes to take effect: +```bash +sudo launchctl stop org.nixos.nix-daemon +sudo launchctl start org.nixos.nix-daemon +``` + +## Development Shell and VSCode + +Now that you have nix installed and configured, you may enter the development +shell: +``` +nix develop +``` +If you are on Apple Silicon and a native shell is not available, you will want +to run this instead: +``` +nix develop --system x86_64-darwin +``` + +If you are a `VSCode` user, you may also start your development session by +executing the following command: +``` +nix develop --command code +``` + +If you are running `nix develop` for the first time, please enter `y` at the +following prompts to create the local nix settings file +`~/.local/share/nix/trusted-settings.json`: +```txt +> do you want to allow configuration setting 'accept-flake-config' to be set to 'true' (y/N)? +> do you want to permanently mark this value as trusted (y/N)? +``` + +It is particularly important to accept the `extra-substituters` and +`extra-trusted-public-keys` settings as these will grant access to our binary +cache. + +When `nix develop` is run for the first time, a significant amount of +dependencies will be downloaded, built and installed. This process may take a +couple of hours but is expected to happen only once. However, if you ever +witness that GHC is also being built from scratch, then it is likely that your +binary cache has not been configured properly or is not being considered. +Accepting the configuration settings as outlined above should be sufficient to +avoid this. Nevertheless, if your caches are still broken, you'll want to review +this document carefully to ensure that your nix installation is properly +configured. + +You will know that your caches are broken if you see this message: +``` +warning: ignoring untrusted substituter 'https://cache.iog.io', you are not a trusted user. +``` + +If is possible that your settings are correct but the nix daemon is not properly +considering them. In this case, stop the `nix develop` process and restart the +`nix-daemon` as follows: +```bash +sudo systemctl stop nix-daemon.service +``` +Once done, you can launch the `nix develop` process again. diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..96d4e60a --- /dev/null +++ b/flake.lock @@ -0,0 +1,146 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1644229661, + "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "foundry": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1725354688, + "narHash": "sha256-KHHFemVt6C/hbGoMzIq7cpxmjdp+KZVZaqbvx02aliY=", + "owner": "shazow", + "repo": "foundry.nix", + "rev": "671672bd60a0d2e5f6757638fdf27e806df755a4", + "type": "github" + }, + "original": { + "owner": "shazow", + "ref": "monthly", + "repo": "foundry.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1666753130, + "narHash": "sha256-Wff1dGPFSneXJLI2c0kkdWTgxnQ416KE6X4KnFkgPYQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f540aeda6f677354f1e7144ab04352f61aaa0118", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1726755586, + "narHash": "sha256-PmUr/2GQGvFTIJ6/Tvsins7Q43KTMvMFhvG6oaYK+Wk=", + "owner": "NixOs", + "repo": "nixpkgs", + "rev": "c04d5652cfa9742b1d519688f65d1bbccea9eb7e", + "type": "github" + }, + "original": { + "owner": "NixOs", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1718428119, + "narHash": "sha256-WdWDpNaq6u1IPtxtYHHWpl5BmabtpmLnMAx0RdJ/vo8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e6cea36f83499eb4e9cd184c8a8e823296b50ad5", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "foundry": "foundry", + "nixpkgs": "nixpkgs_2", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1726972233, + "narHash": "sha256-FlL/bNESOtDQoczRhmPfReNAmLqVg+dAX4HectPOOf0=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "36d73192555e569d27579f6c486fea3ab768823c", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..b8f5ae18 --- /dev/null +++ b/flake.nix @@ -0,0 +1,65 @@ +{ + description = "ethereum-rs project"; + inputs = { + nixpkgs.url = "github:NixOs/nixpkgs/nixos-unstable"; + rust-overlay.url = "github:oxalica/rust-overlay"; + flake-utils.url = "github:numtide/flake-utils"; + foundry.url = "github:shazow/foundry.nix/monthly"; # Use monthly branch for permanent releases + + }; + outputs = { self, nixpkgs, rust-overlay, flake-utils, foundry, ... }@inputs: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = import nixpkgs { + inherit system; + overlays = [ rust-overlay.overlays.default foundry.overlay ]; + }; + + toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + cargoTomlContents = builtins.readFile ./Cargo.toml; + version = (builtins.fromTOML cargoTomlContents).package.version; + + ethereumEs = pkgs.rustPlatform.buildRustPackage { + inherit version; + name = "ethereumEs"; + buildInputs = with pkgs; [ openssl ]; + nativeBuildInputs = with pkgs; [ pkg-config openssl.dev ]; + + src = pkgs.lib.cleanSourceWith { src = self; }; + + cargoLock.lockFile = ./Cargo.lock; + + }; + in { + + overlays.default = final: prev: { ethereumEs = ethereumEs; }; + + gitRev = if (builtins.hasAttr "rev" self) then self.rev else "dirty"; + + devShells.default = pkgs.mkShell { + buildInputs = with pkgs; [ + foundry-bin + solc + toolchain + openssl + cargo-insta + pkg-config + eza + rust-analyzer-unwrapped + nodejs_20 + nodePackages.typescript + nodePackages.typescript-language-server + watchexec + ]; + shellHook = '' + ## for the IDE to access rust crates source code + export RUST_SRC_PATH="${toolchain}/lib/rustlib/src/rust/library" + + ## do not pollute the global cargo repository + export CARGO_HOME="$(pwd)/.cargo" + export PATH="$CARGO_HOME/bin:$PATH" + + ''; + }; + }); +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..8e403514 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,13 @@ +[toolchain] +channel = "nightly" +components = [ + "cargo", + "clippy", + "rust-analyzer", + "rust-src", + "rust-std", + "rustc", + "rustfmt", +] +targets = [ "wasm32-unknown-unknown" ] +profile = "minimal"