phase-a: lux.network/v1alpha1 → lux.cloud/v1 migration scaffolding

Phase A status: BLOCKED on luxfi/operator v0.6.3 + v0.7.0 binaries
(see luxfi/operator d2ecca5 — duplicate Network reconciler
registration makes both crashloop at startup). Cluster rolled back
to v0.3.12 on lux.network/v1alpha1 reconcile, all 3 chains 5/5
healthy.

What this commit lays down for the next attempt (once a v0.6.4 or
v0.7.1 image ships with the operator fix):

- `scripts/migrate-luxnetwork-crds.sh <ctx>` — race-clean CR
  migration script. Walks lux.network/v1alpha1 LuxNetwork,
  LuxChain, LuxGateway, LuxIndexer, LuxExplorer, LuxMPC CRs,
  apiVersion-swaps each to lux.cloud/v1 (dropping the Lux
  prefix on every Kind except LuxNetwork which v0.6.x also
  calls LuxNetwork in the canonical group). Spec/status pass
  through opaque — both CRDs use
  x-kubernetes-preserve-unknown-fields: true. Strips server-side
  metadata. Idempotent.
- `k8s/backups/pre-phase-a-20260602-020926/` — full live state
  snapshot for the 3 DOKS lux clusters, captured BEFORE any
  in-cluster mutation. Used to verify migration and as the rollback
  source if the next attempt needs to re-restore CRs.
- `k8s/PHASE_A_ROLLBACK.md` — step-by-step rollback procedure.

Inventory (lux-k8s only — test-k8s / dev-k8s have zero lux CRs):
- 3 LuxNetworks (luxnetworks.lux.network) — mainnet/testnet/devnet luxd
- 11 LuxChains (luxchains.lux.network) — mainnet a/b/d/g/i/k/m/o/q/r/z
- 3 LuxGateways (luxgateways.lux.network) — */api-gateway
- 1 LuxMPC (luxmpcs.lux.network) — mainnet/lux-mpc
- 0 LuxIndexers, 0 LuxExplorers

In-cluster prep that survived rollback:
- lux.cloud/v1 CRDs installed alongside lux.network/v1alpha1 (idempotent
  apply of `~/work/lux/operator/spec/crd/bases/lux.cloud/`).
- Migrated lux.cloud/v1 CRs already created (apply succeeded, no
  controller bound — inert until v0.6.4+ operator ships).

Next attempt blocked on:
1. CI build of v0.6.4 or v0.7.1 operator image with luxfi/operator
   d2ecca5 fix (push triggers via `hanzo-build-linux-amd64` ARC pool).
2. Bump `k8s/lux-k8s/operator/deployment.yaml` image tag.
3. Re-run scale-down → image-bump → scale-up cycle.

