Commits 2 outstanding change(s) that were sitting uncommitted. No build artifacts and no secrets in the changeset (both checked).
8.6 KiB
chains
Org: luxfi · Ecosystem: lux · Path: /Users/a/work/lux/luxfi/chains
Origin: https://github.com/luxfi/chains.git
Discovery
This file (CLAUDE.md) is the canonical agent-facing readme; LLM.md is a symlink to it. Update either name and both stay in sync.
Where to look first
README.md— human-facing overview (if present)package.json/Cargo.toml/pyproject.toml/go.mod— language & deps.github/workflows/— CI surfacedocs/— extended docs (if present)
Canonical chain roster (LP-0130)
The topology, UTXO ownership rule, and cross-chain fee model are normatively specified by LP-0130 (Chain Topology, UTXO Ownership, and Fee Model). Read that LP before touching any VM's fee/settlement path.
Only P (in node/vms/platformvm) and X (in node/vms/xvm) are
canonical UTXO state machines. Every VM in THIS repo is a
domain-execution chain that MUST consume UTXO settlement via the
chains/fee primitive funded from X.
| Dir | Letter | Role | LP |
|---|---|---|---|
evm/ |
C | Contract / EVM account state | LP-1200 |
dexvm/ |
D | DEX matching + settlement receipts | LP-9000 |
quantumvm/ |
Q | Finality-cert / Quasar aggregation. No user-payable blockspace (validator obligation, LP-0130 §6) | LP-1300 |
zkvm/ |
Z | Rollup / private commitment + nullifier. Shielded supply is an X-escrow wrapper (LP-0130 §2, I-5) | LP-8000 |
aivm/ |
A | Inference receipt + attestation. Rides B's settlement engine (LP-0130 §9) | LP-5000 |
bridgevm/ |
B | Cross-chain message lifecycle. Fees deducted from bridged amount (LP-0130 §8) | LP-6000 |
mpcvm/ |
M | MPC signing / custody. Service fees paid by originating chain (LP-0130 §7); no user M-balance | LP-7100 |
mpcvm/fhe/ |
F | FHE runtime library — a package inside mpcvm, not a chain. See the deployment note below. |
LP-8200 |
Deployment reality (probed on mainnet 96369, platform.getBlockchains). Ten
chains are live: P X + C D Q Z A B G K. M and F are NOT deployed, and the
two are not equally close to shipping:
- M has a full VM (
mpcvm/,mpcvm/cmd/plugin) — it builds, it just has no chain registered on any network. - F has no VM at all.
luxfi/constantsreservesFHEVMID = {'f','h','e','v','m'}andluxfi/node/node/vms.golists it inOptionalVMsas pluginfhevm, so luxd scans--plugin-dirfor a binary that this repo never produces (nofhevm/directory ⇒ nomaketarget ⇒ no binary).mpcvm/fhe/above is the FHE runtime library, not a standalone F-Chain. F-Chain is a spec (LP-8200, LP-167) with no shipping VM.
T-Chain is gone entirely — LP-134 dissolves it with zero remainder (threshold
signing → M, FHE → F, cross-chain messaging/teleport → B). There is no
teleportvm here and no teleportvm VM ID in luxfi/constants.
Service VMs (not canonical primary chains under LP-0130):
| Dir | Letter | Purpose |
|---|---|---|
schain/ |
S | S3-style object storage (on-chain metadata, off-chain blob) |
keyvm/ |
K | Key registry / cryptographic algorithm addressing |
identityvm/ |
I | DID / identity |
graphvm/ |
G | Graph indexing / GraphQL surface |
relayvm/ |
R | Relay message queue |
oraclevm/ |
O | Oracle price / data feed |
Service VMs MAY have domain state and MAY charge fees, but MUST fund their fee balance from X and MUST NOT hold canonical UTXO asset supply.
Fee settlement primitive — chains/fee
chains/fee/{balance,meter,settle,ledger}.go is the shared
admission → meter → burn primitive every non-P/X VM in this repo
uses. Its Burn is a native LUX burn (no coinbase credit) that
reconciles against X-side fee escrow at the epoch fee root (LP-0130
§4).
chains/fee/doc.go is the design intent.
Σ-escrow invariant
At every Q checkpoint (LP-0130 I-8):
Σ (non-P/X fee balances) == Σ (X-side fee escrow)
Drift is a finality-blocking fault. This is the audit invariant every VM's epoch-fee-root emission and reconciliation path exists to satisfy.
VMs in this repo
Each *vm/ dir is a self-contained block.ChainVM plugin. dexvm is the
reference for VM structure + commit discipline (dual-DB: durable baseDB +
per-block versiondb; one db.CommitBatch() at block Accept).
- schain (
schain/) — the Lux S-Chain storage VM, forked fromdexvm's structure. VMID =ids.ID{'s','c','h','a','i','n'}(dexvm's byte pattern). M0 (DONE): one mutationPutManifest{bucket,object,fileIds,size,etag}round-trips through a real Lux block (BuildBlock→Verify→Accept) and commits the manifest to a real on-disk zapdb in ONE atomic batch at Accept;GetManifestreturns it only after Accept. Commit discipline copied verbatim fromdexvm/vm.go:1194(acceptBlock), minus the cross-chain shared-memory leg a storage VM does not have — accept reduces toCommitBatch()+batch.Write()+db.Abort(). State = typed manifest accessors overversiondb(no protobuf; JSON value bodies, prefix keys), mirroringdexvm/state/state.go. Tx wire = type-byte + JSON, one codec (mirrordexvm/txs/tx.go). No blobs/pinning/ networking yet — that is M1+. Test:schain/schain_test.godrives the genuine VM↔engine contract (SubmitTx→ToEngine PendingTxs→BuildBlock→Verify→Accept) over a REALzapdb.New(t.TempDir(),…); proves staged-not-durable before Accept, durable after, and Reject→Abort discards. M1 (DONE): TWO parts. PART A — manifest STATE ROOT (the multi-validator safety prerequisite M0 omitted):state.Root()hashes the committed manifest keyspace deterministically via the zapdb prefix iteratorNewIteratorWithStartAndPrefix(nil, prefixManifest), folding each entry length-prefixed (len(k)||k||len(v)||v) in lexicographic key order (mirror ofdexvm/state/state.go:395StateHash, narrowed to the one keyspace; last-block pointer excluded — it is consensus binding folded via blockHash/height, not object state).VM.computeStateRootfolds blockHash+height withstate.Root()(mirrordexvm/vm.go:1260);ProcessBlockstamps it intoBlockResult.StateRoot(mirrordexvm/vm.go:584). The root travels in the block HEADER (new 32-byte field after parentID; block id commits to it) andBlock.Verifyrecomputes it and REJECTS a mismatch (errStateRootMismatch) + Aborts staged writes — this is the >1-validator safety gate dexvm computed but never compared. Tests (schain/stateroot_test.go): determinism across write order, change-sensitivity (object set / etag / size / fileIds each move the root), and Verify-rejects-tampered-root. PART B — S3 OBJECT path, on-chain-metadata / off-chain-blob split proven end to end (schain/object/):Store.PutObjectstreams the blob to aVolume(OFF chain) → fid, then commits onlyPutManifest{bucket,object,[fid],size,etag}to the VM through a real block (ON chain);GetObjectreads the manifest back and reconstructs the blob from the volume.object.Volumeis the SEAM (Write(blob)→fid, Read(fid)→blob); M1 satisfies it with a faithful in-memoryMemVolumewhose fid shape mirrors hanzo/s3'sneedle.FileId(volumeId,needleIdCookie) and whose etag isbase64(md5(blob))(= hanzo/s3ContentMd5). M2 PLUG POINT (marked inobject/volume.go): swapMemVolumefor a thin adapter overgithub.com/ hanzoai/s3s3/operation.SubmitFiles(assign volume + stream needle →.Fid) and a needle GET — nothing in the VM orobject.Storechanges. Kept inside chains/schain (not importing the hanzoai/s3 module into luxfi/chains) to respect the org/module boundary while proving the exact data model. Test (schain/object_roundtrip_test.go): asserts the blob bytes appear in NO accepted block (bytes.Containsoverblk.Bytes()) and the block stays manifest-small (<4KiB for a 68KiB blob), the manifest IS on chain, and GET byte-reconstructs.
Test/build env gotcha (macOS)
The whole chains test suite links CGO deps that need -lresolv; the CLT cc
fails with library 'resolv' not found unless the macOS SDK syslibroot is set.
Run tests with SDKROOT="$(xcrun --show-sdk-path)" go test ./schain/.... This
affects dexvm and every other VM here too — it is NOT schain-specific.
Sibling repos
See the org-level LLM.md at /Users/a/work/lux/luxfi/LLM.md for the full inventory of sibling repos and inter-repo dependencies.