471 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 38562d5a18 Build on Go 1.27
Build and vet are clean on the go1.27.1 toolchain. Five packages carry
pre-existing test failures -- core, eth/gasprice, internal/ethapi and the
two params/extras suites -- and they fail identically with this change
reverted, including the same invalid chainID 0 panic.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-17 12:59:44 -07:00
zeekayandHanzo Dev f3598dea65 Take the suite release where every config key is <name>Config
precompile v0.19.22 renames the eleven modules that keyed off Verify, Threshold or
Encapsulate, so the fifty-six this registry links now answer to one convention.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 19:36:29 -07:00
zeekayandHanzo Dev 8c06c66a86 registry: link the precompile suite by its own registry
This file named 41 suite packages one by one so their init() would run, because
luxd rejects an upgrade.json activation for a configKey it has never seen with
"unknown precompile config". That made it a second record of what the suite
contains, and it had drifted: aivmbridge, swap and v3 registered in the suite and
were absent here, so no Lux chain could activate them however its genesis was
written.

Importing the suite's registry instead cannot drift — that package derives its set
from the packages that actually register rather than from a list. One record, kept
in the repository that owns the thing recorded.

The list was also pinned to suite v0.19.8 while the suite had moved to v0.19.21,
so even the import alone left 14 of 56 modules linked. With the bump the surface
a luxd built from this module dispatches is 56, which is exactly what the suite
holds — measurable rather than asserted: cmd/surface prints it, and it is the
list an upgrade.json is allowed to name.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 17:59:23 -07:00
zeekayandHanzo Dev 09365ab664 Import says how many blocks a round holds, and says it once
Three things, all in the import path.

The tree did not build. plugin/evm/vm_database.go names AncientShared and
FreezeThreshold on rawdb.OpenOptions; luxfi/geth v1.20.2 has neither and v1.20.3
has both, so a clean checkout failed to compile before any change. Pinned to
v1.20.3.

The blocks-per-round was the literal 2500 inside importBlocksFromFile, so the
only way to change it was to edit and rebuild. It is a parameter now:
admin_importChain takes an optional count, --import-chain-batch sets it for the
startup path, and defaultImportBatch stands in when neither says. The right
number is a property of the machine -- a host with memory to spare amortises one
InsertChain call over far more blocks -- so it does not belong in the source.

Both importers wrote their own copy of the same closure to advance the accepted
marker and commit. There is one persistAcceptedBlock now and both hand it to the
importer. What genuinely differs between them -- the startup path reconciles the
export frontier and syncs consensus state afterwards, because it runs before the
engine is live -- stays where it belongs.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-09 12:34:34 -07:00
zeekayandHanzo Dev 9f54b4984a Depend on the renamed utility package
github.com/luxfi/utils is now github.com/luxfi/util. Import paths and the
module requirement follow the rename, and the luxUtils alias becomes luxUtil.
The old module stays as an indirect requirement that published dependencies
still pull in.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-06 04:33:21 -07:00
zeekayandHanzo Dev 84548b353e deps: pin consensus v1.36.73
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-21 12:28:51 -07:00
zeekayandHanzo Dev e9a8a37514 deps: pin consensus v1.36.72
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-21 12:13:26 -07:00
zeekayandHanzo Dev 6163864204 deps: align EVM plugin with node runtime
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-21 11:51:37 -07:00
zooqueen 0c6e661fec deps: consensus v1.36.3 2026-08-20 22:11:11 -07:00
zeekayandHanzo Dev cf035c527f deps: vm v1.3.12 — a summary is accepted once and a failed accept says so
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-16 08:59:03 -07:00
zeekayandHanzo Dev 1f1ba10a23 deps: vm v1.3.11 — the plugin can answer the state-sync messages
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-16 08:49:18 -07:00
zeekayandHanzo Dev 1bfeb1378b deps: vm v1.3.9 — a recovered panic carries its stack
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-15 23:59:20 -07:00
zeekayandHanzo Dev 4666b68406 deps: vm v1.3.8 — the block handlers stop dereferencing an empty answer
The C-Chain runs as a plugin, so the ZAP server that answers the node lives in
this binary, not in luxd. A node bump alone leaves the old server in place.

