25 Commits
Author SHA1 Message Date
zeekay 2b42aa7f12 decomplect: drop redundant brand denylist from dexvm/registry
forbiddenChainTokens + IsForbiddenChainRef named the off-network white-label
universe by string to reject it. That negative gate is redundant: the
positive gate (ChainVerifier) already admits only real on-chain Lux assets,
so an off-network universe can never pass regardless. Removed the brand list
and the func; kept the genuinely-distinct guards (mock/synthetic liquidity,
ASCII-ticker-as-id). AssertNoForbiddenAssetRefs keeps its signature for the
gate's call shape. No brand strings remain; builds clean.
2026-06-24 11:10:32 -07:00
zeekay c5de091147 dexvm: Gate-A real-assets-only startup enforcement + LABELED rename
VM.Initialize now runs enforceRealAssetsOnly before marking initialized:
fail-closed over the consensus-supplied network identity (never operator-
spoofable). Refuses synthetic flags on a value net, value activation with no
legal consensus mode, a wrong-net/Liquidity manifest, value with no real
assets, bad allowed-kinds. Config gains the real-assets fields (manifest
path + SHA-256 pin, synthetic flags, consensus mode, caps/halt). Renames
HONEST_VALIDATOR_LAUNCH -> HONEST_VALIDATOR_LABELED across the registry
(value qualified by what it IS — labeled CFT parity — not when it runs).
Adds cmd/dex-assets-validate (CI proves every manifest entry real against
the target net RPC) + the validate-asset-manifests workflow. dexvm tests +
registry gate tests green.
2026-06-23 01:03:49 -07:00
zeekay e590e4a91c registry(dexvm): golden KAT — AssetID byte-parity with dexcore (MED-1)
Mirror the canonical cross-home golden KAT: registry.DeriveAssetID must reproduce
the EXACT 32-byte AssetID bytes that luxfi/dex pkg/dexcore.DeriveAssetID asserts
(AssetIDGoldenVectors). Fixed (networkID=2, source chain all-0x11, {ERC20, EVM_NATIVE,
UTXO}) → expected id vectors, byte-identical to the dexcore side. This locks the
resolve↔register equivalence the 0x9999 value path depends on: a registered AssetID
(here) and a swap-derived AssetID (dexcore, via the precompile resolver) name the SAME
asset by the SAME id. A drift in either home's preimage discipline now fails CI in BOTH
suites — a real consensus-identity divergence caught in test, never in prod.

Verified: CGO_ENABLED=0 go test ./dexvm/registry -run GoldenKAT green; the same three
vectors pass in dex/pkg/dexcore.
2026-06-22 22:51:00 -07:00
zeekay 5ff9aca513 feat(dex/registry): embed per-network asset manifests + localnet native builder
Make the per-network asset manifests (mainnet/testnet/devnet) available to a node
binary with no filesystem dependency, so the EVM plugin can build the 0x9999
value-path AssetResolver from the CI-approved, content-hashed asset set compiled
into the binary. Selection is by EVM chainID (96369/96368/96370). Localnet (1337),
whose C-Chain id is environment-specific, gets a runtime-rooted native-only manifest
(LocalnetNativeManifest) synthesised from the node's live cChainID — never a constant.

- embedded.go: //go:embed the three manifests; EmbeddedManifestFor(evmChainID) +
  LocalnetNativeManifest(networkID, cChainID).
- manifest.go: split decodeManifestBytes out of loadManifestBytes so the embed path
  and the disk path share one decoder (shape-validate + content-hash + unknown-field
  rejection identical for both).
2026-06-22 20:56:23 -07:00
zeekay 33634aad32 revert(dexvm): drop C<->D keeper RPC seam (dex.submitTx + dex.getSettlement)
The keeper/venue model is abandoned. The D-Chain (dexvm) trades via its own
consensus-driven state transition (matcher-at-Verify), not via an off-chain
keeper polling dex.getSettlement to drive 0x9999. Revert the three v1.3.16
commits' additions to the v1.3.15 working state:

  - vm.go:           remove GetSettlement + the proceeds-coordinate record
  - chainvm.go:      remove the SubmitTx RPC seam additions
  - api/service.go:  remove dex.submitTx + dex.getSettlement handlers
  - state/state.go:  remove PutSettlement/GetSettlement settlement index
  - api/submit_test.go, state/settlement_test.go: remove keeper-RPC tests

