zeekay 8e04c4e23f evm: fix 0x9999 dispatch consensus-divergence on replay path + harden value/genesis edges (v1.99.34)
Red review of the 0x9999 dated-fork activation (v1.99.33) found ONE HIGH that
blocked the production deploy, plus a money-path footgun and two guards. The
money path (V4 swap ABI, EXTCODESIZE marker, two-phase atomic settle) is
byte-for-byte unchanged — only the dispatch-path timestamp source, the SubBalance
fail-mode, the genesis-builder guard, and stale comments change. Bumps
precompile v0.5.53 -> v0.5.54 (Red L1 comment scrub).

H1 (HIGH, blocked deploy) — consensus-divergence on the relaunch/replay path:
  core.LuxPrecompileOverrider.PrecompileOverride read the PROCESS-GLOBAL
  params.lastRulesContext via GetRulesExtra(Rules{}). That global is rewritten
  last-writer-wins by SetRulesContext on every Rules()/RulesAt() — including
  concurrent eth_call/estimateGas/miner goroutines. The geth EVM invokes
  PrecompileOverride LAZILY during opcode execution, a different instant than when
  precompileHook set the global. On a live, RPC-serving post-fork node replaying a
  PRE-fork RLP block (admin.importChain), a concurrent post-fork eth_call could
  overwrite the global timestamp between the verify goroutine's NewEVM(pre-fork
  block) and its tx dispatch -> the pre-fork block sees 0x9999 ENABLED and
  dispatches SettleContract.Run during plain-account execution -> STATE DIVERGENCE.
  Fix: the dispatch gate now decides from the overrider's OWN per-EVM fields
  (o.chainConfig + o.timestamp) via the pure params.GetExtrasRules — which performs
  the SAME dated-fork (extras.IsDexSettleActive) computation GetRulesExtra did,
  minus the racy global read. Audited every GetRulesExtra reader: only the overrider
  was on the precompile-dispatch path; no other dispatch/consensus-replay call site
  consults the 0x9999 gate. Every replay of a given block now yields the same
  enabled set on every validator, independent of concurrent activity.

L2 (money-path footgun) — registry stateDBBridge.SubBalance fail-open silent mint:
  when the subBalancer type-assertion failed it logged + returned a zero 'previous
  balance' WITHOUT subtracting, while the caller treats the debit as successful ->
  native value minted. Now FAILS CLOSED: it panics, which the EVM recovers into a
  reverted call, so the enclosing value move rolls back rather than committing
  half-done. Structurally unreachable in prod (the concrete adapter implements
  SubBalance) but no longer mints if a future StateDB omits it.

INFO1 (latent footgun) — genesis-config builders bypassed the dated fork:
  SetAllGenesisPrecompiles/AllGenesisPrecompiles iterated ALL RegisteredModules()
  incl the AlwaysOn 0x9999 and wrote timestamp-0 genesis configs, which would enable
  0x9999 from block 0 on a fresh chain — bypassing the dated fork and re-introducing
  the genesis-marker mutation. Both builders now skip AlwaysOn modules.

INFO2 (tests):
  - core: -race regression TestDexSettle_PrecompileOverride_NoGlobalRace reproduces
    the exact relaunch race (pre-fork verify vs concurrent post-fork eth_call
    clobbering the global) and asserts the pre-fork side ALWAYS sees 0x9999 ABSENT,
    post-fork ALWAYS PRESENT. PerEVMTimestamp pins the gate reads o.timestamp not the
    global. Replay e2e asserts a pre-fork value transfer to 0x9999 credits a PLAIN
    account WITHOUT invoking the precompile. All proven to FAIL under the old
    global-read code and PASS under the fix; -race clean.
  - extras + core: TestGenesisPrecompileBuilders_SkipAlwaysOn / _Skip9999 pin INFO1.
  - subbalance test comment refreshed to 0x9999 + fail-closed semantics.
2026-06-21 12:42:42 -07:00
2026-06-02 23:01:55 -07:00
2025-08-01 01:23:42 +00:00
2025-07-21 19:04:03 -05:00
2021-12-15 12:28:56 -08:00
2022-06-27 15:40:58 -04:00
2025-07-21 21:10:03 -05:00
2025-08-01 01:23:42 +00:00
2025-08-01 01:23:42 +00:00
2025-08-01 01:23:42 +00:00

Lux EVM

Releases CI CodeQL License

Lux is a network composed of multiple blockchains. Each blockchain is an instance of a Virtual Machine (VM), much like an object in an object-oriented language is an instance of a class. That is, the VM defines the behavior of the blockchain.