v1.3.8 refuses a VM that returns neither a block nor a reason instead of
dereferencing it, and stops reporting an unnamed failure with the code that
means success.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-15 22:44:08 -07:00
zeekayandHanzo Dev c9694b5871 deps: precompile v0.19.8
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-07 08:21:49 -07:00
zeekayandHanzo Dev cd6ebc6e88 deps: precompile v0.19.7 — the C->D object carries the taker's order
The 0x9999 swap intent gains the operation segment (market, side, limit, size)
appended to the unchanged 69-byte value head. Without it the D-Chain could
consume an intent and credit the taker, but had nothing to place an order with,
so no swap ever crossed and no settlement object was ever produced for
ImportSettlement to consume.

No change to this repo's own code: the D->C settlement object it authenticates
at Block.Verify is still the canonical 69 bytes. Only the C->D leg widened, and
only the C->D leg instructs.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-07 08:16:03 -07:00
zeekayandHanzo Dev 03bd49360b deps: precompile v0.19.6 — the cross-chain object rides in the transaction
Picks up the settle-path change that makes a settled swap replayable: both
C-side consume paths bind to the object bytes the transaction carries and
declare the consumption, instead of reading shared memory mid-execution.
The block-level authentication of that declaration is in this repo
(plugin/evm/dex_atomic_verify.go).

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-07 06:42:07 -07:00
zeekayandHanzo Dev 6ac40f43f7 deps: vm v1.3.6, precompile v0.19.5, api v1.1.3
Picks up the cross-chain atomic capability across the ZAP plugin boundary.
The EVM runs out of process, so its rebuilt Runtime had SharedMemory nil and
BCLookup absent; every DEX 0x9999 settlement reverted "requires the
cross-chain atomic capability" and the Accept-time flush of staged C->D
exports silently no-opped. vm v1.3.6 dials the node's per-chain atomic
server at Initialize and installs both.

precompile v0.19.5 additionally tags C->D swap intents with the discovery
trait the D-Chain enumerates by, without which a real intent is invisible to
D's import drive even once the transport works.

accel v1.2.4 -> v1.3.1 is forced by MVS through precompile, not chosen:
pinning it back drags precompile to v0.19.3.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-06 14:32:30 -07:00
zeekayandHanzo Dev 910950602b deps(evm): luxfi/vm v1.3.1 -> v1.3.3 — the C-Chain plugin never got the map-race fix
node v1.36.35 bumped luxfi/vm to v1.3.3 for a chain.State map race. The C-Chain
does not run in the luxd binary — it is a plugin built from THIS module, and
this module still pinned v1.3.1. So the fix shipped in the process that does not
verify blocks and was missing from the one that does. Read straight off the two
binaries in a v1.36.35 pod:

  /luxd/build/luxd                    github.com/luxfi/[email protected]
  /luxd/build/plugins/mgj786NP7…      github.com/luxfi/[email protected]

It fired in production on lux-testnet luxd-0 within 5 minutes of the roll:

  fatal error: concurrent map writes
  github.com/luxfi/vm/components/chain.(*BlockWrapper).Verify
      luxfi/[email protected]/components/chain/block.go:44
  github.com/luxfi/vm/rpc.(*zapVMServer).handleBlockVerify
      luxfi/[email protected]/rpc/vm_server_zap.go:580

v1.3.3 is exactly the fix for that line — it takes state.blocksLock around
verifiedBlocks[blkID] = bw, which v1.3.1 wrote unlocked from every concurrent
ZAP RPC handler.

Worth flagging separately: the plugin dies while luxd survives, so the pod stays
Ready with restarts=0 and info.isBootstrapped(C) keeps answering true while
eth_blockNumber on /v1/bc/C/rpc times out. The readiness probe cannot see this
failure class; only a per-node tip probe can. Recovery is a pod delete.

go build ./plugin/... ./core/... clean, go vet clean, plugin/evm tests pass.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 09:02:26 -07:00
zeekayandHanzo Dev e216f5f573 deps: gpu v1.1.2 — the older tags name the wrong pkg-config package
gpu v1.0.1/v1.1.0 declare `#cgo pkg-config: lux-gpu` while including
<lux/gpu.h>. Those are two different libraries with confusingly similar names:

  luxgpu.pc   unified GPU acceleration, -lluxgpu,   Cflags -I${includedir}
  lux-gpu.pc  the DEX order matcher,    -llux_gpu,  Cflags -I${includedir}/lux

