Files
zeekay 91a5f90bb8 fix: build again — live node tag, PQ precompile split, genproto ambiguity
`go build ./...` failed outright. Three separate causes, each fixed:

1. DELETED TAG. go.mod pinned luxfi/node v1.30.73, which no longer exists on
   GitHub — the entire v1.26–v1.30 line has been deleted (six versions:
   v1.26.34, v1.29.3, v1.30.4, v1.30.6, v1.30.9, v1.30.73). proxy.golang.org
   still serves them, but GOPRIVATE forces a direct fetch, so resolution fails
   with "unknown revision". Moved to v1.36.15 — the version 14 other repos in
   this workspace already run.

2. RELOCATED PACKAGE. `_ "github.com/luxfi/precompile/pqcrypto"` no longer
   exists; that package was SPLIT into one per primitive. Replaced the single
   blank import with the three it became:

       _ "github.com/luxfi/precompile/mldsa"
       _ "github.com/luxfi/precompile/mlkem"
       _ "github.com/luxfi/precompile/slhdsa"

   Verified each is the same mechanism before switching — all three have an
   init() calling modules.RegisterModule, which is what the old blank import
   was there for.

3. AMBIGUOUS IMPORT. google.golang.org/genproto/googleapis/rpc/status resolved
   in two modules at once — the old monolithic genproto and the split-out
   googleapis/rpc. Bumping genproto past the split removes its copy.

Verified: go build ./... goes from exit 1 to exit 0.

NOTE: an 83MB compiled `evm` binary is tracked in this repo. Building
regenerates it, so it shows as modified on any build. Deliberately restored
rather than committed here — untracking it is a separate call.
2026-07-26 07:08:49 -07:00

183 lines
4.8 KiB
Go

// Copyright (C) 2026, Zoo Labs Foundation. All rights reserved.
// See the file LICENSE for licensing terms.
// zoo-evm is the Zoo Network node -- a sovereign L1/L2 on the Lux Network
// running the Lux EVM with all PQ crypto, threshold sigs, and AI precompiles.
//
// Usage:
//
// zoo-evm Run the node (default)
// zoo-evm version Print version info
//
// When invoked as a VM subprocess (LUX_VM_TRANSPORT set), it enters EVM
// plugin mode. This lets a single binary serve as both the node process
// and the EVM plugin.
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"github.com/luxfi/evm/plugin/evm"
"github.com/luxfi/evm/plugin/runner"
"github.com/luxfi/node/app"
"github.com/luxfi/node/config"
nodeversion "github.com/luxfi/node/version"
luxversion "github.com/luxfi/version"
"github.com/spf13/pflag"
"golang.org/x/term"
// Zoo precompiles -- blank imports trigger init() registration.
// Post-quantum cryptography (NIST PQC standards)
_ "github.com/luxfi/precompile/blake3"
_ "github.com/luxfi/precompile/mldsa"
_ "github.com/luxfi/precompile/mlkem"
_ "github.com/luxfi/precompile/mldsa"
_ "github.com/luxfi/precompile/mlkem"
_ "github.com/luxfi/precompile/slhdsa"
_ "github.com/luxfi/precompile/slhdsa"
// Threshold signatures
_ "github.com/luxfi/precompile/cggmp21"
_ "github.com/luxfi/precompile/frost"
_ "github.com/luxfi/precompile/corona"
// Curves
_ "github.com/luxfi/precompile/ed25519"
_ "github.com/luxfi/precompile/secp256r1"
_ "github.com/luxfi/precompile/sr25519"
// DEX precompile (V4 pool manager at 0x9010)
_ "github.com/luxfi/precompile/dex"
)
// version is the zoo-evm release version.
const version = "0.1.0"
const header = `
______ ___ ___
|___ / / _ \ / _ \
/ / | | | | | | |
/ / | |_| | |_| |
/___| \___/ \___/
`
// Treasury address placeholder. Deploy from m/44'/60'/0'/0/0 of MNEMONIC.
// Genesis alloc uses 0x0000000000000000000000000000000000000000 until real
// treasury address is derived.
func main() {
// VM subprocess mode -- the node launched us as the EVM plugin.
if os.Getenv("LUX_VM_TRANSPORT") != "" {
versionStr := fmt.Sprintf("Zoo-EVM/%s [node=%s, rpcchainvm=%d]",
evm.Version, luxversion.Current, luxversion.RPCChainVMProtocol)
if len(os.Args) > 1 && os.Args[1] == "version" {
fmt.Println(versionStr)
os.Exit(0)
}
runner.Run(versionStr)
return
}
// Subcommand dispatch.
if len(os.Args) > 1 {
switch os.Args[1] {
case "version", "--version", "-v":
printVersion()
return
}
}
runNode()
}
func printVersion() {
versions := nodeversion.GetVersions()
fmt.Printf("zoo-evm %s (luxd %s)\n", version, versions.String())
}
func runNode() {
fs := config.BuildFlagSet()
v, err := config.BuildViper(fs, os.Args[1:])
if errors.Is(err, pflag.ErrHelp) {
os.Exit(0)
}
if err != nil {
fmt.Printf("couldn't configure flags: %s\n", err)
os.Exit(1)
}
if v.GetBool(config.VersionKey) {
fmt.Println(nodeversion.GetVersions().String())
os.Exit(0)
}
nodeConfig, err := config.GetNodeConfig(v)
if err != nil {
fmt.Printf("couldn't load node config: %s\n", err)
os.Exit(1)
}
// Install self as the standard EVM plugin so the node discovers us.
if err := installPlugin(nodeConfig.PluginDir, evm.ID.String()); err != nil {
fmt.Printf("couldn't install EVM plugin: %s\n", err)
os.Exit(1)
}
if term.IsTerminal(int(os.Stdout.Fd())) {
fmt.Print(header)
}
nodeApp, err := app.New(nodeConfig)
if err != nil {
fmt.Printf("couldn't start node: %s\n", err)
os.Exit(1)
}
os.Exit(app.Run(nodeApp))
}
// installPlugin creates a symlink of this binary in the plugin directory
// under the given VM ID name, so the node's VMRegistry discovers it.
func installPlugin(pluginDir string, vmIDStr string) error {
if pluginDir == "" {
home, err := os.UserHomeDir()
if err != nil {
return fmt.Errorf("couldn't get home dir: %w", err)
}
pluginDir = filepath.Join(home, ".lux", "plugins")
}
if err := os.MkdirAll(pluginDir, 0700); err != nil {
return fmt.Errorf("couldn't create plugin dir: %w", err)
}
pluginPath := filepath.Join(pluginDir, vmIDStr)
exe, err := os.Executable()
if err != nil {
return fmt.Errorf("couldn't get executable path: %w", err)
}
exe, err = filepath.EvalSymlinks(exe)
if err != nil {
return fmt.Errorf("couldn't resolve executable path: %w", err)
}
// Atomic install: create temp symlink, then rename (atomic on POSIX).
tmpPath := pluginPath + ".tmp." + strconv.Itoa(os.Getpid())
_ = os.Remove(tmpPath)
if err := os.Symlink(exe, tmpPath); err != nil {
// Fallback to hard link if symlink fails (e.g., cross-device).
if err := os.Link(exe, tmpPath); err != nil {
return fmt.Errorf("couldn't link plugin binary: %w", err)
}
}
if err := os.Rename(tmpPath, pluginPath); err != nil {
_ = os.Remove(tmpPath)
return fmt.Errorf("couldn't install plugin atomically: %w", err)
}
return nil
}