Lux EVM is the unified Virtual Machine (VM) that powers both the C-Chain and L1/L2 Subnet EVM chains. This package consolidates the former Coreth (C-Chain) and Subnet EVM codebases into a single implementation.

Note

: The github.com/luxfi/coreth repository has been deprecated and merged here. See the migration guide below.

This chain implements the Ethereum Virtual Machine and supports Solidity smart contracts as well as most other Ethereum client functionality.

Building

The Subnet EVM runs in a separate process from the main Luxd process and communicates with it over a local ZAP-native connection (LP-186 wire schema, no protobuf, no gRPC).

Luxd Compatibility

[v0.7.0] [email protected] (Protocol Version: 38)
[v0.7.1] [email protected] (Protocol Version: 39)
[v0.7.2] [email protected]/1.13.0-testnet (Protocol Version: 39)
[v0.7.3] [email protected]/1.13.0 (Protocol Version: 39)
[v0.7.4] [email protected] (Protocol Version: 40)
[v0.7.5] [email protected] (Protocol Version: 41)
[v0.7.6] [email protected] (Protocol Version: 42)
[v0.7.7] [email protected] (Protocol Version: 42)

API

The Subnet EVM supports the following API namespaces:

  • eth
  • personal
  • txpool
  • debug

Only the eth namespace is enabled by default. Full documentation for the C-Chain's API can be found here.

Compatibility

The Subnet EVM is compatible with almost all Ethereum tooling, including Remix, Metamask, and Foundry.

C-Chain vs Subnet EVM Mode

This unified EVM package supports both modes:

C-Chain Mode (Primary Network):

  • Atomic transactions for cross-chain transfers (X-Chain ↔ C-Chain)
  • Shared memory integration
  • Primary network consensus

Subnet EVM Mode (L1/L2 Subnets):

  • Configurable fees and gas limits in genesis
  • Simplified hardfork configuration
  • No atomic transactions (cross-chain via Warp messaging)

Migrating from Coreth

If you were using github.com/luxfi/coreth, update your imports:

// Before
import "github.com/luxfi/coreth/core"

// After
import "github.com/luxfi/evm/core"

All coreth functionality is preserved in this package.

Block Format

To support these changes, there have been a number of changes to the EVM block format compared to what exists on the C-Chain and Ethereum. Here we list the changes to the block format as compared to Ethereum.

Block Header

  • BaseFee: Added by EIP-1559 to represent the base fee of the block (present in Ethereum as of EIP-1559)
  • BlockGasCost: surcharge for producing a block faster than the target rate

Create an EVM Subnet on a Local Network

Clone EVM

First install Go 1.23.9 or later. Follow the instructions here. You can verify by running go version.

Set $GOPATH environment variable properly for Go to look for Go Workspaces. Please read this for details. You can verify by running echo $GOPATH.

As a few software will be installed into $GOPATH/bin, please make sure that $GOPATH/bin is in your $PATH, otherwise, you may get error running the commands below.

Download the evm repository into your $GOPATH:

cd $GOPATH
mkdir -p src/github.com/luxfi
cd src/github.com/luxfi
git clone [email protected]:luxfi/evm.git
cd evm

This will clone and checkout to master branch.

Run Local Network

To run a local network, it is recommended to use the lux-cli to set up an instance of EVM on a local Lux Network.

There are two options when using the Lux-CLI:

  1. Use an official EVM release: https://docs.lux.network/subnets/build-first-subnet
  2. Build and deploy a locally built (and optionally modified) version of EVM: https://docs.lux.network/subnets/create-custom-subnet

Releasing

You can refer to the docs/releasing/README.md file for the release process.

Plugin Runtime Env Vars

The EVM plugin reads its rpcchainvm handshake address and transport from the unprefixed env var names that current luxd (v1.26+) sets: VM_RUNTIME_ENGINE_ADDR and VM_TRANSPORT. This matches the canonical names defined in luxfi/vm/rpc/runtime/runtime.go. Earlier builds of this plugin (via luxfi/vm ≤ v1.1.0) read LUX_VM_RUNTIME_ENGINE_ADDR/LUX_VM_TRANSPORT, which are no longer recognized.

S
Description
▼ LUX EVM: Launch your own Ethereum compatible EVM on Lux Network.
Readme
548 MiB
Languages
Go 96.1%
Solidity 1.6%
Shell 1.3%
TypeScript 0.9%
Makefile 0.1%