Under lux-gpu the include resolves to .../include/lux/lux/gpu.h, so every cgo
build failed with "fatal error: lux/gpu.h file not found" — the arm64 stall
signature documented in CLAUDE.md. libluxgpu.dylib is also what actually
exports _lux_gpu_ecrecover_batch.

gpu v1.1.2 already declares luxgpu; only the pin was stale. Builds clean with
CGO_ENABLED=1.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 08:43:44 -07:00
zeekay 2b9f6a58cd fix(deps): patch the AWS SDK EventStream DoS
eventstream -> v1.7.8, service/s3 -> v1.97.3 (minimum patched versions), plus
the luxfi escape versions that keep this module off the deleted geth v1.16.x
tags (crypto v1.20.2, constants v1.6.2, warp v1.24.1, ids v1.3.2, p2p v1.22.1).

Verified against a measured baseline: go test ./... is 58 ok / 7 fail BOTH with
and without this change — identical, so the failures are pre-existing.
2026-07-26 06:21:38 -07:00
zeekayandHanzo Dev 2d1de900e9 go.mod: bump luxfi/dex to v1.14.2 (secp256k1 Metal anchor link fix)
Picks up dex 34c2ad2 / v1.14.2, which gates the secp256k1 Metal anchor behind
dexgpu so a default darwin build links: previously the anchor referenced
secp256k1_ecrecover_address_batch_metal while the lib that defines it was only
linked under -tags dexgpu, breaking the link of the C-Chain plugin binary that
pulls dex/pkg/dex. `go build ./plugin/` now links the 68 MB plugin clean in the
default build.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-21 23:29:59 -07:00
zeekay b50fb82634 chore(deps): bump geth v1.20.1 + luxfi deps — stack unification 2026-07-15 11:23:26 -07:00
zeekayandHanzo Dev 6e53c6fb95 deps: api v1.0.15 -> v1.0.16 — align InitializeResponse wire with node
api v1.0.16 added Capabilities uint64 to zap InitializeResponse (Quasar-export
capability bit). The plugin built at v1.0.15 answered Initialize 8 bytes short,
so node-side Decode died with unexpected EOF — the cross-process ZAP e2e
(node vms/rpcchainvm/zap TestCEvm_DialsZAPdbServer) caught it. Additive field;
plugin leaves the bit clear until the EVM wires CapQuasarExport.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-14 06:59:42 -07:00
zeekayandHanzo Dev 1f8281597a chore(deps): luxfi/vm v1.2.5 -> v1.2.6 (ZAP VM-state serialization fix, parity with v1.104.3-hotfix)
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-07 20:33:18 -07:00
zeekayandHanzo Dev 32c041cb8a deps: dex v1.14.0 + precompile v0.19.0 — dexcore→dex fold alias (fork-safe integer wire)
The dex lx/dexcore→dex fold + exact-integer wire (F1-F5 fork fix, F9 mint fix)
requires bumping dex→v1.14.0 + precompile→v0.19.0. dex_value_wiring.go aliases
the folded matcher pkg as dexcore so the precompile 'dex' package stays distinct.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-02 11:01:40 -07:00
zeekay b2afccc5e2 deps: precompile v0.15.0 -> v0.16.0 (enable-everything surface)
Picks up the enable-everything custom-precompile change (RefuseUnderStrictPQ
removed from all verify-only precompiles; fflonk fail-closed; accel byte-
identity; dex/stableswap/graph determinism). Pairs with this module's standard-
precompile enable so the full builder surface is live in one plugin build.
2026-06-27 21:28:22 -07:00
zeekay 06091588fc evm: precompile v0.15.0 (active-only DEX money path) + retire pqcrypto bundle (standalone mldsa/mlkem/slhdsa); no dormant AtomicStager, no backward compat 2026-06-27 18:48:21 -07:00
zeekay 143c389e3f chore(deps): bump warp v1.22.0 -> v1.23.0, precompile v0.12.0 -> v0.13.0
warp v1.23.0 = typed finality-evidence model + Pulse->Corona relabel.
No evm consumer references the renamed symbols; warp/, warp/validators/, and
precompile/contracts/warp/ tests all pass. Pure dependency bump.
2026-06-27 14:45:17 -07:00
zeekay 2bc16e3494 refactor(warp): Core -> Message — track warp v1.22.0
Rename across the evm warp backend and the warp precompile: warp.Core ->
warp.Message, NewCore -> NewMessage, ParseCore -> ParseMessage, the .Core field
-> .Message, and local core/msgCore/testCore vars -> msg/testMsg. deps: warp
v1.21.0 -> v1.22.0, precompile v0.11.0 -> v0.12.0.