Deps are unchanged from v1.3.15 (go.mod/go.sum identical). bridgevm + dexvm
build clean and all tests pass.
2026-06-22 03:11:57 -07:00
zeekay 99ccfa4766 dexvm: record proceeds coordinate + dex.getSettlement RPC (keeper Phase-B input)
settleFromFills now records the proceeds D->C object's (outputID, amount) under the
collateral ref (the C->D intentID) via state.PutSettlement, written into the versiondb
so it commits atomically with the block. outputID = deriveUTXOID(settlementExportTx.ID(),
0) — the SAME key executeExport puts into shared memory — and the amount is the realized
proceeds; both are pure functions of consensus-agreed inputs (blockHash+txIndex seed the
export identity), so every validator writes the identical record and the StateRoot stays
consensus-safe. The record is purely informational (moves no value; never consulted by
the deterministic settle/consume path).

dex.getSettlement(collateralRef) reads it back (VM.GetSettlement -> state.GetSettlement)
so the off-chain keeper, after submitting the ImportTx + settling RelayOrderTx and the
proposer settles, learns the D->C object's outputID + amount and builds the C-side Phase-B
ImportSettlement (DS01 outputID|amount|intentID) that consumes the object and emits DEXFill.
This closes the keeper's export-discovery gap.

Tests: 3 state round-trip/isolation/escrow-coexistence + 3 RPC pending/found/bad-ref, all
pass (CGO_ENABLED=0; local cgo accel toolchain is broken — CI builds linux/amd64).
2026-06-22 02:23:46 -07:00
zeekay 0d8a06af7d dexvm: expose SubmitTx RPC (the C<->D keeper mempool seam)
The dexvm is a stateless atomic ZAP proxy whose ImportTx/RelayOrderTx/ExportTx
are deterministic block inputs, drawn from the proposer's pending pool. That pool
(ChainVM.SubmitTx -> pendingTxs + engine notify) was unreachable from outside the
process: CreateHandlers exposed only Ping/Status/Relay, so an off-chain keeper had
no way to inject the ImportTx that consumes the C->D atomic object the C-side
0x9999 SubmitSwapIntent writes, nor the settling RelayOrderTx. The full two-phase
seam therefore could not land a DEXFill.

This adds a dex.submitTx JSON-RPC method (api.Service.SubmitTx) that forwards
wire-encoded tx bytes to an api.TxSubmitter and returns the canonical
ids.Checksum256 tx id. The submitter is wired ONLY on the node path
(ChainVM.CreateHandlers builds the service with the ChainVM as submitter); the
inner VM's read-only CreateHandlers (standalone/test) reports ErrSubmitUnavailable.
Bootstrap-gated; admission/fee gate stays in ChainVM.SubmitTx. 6 unit tests cover
unavailable/not-bootstrapped/bad-hex/empty/success(verbatim+TxID)/submitter-error.
2026-06-22 01:23:00 -07:00
zeekay 4e0ddde49b dexvm: pin C<->D atomic seam wire (69-byte, spent witness) against precompile golden
The swap-seam HIGH fix (c242e01) extended encodeExportedOutput to 69 bytes
(rail|owner|asset|amount|spent), where the trailing spent witness carries the matched
INPUT amount on a D->C swap proceeds leg so the C-side ImportSettlement can enforce the
taker's recorded slippage limit. That widening MUST be byte-identical with the precompile's
exportedOutputSize9999 or D would export an object C cannot decode (every swap settlement
reverts ErrNativeSettleMalformed, no taker is ever credited).

