diff --git a/.github/workflows/nix-build.yaml b/.github/workflows/nix-build.yaml new file mode 100644 index 00000000000..a0830629cd1 --- /dev/null +++ b/.github/workflows/nix-build.yaml @@ -0,0 +1,108 @@ +name: "🔧 Nix Build & Cache" + +on: + push: + branches: [main, develop] + pull_request: + branches: [main, develop] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build (${{ matrix.target }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + target: + - aptos-node + - movement + - l1-migration + - aptos-faucet-service + - aptos-transaction-emitter + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Determinate Nix + uses: DeterminateSystems/nix-installer-action@main + + - name: Setup Cachix + uses: cachix/cachix-action@v15 + with: + name: movementlabs + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + + - name: Build ${{ matrix.target }} + run: | + cd nix + nix build .#${{ matrix.target }} -L --accept-flake-config + + - name: Verify binary + run: | + ls -la result/bin/ + ./result/bin/${{ matrix.target }} --version || ./result/bin/${{ matrix.target }} --help || true + + build-all: + name: Build All Binaries + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Determinate Nix + uses: DeterminateSystems/nix-installer-action@main + + - name: Setup Cachix + uses: cachix/cachix-action@v15 + with: + name: movementlabs + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + + - name: Build all binaries + run: | + cd nix + nix build .#all-binaries -L --accept-flake-config + + - name: List all binaries + run: ls -la result/bin/ + + containers: + name: Build Containers + runs-on: ubuntu-latest + needs: build + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Determinate Nix + uses: DeterminateSystems/nix-installer-action@main + + - name: Setup Cachix + uses: cachix/cachix-action@v15 + with: + name: movementlabs + authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + + - name: Build aptos-node container + run: | + cd nix + nix build .#container-aptos-node -L --accept-flake-config + + - name: Build faucet container + run: | + cd nix + nix build .#container-aptos-faucet-service -L --accept-flake-config + + - name: Load and verify containers + run: | + docker load < result + docker images | grep -E "(aptos-node|aptos-faucet)" diff --git a/Justfile b/Justfile index 918c3f7f8ec..f9a7df06faf 100644 --- a/Justfile +++ b/Justfile @@ -6,7 +6,11 @@ set shell := ["bash", "-c"] # Default target default: build -# Build the project or a specific binary using Nix development shell +# ============================================================================== +# Development Shell Commands (fast iteration with cargo) +# ============================================================================== + +# Build the project or a specific binary using Nix development shell (for development) build binary="all" profile="dev": #!/usr/bin/env bash if [ "{{profile}}" != "release" ]; then @@ -44,17 +48,217 @@ clippy: @echo "Running clippy..." nix --extra-experimental-features "nix-command flakes" develop -c cargo clippy -- --deny warnings -# Clean build artifacts -clean: - @echo "Cleaning build artifacts..." - rm -rf result target +# Build any binary by package name (cargo-based) +build-bin package: + @echo "Building {{package}} with Nix development shell..." + nix develop -c cargo build --release -p {{package}} + @echo "Binary available at target/release/{{package}}" -# Update flake.lock -update: - @echo "Updating flake.lock..." - nix flake update +# ============================================================================== +# Nix Build Commands (reproducible builds with Cachix caching) +# ============================================================================== + +# Build a specific binary using Nix (reproducible, cached via Cachix) +build-nix binary="aptos-node": + #!/usr/bin/env bash + echo "Building {{binary}} with Nix (reproducible build)..." + echo "This build can be cached and shared via Cachix." + echo "" + nix build .#{{binary}} -L + RESULT_PATH=$(readlink result) + echo "" + echo "Build complete!" + echo "Binary path: $RESULT_PATH/bin/{{binary}}" + echo "" + echo "To run: ./result/bin/{{binary}}" + +# Build all binaries using Nix (reproducible, cached via Cachix) +build-all-nix: + #!/usr/bin/env bash + echo "Building all binaries with Nix (reproducible build)..." + echo "This build can be cached and shared via Cachix." + echo "" + nix build .#all-binaries -L + RESULT_PATH=$(readlink result) + echo "" + echo "Build complete! All binaries available at:" + echo " $RESULT_PATH/bin/aptos-node" + echo " $RESULT_PATH/bin/movement" + echo " $RESULT_PATH/bin/l1-migration" + echo " $RESULT_PATH/bin/aptos-faucet-service" + echo " $RESULT_PATH/bin/aptos-transaction-emitter" + +# ============================================================================== +# Cachix Commands (share builds with team) +# ============================================================================== + +# Push a built binary to Cachix (requires auth: cachix authtoken YOUR_TOKEN) +cache-push binary="all-binaries": + #!/usr/bin/env bash + if ! command -v cachix &> /dev/null; then + echo "Error: Cachix CLI not installed." + echo "Install with: nix profile install nixpkgs#cachix" + echo "Then authenticate: cachix authtoken YOUR_TOKEN" + exit 1 + fi + + echo "Building and pushing {{binary}} to Cachix..." + echo "" + + # Build first if result doesn't exist or is different target + if [ ! -L result ] || [ "$(readlink result)" != "$(nix build .#{{binary}} --print-out-paths 2>/dev/null)" ]; then + nix build .#{{binary}} -L + fi + + echo "" + echo "Pushing to Cachix..." + cachix push movementlabs ./result + + echo "" + echo "Done! Others can now pull this build with:" + echo " nix build .#{{binary}}" + +# Push all binaries to Cachix +cache-push-all: + #!/usr/bin/env bash + if ! command -v cachix &> /dev/null; then + echo "Error: Cachix CLI not installed." + echo "Install with: nix profile install nixpkgs#cachix" + echo "Then authenticate: cachix authtoken YOUR_TOKEN" + exit 1 + fi + + echo "Building and pushing all binaries to Cachix..." + echo "This may take a while for the initial build (~30-60 min)." + echo "" + + nix build .#all-binaries -L + + echo "" + echo "Pushing to Cachix..." + cachix push movementlabs ./result + + echo "" + echo "Done! Others can now pull these builds with:" + echo " nix build .#all-binaries" + echo "" + echo "Individual binaries are also cached:" + echo " nix build .#aptos-node" + echo " nix build .#movement" + echo " etc." + +# Check Cachix setup status +cache-status: + #!/usr/bin/env bash + echo "Cachix Status" + echo "=============" + echo "" + if ! command -v cachix &> /dev/null; then + echo "Cachix CLI: NOT INSTALLED" + echo " Install with: nix profile add nixpkgs#cachix" + else + echo "Cachix CLI: $(cachix --version)" + echo "" + if [ -f "$HOME/.config/cachix/cachix.dhall" ]; then + echo "Authentication: CONFIGURED" + echo " Config: $HOME/.config/cachix/cachix.dhall" + else + echo "Authentication: NOT CONFIGURED" + echo " Run: cachix authtoken YOUR_TOKEN" + fi + fi + echo "" + echo "Nix trusted-users:" + nix show-config 2>/dev/null | grep trusted-users || echo " (not configured)" + echo "" + echo "Cachix substituters configured:" + nix show-config 2>/dev/null | grep -i movementlabs || echo " (using flake config)" + +# Watch store and auto-push to Cachix (run in background while developing) +cache-watch: + #!/usr/bin/env bash + if ! command -v cachix &> /dev/null; then + echo "Error: Cachix CLI not installed." + echo "Install with: nix profile add nixpkgs#cachix" + exit 1 + fi + echo "Starting Cachix watch mode..." + echo "All new Nix builds will be automatically pushed to movementlabs cache." + echo "Press Ctrl+C to stop." + echo "" + cachix watch-store movementlabs + +# Build and push with watch-exec (auto-pushes build results) +cache-build binary="all-binaries": + #!/usr/bin/env bash + if ! command -v cachix &> /dev/null; then + echo "Error: Cachix CLI not installed." + echo "Install with: nix profile add nixpkgs#cachix" + exit 1 + fi + echo "Building {{binary}} and auto-pushing to Cachix..." + echo "" + cachix watch-exec movementlabs -- nix build .#{{binary}} -L + +# ============================================================================== +# Container Commands (Nix-based container builds) +# ============================================================================== + +# Build a container image using Nix dockerTools (Linux only) +container-nix container="aptos-node": + #!/usr/bin/env bash + echo "Building container image for {{container}} with Nix..." + echo "" + nix build .#container-{{container}} -L + RESULT_PATH=$(readlink result) + echo "" + echo "Container image built!" + echo "Image tarball: $RESULT_PATH" + echo "" + echo "To load into Docker: docker load < $RESULT_PATH" + echo "Or use: just container-load {{container}}" + +# Load a Nix-built container image into Docker +container-load container="aptos-node": + #!/usr/bin/env bash + echo "Loading {{container}} container image into Docker..." + IMAGE_PATH=$(nix build .#container-{{container}} --print-out-paths) + docker load < "$IMAGE_PATH" + echo "" + echo "Image loaded! Available as:" + echo " ghcr.io/movementlabsxyz/{{container}}:nix" + echo "" + echo "To run: docker run ghcr.io/movementlabsxyz/{{container}}:nix" + +# Push a Nix-built container image to GHCR +container-push container="aptos-node" tag="": + #!/usr/bin/env bash + # Default tag to git short SHA if not provided + if [ -z "{{tag}}" ]; then + TAG=$(git rev-parse --short HEAD) + else + TAG="{{tag}}" + fi + + echo "Pushing {{container}} container to GHCR with tag: $TAG" + echo "" + + # Build and load the image first + IMAGE_PATH=$(nix build .#container-{{container}} --print-out-paths) + docker load < "$IMAGE_PATH" + + # Tag for the target registry + docker tag ghcr.io/movementlabsxyz/{{container}}:nix ghcr.io/movementlabsxyz/{{container}}:$TAG + + # Push to GHCR + echo "Pushing to ghcr.io/movementlabsxyz/{{container}}:$TAG ..." + docker push ghcr.io/movementlabsxyz/{{container}}:$TAG + + echo "" + echo "Container pushed successfully!" + echo " ghcr.io/movementlabsxyz/{{container}}:$TAG" -# Build Docker image +# Build Docker image using traditional Dockerfile (legacy method) container-build container="aptos-node" tag="latest" profile="release": #!/usr/bin/env bash # Check if Docker is installed @@ -92,7 +296,7 @@ container-build container="aptos-node" tag="latest" profile="release": just build {{container}} {{profile}} ;; esac - + # Set binary path based on profile if [ "{{profile}}" = "release" ]; then @@ -102,44 +306,89 @@ container-build container="aptos-node" tag="latest" profile="release": else BINARY_PATH="target/{{profile}}" fi - + echo "Building Docker image for '{{container}}' using binary at $BINARY_PATH..." docker build \ --build-arg BINARY_PATH="$BINARY_PATH" \ -f docker/{{container}}/Dockerfile \ -t ghcr.io/movementlabsxyz/{{container}}:{{tag}} . - + # Clean up the copied binary rm -f aptos-test -# Build any binary by package name -build-bin package: - @echo "Building {{package}} with Nix development shell..." - nix develop -c cargo build --release -p {{package}} - @echo "Binary available at target/release/{{package}}" +# ============================================================================== +# Utility Commands +# ============================================================================== + +# Clean build artifacts +clean: + @echo "Cleaning build artifacts..." + rm -rf result target + +# Update flake.lock +update: + @echo "Updating flake.lock..." + nix flake update # List available binary build targets list-binaries: - @echo "Available binary build targets:" - @echo " Generic: just build " - @echo " Common binaries:" - @echo " aptos-node - Main Aptos node" - @echo " aptos - Aptos CLI tool" - @echo " aptos-debugger - Debugging tool" - @echo " aptos-backup-cli - Backup CLI tool" - @echo " aptos-keygen - Key generation tool" - @echo " transaction-emitter - Transaction emitter" - @echo " aptos-node-checker - Node checker tool" @echo "" - @echo "Use 'just build' to build all packages" - @echo "Use 'just build-bin ' for custom package builds" + @echo "================================================================================" + @echo " Available Binary Build Targets" + @echo "================================================================================" + @echo "" + @echo "NIX BUILD TARGETS (reproducible, cached via Cachix):" + @echo " just build-nix aptos-node - Main Aptos node binary" + @echo " just build-nix movement - Movement CLI (renamed from aptos)" + @echo " just build-nix l1-migration - L1 migration tool" + @echo " just build-nix aptos-faucet-service - Faucet service for test networks" + @echo " just build-nix aptos-transaction-emitter - Transaction testing tool" + @echo " just build-all-nix - Build all five binaries" + @echo "" + @echo "CARGO BUILD TARGETS (faster iteration, uses dev shell):" + @echo " just build aptos-node - Build with cargo (dev profile)" + @echo " just build aptos-node release - Build with cargo (release profile)" + @echo " just build - Build entire workspace" + @echo " just build-bin - Build any cargo package" + @echo "" + @echo "CONTAINER TARGETS (Nix-based containers):" + @echo " just container-nix aptos-node - Build aptos-node container" + @echo " just container-nix aptos-faucet-service - Build faucet container" + @echo " just container-load - Load container into Docker" + @echo " just container-push [tag] - Push container to GHCR" + @echo "" + @echo "CACHIX (share builds with team):" + @echo " just cache-push - Build and push to Cachix" + @echo " just cache-push-all - Build and push all binaries" + @echo " just cache-status - Check Cachix setup status" + @echo "" + @echo "================================================================================" # Help - list available recipes help: @just --list @echo "" - @echo "Binary Build Options:" - @echo " Use 'just list-binaries' to see available binary build targets" - @echo " Use 'just build ' for common binary builds" - @echo " Use 'just build' to build all packages" - @echo " Use 'just build-bin ' for custom package builds" \ No newline at end of file + @echo "================================================================================" + @echo " Quick Reference" + @echo "================================================================================" + @echo "" + @echo "DEVELOPMENT:" + @echo " just dev - Enter Nix development shell" + @echo " just build - Build all with cargo (fast iteration)" + @echo " just test - Run tests" + @echo "" + @echo "PRODUCTION BUILDS:" + @echo " just build-nix - Build single binary (reproducible, cached)" + @echo " just build-all-nix - Build all binaries (reproducible, cached)" + @echo "" + @echo "CONTAINERS:" + @echo " just container-nix - Build container with Nix" + @echo " just container-load - Load into Docker" + @echo " just container-push - Push to GHCR" + @echo "" + @echo "SHARE BUILDS (Cachix):" + @echo " just cache-push-all - Build all & push to cache" + @echo " just cache-status - Check Cachix setup" + @echo "" + @echo "Use 'just list-binaries' for complete list of build targets" + @echo "================================================================================" diff --git a/README.md b/README.md index 4a48f6e5d9a..9dba3f50caf 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,46 @@ Aptos is a layer 1 blockchain bringing a paradigm shift to Web3 through better t * Follow us on [Twitter](https://twitter.com/Aptos). * Join us on the [Aptos Discord](https://discord.gg/aptosnetwork). +## Building with Nix + +We recommend using [Determinate Nix](https://determinate.systems/nix/) for reproducible builds. Determinate Nix is a validated downstream distribution of Nix with performance enhancements (parallel evaluation, lazy trees) and flakes enabled by default. + +### Quick Start + +```bash +# Install Determinate Nix +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install + +# Restart your shell, then build +nix build .#aptos-node -L + +# Or enter development shell +nix develop +``` + +### Why Determinate Nix? + +| Feature | Standard Nix | Determinate Nix | +|---------|-------------|-----------------| +| Flakes | Experimental | **Stable** | +| Parallel evaluation | No | **Yes (2x faster)** | +| Lazy trees | No | **Yes (3x faster, 20x less disk)** | +| Native Linux builder (macOS) | Manual setup | **Built-in** | + +### Troubleshooting: "public key is not valid" Error + +If you encounter `error: public key is not valid` when running nix commands, this is caused by FlakeHub cache keys that Determinate Nix adds by default. To fix: + +```bash +sudo nano /etc/nix/nix.conf +# Comment out or remove the line starting with: extra-trusted-public-keys = cache.flakehub.com-3:... +sudo launchctl stop org.nixos.nix-daemon && sudo launchctl start org.nixos.nix-daemon +``` + +For detailed setup instructions, see: +- [Nix Build Setup Guide](docs/nix-build-setup.md) +- [Binary Cache Setup Guide](docs/nix-cachix-setup.md) + ## Contributing You can learn more about contributing to the Aptos project by reading our [Contribution Guide](https://github.com/aptos-labs/aptos-core/blob/main/CONTRIBUTING.md) and by viewing our [Code of Conduct](https://github.com/aptos-labs/aptos-core/blob/main/CODE_OF_CONDUCT.md). diff --git a/docs/nix-build-setup.md b/docs/nix-build-setup.md new file mode 100644 index 00000000000..7fe91be7863 --- /dev/null +++ b/docs/nix-build-setup.md @@ -0,0 +1,311 @@ +# Nix Build Setup Guide + +This document explains how to set up your development environment for building Aptos Core using Nix and the reproducible build system. + +## Overview + +The Aptos Core build system supports two approaches: + +1. **Cargo builds** (via `nix develop`): Fast iteration during development +2. **Nix builds** (via `nix build`): Reproducible builds with Cachix caching + +The Nix build approach is recommended for production builds as it: + +- Produces bit-for-bit reproducible builds +- Leverages Cachix for binary caching (avoiding recompilation) +- Ensures consistent builds across different machines +- Can be easily integrated into CI/CD pipelines + +## Prerequisites + +### 1. Install Determinate Nix (Recommended) + +We **strongly recommend** using [Determinate Nix](https://determinate.systems/nix/) instead of standard Nix. Determinate Nix is a validated downstream distribution that provides: + +| Feature | Standard Nix | Determinate Nix | +|---------|-------------|-----------------| +| **Flakes** | Experimental (requires flag) | Stable by default | +| **New CLI (`nix` command)** | Experimental | Stable by default | +| **Parallel evaluation** | Not available | 50%+ faster evaluations | +| **Lazy trees** | Not available | 3x+ faster, 20x less disk usage | +| **Native Linux builder (macOS)** | Requires manual setup | Built-in, zero config | +| **Automatic garbage collection** | Manual | Automatic | +| **License** | LGPL v2.1 | LGPL v2.1 (same, fully open source) | + +Install Determinate Nix: + +```bash +curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install +``` + +After installation, restart your shell or run: + +```bash +. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh +``` + +Verify installation: + +```bash +nix --version +# Should show: nix (Determinate Nix X.Y.Z) 2.X.Y +``` + +#### Upgrading Determinate Nix + +To upgrade to the latest version: + +```bash +sudo determinate-nixd upgrade +``` + +### 2. Alternative: Standard Nix (Not Recommended) + +If you prefer standard Nix, you'll need to enable flakes manually. + +Install standard Nix: + +```bash +curl -L https://nixos.org/nix/install | sh +``` + +Add to `~/.config/nix/nix.conf`: + +```ini +experimental-features = nix-command flakes +``` + +Or use the command-line flag: `nix --extra-experimental-features "nix-command flakes" ...` + +**Note**: You will miss out on parallel evaluation, lazy trees, and other performance improvements available in Determinate Nix. + +### 3. Install Just (optional but recommended) + +Just is a command runner that simplifies build commands: + +```bash +# With Nix +nix profile install nixpkgs#just + +# Or with Homebrew (macOS) +brew install just + +# Or with Cargo +cargo install just +``` + +## Quick Start + +### Building with Nix (Recommended for Production) + +```bash +# Clone the repository +git clone https://github.com/movementlabsxyz/aptos-core.git +cd aptos-core + +# Build a single binary (reproducible, cached) +just build-nix aptos-node + +# Build all binaries +just build-all-nix + +# The binary will be available at ./result/bin/ +./result/bin/aptos-node --version +``` + +### Development Workflow + +```bash +# Enter the development shell (with all build tools) +just dev + +# Build with cargo for fast iteration +cargo build -p aptos-node + +# Run tests +cargo test +``` + +## Available Build Targets + +### Binary Packages + +| Target | Description | Command | +|--------|-------------|---------| +| `aptos-node` | Main Aptos validator/fullnode binary | `just build-nix aptos-node` | +| `movement` | Movement CLI tool (renamed from aptos) | `just build-nix movement` | +| `l1-migration` | L1 migration utility | `just build-nix l1-migration` | +| `aptos-faucet-service` | Faucet service for test networks | `just build-nix aptos-faucet-service` | +| `aptos-transaction-emitter` | Transaction testing/benchmarking tool | `just build-nix aptos-transaction-emitter` | +| `all-binaries` | All five binaries combined | `just build-all-nix` | + +### Container Images + +| Target | Description | Command | +|--------|-------------|---------| +| `container-aptos-node` | Node container (includes aptos-node, movement, l1-migration) | `just container-nix aptos-node` | +| `container-aptos-faucet-service` | Faucet service container | `just container-nix aptos-faucet-service` | + +Note: Container builds are only available on Linux systems. + +## Direct Nix Commands + +If you prefer using Nix commands directly instead of Just: + +```bash +# Build a specific binary +nix build .#aptos-node -L + +# Build all binaries +nix build .#all-binaries -L + +# Build a container image (Linux only) +nix build .#container-aptos-node -L + +# Enter development shell +nix develop + +# Run a binary directly +nix run .#aptos-node -- --version + +# Show all available packages +nix flake show +``` + +## Platform Support + +The build system supports: + +- **aarch64-darwin** (Apple Silicon Macs) +- **x86_64-linux** (Linux x86_64) + +Platform-specific notes: + +- **macOS**: Container builds are not available (containers require Linux) +- **Linux**: Full feature support including container builds + +## Cachix Integration + +For faster builds via binary caching, see [Cachix Setup Guide](./nix-cachix-setup.md). + +## Troubleshooting + +### Nix daemon not running + +If you see "error: cannot connect to daemon": + +```bash +# macOS +sudo launchctl start org.nixos.nix-daemon + +# Linux +sudo systemctl start nix-daemon +``` + +### Permission denied errors + +Ensure your user is in a trusted group. On macOS with Determinate Systems' Nix, configure trusted users in `/etc/nix/nix.custom.conf`: + +```bash +# macOS with Determinate Nix (recommended) +sudo tee /etc/nix/nix.custom.conf << 'EOF' +trusted-users = root @admin @staff +trusted-substituters = https://cache.flakehub.com https://movementlabs.cachix.org +trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= movementlabs.cachix.org-1:qqCkWyzFSZCH2Tcy/HPRXVOOlYR3Sv+4GKMXSZtyN8s= +accept-flake-config = true +EOF + +# Linux with standard Nix +sudo sh -c 'echo "trusted-users = root @wheel" >> /etc/nix/nix.conf' +``` + +**Important**: On macOS, using groups (`@admin`, `@staff`) is more reliable than individual usernames. + +Then restart the Nix daemon: + +```bash +# macOS +sudo launchctl stop org.nixos.nix-daemon && sudo launchctl start org.nixos.nix-daemon + +# Linux +sudo systemctl restart nix-daemon +``` + +### Darwin framework linking errors (macOS) + +If you see framework-related errors on macOS, ensure Xcode command line tools are installed: + +```bash +xcode-select --install +``` + +### Disk space issues + +Nix stores build artifacts in `/nix/store`. To clean up old generations: + +```bash +# Remove old generations (keeps last 7 days) +nix-collect-garbage --delete-older-than 7d + +# Remove all unreachable paths +nix-collect-garbage -d +``` + +### Build taking too long + +Without Cachix configured, builds must compile everything from source. Set up Cachix (see [Cachix Setup Guide](./nix-cachix-setup.md)) to pull pre-built binaries. + +### "public key is not valid" Error + +If you see `error: public key is not valid` when running any nix command: + +**Cause**: Determinate Nix adds FlakeHub cache keys to `/etc/nix/nix.conf` by default. These keys can trigger a validation error in some Nix versions. + +**Fix**: Edit `/etc/nix/nix.conf` and comment out or remove the `extra-trusted-public-keys` line containing FlakeHub keys: + +```bash +# Backup and edit the config +sudo cp /etc/nix/nix.conf /etc/nix/nix.conf.bak +sudo nano /etc/nix/nix.conf + +# Find and comment out this line (starts with): +# extra-trusted-public-keys = cache.flakehub.com-3:... cache.flakehub.com-4:... (etc) + +# Restart the daemon +# macOS: +sudo launchctl stop org.nixos.nix-daemon && sudo launchctl start org.nixos.nix-daemon + +# Linux: +sudo systemctl restart nix-daemon +``` + +**Note**: This removes FlakeHub cache integration but does not affect Cachix or other caches. If you need FlakeHub, contact Determinate Systems for support. + +## Understanding the Build System + +### File Structure + +- `nix/flake.nix` - Main Nix flake defining packages and development shells +- `flake.lock` - Locked input versions for reproducibility +- `Justfile` - Command runner recipes for common tasks +- `rust-toolchain.toml` - Rust version specification (1.86.0) + +### How Crane Works + +The build system uses [Crane](https://github.com/ipetkov/crane) for Rust builds: + +1. **Dependency caching**: `craneLib.buildDepsOnly` builds all dependencies once +2. **Incremental builds**: Only recompiles changed source code +3. **Binary caching**: Built artifacts can be cached in Cachix +4. **Platform handling**: Automatically handles Darwin/Linux differences + +### Build Artifacts + +- **Development builds**: Stored in `target/` (not reproducible) +- **Nix builds**: Stored in `/nix/store/` and symlinked to `result/` + +## Next Steps + +1. Set up [Cachix](./nix-cachix-setup.md) for faster builds +2. Run `just help` to see all available commands +3. Run `just list-binaries` for detailed build target information diff --git a/docs/nix-cachix-setup.md b/docs/nix-cachix-setup.md new file mode 100644 index 00000000000..126c2d70137 --- /dev/null +++ b/docs/nix-cachix-setup.md @@ -0,0 +1,285 @@ +# Binary Cache Setup Guide + +This document explains how to configure Nix binary caching so team members can share builds and avoid redundant compilation during PR reviews. + +## Overview + +With Cachix configured: +1. Developer A builds `aptos-node` and pushes to cache (~30 min) +2. Developer B reviewing the PR pulls the pre-built binary (~30 sec) +3. CI/CD can also populate the cache for main branch builds + +## One-Time Admin Setup + +**Someone with org admin access needs to do this once:** + +### 1. Create the Cachix Cache + +1. Go to https://app.cachix.org +2. Sign in with GitHub (use Movement Labs org account) +3. Create a new cache named `movementlabs` +4. Set it as **public** (allows anyone to pull without auth) +5. Note the signing key shown after creation + +### 2. Generate Auth Tokens + +Create tokens for team members and CI: + +1. Go to cache settings → Auth Tokens +2. Create tokens with **Write** permission +3. Distribute tokens securely to team members (1Password recommended) + +### 3. Verify the Public Key + +The flake uses this public key - verify it matches your cache: + +``` +movementlabs.cachix.org-1:qqCkWyzFSZCH2Tcy/HPRXVOOlYR3Sv+4GKMXSZtyN8s= +``` + +If different, update `nixConfig` in `flake.nix` and `nix/flake.nix`. + +## Developer Setup + +### Step 1: Add Yourself as Trusted User + +On macOS, using group-based trust (`@admin` or `@staff`) is more reliable than individual usernames: + +```bash +# For Determinate Nix on macOS (recommended) +# Using groups ensures all admin/staff users are trusted +sudo tee /etc/nix/nix.custom.conf << 'EOF' +trusted-users = root @admin @staff +trusted-substituters = https://cache.flakehub.com https://movementlabs.cachix.org +trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= movementlabs.cachix.org-1:qqCkWyzFSZCH2Tcy/HPRXVOOlYR3Sv+4GKMXSZtyN8s= +accept-flake-config = true +EOF + +# For standard Nix on Linux +sudo sh -c 'echo "trusted-users = root @wheel" >> /etc/nix/nix.conf' + +# Restart Nix daemon +# macOS: +sudo launchctl stop org.nixos.nix-daemon && sudo launchctl start org.nixos.nix-daemon + +# Linux: +sudo systemctl restart nix-daemon +``` + +**Note**: Using individual usernames (e.g., `trusted-users = root myusername`) may not work reliably on macOS with Determinate Systems' Nix. Using groups (`@admin`, `@staff`, `@wheel`) is the recommended approach. + +### Step 2: Install and Configure Cachix CLI + +```bash +# Option A: Standard installation (recommended) +nix profile add nixpkgs#cachix + +# Option B: Use via nix shell (no permanent install needed) +nix shell nixpkgs#cachix -c cachix --version +``` + +#### Troubleshooting: "public key is not valid" Error + +If you encounter the error `error: public key is not valid` when installing cachix, this is a known issue with certain key configurations. Use the workaround: + +```bash +# Install with only the cache.nixos.org key +nix profile add nixpkgs#cachix --option trusted-public-keys "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" +``` + +This bypasses the key validation issue while still using the official NixOS cache. The movementlabs cache will still work for other operations once cachix is installed. + +```bash +# Authenticate with your token (get from team lead or 1Password) +# Token is saved to ~/.config/cachix/cachix.dhall +cachix authtoken YOUR_AUTH_TOKEN +``` + +### Step 3: Verify Setup + +```bash +# Should not show "untrusted substituter" warnings +nix flake check --no-build +``` + +## Workflow: Building and Sharing + +### Push Your Builds to Cache + +After building locally, push to cache so others can pull: + +```bash +# Build a package +nix build .#aptos-node -L + +# Push the result to cache +cachix push movementlabs ./result + +# Or build and push in one command +nix build .#aptos-node -L | cachix push movementlabs +``` + +### Push All Binaries + +```bash +# Build all binaries +nix build .#all-binaries -L + +# Push the entire result (includes all 5 binaries) +cachix push movementlabs ./result +``` + +### Pull from Cache (Automatic) + +Once someone has pushed a build, others automatically get it: + +```bash +# This will download from cache if available, otherwise build +nix build .#aptos-node -L +``` + +You'll see cache hits in the output: +``` +copying path '/nix/store/xxx-aptos-node-0.1.0' from 'https://movementlabs.cachix.org'... +``` + +## PR Review Workflow + +### For PR Authors + +After pushing your PR branch: + +```bash +# Build and push so reviewers don't have to build +nix build .#all-binaries -L +cachix push movementlabs ./result + +# Add a comment to the PR +echo "Binaries pushed to Cachix - reviewers can pull with: nix build .#all-binaries" +``` + +### For PR Reviewers + +```bash +# Checkout the PR branch +gh pr checkout 123 + +# Build - will pull from cache if author pushed +nix build .#aptos-node -L + +# Test the binary +./result/bin/aptos-node --version +``` + +## CI/CD Integration + +Add to your GitHub Actions workflow: + +```yaml +- name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + +- name: Setup Cachix + uses: cachix/cachix-action@v14 + with: + name: movementlabs + authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' + +- name: Build and push + run: | + nix build .#all-binaries -L + cachix push movementlabs ./result +``` + +Store `CACHIX_AUTH_TOKEN` in GitHub repository secrets. + +## Troubleshooting + +### "Binary cache movementlabs doesn't exist" + +The cache hasn't been created yet. See "One-Time Admin Setup" above. + +### "Untrusted substituter" Warning + +Add yourself to `trusted-users` - see Step 1 in Developer Setup. + +### "Permission denied" When Pushing + +Your auth token doesn't have write access. Get a new token from an admin. + +### Cache Misses (Always Building from Source) + +1. The specific derivation hasn't been pushed yet +2. The flake inputs changed (different nixpkgs = different hashes) +3. Check if cache is configured: `nix show-config | grep movementlabs` + +### Slow Uploads + +Large binaries take time to upload. The `aptos-node` binary is ~200MB+. + +```bash +# Check upload progress with verbose output +cachix push movementlabs ./result -v +``` + +### "public key is not valid" Error + +If you see `error: public key is not valid` when running any nix command (including `nix build`, `nix develop`, or even `nix profile add nixpkgs#cachix`): + +**Cause**: Determinate Nix adds FlakeHub cache keys to `/etc/nix/nix.conf` by default. These keys can trigger a validation error. + +**Fix**: Edit `/etc/nix/nix.conf` and comment out or remove the `extra-trusted-public-keys` line containing FlakeHub keys: + +```bash +# Backup and edit +sudo cp /etc/nix/nix.conf /etc/nix/nix.conf.bak +sudo nano /etc/nix/nix.conf + +# Comment out this line (starts with): +# extra-trusted-public-keys = cache.flakehub.com-3:... cache.flakehub.com-4:... + +# Restart daemon (macOS) +sudo launchctl stop org.nixos.nix-daemon && sudo launchctl start org.nixos.nix-daemon + +# Restart daemon (Linux) +sudo systemctl restart nix-daemon +``` + +This does not affect Cachix - only FlakeHub cache is disabled. + +## How It Works + +### Nix Store Paths + +Each build produces a unique path like: +``` +/nix/store/abc123...-aptos-node-0.1.0 +``` + +The hash (`abc123...`) is determined by all inputs - source code, dependencies, build flags. Same inputs = same hash = cache hit. + +### Flake Configuration + +Cachix configuration is handled via your system's `/etc/nix/nix.custom.conf` rather than in the flake itself. This avoids "public key is not valid" errors that can occur when keys are specified in multiple places. + +When you follow the Developer Setup steps above, your system will be configured to use the Movement Labs Cachix cache automatically. + +### Dependency Caching (Crane) + +The flake uses crane's `buildDepsOnly` to cache dependencies separately: + +```nix +cargoArtifacts = craneLib.buildDepsOnly commonArgs; +``` + +Benefits: +- Dependencies cached independently of source changes +- Source-only changes rebuild faster even on cache miss +- Multiple binaries share the same dependency cache + +## Security Notes + +- The public key cryptographically verifies all downloaded artifacts +- Only authenticated users with write tokens can push +- The cache is read-only for unauthenticated users +- Never commit auth tokens to git - use environment variables or secrets managers diff --git a/flake.lock b/flake.lock index 7243e698a30..942c573c043 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,20 @@ { "nodes": { + "crane": { + "locked": { + "lastModified": 1765739568, + "narHash": "sha256-gQYx35Of4UDKUjAYvmxjUEh/DdszYeTtT6MDin4loGE=", + "owner": "ipetkov", + "repo": "crane", + "rev": "67d2baff0f9f677af35db61b32b5df6863bcc075", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" @@ -20,11 +35,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1755615617, - "narHash": "sha256-HMwfAJBdrr8wXAkbGhtcby1zGFvs+StOp19xNsbqdOg=", + "lastModified": 1765472234, + "narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "20075955deac2583bb12f07151c2df830ef346b4", + "rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b", "type": "github" }, "original": { @@ -52,6 +67,7 @@ }, "root": { "inputs": { + "crane": "crane", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", "rust-overlay": "rust-overlay" @@ -62,11 +78,11 @@ "nixpkgs": "nixpkgs_2" }, "locked": { - "lastModified": 1755916474, - "narHash": "sha256-r0WnHKwA8DQNSHDmN3LNaqu41GbWDYqLS7IQAGR+6Wg=", + "lastModified": 1765766816, + "narHash": "sha256-m2au5a2x9L3ikyBi0g3/NRJSjmHVDvT42mn+O6FlyPs=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "897ecf2b25be05e6ccb7661703f9f2fdec155f42", + "rev": "4f53a635709d82652567f51ef7af4365fbc0c88b", "type": "github" }, "original": { diff --git a/nix/flake.lock b/nix/flake.lock index 855cc86e497..942c573c043 100644 --- a/nix/flake.lock +++ b/nix/flake.lock @@ -1,12 +1,30 @@ { "nodes": { + "crane": { + "locked": { + "lastModified": 1765739568, + "narHash": "sha256-gQYx35Of4UDKUjAYvmxjUEh/DdszYeTtT6MDin4loGE=", + "owner": "ipetkov", + "repo": "crane", + "rev": "67d2baff0f9f677af35db61b32b5df6863bcc075", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1659877975, - "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "c0e246b9b822c0bc27cf052f6f64bd73064edf65", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -17,11 +35,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1665580254, - "narHash": "sha256-hO61XPkp1Hphl4HGNzj1VvDH5URt7LI6LaY/385Eul4=", + "lastModified": 1765472234, + "narHash": "sha256-9VvC20PJPsleGMewwcWYKGzDIyjckEz8uWmT0vCDYK0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "f634d427b3ef4e9d039676353688f388d8ffa350", + "rev": "2fbfb1d73d239d2402a8fe03963e37aab15abe8b", "type": "github" }, "original": { @@ -31,20 +49,40 @@ "type": "github" } }, + "nixpkgs_2": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { + "crane": "crane", "flake-utils": "flake-utils", "nixpkgs": "nixpkgs", "rust-overlay": "rust-overlay" } }, "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, "locked": { - "lastModified": 1665354512, - "narHash": "sha256-m8wKt+oO9lWWl3qG9JQ312Q5eCwTv9WJRGgS7BrZCU4=", + "lastModified": 1765766816, + "narHash": "sha256-m2au5a2x9L3ikyBi0g3/NRJSjmHVDvT42mn+O6FlyPs=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "e53b08f709564491808ee1470a8645c4ba4050d4", + "rev": "4f53a635709d82652567f51ef7af4365fbc0c88b", "type": "github" }, "original": { @@ -52,8 +90,23 @@ "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 -} \ No newline at end of file +} diff --git a/nix/flake.nix b/nix/flake.nix index 2593d0a9f75..e02574118e9 100644 --- a/nix/flake.nix +++ b/nix/flake.nix @@ -1,33 +1,274 @@ { description = "Aptos Core - Layer 1 blockchain"; + # Note: Cachix configuration is handled via system config (/etc/nix/nix.custom.conf) + # rather than here to avoid "public key is not valid" errors with some Nix versions. + # See docs/nix-cachix-setup.md for setup instructions. + inputs = { + # Use nixpkgs-unstable (25.11+) as required by crane nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; rust-overlay.url = "github:oxalica/rust-overlay"; + crane.url = "github:ipetkov/crane"; }; - outputs = { self, nixpkgs, flake-utils, rust-overlay }: - flake-utils.lib.eachDefaultSystem (system: + outputs = { self, nixpkgs, flake-utils, rust-overlay, crane }: + flake-utils.lib.eachSystem [ "aarch64-darwin" "x86_64-linux" ] (system: let overlays = [ (import rust-overlay) ]; pkgs = import nixpkgs { inherit system overlays; }; + lib = pkgs.lib; + stdenv = pkgs.stdenv; + + # Rust toolchain from rust-toolchain.toml rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml; - # Create a custom rustPlatform with the specified toolchain - customRustPlatform = pkgs.makeRustPlatform { - rustc = rustToolchain; - cargo = rustToolchain; + # Create craneLib with our toolchain + craneLib = (crane.mkLib pkgs).overrideToolchain rustToolchain; + + # Darwin SDK for macOS (new pattern as of nixpkgs 25.11+) + # See: https://discourse.nixos.org/t/the-darwin-sdks-have-been-updated/55295 + darwinBuildInputs = lib.optionals stdenv.isDarwin [ + pkgs.apple-sdk_15 + pkgs.libiconv + ]; + + # Source filtering - include Rust files and embedded assets + src = lib.cleanSourceWith { + src = ./..; + filter = path: type: + (craneLib.filterCargoSources path type) + || (builtins.match ".*\\.proto$" path != null) + || (builtins.match ".*\\.toml$" path != null) + || (builtins.match ".*\\.json$" path != null) # JWKS test keys (include_str!) + || (builtins.match ".*\\.pem$" path != null) # Cryptographic keys (include_str!) + || (builtins.match ".*\\.bpl$" path != null) # Boogie prover prelude (include_bytes!) + || (builtins.match ".*\\.mv$" path != null) # Move bytecode (include_bytes!) + || (builtins.match ".*\\.errmap$" path != null) # Move error descriptions (include_bytes!) + || (builtins.match ".*\\.yaml$" path != null) # Config test data (include_str!) + || (builtins.match ".*\\.txt$" path != null) # Test proofs and other text files (include_str!) + || (builtins.match ".*\\.html$" path != null) # API spec docs (include_str!) + || (builtins.match ".*\\.version$" path != null) # Version files (include_str!) + || (builtins.match ".*aptos-move/.*" path != null) + || (builtins.match ".*movement-migration/.*" path != null); }; + # Platform-specific RUSTFLAGS + # SSE4.2 is only available on x86_64 + platformRustFlags = lib.optionalString (system == "x86_64-linux") "-C target-feature=+sse4.2"; + + # Common build inputs for all packages (platform-aware) + commonBuildInputs = with pkgs; [ + openssl + rocksdb + zlib + jemalloc + protobuf + ] ++ darwinBuildInputs ++ lib.optionals stdenv.isLinux [ + elfutils + udev + systemd + ]; + + # Common native build inputs + commonNativeBuildInputs = with pkgs; [ + pkg-config + cmake + clang + llvm + lld + protobuf + rustPlatform.bindgenHook + ]; + + # Library path for linking (platform-aware) + libraryPath = lib.makeLibraryPath ([ + pkgs.openssl + pkgs.rocksdb + pkgs.zlib + pkgs.jemalloc + pkgs.stdenv.cc.cc.lib + ] ++ lib.optionals stdenv.isLinux [ + pkgs.elfutils + ]); + + # Common arguments for all crane builds + commonArgs = { + inherit src; + strictDeps = true; + + buildInputs = commonBuildInputs; + nativeBuildInputs = commonNativeBuildInputs; + + # Environment variables + LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; + ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; + CARGO_BUILD_RUSTFLAGS = "${platformRustFlags} -C opt-level=3"; + JEMALLOC_SYS_WITH_MALLOC_CONF = ""; + + # Additional library paths for linking + LD_LIBRARY_PATH = libraryPath; + } // lib.optionalAttrs stdenv.isLinux { + # On Linux, use system jemalloc. On macOS, let jemalloc-sys build from source + # to get the correct _rjem_ prefixed symbols that jemallocator expects. + JEMALLOC_OVERRIDE = "${pkgs.jemalloc}/lib/libjemalloc.so"; + }; + + # Build dependencies only (for caching) + cargoArtifacts = craneLib.buildDepsOnly (commonArgs // { + pname = "aptos-deps"; + version = "0.1.0"; + # Use all workspace crates for deps caching + cargoExtraArgs = "--workspace"; + }); + + # Helper function to build a specific binary + mkPackage = { pname, cargoPackage ? pname, binary ? pname }: craneLib.buildPackage (commonArgs // { + inherit pname cargoArtifacts; + version = "0.1.0"; + cargoExtraArgs = "-p ${cargoPackage}"; + # Only install the specific binary + postInstall = '' + # Ensure only the target binary is in bin/ + if [ -f "$out/bin/${binary}" ]; then + echo "Binary ${binary} built successfully" + else + echo "Warning: Expected binary ${binary} not found" + ls -la "$out/bin/" || true + fi + ''; + }); + + # Individual package definitions + aptos-node = mkPackage { + pname = "aptos-node"; + cargoPackage = "aptos-node"; + binary = "aptos-node"; + }; + + # movement binary (CLI tool, formerly named aptos) + movement = mkPackage { + pname = "movement"; + cargoPackage = "movement"; + binary = "movement"; + }; + + l1-migration = mkPackage { + pname = "l1-migration"; + cargoPackage = "l1-migration"; + binary = "l1-migration"; + }; + + aptos-faucet-service = mkPackage { + pname = "aptos-faucet-service"; + cargoPackage = "aptos-faucet-service"; + binary = "aptos-faucet-service"; + }; + + aptos-transaction-emitter = mkPackage { + pname = "aptos-transaction-emitter"; + cargoPackage = "aptos-transaction-emitter"; + binary = "aptos-transaction-emitter"; + }; + + # All binaries combined + all-binaries = pkgs.symlinkJoin { + name = "aptos-all-binaries"; + paths = [ + aptos-node + movement + l1-migration + aptos-faucet-service + aptos-transaction-emitter + ]; + }; + + # Container runtime dependencies (Linux only - containers run on Linux) + containerRuntimeDeps = with pkgs; [ + jemalloc + elfutils + rocksdb + openssl + zlib + cacert + # For shell access in container debugging + bashInteractive + coreutils + ]; + + # Container for aptos-node (includes aptos-node, movement, l1-migration) + # Only available on Linux + container-aptos-node = if stdenv.isLinux then pkgs.dockerTools.buildImage { + name = "ghcr.io/movementlabsxyz/aptos-node"; + tag = "nix"; + + copyToRoot = pkgs.buildEnv { + name = "aptos-node-root"; + paths = [ + aptos-node + movement + l1-migration + ] ++ containerRuntimeDeps; + pathsToLink = [ "/bin" "/lib" "/etc" ]; + }; + + config = { + Env = [ + "LD_LIBRARY_PATH=/lib" + "SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt" + ]; + Entrypoint = [ "/bin/aptos-node" ]; + Cmd = [ "--version" ]; + WorkingDir = "/app"; + }; + + # Create backwards compatibility symlink: aptos -> movement + extraCommands = '' + mkdir -p app + ln -sf /bin/movement bin/aptos || true + ''; + } else null; + + # Container for aptos-faucet-service (Linux only) + container-aptos-faucet-service = if stdenv.isLinux then pkgs.dockerTools.buildImage { + name = "ghcr.io/movementlabsxyz/aptos-faucet-service"; + tag = "nix"; + + copyToRoot = pkgs.buildEnv { + name = "aptos-faucet-service-root"; + paths = [ + aptos-faucet-service + ] ++ containerRuntimeDeps; + pathsToLink = [ "/bin" "/lib" "/etc" ]; + }; + + config = { + Env = [ + "LD_LIBRARY_PATH=/lib" + "SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt" + ]; + Entrypoint = [ "/bin/aptos-faucet-service" ]; + Cmd = [ "-h" ]; + WorkingDir = "/app"; + }; + + extraCommands = '' + mkdir -p app + ''; + } else null; + in { packages = { - # Packages removed - using development shell approach instead - # Use 'just build' or 'just aptos-node' for building + inherit aptos-node movement l1-migration aptos-faucet-service aptos-transaction-emitter; + inherit all-binaries; + default = all-binaries; + } // lib.optionalAttrs stdenv.isLinux { + inherit container-aptos-node container-aptos-faucet-service; }; devShells = { @@ -49,57 +290,113 @@ protobuf libclang llvm - lld # Add lld linker for Rust builds - elfutils - elfutils.dev # Add elfutils dev package for headers - elfutils.out # Add elfutils main package for libdw.so.1 - zlib # Added zlib library - pkgs.udev - jemalloc # Added jemalloc for jemalloc-sys override + lld + zlib + jemalloc # Development tools git curl jq nodejs + ] ++ lib.optionals stdenv.isDarwin [ + apple-sdk_15 + libiconv + ] ++ lib.optionals stdenv.isLinux [ + elfutils + elfutils.dev + elfutils.out + udev ]; # Environment variables for library paths LIBCLANG_PATH = "${pkgs.libclang.lib}/lib"; BINDGEN_EXTRA_CLANG_ARGS = "-I${pkgs.libclang.dev}/include"; - + # Add PKG_CONFIG_PATH to help find libraries - PKG_CONFIG_PATH = "${pkgs.elfutils.dev}/lib/pkgconfig:${pkgs.zlib}/lib/pkgconfig:$PKG_CONFIG_PATH"; - + PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" ([ + pkgs.zlib + ] ++ lib.optionals stdenv.isLinux [ + pkgs.elfutils.dev + ]); + # Additional library paths - LD_LIBRARY_PATH = "${pkgs.libclang.lib}/lib:${pkgs.llvm.lib}/lib:${pkgs.elfutils}/lib:${pkgs.elfutils.out}/lib:${pkgs.zlib}/lib:${pkgs.jemalloc}/lib:${pkgs.rocksdb}/lib:${pkgs.stdenv.cc.cc.lib}/lib:${pkgs.openssl.out}/lib:$LD_LIBRARY_PATH"; + LD_LIBRARY_PATH = lib.makeLibraryPath ([ + pkgs.libclang.lib + pkgs.llvm.lib + pkgs.zlib + pkgs.jemalloc + pkgs.rocksdb + pkgs.stdenv.cc.cc.lib + pkgs.openssl.out + ] ++ lib.optionals stdenv.isLinux [ + pkgs.elfutils + pkgs.elfutils.out + ]); # Environment variables for build configuration - CARGO_BUILD_RUSTFLAGS = "-C target-feature=+sse4.2 -C opt-level=3"; - RUST_BACKTRACE = 1; + CARGO_BUILD_RUSTFLAGS = "${platformRustFlags} -C opt-level=3"; + RUST_BACKTRACE = "1"; ROCKSDB_LIB_DIR = "${pkgs.rocksdb}/lib"; - + # Fix jemalloc-sys build issues with strerror_r JEMALLOC_SYS_WITH_MALLOC_CONF = ""; # Override jemalloc-sys to use system jemalloc instead of building from source - JEMALLOC_OVERRIDE = "${pkgs.jemalloc}/lib/libjemalloc.so"; + JEMALLOC_OVERRIDE = if stdenv.isLinux then "${pkgs.jemalloc}/lib/libjemalloc.so" else "${pkgs.jemalloc}/lib/libjemalloc.dylib"; # Shell hooks to ensure correct toolchain is used shellHook = '' echo "Welcome to the Aptos Node development environment" echo "Run 'cargo build' to build the project" - + echo "" + echo "Nix build commands available:" + echo " nix build .#aptos-node - Build aptos-node binary" + echo " nix build .#movement - Build movement CLI binary" + echo " nix build .#l1-migration - Build l1-migration tool" + echo " nix build .#aptos-faucet-service - Build faucet service" + echo " nix build .#aptos-transaction-emitter - Build transaction emitter" + echo " nix build .#all-binaries - Build all binaries" + ${lib.optionalString stdenv.isLinux ''echo " nix build .#container-aptos-node - Build aptos-node container"''} + echo "" + # Ensure Nix-provided Clang and LLVM are used export PATH="${pkgs.clang}/bin:${pkgs.llvm}/bin:$PATH" ''; }; }; + # Apps for running binaries directly with 'nix run' apps = { aptos-node = { type = "app"; - program = "${self.packages.${system}.aptos-node}/bin/aptos-node"; + program = "${aptos-node}/bin/aptos-node"; + meta.description = "Aptos blockchain node"; + }; + movement = { + type = "app"; + program = "${movement}/bin/movement"; + meta.description = "Movement CLI tool"; + }; + l1-migration = { + type = "app"; + program = "${l1-migration}/bin/l1-migration"; + meta.description = "L1 migration utility"; + }; + aptos-faucet-service = { + type = "app"; + program = "${aptos-faucet-service}/bin/aptos-faucet-service"; + meta.description = "Aptos faucet service"; + }; + aptos-transaction-emitter = { + type = "app"; + program = "${aptos-transaction-emitter}/bin/aptos-transaction-emitter"; + meta.description = "Transaction testing and benchmarking tool"; + }; + default = { + type = "app"; + program = "${aptos-node}/bin/aptos-node"; + meta.description = "Aptos blockchain node (default)"; }; }; }); -} \ No newline at end of file +}