geth's core/types and core/vm imports are untouched — the rename is scoped to
the warp message type, never the geth core package. ./warp/... and
./precompile/contracts/warp/... green, including TestWarpWrongNetworkID.
2026-06-27 00:48:35 -07:00
zeekay a6b22c9824 refactor(warp,precompile)!: decomplect ZAP types — warp v1.21.0, precompile v0.11.0
Track the upstream rename across the evm warp backend
(warp/{service,backend,verifier_backend}) and the warp precompile
(precompile/contracts/warp/{config,contract,contract_warp_handler},
precompileconfig): SignedCore->Core, WarpEnvelope->Envelope.

Identifiers only — the digest D, ZAP c14n bytes and BLS Beam / Corona Pulse /
ML-DSA signing domains are unchanged. ./warp/... and
./precompile/contracts/warp/... green, including the 10k-validator predicate
sign->aggregate->verify.
2026-06-26 22:25:27 -07:00
zeekay f9280978e3 feat(warp): migrate evm onto warp v1.20.0 SignedCore/WarpEnvelope ZAP (drop deleted UnsignedMessage RLP API)
Hard-fork the last evm warp consumers onto the canonical ZAP message format
(one and one way only). warp v1.20.0 deleted UnsignedMessage; the signed
subject is now warp.SignedCore (D = keccak256(coreDST ‖ zap_c14n)) and the
signed wrapper is warp.WarpEnvelope. The BLS Beam signs warp.BeamSigningBytes(D).

deps: warp v1.19.5 -> v1.20.0, precompile v0.5.59 -> v0.10.0.

- warp/{backend,verifier_backend,service}: UnsignedMessage -> SignedCore;
  NewMessage -> NewWarpEnvelope; sign/verify over BeamSigningBytes(core.ID()).
- precompile/contracts/warp: ParseMessage -> ParseWarpEnvelope; .UnsignedMessage
  -> .Core; .Signature.(*BitSetSignature) -> .Beam (concrete). VerifyPredicate
  verifies the Beam over D with exported primitives (Bits + bls +
  BeamSigningBytes) because the precompile quorum denominator must include
  keyless validators, which warp.VerifyEnvelope/GetCanonicalValidatorSet reject.
- precompileconfig.WarpMessageWriter.AddMessage(*SignedCore) (mirrors precompile v0.10.0).
- plugin/evm/vm.go: warpVerifierAdapter over *SignedCore; collapse the duplicate
  external-warp import alias (warptypes -> luxwarp).
- remove redundant warp/{aggregator,bls_adapter,signer_adapter}.go: provably-dead
  duplicates of warp.SignatureAggregator / warp.NewSigner (zero production refs).
- tests migrated to ZAP; fixed a pre-existing offchain message-key test bug;
  revived the predicate suite (validator state injected via Runtime, the
  production path, replacing the decoupled WithValidatorState key).

Verified: go build ./... green; go test ./warp/... ./precompile/contracts/warp/...
green (incl. 10k-validator TestWarpPredicate). grep UnsignedMessage = 0.
2026-06-26 21:27:25 -07:00
zeekay dd70b64d16 deps(evm): bump chains v1.3.19 -> v1.3.22 (restores dropped forbidden.go)
chains v1.3.19's dexvm/registry references AssertNoForbiddenAssetRefs,
looksLikeASCIITickerID, toHex and fromHex, but the file defining them
(forbidden.go) was dropped in that re-tagged release, so plugin/evm failed to
build (undefined symbols). The helpers are present again from v1.3.21; bump to
the latest v1.3 patch, v1.3.22.