native_seam_parity_test pins the lockstep on the D side: a hardcoded golden vector
(reproduced byte-for-byte by precompile/dex/native_seam_parity_test) + a round-trip that
proves the spent witness survives + a wrong-width rejection. If either repo's layout drifts,
one of the twin parity tests fails BEFORE the bytes reach consensus. Closes the dangling
'native_seam_parity_test pins it' reference in atomic.go.
2026-06-21 22:41:07 -07:00
zeekay 0777aeed15 dexvm: plumb fill-attestation pubkey through genesis + carry matched-spent on proceeds (swap-seam)
HIGH (inert attestation gate): FillAttestationPubKey was read by settleCarried but
NEVER written — parseConfig copied only 10 enumerated fields and parseGenesis carried
only DexZapEndpoint+TrustedChains. So in prod the pubkey was nil, verifyFillAttestation
returned nil, trustCarried was always true, and the fabricated-fills guard could never
engage: a malicious/MITM proposer could settle fabricated fills and drain a cross-taker's
seam reserve via the proceeds leg. Fix: add FillAttestationPubKey (hex) to the Genesis
struct + parseGenesis, assigned into vm.Config. It is GENESIS-pinned only — deliberately
absent from parseConfig — because it is consensus-affecting (gates trustCarried ->
escrow-consume + export legs -> computeStateRoot); a per-node value would fork the
StateRoot. A wrong-width key is a FATAL genesis error (fail-closed). FillAttestationSeed
stays json:"-" (KMS-only, never in a genesis/config blob).

MEDIUM (consensus comment): config.go now states the stronger invariant — the pubkey is
STRICTER than DexZapEndpoint (which is node-local transport, not recomputed in the
deterministic settle path) and MUST be a single genesis-pinned constant.

MEDIUM (taker-authenticated MEV floor): the proceeds export object now carries the matched
input (AtomicOutput.Spent; shared-memory object 61->69 bytes, both repos in lockstep) so
the C-side ImportSettlement can enforce the taker's OWN recorded slippage limit
(proceeds >= spent*worstRate) independently of the keeper's relay-supplied priceLimit. A
keeper that zeroes the relay limit to sandwich the taker still produces a proceeds object
C will refuse; understating spent loosens the floor but inflates refund, which the
per-taker principal cap + seam-reserve conservation independently bound.

Tests (redteam, CGO_ENABLED=0 pure Go): redteam_genesis_attestation_test drives a REAL
genesis blob through Initialize->parseGenesis (NOT a direct Config write) and proves the
pubkey reaches Config, a fabricated/unattested block becomes a full refund by virtue of
genesis alone, a wrong-width genesis key fails Initialize closed, and the runtime config
blob cannot set the consensus-affecting pubkey. native_seam canary pins the joint 69-byte
object wire (incl. spent) across both repos. Full dexvm redteam + unit suites green.
2026-06-21 22:41:07 -07:00
zeekay 8980d99883 dexvm: close HIGH-1 proceeds-unclaimable + MEV floor + fill attestation (swap-seam)
HIGH-1 (THE happy-path break, swapsWork=NO): settleFromFills exported the taker's
PROCEEDS leg under assetFromRef(ref,leg)=SHA256(ref||leg), a synthetic routing handle.
The C-side ImportSettlement requires recAsset==assetID(currency_out) (the injective id
that also keys seamReserve[assetOut]); a SHA256 handle never matched, so the proceeds
credit ALWAYS reverted (ErrNativeSettleAsset) and the taker never received their swap
output. FIX: settleFromFills exports the proceeds leg under the REAL output-asset id
carried with the settling relay (RelayOrderTx.AssetOut, signature-bound, keeper-asserted
and C-bound => a wrong value is taker-liveness-only, never theft/mint). Removed the dead
assetFromRef SHA256 helper. Kept the prior pass's owner-bind + one-time-consume +
per-intent binding intact.

MEDIUM (bounded sandwich/MEV): settleFromFills now enforces a worst-acceptable CLOB
price carried from the relay (RelayOrderTx.PriceLimit/LimitIsUpper, derived from the V4
SqrtPriceLimitX96): a fill worse than the limit is refused (BUY ceiling, SELL floor;
0=no limit), leaving the escrow reclaimable.