Forward-only, no AI slop, no API breakage, current chains stay alive
during entire procedure.
This commit is contained in:
2026-06-02 02:22:54 -07:00
parent 78be703f9c
commit c7f64a18b3
12 changed files with 1633 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
# Phase A — Operator Migration Rollback Procedure
The Phase A migration (`lux.network/v1alpha1` LuxNetwork etc. → `lux.cloud/v1`
managed by operator v0.6.3) hit an upstream operator bug at first attempt
on 2026-06-02 (see luxfi/operator d2ecca5).
This file documents how to roll back if a future attempt fails.
## What Phase A does
1. Backs up live CRs to `k8s/backups/pre-phase-a-<ts>/`
2. Installs `lux.cloud` CRDs alongside `lux.network` CRDs
3. Runs `scripts/migrate-luxnetwork-crds.sh <ctx>` which apiVersion-swaps
each CR (LuxNetwork stays LuxNetwork; LuxChain→Chain; LuxGateway→Gateway;
LuxIndexer→Indexer; LuxExplorer→Explorer; LuxMPC→MPC)
4. Scales legacy operator (v0.3.x) to 0 replicas
5. Applies `k8s/lux-k8s/operator/deployment.yaml` (v0.6.x image,
`--api-group=lux.cloud`)
6. Verifies new operator reconciles new CRs and StatefulSets stay healthy
## Rollback (in order)
### A) Scale v0.6.x operator to 0
```
kubectl --context=<ctx> -n lux-system scale deploy lux-operator --replicas=0
```
### B) Patch deployment back to v0.3.12 + legacy args
```
kubectl --context=<ctx> -n lux-system patch deploy lux-operator --type=json -p='[
{"op":"replace","path":"/spec/template/spec/containers/0/image","value":"ghcr.io/luxfi/operator:v0.3.12"},
{"op":"replace","path":"/spec/template/spec/containers/0/args","value":["--namespace","","--log-level","info","--metrics-port","8080","--health-port","8081","--leader-election"]}
]'
```
### C) Restore ClusterRole rules for the legacy `lux.network` apiGroup
(v0.6.x manifest replaces the ClusterRole to only cover `lux.cloud`.)
```
kubectl --context=<ctx> apply -f - <<'EOF'
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: lux-operator
rules:
- apiGroups: ["lux.network"]
resources:
- luxnetworks
- luxnetworks/status
- luxchains
- luxchains/status
- luxgateways
- luxgateways/status
- luxindexers
- luxindexers/status
- luxexplorers
- luxexplorers/status
- luxmpcs
- luxmpcs/status
verbs: ["*"]
- apiGroups: ["lux.cloud"]
resources:
- networks
- networks/status
- luxnetworks
- luxnetworks/status
- chains
- chains/status
- gateways
- gateways/status
- mpcs
- mpcs/status
- indexers
- indexers/status
- explorers
- explorers/status
verbs: ["*"]
- apiGroups: ["apps"]
resources: ["statefulsets", "deployments", "daemonsets", "replicasets"]
verbs: ["*"]
- apiGroups: [""]
resources: ["pods", "services", "configmaps", "secrets", "persistentvolumeclaims", "events", "serviceaccounts", "pods/exec"]
verbs: ["*"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: ["*"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["*"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["*"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["*"]
- apiGroups: ["secrets.lux.network"]
resources: ["kmssecrets"]
verbs: ["*"]
EOF
```
### D) Scale legacy operator back to 1
```
kubectl --context=<ctx> -n lux-system scale deploy lux-operator --replicas=1
```
### E) (Optional) delete migrated lux.cloud CRs
The legacy v1alpha1 CRs were left untouched, so legacy reconcile resumes
immediately. The new lux.cloud CRs become inert (no reconciler) and are
safe to leave in place — but for a clean rollback:
```
for k in luxnetworks chains gateways mpcs indexers explorers; do
kubectl --context=<ctx> get ${k}.lux.cloud -A --no-headers \
| awk '{print $1,$2}' \
| while read ns name; do
kubectl --context=<ctx> -n "$ns" delete ${k}.lux.cloud "$name"
done
done
```
### F) (Optional) uninstall lux.cloud CRDs
If a clean rollback is needed:
```
kubectl --context=<ctx> delete -f ~/work/lux/operator/spec/crd/bases/lux.cloud/
```
CRDs that still have CRs in them block deletion until step E completes
for that Kind.
## Verification after rollback
```
# Operator pod healthy
kubectl --context=<ctx> -n lux-system get pods -l app=lux-operator
kubectl --context=<ctx> -n lux-system logs -l app=lux-operator --tail=20
# StatefulSets still 5/5 ready
for ns in lux-mainnet lux-testnet lux-devnet; do
kubectl --context=<ctx> -n $ns get sts luxd
done
```
@@ -0,0 +1 @@
customresourcedefinition.apiextensions.k8s.io/luxmpcs.lux.network
@@ -0,0 +1,12 @@
customresourcedefinition.apiextensions.k8s.io/clustergenerators.secrets.lux.network
customresourcedefinition.apiextensions.k8s.io/kmsdynamicsecrets.secrets.lux.network
customresourcedefinition.apiextensions.k8s.io/kmspushsecrets.secrets.lux.network
customresourcedefinition.apiextensions.k8s.io/kmssecrets.secrets.lux.network
customresourcedefinition.apiextensions.k8s.io/luxchains.lux.network
customresourcedefinition.apiextensions.k8s.io/luxexplorers.lux.network
customresourcedefinition.apiextensions.k8s.io/luxgateways.lux.network
customresourcedefinition.apiextensions.k8s.io/luxindexers.lux.network
customresourcedefinition.apiextensions.k8s.io/luxmpcs.lux.network
customresourcedefinition.apiextensions.k8s.io/luxnetworks.lux.network
customresourcedefinition.apiextensions.k8s.io/passwords.secrets.lux.network
customresourcedefinition.apiextensions.k8s.io/uuids.secrets.lux.network
@@ -0,0 +1,302 @@
apiVersion: v1
items:
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"a-chain","lux.network/network":"mainnet"},"name":"a-chain","namespace":"lux-mainnet"},"spec":{"alias":"A","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/aivm:v0.1.0","chainConfig":{"cgo":false},"vmType":"aivm"}}}
creationTimestamp: "2026-04-30T19:53:35Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: a-chain
lux.network/network: mainnet
name: a-chain
namespace: lux-mainnet
resourceVersion: "62906643"
uid: 54b30375-2210-45a6-9fb7-b6bdaaba4e51
spec:
alias: A
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/aivm:v0.1.0
chainConfig:
cgo: false
vmType: aivm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"b-chain","lux.network/network":"mainnet"},"name":"b-chain","namespace":"lux-mainnet"},"spec":{"alias":"B","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/bridgevm:v0.1.0","chainConfig":{"cgo":false},"vmType":"bridgevm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: b-chain
lux.network/network: mainnet
name: b-chain
namespace: lux-mainnet
resourceVersion: "62906646"
uid: d1c5972b-326c-486f-a2d9-0b9f2cb7baa8
spec:
alias: B
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/bridgevm:v0.1.0
chainConfig:
cgo: false
vmType: bridgevm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"d-chain","lux.network/network":"mainnet"},"name":"d-chain","namespace":"lux-mainnet"},"spec":{"alias":"D","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/dexvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"dexvm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: d-chain
lux.network/network: mainnet
name: d-chain
namespace: lux-mainnet
resourceVersion: "62906650"
uid: 26629e55-b50a-4dec-9a9e-fa66655450ef
spec:
alias: D
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/dexvm:v0.1.0
chainConfig:
cgo: false
vmType: dexvm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"g-chain","lux.network/network":"mainnet"},"name":"g-chain","namespace":"lux-mainnet"},"spec":{"alias":"G","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/graphvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"graphvm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: g-chain
lux.network/network: mainnet
name: g-chain
namespace: lux-mainnet
resourceVersion: "62906652"
uid: d7a7f3b1-d71f-4ab0-a833-421a346aa6d5
spec:
alias: G
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/graphvm:v0.1.0
chainConfig:
cgo: false
vmType: graphvm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"i-chain","lux.network/network":"mainnet"},"name":"i-chain","namespace":"lux-mainnet"},"spec":{"alias":"I","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/identityvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"identityvm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: i-chain
lux.network/network: mainnet
name: i-chain
namespace: lux-mainnet
resourceVersion: "62906654"
uid: 3837654f-9b3b-48ae-a464-c41fb47bb2d6
spec:
alias: I
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/identityvm:v0.1.0
chainConfig:
cgo: false
vmType: identityvm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"k-chain","lux.network/network":"mainnet"},"name":"k-chain","namespace":"lux-mainnet"},"spec":{"alias":"K","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/keyvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"keyvm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: k-chain
lux.network/network: mainnet
name: k-chain
namespace: lux-mainnet
resourceVersion: "62906657"
uid: 5827070c-b133-4238-898b-0baae5d63442
spec:
alias: K
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/keyvm:v0.1.0
chainConfig:
cgo: false
vmType: keyvm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"m-chain","lux.network/network":"mainnet"},"name":"m-chain","namespace":"lux-mainnet"},"spec":{"alias":"M","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/thresholdvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"thresholdvm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: m-chain
lux.network/network: mainnet
name: m-chain
namespace: lux-mainnet
resourceVersion: "62906660"
uid: 1cf075b0-84fe-4aea-abfa-c2ea07634694
spec:
alias: M
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/thresholdvm:v0.1.0
chainConfig:
cgo: false
vmType: thresholdvm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"o-chain","lux.network/network":"mainnet"},"name":"o-chain","namespace":"lux-mainnet"},"spec":{"alias":"O","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/oraclevm:v0.1.0","chainConfig":{"cgo":false},"vmType":"oraclevm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: o-chain
lux.network/network: mainnet
name: o-chain
namespace: lux-mainnet
resourceVersion: "62906663"
uid: fb8a8b1b-9958-4ce2-b57a-26fda4f2f371
spec:
alias: O
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/oraclevm:v0.1.0
chainConfig:
cgo: false
vmType: oraclevm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"q-chain","lux.network/network":"mainnet"},"name":"q-chain","namespace":"lux-mainnet"},"spec":{"alias":"Q","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/quantumvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"quantumvm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: q-chain
lux.network/network: mainnet
name: q-chain
namespace: lux-mainnet
resourceVersion: "62906665"
uid: d3dcf9de-8790-4923-8b56-9e4e760353fc
spec:
alias: Q
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/quantumvm:v0.1.0
chainConfig:
cgo: false
vmType: quantumvm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"r-chain","lux.network/network":"mainnet"},"name":"r-chain","namespace":"lux-mainnet"},"spec":{"alias":"R","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/relayvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"relayvm"}}}
creationTimestamp: "2026-04-30T19:53:36Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: r-chain
lux.network/network: mainnet
name: r-chain
namespace: lux-mainnet
resourceVersion: "62906670"
uid: 283e3e3e-473b-4eac-90be-602a15f92edb
spec:
alias: R
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/relayvm:v0.1.0
chainConfig:
cgo: false
vmType: relayvm
status:
conditions: []
phase: Pending
- apiVersion: lux.network/v1alpha1
kind: LuxChain
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxChain","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/chain":"z-chain","lux.network/network":"mainnet"},"name":"z-chain","namespace":"lux-mainnet"},"spec":{"alias":"Z","networkRef":"luxd","vm":{"binaryUrl":"ghcr.io/luxfi/zkvm:v0.1.0","chainConfig":{"cgo":false},"vmType":"zkvm"}}}
creationTimestamp: "2026-04-30T19:53:37Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/chain: z-chain
lux.network/network: mainnet
name: z-chain
namespace: lux-mainnet
resourceVersion: "62906673"
uid: 019862ce-1682-4d0c-9006-5fe51fbe544c
spec:
alias: Z
networkRef: luxd
vm:
binaryUrl: ghcr.io/luxfi/zkvm:v0.1.0
chainConfig:
cgo: false
vmType: zkvm
status:
conditions: []
phase: Pending
kind: List
metadata:
resourceVersion: ""
@@ -0,0 +1,5 @@
apiVersion: v1
items: []
kind: List
metadata:
resourceVersion: ""
@@ -0,0 +1,270 @@
apiVersion: v1
items:
- apiVersion: lux.network/v1alpha1
kind: LuxGateway
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxGateway","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/network":"devnet"},"name":"api-gateway","namespace":"lux-devnet"},"spec":{"autoRoutes":true,"cors":{"allowedHeaders":["Content-Type","Authorization"],"allowedMethods":["GET","POST","OPTIONS"],"allowedOrigins":["*"]},"customRoutes":[{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/2caKCdNop9C4oAPR1kYihN53HeSRDXD3JyMKS7ntfcpQYucmii/rpc","timeout":30},{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/zoo/rpc","timeout":30},{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/tecXMucYDxwN65mebPE6cvQ9GynG6Y5WEvwGFsY3xVDWHxiqT/rpc","timeout":30},{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/hanzo/rpc","timeout":30},{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/213ZsFLRCBSmrii4huQqa6S3SxYPP8ec6dPEn6ad4CtLk3RdXp/rpc","timeout":30},{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/spc/rpc","timeout":30},{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/MEGAgimfcodi7QaqCruFpTkNM6fqu7ZduLmWJJjGQwUg8uDPJ/rpc","timeout":30},{"backend":"http://luxd-headless.lux-devnet.svc:9650","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/pars/rpc","timeout":30}],"host":"api.devnet.lux.network","indexerRefs":["indexer-c","indexer-zoo","indexer-hanzo","indexer-spc","indexer-pars"],"networkRef":"luxd","port":8080,"rateLimit":{"burst":200,"requestsPerSecond":100},"replicas":1}}
reconcile-at: "2026-03-02T06:44:35Z"
creationTimestamp: "2026-03-02T06:26:33Z"
generation: 2
labels:
app.kubernetes.io/part-of: lux-network
lux.network/network: devnet
name: api-gateway
namespace: lux-devnet
resourceVersion: "74762068"
uid: 7fbadf67-928a-4605-8f56-97f9e17c756e
spec:
autoRoutes: true
cors:
allowedHeaders:
- Content-Type
- Authorization
allowedMethods:
- GET
- POST
- OPTIONS
allowedOrigins:
- '*'
customRoutes:
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/2caKCdNop9C4oAPR1kYihN53HeSRDXD3JyMKS7ntfcpQYucmii/rpc
timeout: 30
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/zoo/rpc
timeout: 30
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/tecXMucYDxwN65mebPE6cvQ9GynG6Y5WEvwGFsY3xVDWHxiqT/rpc
timeout: 30
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/hanzo/rpc
timeout: 30
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/213ZsFLRCBSmrii4huQqa6S3SxYPP8ec6dPEn6ad4CtLk3RdXp/rpc
timeout: 30
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/spc/rpc
timeout: 30
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/MEGAgimfcodi7QaqCruFpTkNM6fqu7ZduLmWJJjGQwUg8uDPJ/rpc
timeout: 30
- backend: http://luxd-headless.lux-devnet.svc:9650
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/pars/rpc
timeout: 30
host: api.devnet.lux.network
indexerRefs:
- indexer-c
- indexer-zoo
- indexer-hanzo
- indexer-spc
- indexer-pars
networkRef: luxd
port: 8080
rateLimit:
burst: 200
requestsPerSecond: 100
replicas: 1
status:
chainRoutes: {}
conditions: []
externalEndpoint: https://api.devnet.lux.network
phase: Ready
readyReplicas: 2
routeCount: 15
- apiVersion: lux.network/v1alpha1
kind: LuxGateway
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxGateway","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/network":"mainnet"},"name":"api-gateway","namespace":"lux-mainnet"},"spec":{"autoRoutes":true,"cors":{"allowedHeaders":["Content-Type","Authorization"],"allowedMethods":["GET","POST","OPTIONS"],"allowedOrigins":["https://lux.network","https://explorer.lux.network","https://lux.exchange"]},"explorerRefs":["explorer"],"host":"api.lux.network","image":{"repository":"ghcr.io/luxfi/gateway","tag":"v0.1.0"},"indexerRefs":["lux-mainnet-indexer"],"networkRef":"luxd","port":8080,"rateLimit":{"burst":400,"requestsPerSecond":200},"replicas":3,"tls":{"certManager":true,"issuer":"letsencrypt-prod","secretName":"api-lux-network-tls"}}}
reconcile-at: "2026-03-02T06:44:34Z"
creationTimestamp: "2026-03-02T06:26:22Z"
generation: 3
labels:
app.kubernetes.io/part-of: lux-network
lux.network/network: mainnet
name: api-gateway
namespace: lux-mainnet
resourceVersion: "74762061"
uid: f692fcd3-e1d4-4c13-bd94-cda4f6300b68
spec:
autoRoutes: true
cors:
allowedHeaders:
- Content-Type
- Authorization
allowedMethods:
- GET
- POST
- OPTIONS
allowedOrigins:
- https://lux.network
- https://explorer.lux.network
- https://lux.exchange
explorerRefs:
- explorer
host: api.lux.network
image:
repository: ghcr.io/luxfi/gateway
tag: v0.1.0
indexerRefs:
- lux-mainnet-indexer
networkRef: luxd
port: 8080
rateLimit:
burst: 400
requestsPerSecond: 200
replicas: 3
tls:
certManager: true
issuer: letsencrypt-prod
secretName: api-lux-network-tls
status:
chainRoutes: {}
conditions: []
externalEndpoint: https://api.lux.network
phase: Ready
readyReplicas: 2
routeCount: 7
- apiVersion: lux.network/v1alpha1
kind: LuxGateway
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxGateway","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/network":"testnet"},"name":"api-gateway","namespace":"lux-testnet"},"spec":{"autoRoutes":true,"cors":{"allowedHeaders":["Content-Type","Authorization"],"allowedMethods":["GET","POST","OPTIONS"],"allowedOrigins":["*"]},"customRoutes":[{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/2Uw1b5tf63vamHsWVeSW9uHcGBVbF5CYHS9JiLWttusY4Vvjsn/rpc","timeout":30},{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/zoo/rpc","timeout":30},{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/2wbYEFh7ELuovqXhyYeCLvweZrcEgNUoZVJUAtw145qTVAUJxE/rpc","timeout":30},{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/hanzo/rpc","timeout":30},{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/u4pC2tT61o83pbQ8qwAyfXXGF6nyGFNSwCYHEFcUeESGiNKfu/rpc","timeout":30},{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/spc/rpc","timeout":30},{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/is5GUzsKHk3Z4Q5JXTjF4Ld9p4TnEs81tJFdaBiEBJVkaFrrs/rpc","timeout":30},{"backend":"http://luxd-headless.lux-testnet.svc:9640","methods":["GET","POST","OPTIONS"],"path":"/ext/bc/pars/rpc","timeout":30}],"host":"api.testnet.lux.network","indexerRefs":["indexer-c","indexer-zoo","indexer-hanzo","indexer-spc","indexer-pars"],"networkRef":"luxd","port":8080,"rateLimit":{"burst":200,"requestsPerSecond":100},"replicas":1}}
reconcile-at: "2026-03-02T06:44:34Z"
creationTimestamp: "2026-03-02T06:26:33Z"
generation: 2
labels:
app.kubernetes.io/part-of: lux-network
lux.network/network: testnet
name: api-gateway
namespace: lux-testnet
resourceVersion: "69666567"
uid: 83959cd0-af38-4167-9ba4-f19f2aa844d4
spec:
autoRoutes: true
cors:
allowedHeaders:
- Content-Type
- Authorization
allowedMethods:
- GET
- POST
- OPTIONS
allowedOrigins:
- '*'
customRoutes:
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/2Uw1b5tf63vamHsWVeSW9uHcGBVbF5CYHS9JiLWttusY4Vvjsn/rpc
timeout: 30
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/zoo/rpc
timeout: 30
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/2wbYEFh7ELuovqXhyYeCLvweZrcEgNUoZVJUAtw145qTVAUJxE/rpc
timeout: 30
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/hanzo/rpc
timeout: 30
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/u4pC2tT61o83pbQ8qwAyfXXGF6nyGFNSwCYHEFcUeESGiNKfu/rpc
timeout: 30
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/spc/rpc
timeout: 30
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/is5GUzsKHk3Z4Q5JXTjF4Ld9p4TnEs81tJFdaBiEBJVkaFrrs/rpc
timeout: 30
- backend: http://luxd-headless.lux-testnet.svc:9640
methods:
- GET
- POST
- OPTIONS
path: /ext/bc/pars/rpc
timeout: 30
host: api.testnet.lux.network
indexerRefs:
- indexer-c
- indexer-zoo
- indexer-hanzo
- indexer-spc
- indexer-pars
networkRef: luxd
port: 8080
rateLimit:
burst: 200
requestsPerSecond: 100
replicas: 1
status:
chainRoutes: {}
conditions: []
externalEndpoint: https://api.testnet.lux.network
phase: Ready
readyReplicas: 2
routeCount: 15
kind: List
metadata:
resourceVersion: ""
@@ -0,0 +1,5 @@
apiVersion: v1
items: []
kind: List
metadata:
resourceVersion: ""
@@ -0,0 +1,47 @@
apiVersion: v1
items:
- apiVersion: lux.network/v1alpha1
kind: LuxMPC
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxMPC","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/network":"mainnet"},"name":"lux-mpc","namespace":"lux-mainnet"},"spec":{"apiPort":8081,"backup":{"bucket":"lux-mpc-keyset-backup","credentialsSecret":"hanzo-s3-secret","endpoint":"https://s3.lux.network","intervalSeconds":3600,"region":"us-east-1"},"clusterIssuer":"letsencrypt-prod","cpuLimit":"2000m","cpuRequest":"500m","dashboardApiUrl":"https://mpc.lux.network/v1","dashboardImage":"ghcr.io/luxfi/mpc-dashboard:v0.1.0","hostname":"mpc.lux.network","iamClientId":"lux-mpc","iamUrl":"https://lux.id","image":"ghcr.io/luxfi/mpc-api:v0.1.0","imagePullPolicy":"IfNotPresent","memoryLimit":"4Gi","memoryRequest":"1Gi","nodes":5,"p2pPort":9999,"secretName":"lux-mpc-keyset","storage":"50Gi","storageClass":"do-block-storage","threshold":3,"tlsSecret":"mpc-lux-network-tls"}}
creationTimestamp: "2026-04-30T19:55:33Z"
generation: 1
labels:
app.kubernetes.io/part-of: lux-network
lux.network/network: mainnet
name: lux-mpc
namespace: lux-mainnet
resourceVersion: "62908702"
uid: 5f3c0f50-7f7d-4180-b0f8-6e5f1244b588
spec:
apiPort: 8081
backup:
bucket: lux-mpc-keyset-backup
credentialsSecret: hanzo-s3-secret
endpoint: https://s3.lux.network
intervalSeconds: 3600
region: us-east-1
clusterIssuer: letsencrypt-prod
cpuLimit: 2000m
cpuRequest: 500m
dashboardApiUrl: https://mpc.lux.network/v1
dashboardImage: ghcr.io/luxfi/mpc-dashboard:v0.1.0
hostname: mpc.lux.network
iamClientId: lux-mpc
iamUrl: https://lux.id
image: ghcr.io/luxfi/mpc-api:v0.1.0
imagePullPolicy: IfNotPresent
memoryLimit: 4Gi
memoryRequest: 1Gi
nodes: 5
p2pPort: 9999
secretName: lux-mpc-keyset
storage: 50Gi
storageClass: do-block-storage
threshold: 3
tlsSecret: mpc-lux-network-tls
kind: List
metadata:
resourceVersion: ""
@@ -0,0 +1,589 @@
apiVersion: v1
items:
- apiVersion: lux.network/v1alpha1
kind: LuxNetwork
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxNetwork","metadata":{"annotations":{},"name":"luxd","namespace":"lux-devnet"},"spec":{"adoptExisting":true,"chainTracking":{"trackAllChains":true},"consensus":{"sybilProtectionEnabled":true},"image":{"pullPolicy":"IfNotPresent","repository":"ghcr.io/luxfi/node","tag":"v1.27.23"},"networkId":3,"ports":{"http":9650,"staking":9651},"seedRestore":{"enabled":true,"objectStoreUrl":"http://s3.lux-system.svc.cluster.local:9000/lux-snapshots/devnet/devnet-node0-full.tar.gz","sourceType":"ObjectStore"},"snapshotSchedule":{"accessKey":"hanzo","bucket":"lux-snapshots","enabled":true,"includeRlpExports":true,"intervalSeconds":3600,"maxRetained":5,"objectStoreEndpoint":"http://s3.lux-system.svc.cluster.local:9000","prefix":"devnet","secretKeyRef":"hanzo-s3-secret","sourceNodeIndex":0},"staking":{"kms":{"auth":{"credentialsNamespace":"lux-system","credentialsSecret":"universal-auth-credentials"},"envSlug":"devnet","hostApi":"https://kms.lux.network/api","projectSlug":"lux-infra","resyncInterval":300,"secretsPath":"/staking"},"secretName":"luxd-staking"},"validators":5}}
creationTimestamp: "2026-03-21T17:55:34Z"
generation: 27
name: luxd
namespace: lux-devnet
resourceVersion: "77700420"
uid: 089770ea-416e-4349-b087-ce36d0e6640c
spec:
adoptExisting: true
allowValidatorRemoval: true
chainTracking:
trackAllChains: true
consensus:
sybilProtectionEnabled: true
genesisConfigMap: luxd-genesis
image:
pullPolicy: IfNotPresent
repository: ghcr.io/luxfi/node
tag: v1.28.0
networkId: 3
ports:
http: 9650
staking: 9651
resources:
cpuLimit: "2"
cpuRequest: 500m
memoryLimit: 8Gi
memoryRequest: 2Gi
seedRestore:
enabled: false
objectStoreUrl: http://s3.lux-system.svc.cluster.local:9000/lux-snapshots/devnet/devnet-node0-full.tar.gz
sourceType: ObjectStore
snapshotSchedule:
accessKey: hanzo
bucket: lux-snapshots
enabled: true
includeRlpExports: true
intervalSeconds: 3600
maxRetained: 5
objectStoreEndpoint: http://s3.lux-system.svc.cluster.local:9000
prefix: devnet
secretKeyRef: hanzo-s3-secret
sourceNodeIndex: 0
staking:
kms:
auth:
credentialsNamespace: lux-system
credentialsSecret: universal-auth-credentials
envSlug: devnet
hostApi: https://kms.lux.network/api
projectSlug: lux-infra
resyncInterval: 300
secretsPath: /staking
secretName: luxd-staking
validators: 5
status:
bootstrapEndpoints:
- http://luxd-0.luxd-headless.lux-devnet.svc:9650
- http://luxd-1.luxd-headless.lux-devnet.svc:9650
- http://luxd-2.luxd-headless.lux-devnet.svc:9650
- http://luxd-3.luxd-headless.lux-devnet.svc:9650
- http://luxd-4.luxd-headless.lux-devnet.svc:9650
chainStatuses:
2uf4pnDukwqQisYJNFNPXD21R3vJho7CPpLWGBvN9cqfe1Gjxu:
alias: liquiddex
healthy: false
C:
alias: C
blockHeight: 35
healthy: true
P:
alias: P
blockHeight: 10
healthy: true
komoGqc3zoGfYDShmNvWzwx2FnYZHJUkjAYYSYPhymrFi4bi2:
alias: liquidevm
blockHeight: 0
healthy: true
conditions: []
degradedReasons: []
externalIps:
luxd-0: 164.90.247.220
luxd-1: 146.190.14.112
luxd-2: 24.199.68.130
luxd-3: 134.199.184.181
luxd-4: 209.38.172.213
networkId: 3
networkMetrics:
bootstrappedChains: 0
heightSkew: 0
maxPHeight: 0
minPHeight: 0
totalPeers: 0
nodeStatuses:
luxd-0:
bootstrapped: true
cChainHeight: 35
chainsCount: 2
connectedPeers: 4
externalIp: 164.90.247.220
healthy: true
inboundPeers: 0
nodeId: NodeID-Mf3JfSY91oDwfBqf7rCLmhg4NDtDghw1f
outboundPeers: 4
pChainHeight: 10
startTime: "2026-03-21T20:20:39+00:00"
luxd-1:
bootstrapped: true
cChainHeight: 35
chainsCount: 2
connectedPeers: 4
externalIp: 146.190.14.112
healthy: true
inboundPeers: 0
nodeId: NodeID-2TwSZ2oyeBK2mv7JiseEQ8m74rotDj4QR
outboundPeers: 4
pChainHeight: 10
startTime: "2026-03-21T20:20:39+00:00"
luxd-2:
bootstrapped: true
cChainHeight: 35
chainsCount: 2
connectedPeers: 4
externalIp: 24.199.68.130
healthy: true
inboundPeers: 0
nodeId: NodeID-Ld9VFBQ9zGbd79z2vzaAqkQ3jHuqbtRpo
outboundPeers: 4
pChainHeight: 10
startTime: "2026-03-23T05:16:36+00:00"
luxd-3:
bootstrapped: true
cChainHeight: 35
chainsCount: 2
connectedPeers: 4
externalIp: 134.199.184.181
healthy: true
inboundPeers: 0
nodeId: NodeID-8mY2fhUehN27v3LCU84BnnKEoeRfd2weC
outboundPeers: 4
pChainHeight: 10
startTime: "2026-03-21T20:20:40+00:00"
luxd-4:
bootstrapped: true
cChainHeight: 35
chainsCount: 2
connectedPeers: 4
externalIp: 209.38.172.213
healthy: true
inboundPeers: 0
nodeId: NodeID-4smuFz5Z9cm8BEyQU1oPQ9nwgXyMgaNqu
outboundPeers: 4
pChainHeight: 10
startTime: "2026-03-23T04:40:55+00:00"
phase: Degraded
readyValidators: 0
snapshotCount: 0
totalValidators: 5
- apiVersion: lux.network/v1alpha1
kind: LuxNetwork
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxNetwork","metadata":{"annotations":{},"labels":{"app.kubernetes.io/part-of":"lux-network","lux.network/network":"mainnet"},"name":"luxd","namespace":"lux-mainnet"},"spec":{"adoptExisting":false,"chainTracking":{"trackAllChains":true},"consensus":{"pqLayers":["bls","corona","mldsa"],"sybilProtectionEnabled":true,"type":"quasar","zapPort":9999},"genesisConfigMap":"luxd-genesis","image":{"repository":"ghcr.io/luxfi/node","tag":"1.27.4"},"networkId":1,"pluginSource":{"bucket":"s3://lux-plugins/v1.1.0/","credentialsSecret":"hanzo-s3-secret","endpoint":"https://s3.lux.network","kmsConfigPath":"lux/mainnet/plugins","vmPlugins":[{"objectKey":"aivm-linux-amd64","vmId":"aivm"},{"objectKey":"bridgevm-linux-amd64","vmId":"bridgevm"},{"objectKey":"dexvm-linux-amd64","vmId":"dexvm"},{"objectKey":"graphvm-linux-amd64","vmId":"graphvm"},{"objectKey":"identityvm-linux-amd64","vmId":"identityvm"},{"objectKey":"keyvm-linux-amd64","vmId":"keyvm"},{"objectKey":"thresholdvm-linux-amd64","vmId":"thresholdvm"},{"objectKey":"oraclevm-linux-amd64","vmId":"oraclevm"},{"objectKey":"quantumvm-linux-amd64","vmId":"quantumvm"},{"objectKey":"relayvm-linux-amd64","vmId":"relayvm"},{"objectKey":"zkvm-linux-amd64","vmId":"zkvm"}]},"podAntiAffinity":true,"ports":{"http":9630,"staking":9631},"seedRestore":{"enabled":true,"objectStoreUrl":"https://s3.lux.network/lux-snapshots/mainnet/mainnet-node0-full.tar.gz","sourceType":"ObjectStore"},"snapshotSchedule":{"accessKey":"hanzo","bucket":"lux-snapshots","enabled":true,"includeRlpExports":true,"intervalSeconds":3600,"maxRetained":5,"objectStoreEndpoint":"https://s3.lux.network","prefix":"mainnet","secretKeyRef":"hanzo-s3-secret","sourceNodeIndex":0},"staking":{"keyDerivation":{"bip44Path":"m/9000'/96369'","mnemonicSecret":"lux-master-mnemonic"},"kms":{"auth":{"credentialsNamespace":"lux-system","credentialsSecret":"universal-auth-credentials"},"envSlug":"mainnet","hostApi":"http://kms.lux-system.svc.cluster.local/api","projectSlug":"lux-infra","resyncInterval":300,"secretsPath":"/staking"},"secretName":"luxd-staking"},"startupGate":{"onTimeout":"StartAnyway","timeoutSeconds":30},"upgradeConfig":{"durangoTimestamp":0,"etnaTimestamp":0,"fortunaTimestamp":0,"graniteTimestamp":0},"upgradeStrategy":{"healthCheckBetweenRestarts":true,"maxUnavailable":1,"stabilizationSeconds":60,"strategyType":"RollingCanary"},"validators":5}}
reconcile.lux.network/touch: "1779223282"
creationTimestamp: "2026-02-25T05:43:28Z"
generation: 25
labels:
app.kubernetes.io/part-of: lux-network
lux.network/network: mainnet
name: luxd
namespace: lux-mainnet
resourceVersion: "79342696"
uid: 555ccdc5-b452-4fbe-ac94-552e89a9cef0
spec:
adoptExisting: false
chainTracking:
trackAllChains: true
consensus:
pqLayers:
- bls
- corona
- mldsa
sybilProtectionEnabled: true
type: quasar
zapPort: 9999
genesisConfigMap: luxd-genesis
image:
repository: ghcr.io/luxfi/node
tag: 1.27.4
networkId: 1
pluginSource:
bucket: s3://lux-plugins/v1.1.0/
credentialsSecret: hanzo-s3-secret
endpoint: https://s3.lux.network
kmsConfigPath: lux/mainnet/plugins
vmPlugins:
- objectKey: aivm-linux-amd64
vmId: aivm
- objectKey: bridgevm-linux-amd64
vmId: bridgevm
- objectKey: dexvm-linux-amd64
vmId: dexvm
- objectKey: graphvm-linux-amd64
vmId: graphvm
- objectKey: identityvm-linux-amd64
vmId: identityvm
- objectKey: keyvm-linux-amd64
vmId: keyvm
- objectKey: thresholdvm-linux-amd64
vmId: thresholdvm
- objectKey: oraclevm-linux-amd64
vmId: oraclevm
- objectKey: quantumvm-linux-amd64
vmId: quantumvm
- objectKey: relayvm-linux-amd64
vmId: relayvm
- objectKey: zkvm-linux-amd64
vmId: zkvm
podAntiAffinity: true
ports:
http: 9630
staking: 9631
seedRestore:
enabled: true
objectStoreUrl: https://s3.lux.network/lux-snapshots/mainnet/mainnet-node0-full.tar.gz
sourceType: ObjectStore
snapshotSchedule:
accessKey: hanzo
bucket: lux-snapshots
enabled: true
includeRlpExports: true
intervalSeconds: 3600
maxRetained: 5
objectStoreEndpoint: https://s3.lux.network
prefix: mainnet
secretKeyRef: hanzo-s3-secret
sourceNodeIndex: 0
staking:
keyDerivation:
bip44Path: m/9000'/96369'
mnemonicSecret: lux-master-mnemonic
kms:
auth:
credentialsNamespace: lux-system
credentialsSecret: universal-auth-credentials
envSlug: mainnet
hostApi: http://kms.lux-system.svc.cluster.local/api
projectSlug: lux-infra
resyncInterval: 300
secretsPath: /staking
secretName: luxd-staking
startupGate:
onTimeout: StartAnyway
timeoutSeconds: 30
upgradeConfig:
durangoTimestamp: 0
etnaTimestamp: 0
fortunaTimestamp: 0
graniteTimestamp: 0
upgradeStrategy:
healthCheckBetweenRestarts: true
maxUnavailable: 1
stabilizationSeconds: 60
strategyType: RollingCanary
validators: 5
status:
bootstrapEndpoints:
- http://luxd-0.luxd-headless.lux-mainnet.svc:9630
- http://luxd-1.luxd-headless.lux-mainnet.svc:9630
- http://luxd-2.luxd-headless.lux-mainnet.svc:9630
- http://luxd-3.luxd-headless.lux-mainnet.svc:9630
- http://luxd-4.luxd-headless.lux-mainnet.svc:9630
chainStatuses:
2GiQb73CeJESjc4omFv2YtQHZrRgJf25NXPzAr5J6UNHRcDV2F:
alias: hanzo
blockHeight: 30
healthy: true
2Y625Kvdd4wZ5LKx9kLSf1jGALyARmXVN1YsTb4F3Hzv4bPDbp:
alias: zoo
blockHeight: 832
healthy: true
2pUskxqaL5Bpx7uRUGG1fDjPckjxQ4UKX4sLKeaS1NdSVBJd3F:
alias: pars
blockHeight: 28
healthy: true
C:
alias: C
blockHeight: 0
healthy: true
P:
alias: P
blockHeight: 260
healthy: true
rtjwvtE1tEvrokmpeYdTq7b2zqZgmybKwR5MLjKMGAR1W78dQ:
alias: spc
blockHeight: 10
healthy: true
conditions: []
degradedReasons: []
externalIps:
luxd-0: 209.38.118.46
luxd-1: 209.38.174.69
luxd-2: 24.144.69.101
luxd-3: 134.199.187.56
luxd-4: 143.198.246.173
luxd-5: 134.199.137.189
networkId: 1
networkMetrics:
bootstrappedChains: 1
heightSkew: 166
maxPHeight: 260
minPHeight: 94
totalPeers: 20
nodeStatuses:
luxd-0:
bootstrapped: true
cChainHeight: 0
chainsCount: 0
connectedPeers: 4
externalIp: 209.38.118.46
healthy: true
inboundPeers: 0
nodeId: NodeID-Mf3JfSY91oDwfBqf7rCLmhg4NDtDghw1f
outboundPeers: 4
pChainHeight: 260
startTime: "2026-06-02T01:27:47+00:00"
luxd-1:
bootstrapped: true
cChainHeight: 1083590
chainsCount: 0
connectedPeers: 4
externalIp: 209.38.174.69
healthy: true
inboundPeers: 0
nodeId: NodeID-2TwSZ2oyeBK2mv7JiseEQ8m74rotDj4QR
outboundPeers: 4
pChainHeight: 94
startTime: "2026-06-01T20:23:06+00:00"
luxd-2:
bootstrapped: true
cChainHeight: 1083590
chainsCount: 0
connectedPeers: 4
externalIp: 24.144.69.101
healthy: true
inboundPeers: 0
nodeId: NodeID-Ld9VFBQ9zGbd79z2vzaAqkQ3jHuqbtRpo
outboundPeers: 4
pChainHeight: 260
startTime: "2026-06-01T20:21:18+00:00"
luxd-3:
bootstrapped: true
cChainHeight: 1083590
chainsCount: 0
connectedPeers: 4
externalIp: 134.199.187.56
healthy: true
inboundPeers: 0
nodeId: NodeID-8mY2fhUehN27v3LCU84BnnKEoeRfd2weC
outboundPeers: 4
pChainHeight: 260
startTime: "2026-06-01T20:19:32+00:00"
luxd-4:
bootstrapped: true
cChainHeight: 1083542
chainsCount: 0
connectedPeers: 4
externalIp: 143.198.246.173
healthy: true
inboundPeers: 0
nodeId: NodeID-DwsrqSkPoE3pXWrUt9nkJ5yBycwRQ246X
outboundPeers: 4
pChainHeight: 260
startTime: "2026-06-01T20:17:46+00:00"
luxd-5:
bootstrapped: false
cChainHeight: 0
chainsCount: 0
connectedPeers: 0
externalIp: 134.199.137.189
healthy: false
inboundPeers: 0
nodeId: NodeID-GVQ8rMhHZcyGnm5okcn34yq2cdcvF6aG
outboundPeers: 0
pChainHeight: 0
startTime: "2026-03-17T06:49:55+00:00"
luxd-6:
bootstrapped: false
chainsCount: 0
connectedPeers: 0
healthy: false
inboundPeers: 0
outboundPeers: 0
startTime: "2026-03-17T06:50:05+00:00"
luxd-7:
bootstrapped: false
chainsCount: 0
connectedPeers: 0
healthy: false
inboundPeers: 0
outboundPeers: 0
startTime: "2026-03-17T06:49:49+00:00"
phase: Running
readyValidators: 5
snapshotCount: 0
totalValidators: 5
- apiVersion: lux.network/v1alpha1
kind: LuxNetwork
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"lux.network/v1alpha1","kind":"LuxNetwork","metadata":{"annotations":{},"name":"luxd","namespace":"lux-testnet"},"spec":{"adoptExisting":true,"chainTracking":{"trackAllChains":true},"chainUpgradeConfig":{"precompileUpgrades":[{"dexConfig":{"blockTimestamp":0,"enableFlashLoans":true,"enableHooks":true,"maxPools":10000}},{"routerConfig":{"blockTimestamp":0}}]},"consensus":{"sybilProtectionEnabled":true},"image":{"pullPolicy":"IfNotPresent","repository":"ghcr.io/luxfi/node","tag":"v1.23.31"},"networkId":2,"ports":{"http":9640,"staking":9641},"seedRestore":{"enabled":true,"objectStoreUrl":"http://s3.lux-system.svc.cluster.local:9000/lux-snapshots/testnet/testnet-node0-full.tar.gz","sourceType":"ObjectStore"},"snapshotSchedule":{"accessKey":"hanzo","bucket":"lux-snapshots","enabled":true,"includeRlpExports":true,"intervalSeconds":3600,"maxRetained":5,"objectStoreEndpoint":"http://s3.lux-system.svc.cluster.local:9000","prefix":"testnet","secretKeyRef":"hanzo-s3-secret","sourceNodeIndex":0},"staking":{"kms":{"auth":{"credentialsNamespace":"lux-system","credentialsSecret":"universal-auth-credentials"},"envSlug":"testnet","hostApi":"https://kms.lux.network/api","projectSlug":"lux-infra","resyncInterval":300,"secretsPath":"/staking"},"secretName":"luxd-staking"},"validators":8}}
creationTimestamp: "2026-02-25T05:43:28Z"
generation: 20
name: luxd
namespace: lux-testnet
resourceVersion: "78932442"
uid: cc7032e2-555b-4b03-9e99-9dfc6aa01b6c
spec:
adoptExisting: true
chainTracking:
trackAllChains: true
consensus:
sybilProtectionEnabled: true
image:
pullPolicy: IfNotPresent
repository: ghcr.io/luxfi/node
tag: v1.23.31
networkId: 2
ports:
http: 9640
staking: 9641
seedRestore:
enabled: true
objectStoreUrl: http://s3.lux-system.svc.cluster.local:9000/lux-snapshots/testnet/testnet-node0-full.tar.gz
sourceType: ObjectStore
snapshotSchedule:
accessKey: hanzo
bucket: lux-snapshots
enabled: true
includeRlpExports: true
intervalSeconds: 3600
maxRetained: 5
objectStoreEndpoint: http://s3.lux-system.svc.cluster.local:9000
prefix: testnet
secretKeyRef: hanzo-s3-secret
sourceNodeIndex: 0
staking:
kms:
auth:
credentialsNamespace: lux-system
credentialsSecret: universal-auth-credentials
envSlug: testnet
hostApi: https://kms.lux.network/api
projectSlug: lux-infra
resyncInterval: 300
secretsPath: /staking
secretName: luxd-staking
validators: 5
status:
bootstrapEndpoints:
- http://luxd-0.luxd-headless.lux-testnet.svc:9640
- http://luxd-1.luxd-headless.lux-testnet.svc:9640
- http://luxd-2.luxd-headless.lux-testnet.svc:9640
- http://luxd-3.luxd-headless.lux-testnet.svc:9640
- http://luxd-4.luxd-headless.lux-testnet.svc:9640
chainStatuses:
2Uw1b5tf63vamHsWVeSW9uHcGBVbF5CYHS9JiLWttusY4Vvjsn:
alias: zoo
healthy: false
2wbYEFh7ELuovqXhyYeCLvweZrcEgNUoZVJUAtw145qTVAUJxE:
alias: hanzo
healthy: false
C:
alias: C
blockHeight: 975
healthy: true
P:
alias: P
blockHeight: 112
healthy: true
is5GUzsKHk3Z4Q5JXTjF4Ld9p4TnEs81tJFdaBiEBJVkaFrrs:
alias: pars
healthy: false
u4pC2tT61o83pbQ8qwAyfXXGF6nyGFNSwCYHEFcUeESGiNKfu:
alias: spc
healthy: false
conditions: []
degradedReasons: []
externalIps:
luxd-0: 134.199.187.16
luxd-1: 209.38.174.84
luxd-2: 209.38.173.80
luxd-3: 134.199.187.62
luxd-4: 164.90.247.204
networkId: 2
networkMetrics:
bootstrappedChains: 2
heightSkew: 0
maxPHeight: 112
minPHeight: 112
totalPeers: 20
nodeStatuses:
luxd-0:
bootstrapped: true
cChainHeight: 975
chainsCount: 1
connectedPeers: 4
externalIp: 134.199.187.16
healthy: true
inboundPeers: 0
nodeId: NodeID-Mf3JfSY91oDwfBqf7rCLmhg4NDtDghw1f
outboundPeers: 4
pChainHeight: 112
startTime: "2026-06-01T20:15:57+00:00"
luxd-1:
bootstrapped: true
cChainHeight: 975
chainsCount: 1
connectedPeers: 4
externalIp: 209.38.174.84
healthy: true
inboundPeers: 0
nodeId: NodeID-2TwSZ2oyeBK2mv7JiseEQ8m74rotDj4QR
outboundPeers: 4
pChainHeight: 112
startTime: "2026-06-01T20:14:15+00:00"
luxd-2:
bootstrapped: true
cChainHeight: 975
chainsCount: 1
connectedPeers: 4
externalIp: 209.38.173.80
healthy: true
inboundPeers: 0
nodeId: NodeID-Ld9VFBQ9zGbd79z2vzaAqkQ3jHuqbtRpo
outboundPeers: 4
pChainHeight: 112
startTime: "2026-06-01T20:12:32+00:00"
luxd-3:
bootstrapped: true
cChainHeight: 757
chainsCount: 1
connectedPeers: 4
externalIp: 134.199.187.62
healthy: true
inboundPeers: 0
nodeId: NodeID-8mY2fhUehN27v3LCU84BnnKEoeRfd2weC
outboundPeers: 4
pChainHeight: 112
startTime: "2026-06-01T20:10:43+00:00"
luxd-4:
bootstrapped: true
cChainHeight: 975
chainsCount: 1
connectedPeers: 4
externalIp: 164.90.247.204
healthy: true
inboundPeers: 0
nodeId: NodeID-4smuFz5Z9cm8BEyQU1oPQ9nwgXyMgaNqu
outboundPeers: 4
pChainHeight: 112
startTime: "2026-06-01T20:09:01+00:00"
luxd-5:
bootstrapped: true
cChainHeight: 0
chainsCount: 1
connectedPeers: 0
healthy: false
inboundPeers: 0
nodeId: NodeID-7h6LpGqSHKUydyH4Y7xpzRY4NqYf29q1V
outboundPeers: 0
pChainHeight: 0
startTime: "2026-03-19T06:37:13+00:00"
phase: Running
readyValidators: 5
snapshotCount: 0
totalValidators: 5
kind: List
metadata:
resourceVersion: ""
@@ -0,0 +1,112 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "12"
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"lux-operator"},"name":"lux-operator","namespace":"lux-system"},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"lux-operator"}},"template":{"metadata":{"labels":{"app":"lux-operator"}},"spec":{"containers":[{"args":["--namespace","","--log-level","info","--metrics-port","8080","--health-port","8081","--leader-election"],"image":"ghcr.io/luxfi/operator:v0.3.11","imagePullPolicy":"Always","livenessProbe":{"failureThreshold":5,"httpGet":{"path":"/healthz","port":8081},"initialDelaySeconds":10,"periodSeconds":30,"timeoutSeconds":3},"name":"operator","ports":[{"containerPort":8080,"name":"metrics"},{"containerPort":8081,"name":"health"}],"readinessProbe":{"failureThreshold":3,"httpGet":{"path":"/healthz","port":8081},"initialDelaySeconds":3,"periodSeconds":10,"timeoutSeconds":3},"resources":{"limits":{"cpu":"1","memory":"512Mi"},"requests":{"cpu":"100m","memory":"128Mi"}}}],"imagePullSecrets":[{"name":"ghcr-luxfi"}],"serviceAccountName":"lux-operator"}}}}
creationTimestamp: "2026-02-25T05:42:55Z"
generation: 19
labels:
app: lux-operator
name: lux-operator
namespace: lux-system
resourceVersion: "64798812"
uid: 400d0a65-534a-4762-bf4c-7433b1dcd37e
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: lux-operator
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
kubectl.kubernetes.io/restartedAt: "2026-03-21T10:52:02-07:00"
labels:
app: lux-operator
spec:
containers:
- args:
- --namespace
- ""
- --log-level
- info
- --metrics-port
- "8080"
- --health-port
- "8081"
- --leader-election
image: ghcr.io/luxfi/operator:v0.3.12
imagePullPolicy: Always
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 8081
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 3
name: operator
ports:
- containerPort: 8080
name: metrics
protocol: TCP
- containerPort: 8081
name: health
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 8081
scheme: HTTP
initialDelaySeconds: 3
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 3
resources:
limits:
cpu: "1"
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: ghcr-luxfi
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: lux-operator
serviceAccountName: lux-operator
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2026-02-25T05:42:55Z"
lastUpdateTime: "2026-03-21T17:52:15Z"
message: ReplicaSet "lux-operator-55b598dc94" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
- lastTransitionTime: "2026-05-03T05:02:16Z"
lastUpdateTime: "2026-05-03T05:02:16Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
observedGeneration: 19
readyReplicas: 1
replicas: 1
updatedReplicas: 1
@@ -0,0 +1 @@
customresourcedefinition.apiextensions.k8s.io/luxmpcs.lux.network
+134
View File
@@ -0,0 +1,134 @@
#!/usr/bin/env bash
#
# migrate-luxnetwork-crds.sh — Phase A: lux.network/v1alpha1 → lux.cloud/v1
#
# Migrates all live CRs from the legacy `lux.network` API group at v1alpha1
# to the canonical `lux.cloud` API group at v1 (operator v0.6.3).
#
# Kind mapping:
# LuxNetwork → LuxNetwork (name unchanged)
# LuxChain → Chain (drop Lux prefix)
# LuxGateway → Gateway (drop Lux prefix)
# LuxIndexer → Indexer (drop Lux prefix)
# LuxExplorer → Explorer (drop Lux prefix)
# LuxMPC → MPC (drop Lux prefix)
#
# Spec/status pass through opaque (both CRDs use
# x-kubernetes-preserve-unknown-fields: true).
#
# Mode of operation:
# 1. List source kind in source group
# 2. For each item: read full yaml, swap apiVersion + kind,
# strip server-side metadata (resourceVersion, uid, generation,
# managedFields, creationTimestamp, status), apply under new group
# 3. Verify both CRs coexist (legacy + migrated) before any deletion
#
# Idempotent: re-applying produces same target CR (server-side merge by name).
#
# Usage:
# ./migrate-luxnetwork-crds.sh <kubectl-context> [--dry-run]
#
# Env:
# YQ — yq v4 binary path (default: yq). Required.
set -euo pipefail
CTX="${1:-}"
DRY_RUN=""
if [[ "${2:-}" == "--dry-run" ]]; then
DRY_RUN="--dry-run=client"
fi
if [[ -z "$CTX" ]]; then
echo "usage: $0 <kubectl-context> [--dry-run]" >&2
exit 2
fi
YQ="${YQ:-yq}"
if ! command -v "$YQ" >/dev/null 2>&1; then
echo "FATAL: yq v4+ required on PATH (or set YQ=)" >&2
exit 2
fi
# kind → (sourceGVR, targetGVR, targetKind)
# kubectl-friendly: lux<resource>.lux.network/v1alpha1 → <target>.lux.cloud/v1
declare -a KINDS=(
"luxnetwork:luxnetworks.lux.network:luxnetworks.lux.cloud:LuxNetwork:lux.cloud/v1"
"luxchain:luxchains.lux.network:chains.lux.cloud:Chain:lux.cloud/v1"
"luxgateway:luxgateways.lux.network:gateways.lux.cloud:Gateway:lux.cloud/v1"
"luxindexer:luxindexers.lux.network:indexers.lux.cloud:Indexer:lux.cloud/v1"
"luxexplorer:luxexplorers.lux.network:explorers.lux.cloud:Explorer:lux.cloud/v1"
"luxmpc:luxmpcs.lux.network:mpcs.lux.cloud:MPC:lux.cloud/v1"
)
TMP=$(mktemp -d -t lux-cr-migrate-XXXXXXXX)
trap 'rm -rf "$TMP"' EXIT
echo "Working dir: $TMP"
echo "Context: $CTX"
echo
migrated_total=0
for entry in "${KINDS[@]}"; do
IFS=':' read -r tag src_gvr dst_gvr dst_kind dst_apiver <<<"$entry"
echo "=== $tag : $src_gvr → $dst_gvr ($dst_kind / $dst_apiver) ==="
# List items in source — succeeds even if 0 items
if ! list_yaml=$(kubectl --context="$CTX" get "$src_gvr" -A -o yaml 2>/dev/null); then
echo " (source CRD $src_gvr not present, skipping)"
continue
fi
# Count items
count=$(printf '%s' "$list_yaml" | "$YQ" '.items | length' -)
if [[ "$count" == "0" || -z "$count" ]]; then
echo " (no items)"
continue
fi
echo " found $count item(s)"
# Emit each item, swap apiVersion + kind, strip server fields, apply
for i in $(seq 0 $((count - 1))); do
item_file="$TMP/${tag}-${i}.yaml"
printf '%s' "$list_yaml" | "$YQ" ".items[$i]
| .apiVersion = \"$dst_apiver\"
| .kind = \"$dst_kind\"
| del(.metadata.resourceVersion)
| del(.metadata.uid)
| del(.metadata.generation)
| del(.metadata.managedFields)
| del(.metadata.creationTimestamp)
| del(.metadata.selfLink)
| del(.metadata.ownerReferences)
| del(.metadata.annotations[\"kubectl.kubernetes.io/last-applied-configuration\"])
| del(.status)" - > "$item_file"
ns=$("$YQ" '.metadata.namespace' "$item_file")
name=$("$YQ" '.metadata.name' "$item_file")
echo " → $ns/$name"
if [[ -n "$DRY_RUN" ]]; then
kubectl --context="$CTX" apply $DRY_RUN -f "$item_file" -o name | sed 's/^/ /'
else
kubectl --context="$CTX" apply -f "$item_file" -o name | sed 's/^/ /'
fi
migrated_total=$((migrated_total + 1))
done
done
echo
echo "=== TOTAL: $migrated_total CR(s) migrated (or planned in dry-run) ==="
echo
echo "=== POST-MIGRATION INVENTORY ==="
echo "--- legacy lux.network CRs (should still be present) ---"
for entry in "${KINDS[@]}"; do
IFS=':' read -r tag src_gvr _ _ _ <<<"$entry"
count=$(kubectl --context="$CTX" get "$src_gvr" -A --no-headers 2>/dev/null | wc -l | tr -d ' ')
printf " %-30s %d\n" "$src_gvr" "$count"
done
echo "--- new lux.cloud CRs (should match counts) ---"
for entry in "${KINDS[@]}"; do
IFS=':' read -r tag _ dst_gvr _ _ <<<"$entry"
count=$(kubectl --context="$CTX" get "$dst_gvr" -A --no-headers 2>/dev/null | wc -l | tr -d ' ')
printf " %-30s %d\n" "$dst_gvr" "$count"
done