MVS pulls the patch-level deps chains v1.3.22 requires: consensus v1.25.29,
crypto v1.19.26, dex v1.5.20 (zap v0.8.11 indirect). All x.x.x+ patch bumps, no
minor/major. Full repo builds; core/params/snapshot suites green and unchanged.
2026-06-26 20:03:21 -07:00
zeekay b02e2879a6 deps: bump chains v1.3.19 + consensus v1.25.21 + precompile v0.5.59 (no stragglers) 2026-06-23 09:29:06 -07:00
zeekay f849f49cdd deps: pin precompile v0.5.58 + runtime v1.1.3 (closes release-gate-b)
precompile v0.5.58 carries the 0x9999 value-path soundness floor (Block-STM
access-set, decentralized halt, in-state-vault/EVM-Call resolution; contains
the gate-b commit 23f49b6) and runtime v1.1.3 the GovernanceController seam
the value path reads. Builds standalone without go.work; gate-b closed
(evm no longer links the pre-fix precompile v0.5.57).
2026-06-23 01:08:42 -07:00
zeekay 54450ae372 deps: require precompile v0.5.57 (ERC-20 settle CALL-only DELEGATECALL guard)
Consumes luxfi/precompile v0.5.57 — the RED-CLEARED money-path fix adding the
CALL-only guard (ErrSettleWrongContext) on 0x9999/0x9996 Run. Pairs with this
repo's callableEnvAllowlist gate so the env Call surface reaches only the DEX
settlement family. go.sum regenerated via 'go mod tidy' against the tagged
module (GOWORK=off — the CI condition).
2026-06-22 14:37:01 -07:00
zeekay 582f78fe53 deps: consume precompile v0.5.56 (0x9999 swap-seam r2) 2026-06-21 22:47:49 -07:00
zeekay 4d8629eb6f deps: bump vm v1.2.5 + api v1.0.15 (UTXOAssetID rename — fixes LuxAssetID build break, latest patch) 2026-06-21 22:44:55 -07:00
zeekay 935da100ec deps: converge threshold v1.9.9 + crypto v1.19.21 + database v1.20.3 + geth v1.17.12 + warp v1.19.5 + metric v1.5.9 + proto v1.3.5 (latest patch within v1.x.x) 2026-06-21 22:38:15 -07:00
zeekay 5d775c144f evm: require precompile v0.5.55 (native 0x9999 DEXFill/Initialize emission) (v1.99.35)
Pins the precompile tag that exports dex.DexSettleActivationTime so the
dexsettle_guard DRY test compiles and enforces extras==dex mirror equality.
go test -tags dexsettle_guard ./core/ PASSES against the pinned tag.
2026-06-21 14:27:59 -07:00
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
zeekay d6a6584ad1 dex(0x9999): timestamp-gated dated-fork activation + marker install (v1.99.33)
Replace the v1.99.32 "always-on, dispatch-only, no marker" activation of the
0x9999 DEX settlement money path with the CTO's exact model: a SINGLE canonical
dated fork that both enables dispatch AND installs the EXTCODESIZE marker —
forward, at the fork boundary, never in historical genesis.

The fork: extras.DexSettleActivationTime = 1766704800 (Dec 25 2025 00:00:00 UTC),
defined ONCE in params/extras/network_upgrades.go alongside the Durango/Quasar/
Fortuna/Granite built-in upgrades. NOT per-net config (no per-net upgrade.json
precompileUpgrades entry, no genesisPrecompiles entry) — one dated fork, identical
on every Lux network, DRY. This is the proper canonical fork mechanism for a
system precompile that takes no per-net parameters (0x9999 resolves protocolFee-
Controller=DefaultDAOTreasury and dChainID at runtime from the consensus context).

Two coupled effects, both gated on that one timestamp:

  1. DISPATCH (params/config_extra.go GetExtrasRules): the AlwaysOnModules() inject
     into the enabled precompile set is now wrapped in extras.IsDexSettleActive(ts)
     — present at/after Dec 25, ABSENT before. This is REQUIRED for canonical
     history: replaying a pre-Dec-25 block (the ~/work/lux/state RLP snapshot, e.g.
     lux-mainnet 96369 = 1,082,780 blocks via admin.importChain) must see 0x9999 as
     a PLAIN ACCOUNT so a historical value transfer to that address behaves as it
     did originally, not as a precompile dispatch. The prior unconditional inject
     would have diverged replay from canonical state.

  2. MARKER (core/state_processor_ext.go ApplyPrecompileActivations): on the block
     transition that CROSSES the fork (params.IsDexSettleForkTransition →
     extras.IsForkTransition), write the STANDARD precompile-activation marker
     (SetNonce=1 + SetCode{0x1}) into 0x9999 — identical to the config-driven path.
     This is the forward state upgrade: EXTCODESIZE(0x9999)>0, eth_getCode!=0x, and
     Solidity's contract-existence guard passes for a typed IPoolManager(0x9999)
     .swap(...). The prior change DROPPED this marker to avoid mutating genesis;
     installing it forward at the fork preserves the genesis hash (pre-activation
     blocks get NO marker) while making typed calls work post-activation. Reverts
     the v1.99.32 "writes NO genesis state for always-on modules" skip.