MEDIUM (single-proposer fabricated fills): populate+verify the reserved carried-fills
attestation. The venue signs blake3(domain||blockHash||entries) with Ed25519; every
validator verifies it before settling (verifyFillAttestation), gated behind
Config.FillAttestationPubKey (default-on once set; fail-secure full-refund when a block's
fills are unattested/forged). Config note: the pubkey MUST be identical across validators
(consensus-affecting, same class as DexZapEndpoint).

Tests (CGO_ENABLED=0, default + redteam): TestRED_SwapProceeds_* (unit + e2e happy-path
credit under the real output asset), TestRED_SwapSlippageLimit_*, TestRED_FillAttestation_*
(verify/forge/fabricated-refund/off-by-default). Full dexvm suite green.

Extends fix/swap-rail-escrow-owner-bind (27f4c35). Within chains v1.3.15.
2026-06-21 22:41:07 -07:00
zeekayandGitHub 6e46d242f6 Thinking Chains: chains (#6)
* dexvm: bind swap-settle authority+payout to authenticated escrow owner (CRITICAL escrow-theft fix)

The swap rail delegated per-taker refund-liveness + relay authority to the
unauthenticated RelayOrderTx sender with NO C-side owner binding, letting any
fee-paying tx name a victim's collateral ref and settle the locked collateral to
the attacker out of the shared seam reserve (cross-depositor theft).

Fix (load-bearing, derives authority from the already-authenticated cross-chain
object owner — the platformvm import/export model):
- state/state.go: escrow value is now owner(20)|asset(32)|amount(8); the owner
  leads. PutEscrow/GetEscrow carry it.
- atomic.go executeImport: persist the AUTHENTICATED importedOwner (read back from
  the consumed C->D shared-memory object) into the escrow.
- vm.go settleFromFills: a settle is authorized ONLY by the escrow's recorded
  owner (errSettleUnauthorized otherwise), and BOTH proceeds+refund legs export to
  that owner, never to the relay tx sender.
- txs/tx.go: RelayOrderTx.Verify now does present-gated secp256k1 authentication of
  From (Sign/SigningBytes/verifyFrom), wiring the dangling ErrInvalidSignature.
  From bears NO authority (authority is the escrow owner), so an unsigned relay is
  admissible and cannot escalate; a present-but-invalid signature is rejected.

Regression: redteam_escrow_owner_test.go proves the attacker is credited 0 even
with a valid own-key signature (defense in depth: escrow-owner bind holds
independent of the signature). Fixed a pre-existing off-by-one in
TestRED_FractionalFill (export asset offset). All dexvm tests pass (default +
-tags redteam, CGO_ENABLED=0 pure-Go).

Gated on red re-verify; NOT promoted to testnet/mainnet.

* aivm: A-Chain quorum-settlement engine (provider stake/slash, beacon selection, commit-reveal, settlement, receipt export, import committed C intent). LP-5300. NOTE: branched on swap-rail base; rebase to main on merge.

---------

Co-authored-by: zeekay <[email protected]>
2026-06-21 20:53:39 -07:00
zeekay a1169a810e dexvm: rail-tag the C<->D atomic object (D side of Red H1 fix)
The D side of the precompile/dex H1 rail-binding. The shared-memory object wire
goes 60->61 bytes: rail(1)|owner(20)|asset(32)|amount(8), byte-identical to the
precompile's exportedOutputSize9999. The rail tag is the lane the value travels
(RailSwap=0 default / RailLP=1) and round-trips through the atomic core unchanged.

- txs.AtomicOutput gains Rail; ImportTx/ExportTx.Verify enforce one-rail-per-leg
  (structural half, mirroring the asset bind).
- encode/decodeExportedOutput carry the rail byte (decode now returns rail too).
- executeImport binds the credited outputs' rail to the consumed UTXO's RECORDED
  rail (authoritative half; errImportMixedRails), so an import cannot re-lane
  value — a swap object onto the LP lane or vice-versa.
- executeWithdraw (the LP collect/withdraw export) stamps RailLP; the fill/refund
  settlement exports (settleFromFills) stay RailSwap (zero default).

New: TestNativeRail_ImportRejectsRailMismatch (both directions) +
TestNativeRail_ImportAcceptsMatchingRail (positive control). Wire-parity canary
TestNativeSeam_WireMatchesPrecompile asserts byte-identity on BOTH rails. LP-seam
round-trip + conservation/redteam offset helpers updated to the 61-byte wire.

CGO_ENABLED=0 GOWORK=off go test ./dexvm/... green.
2026-06-21 02:59:34 -07:00
zeekay fa7d32c86c dexvm: LP D-committed seam round-trip tests (commit import / collect export)
Prove the D side of the LP rail (precompile/dex 0x9999 modifyLiquidity /
collectPosition) consumes/produces the EXACT atomic wire WITHOUT any new D-side
primitive: a position-commit object (DL01) is byte-identical to any value object,
so the C->D commit leg == executeDeposit (atomic import -> CLOB ledger credit; the
position's collateral + fee accrual lives in the CLOB, funded by the consumed
object) and the D->C collect leg == executeWithdraw (debit realized balance ->
atomic export). Three tests: commit-funds-position (+ replay reject),
collect-exports-principal+fees, full round-trip conserves.
2026-06-21 02:15:54 -07:00
zeekay c8e45e6161 dexvm: native C<->D atomic seam round-trip tests
Prove the dexvm import/export wire is byte-identical to the precompile's atomic
object (TestNativeSeam_WireMatchesPrecompile), that a C->D object the precompile
PUT imports cleanly on D, that a D->C export the dexvm writes decodes as the
precompile's settlement object, and the full C->D->C round trip. Locks the
cross-chain seam compatibility the 0x9999 money path depends on.
2026-06-21 00:19:25 -07:00
zeekay 69d6251fa4 dexvm: bind import credit to consumed-UTXO asset/owner + custody hardening
executeImport reads the consumed UTXO owner|asset|amount from shared memory and binds the credit to it (rejects declared!=actual; native-aliasing closed); two-pass validate-then-consume so a rejected import mutates nothing. Withdraw-rail consume-once on fillRef.
2026-06-19 11:34:41 -07:00
zeekay 8f733194b3 chains/dexvm: atomic custody rail (custody.go) — deposit=import+credit, withdraw=debit+export
executeDeposit = executeImport (atomic C/X debit, consume-once) + clob_deposit relay (credit
D-Chain balance; refuses credited!=imported). executeWithdraw = clob_withdraw (debit, realized
clamped) + executeExport (credit exactly realized; refuses realized>want). Reuses the
conservation-tested ImportTx/ExportTx rail. custody_conservation_test: real atomic.SharedMemory,
deposit→trade→withdraw conserves C in==out, UTXO consumed once. NOTE: not yet wired into the
carried-fills BuildBlock plan (network-upgrade-gated follow-up, like #9).
2026-06-17 21:10:33 -07:00
zeekay 562bee534a chains/dexvm: #9 consensus-fork fix — proposer-relays-once + carry-fills-in-block
Decomplect obtain-fills (proposer, BuildBlock, once network-wide) from settle-from-carried-
fills (deterministic, Accept). No validator relays at Verify/Accept -> block output is a pure
fn of (height, carried ts, tx bytes, carried fills) -> byte-identical StateRoot. NEW
carried_fills.go wire section (block + vertex) with a RESERVED fill-signature field for the
future trustless path (no 2nd wire bump). #7 computeStateRoot completed (commits state+atomic).
TestRED_PerValidatorRelay_SplitsConsensus PASS (0 cross-validator relay); redteam 21/0 (37/0);
conservation/determinism green; race-clean. NETWORK-UPGRADE-GATED wire-format change.
2026-06-17 17:12:55 -07:00
zeekay 4e21d9910a chains/dexvm: rip out matcher+state -> stateless atomic ZAP proxy
orderbook/perpetuals/lending/mev dirs + backend.go deleted; vm.go 2230->830 lines.
NEW atomic.go (shared-memory import/export at Block.Accept) + relay.go (rpc.ZAPDial,
frame byte-identical to zapwire, no luxfi/dex dep). State holds only nonce:/receipt:/
consumed: -- no order/pool/position keys. txs reduced to import/export/relay. NEW
conservation_test.go::TestEndToEndAtomicValueConservation. Verified -tags dchain build+tests
green -race; grep matchAllOrders|tryMatch|crossOrders empty.
2026-06-17 13:31:58 -07:00
zeekay b8a2a5c4dc chains: scrub private-repo leakage from GPU bridges
OSS public chains module must not reference the private GPU plugin
implementation by repo name or filesystem path. Two leak types fixed:

1. Hard compile-time dependency in quantumvm:
   `#cgo CFLAGS: -I${SRCDIR}/../../../lux-private/gpu-kernels/include`
   Vendor the public ABI v14 header (backend_plugin.h + crypto.h, 1475
   LOC total) into chains/internal/luxgpu/include/lux/gpu/ and point
   CFLAGS at the in-tree path. Plugin DSO is still dlopen'd at runtime
   — only the public C ABI surface is vendored.

2. Soft leakage — `LUX_PRIVATE_GPU_KERNELS_DIR` env vocabulary, dev-tree
   probe paths to ~/work/lux-private/gpu-kernels/build/..., prose
   mentions of "lux-private/gpu-kernels" in package comments.
   All replaced with `LUX_GPU_PLUGIN_DIR` (universal env) and generic
   "GPU plugin" prose.

Bridges affected: aivm, bridgevm, dexvm, quantumvm, thresholdvm.
All 139 tests PASS post-scrub under both build tags. No functional
behavior change — only path / env / prose.
2026-06-05 15:46:00 -07:00
zeekay c1ef83cf34 dexvm: wire GPU plugin substrate via dlopen+dlsym
Adds four Go files to chains/dexvm so the DEX VM can call into the
lux-private/gpu-kernels plugin DEX launchers (AMM xyk + CLOB matcher +
BookArena lifecycle) without a build-time pkg-config dependency:

* backend.go            cross-build types: GPUBackend enum, LuxAmmReservePair
                        (16 bytes, byte-equal to include/lux/gpu/dex.h),
                        CLOB ABI constants, ErrGPUNotAvailable.
* dexvm_gpu.go (cgo)    dlopen probe at init() in order
                        cuda -> hip -> metal -> vulkan -> webgpu, resolving
                        lux_<backend>_{amm_xyk_batch,dex_clob_match,
                        dex_clob_arena_create,dex_clob_arena_destroy}.
                        Exposes AutoBackend / AMMSwap / CLOBMatch /
                        ArenaCreate / ArenaDestroy. unsafe.Sizeof guards
                        the AMM struct layout against silent ABI drift.
* dexvm_gpu_nocgo.go    symmetric stubs returning ErrGPUNotAvailable so
                        the package surface is identical under both tags.
* dexvm_gpu_test.go     round-trip test: dlopens the metal plugin (or any
                        other found under LUX_GPU_PLUGIN_DIR), runs a
                        single-pair AMM swap, asserts byte-equal output
                        to the CPU oracle (constant-product 1000 -> 1998
                        at rx=1M, ry=2M).

Existing dexvm vm.go / orderbook logic is untouched - consumers opt in
explicitly when ready. Both 'go build ./dexvm/...' and
'go build -tags cgo ./dexvm/...' are green.

Test output with LUX_GPU_PLUGIN_DIR=$HOME/work/lux-private/gpu-kernels/build-metal/backends/metal:
  --- PASS: TestGPUAMMSwapRoundTrip (0.08s) [backend=metal]
  --- PASS: TestGPUAMMSwapEmpty     (0.00s)
2026-06-05 14:54:56 -07:00
zeekay 9926e395b2 dexvm: gate user tx on FeePolicy (MinTxFee floor)
SubmitTx is the canonical user-mempool entry on D-Chain — every public
submission funnels through here. Attach a FlatPolicy at MinTxFeeFloor
(1 mLUX) in Initialize and gate SubmitTx through ValidateFee so
zero-fee user txs are refused before they touch pendingTxs. Internal
consensus-engine -> VM paths bypass the gate.
2026-05-21 16:47:55 -07:00
zeekay 38a694bde4 Consolidate VMs into single chains module; cevm Metal anchor + V4 dispatch
VM consolidation (one module, one place only):
- Removed per-VM go.mod/go.sum/VERSION from {aivm,bridgevm,dexvm,evm,
  graphvm,identityvm,keyvm,oraclevm,quantumvm,relayvm,thresholdvm,zkvm}
- All VMs now compile under github.com/luxfi/chains root module
- aivm/, dexvm/, identityvm/, keyvm/, oraclevm/ factory.go + vm.go updated
  for AccelHost wiring

cevm Go-side (evm/cevm/):
- cevm.go, cevm_cgo.go, cevm_nocgo.go: ExecuteBlockV4(backend, threads,
  txs, ctx, state) with StateAccount snapshot
- cevm_secp256k1.go: BatchRecoverSenders Metal LDFLAGS
- cevm_secp256k1_metal_anchor_darwin.{c,go}: anchor to keep linker from
  dropping libsecp256k1_metal.a
- cevm_secp256k1_nocgo.go: stub for non-cgo builds
- plugin.go, fetch-luxcpp.sh, luxcpp-SHA256SUMS, LUXCPP_VERSION:
  pinned luxcpp consumption
- evm/cevm/parallel/parallel.go: BlockExecutor adapter calls
  cevm.ExecuteBlockV4 with state snapshot built from txs+statedb

Quantum/ZK witness:
- quantumvm/quasar_witness.go, zkvm/zwitness.go

go.mod: removed dead `replace github.com/ethereum/go-ethereum => luxfi/geth`
directive (caused dual-path conflict after math semver bump; no remaining
ethereum/go-ethereum imports in source). go mod tidy clean.

Tests: TestBatchRecoverSenders PASS through Metal anchor (cevm package).
2026-05-05 10:17:49 -07:00
zeekay ccca40e63b fix: dexvm VMID type + quantumvm RPC name
- dexvm.VMID: [32]byte → ids.ID (consistent with other 10 VMs)
- quantumvm RPC service: "qvm" → "quantumvm" (matches package + dir)

Removes last vestiges of the old short-name convention.
2026-04-13 05:49:35 -07:00
zeekay 8045450815 feat: move all VM implementations into chains/
VMs now live in ONE place: chains/<name>/ owns the full implementation.
Previously split across node/vms/<name>/ (impl) + chains/<name>/main.go
(plugin wrapper). Now consolidated.

New layout:
  chains/<name>vm/*.go              — package <name>vm (VM code)
  chains/<name>vm/cmd/plugin/main.go — package main (plugin binary)
  chains/<name>vm/go.mod             — module github.com/luxfi/chains/<name>vm

Moved 11 VMs: aivm, bridgevm, dexvm, graphvm, identityvm, keyvm,
oraclevm, quantumvm, relayvm, thresholdvm, zkvm.

External callers now import github.com/luxfi/chains/<name> directly.
2026-04-13 05:27:00 -07:00
zeekay ea6e37dc24 feat: VM plugin monorepo — 14 independent binaries
Each VM builds as a standalone binary that the Lux node loads via
--plugin-dir. Node no longer bakes optional VMs in-process.

VMs: evm, dexvm, aivm, bridgevm, graphvm, identityvm, keyvm,
oraclevm, quantumvm, relayvm, servicenodevm, teleportvm,
thresholdvm, zkvm.

All 13 node-dependent VMs compile and report version correctly.
EVM requires CGo (luxcpp) — builds in CI only.
2026-04-12 13:05:45 -07:00