IsForkTransition fires exactly once (!parentForked && currentForked). For a fresh
net whose genesis timestamp is already >= the fork (parent==nil), it fires at
genesis — so fresh/local/new nets carry the marker from block 0 via the SAME
mechanism, no separate genesisPrecompiles entry (CTO step 4). For an existing net
(genesis ts < fork) it does NOT fire at genesis — genesis hash immutable — and
fires forward at the Dec 25 block.

KEPT byte-for-byte: runtime DChainID via BCLookup.Lookup("D"), DefaultDAOTreasury
protocolFeeController, networkID/cChainID from runtime context, AlwaysOn module
tagging + AlwaysOnModules(), all settlement/money-path logic.

0x9010: with precompile v0.5.53 the 0x9010 module is no longer registered, so the
EVM never dispatches it and eth_getCode(0x9010)=0x. registry comment updated to
LP-9999. No EVM-side 0x9010 dispatch reference existed.

deps: precompile v0.5.52 -> v0.5.53.

Tests (core/precompile_alwayson_test.go, rewritten — DRY, replaces the prior
unconditional/no-marker assertions):
  - TestDexSettle_DispatchGate_TimestampGated: 0x9999 absent pre-fork, present
    at/after (replay safety + post-activation dispatch).
  - TestDexSettle_NoGenesisMarker_ExistingNet: genesis (ts<fork) writes no marker
    (genesis hash immutable).
  - TestDexSettle_MarkerInstalledAtForkTransition: marker (nonce=1 + code, EXTCODESIZE>0)
    installed at the boundary block.
  - TestDexSettle_ForkTransitionFiresOnce: fires once; fresh-net genesis>=fork at
    block 0; existing-net genesis<fork not at genesis.
  - TestAlwaysOn_9999_Registered: 0x9999 bridged AlwaysOn.
  core + params/extras green incl. the real-mainnet genesis-hash guards. (Two
  pre-existing unrelated failures on pristine main: params/config_test.go references
  a removed DurangoTimestamp field; params/extras mainnet upgrade.json ringConfig/
  warpConfig timestamp guards — both fail identically with these changes stashed.)
2026-06-21 12:09:46 -07:00
zeekay 570308a113 dex(0x9999): always-on settlement activation + runtime DChainID (v1.99.32)
Wire the EVM side of the always-on DEX settlement money path 0x9999. It is ACTIVE
on every chain from genesis with NO config entry — neither a genesis-inlined
precompile nor a precompileUpgrades timestamp. Zero per-net config, one way.

Activation is DISPATCH-only (genesis state is consensus-critical and immutable):
  - params.GetExtrasRules injects every modules.AlwaysOnModules() entry into the
    enabled precompile set unconditionally (every chain, every timestamp). This is
    what PrecompileOverride.IsPrecompileEnabled consults, so 0x9999 runs for a
    tx-to-0x9999, a low-level CALL/STATICCALL, and the 0x9010 V4 forward.
  - ApplyPrecompileActivations writes NO genesis state for always-on modules. An
    EXTCODESIZE marker at genesis would change the genesis hash and FORK existing
    networks (a fresh-syncing node would disagree with the committed genesis). The
    real lux-mainnet genesis hash is preserved (TestSkipPostMergeFieldsGenesisHash).
  - The always-on module's Configurator is never invoked (no activating config).

DChainID runtime resolution (THE crux): contract.AtomicState gains DChainID(); the
EVM adapter (accessibleStateAdapter) resolves it from the consensus context via
runtime.GetBCLookup().Lookup("D") — the dexvm "D"/"dex"/"dexvm" alias the node
registers in initChainAliases before any chain bootstraps. Identical on every
validator and re-execution; ids.Empty on a network with no dexvm (seam stays closed,
fail-secure). The registry bridge forwards DChainID across the internal/external
AtomicState surfaces. modules.Module gains AlwaysOn (+ AlwaysOnModules()), bridged
from github.com/luxfi/precompile.

deps: precompile v0.5.51 -> v0.5.52 (DChainID + AlwaysOn + always-on settle module).

Tests: core suite green incl. the real-mainnet genesis-hash guards. New
core/precompile_alwayson_test.go: 0x9999 registers AlwaysOn, is dispatch-enabled with
NO config at genesis + far-future ts, and writes NO genesis state (genesis-hash
immutability). (Two pre-existing unrelated failures: params/config_test.go references
a removed DurangoTimestamp field; mainnet upgrade.json aiMining/warp timestamp guards
— both fail identically on pristine main.)
2026-06-21 09:21:06 -07:00
zeekay e4b9114917 deps: bump geth v1.17.12 + precompile v0.5.51 for DEX native-atomic-seam release (v1.99.31) 2026-06-21 07:16:50 -07:00
zeekay 197d7d4136 deps: precompile v0.5.50 + clean go.sum (consensus/geth hashes corrected)
Bump precompile v0.5.49->v0.5.50 (clean go.sum; 0x9999 surface unchanged) and
regenerate evm's go.sum from a clean module cache (v1.99.29's consensus/geth
hashes were poisoned by a tampered local cache). No evm code change. go mod
verify clean; build+test green.
2026-06-20 22:12:29 -07:00
zeekay 9cb5053be8 plugin/evm: remove deprecated DexZap live-backend wiring; precompile v0.5.49
The C-Chain DEX settles certified D-Chain fill receipts at the 0x9999 precompile
(LP-9999); it never queries a live matcher. Remove the deprecated
DexZapEndpoint -> SetBackend(NewZAPEngine()) wiring from vm.go and the
DexZapEndpoint config knob: a synchronous in-block ZAP query against the
D-Chain's moving book forks consensus (each validator observes differently-timed
fills -> divergent StateRoot, proven by chains/dexvm
TestRED_PerValidatorRelay_SplitsConsensus). ZAP survives only as the dexvm's own
build-path transport, never as a C-Chain live backend. Receipts ride in V4 swap
hookData and are verified inline (deterministic BLS).

Bump github.com/luxfi/precompile v0.5.47 -> v0.5.49 to embed the complete,
red-swarm-hardened 0x9999 receipt-settlement surface.
2026-06-20 14:57:25 -07:00
zeekay 87dcd2552e deps: pin geth v1.17.11 + consensus v1.25.18 + precompile v0.5.47 (real semver); MVS-propagate transitive bumps 2026-06-19 14:43:16 -07:00
zeekay ab10a99880 evm: bump precompile v0.5.45 -> v0.5.46 (DEX embedded-engine vestige removed; one path inert | ZAP->D-Chain)
Builds CGO on+off; core SubBalance regression green.
2026-06-18 10:41:35 -07:00
zeekay c7b5c65227 evm v1.99.26: bump precompile v0.5.44 -> v0.5.45 (durable cancel-authorization binding)
Picks up the EVM-path 0x9010 cancel fix: the owner<->order cancel-auth binding
now lives in durable StateDB (PoolManager seam) instead of the backend's process
memory, so a cancel survives the EVM's ~5x multi-execution and a node restart.
Builds CGO on + off; core precompile SubBalance regression green.
2026-06-18 10:14:52 -07:00
zeekay 3d9ee0fb4f evm: FIX native-MINT bug in precompile StateDB bridge + precompile v0.5.44
CRITICAL: stateDBBridge.SubBalance type-asserts the concrete adapter else SILENTLY no-ops; the
internal contract.StateDB had AddBalance but no SubBalance and stateDBAdapter only implemented
AddBalance → a precompile debiting native value (DEX withdraw) CREDITED the caller while debiting
NOTHING = native mint (caught live: vault 100000, wallet +100000). The DEX is the first precompile
to debit native value so the path was never exercised. Added stateDBAdapter.SubBalance + regression
guard (core/precompile_statedb_subbalance_test.go); zero 'SubBalance fallback' warnings. Bump
precompile v0.5.43→v0.5.44 (PoolManager pure-ingress custody).
2026-06-17 22:30:58 -07:00
zeekay c45e87b670 evm: bump luxfi/precompile v0.5.42 → v0.5.43 (autoSettle removed; non-native legs deposit into D-Chain) 2026-06-17 21:11:12 -07:00