mirror of
https://github.com/luxfi/genesis.git
synced 2026-07-27 04:11:41 +00:00
Merge branch 'fix/retire-brand-l2-in-luxd-bootstrap'
This commit is contained in:
+42
-20
@@ -56,21 +56,24 @@ var (
|
||||
AChainAliases = []string{"A", "ai", "aivm"}
|
||||
// BChainAliases are the default aliases for the B-Chain (Bridge)
|
||||
BChainAliases = []string{"B", "bridge", "bridgevm"}
|
||||
// TChainAliases are the default aliases for the T-Chain (Threshold-FHE).
|
||||
// "F" / "fhe" alias the threshold-FHE chain since this is the
|
||||
// encrypted-compute chain in conceptual letter-chain taxonomy
|
||||
// (LP-134 / "F-Chain" in user-facing docs). The on-disk shard
|
||||
// stays tchain.json — letter is decomplected from product name.
|
||||
TChainAliases = []string{"T", "threshold", "thresholdvm", "F", "fhe", "fhevm"}
|
||||
// FChainAliases are the default aliases for the F-Chain (threshold-FHE).
|
||||
// LP-134: F-Chain runs the ThresholdVM substrate in FHE mode (confidential
|
||||
// compute / off-EVM threshold DECRYPT). It supersedes the retired T-Chain;
|
||||
// the legacy "T"/"threshold" labels now belong only to teleportvm
|
||||
// (LP-6332). On-disk shard: fchain.json.
|
||||
FChainAliases = []string{"F", "fhe", "fhevm"}
|
||||
// ZChainAliases are the default aliases for the Z-Chain (ZK)
|
||||
ZChainAliases = []string{"Z", "zk", "zkvm"}
|
||||
// GChainAliases are the default aliases for the G-Chain (Graph)
|
||||
GChainAliases = []string{"G", "graph", "graphvm"}
|
||||
// KChainAliases are the default aliases for the K-Chain (KMS / MPC).
|
||||
// "M" / "mpc" alias the KMS chain since this is the MPC-topology
|
||||
// chain in conceptual letter-chain taxonomy (LP-134 / "M-Chain"
|
||||
// in user-facing docs). The on-disk shard stays kchain.json.
|
||||
KChainAliases = []string{"K", "kms", "kmsvm", "M", "mpc", "mpcvm"}
|
||||
// KChainAliases are the default aliases for the K-Chain (KMS).
|
||||
// LP-134: "K stays keyvm" — the threshold-MPC labels M/mpc/mpcvm moved off
|
||||
// K onto the M-Chain (MChainAliases). K-Chain is pure KMS key management.
|
||||
KChainAliases = []string{"K", "key", "keyvm", "kms", "kmsvm"}
|
||||
// MChainAliases are the default aliases for the M-Chain (threshold-MPC).
|
||||
// LP-134: M-Chain runs the ThresholdVM substrate in MPC mode (CGGMP21 /
|
||||
// FROST threshold SIGNING for bridge custody). On-disk shard: mchain.json.
|
||||
MChainAliases = []string{"M", "mpc", "mpcvm"}
|
||||
|
||||
// VMAliases are the default aliases for VMs
|
||||
VMAliases = map[ids.ID][]string{
|
||||
@@ -576,10 +579,15 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
|
||||
// chains exist is a function of which shards the operator shipped,
|
||||
// not a runtime knob.
|
||||
//
|
||||
// Order is fixed (X→C→D→Q→A→B→T→Z→G→K) and preserved across
|
||||
// Order is fixed (X→C→D→Q→A→B→F→Z→G→K→M) and preserved across
|
||||
// presence/absence so byte-identical genesis holds when the same
|
||||
// shard set is supplied. Append-only — reordering shifts the
|
||||
// P-Chain genesis byte layout.
|
||||
//
|
||||
// LP-134: F-Chain and M-Chain both run the ThresholdVM substrate (F in
|
||||
// FHE mode, M in MPC mode) — they share constants.ThresholdVMID and are
|
||||
// disambiguated by BlockchainName. F-Chain occupies the retired T-Chain's
|
||||
// slot (same VM); M-Chain is appended, keeping Z/G/K byte-stable.
|
||||
chainEntries := []struct {
|
||||
GenesisData []byte
|
||||
VMID ids.ID
|
||||
@@ -593,10 +601,11 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
|
||||
{GenesisData: []byte(config.QChainGenesis), VMID: constants.QuantumVMID, Name: "Q-Chain"},
|
||||
{GenesisData: []byte(config.AChainGenesis), VMID: constants.AIVMID, Name: "A-Chain"},
|
||||
{GenesisData: []byte(config.BChainGenesis), VMID: constants.BridgeVMID, Name: "B-Chain"},
|
||||
{GenesisData: []byte(config.TChainGenesis), VMID: constants.ThresholdVMID, Name: "T-Chain"},
|
||||
{GenesisData: []byte(config.FChainGenesis), VMID: constants.ThresholdVMID, Name: "F-Chain"},
|
||||
{GenesisData: []byte(config.ZChainGenesis), VMID: constants.ZKVMID, Name: "Z-Chain"},
|
||||
{GenesisData: []byte(config.GChainGenesis), VMID: constants.GraphVMID, Name: "G-Chain"},
|
||||
{GenesisData: []byte(config.KChainGenesis), VMID: constants.KeyVMID, Name: "K-Chain"},
|
||||
{GenesisData: []byte(config.MChainGenesis), VMID: constants.ThresholdVMID, Name: "M-Chain"},
|
||||
}
|
||||
chains := []genesis.Chain{}
|
||||
for _, e := range chainEntries {
|
||||
@@ -787,12 +796,25 @@ func Aliases(genesisBytes []byte) (map[string][]string, map[ids.ID][]string, err
|
||||
}
|
||||
chainAliases[chainID] = BChainAliases
|
||||
case constants.ThresholdVMID:
|
||||
apiAliases[endpoint] = []string{
|
||||
"T", "threshold", "thresholdvm",
|
||||
path.Join(constants.ChainAliasPrefix, "T"),
|
||||
path.Join(constants.ChainAliasPrefix, "threshold"),
|
||||
// LP-134: F-Chain (FHE mode) and M-Chain (MPC mode) both run the
|
||||
// ThresholdVM substrate, so they share constants.ThresholdVMID.
|
||||
// They are distinct chains — disambiguate by the CreateChainTx's
|
||||
// BlockchainName (set from the chain entry Name in FromConfig).
|
||||
if uChain.BlockchainName == "M-Chain" {
|
||||
apiAliases[endpoint] = []string{
|
||||
"M", "mpc", "mpcvm",
|
||||
path.Join(constants.ChainAliasPrefix, "M"),
|
||||
path.Join(constants.ChainAliasPrefix, "mpc"),
|
||||
}
|
||||
chainAliases[chainID] = MChainAliases
|
||||
} else {
|
||||
apiAliases[endpoint] = []string{
|
||||
"F", "fhe", "fhevm",
|
||||
path.Join(constants.ChainAliasPrefix, "F"),
|
||||
path.Join(constants.ChainAliasPrefix, "fhe"),
|
||||
}
|
||||
chainAliases[chainID] = FChainAliases
|
||||
}
|
||||
chainAliases[chainID] = TChainAliases
|
||||
case constants.ZKVMID:
|
||||
apiAliases[endpoint] = []string{
|
||||
"Z", "zk", "zkvm",
|
||||
@@ -809,9 +831,9 @@ func Aliases(genesisBytes []byte) (map[string][]string, map[ids.ID][]string, err
|
||||
chainAliases[chainID] = GChainAliases
|
||||
case constants.KeyVMID:
|
||||
apiAliases[endpoint] = []string{
|
||||
"K", "kms", "kmsvm",
|
||||
"K", "key", "keyvm", "kms",
|
||||
path.Join(constants.ChainAliasPrefix, "K"),
|
||||
path.Join(constants.ChainAliasPrefix, "kms"),
|
||||
path.Join(constants.ChainAliasPrefix, "key"),
|
||||
}
|
||||
chainAliases[chainID] = KChainAliases
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ func TestFromConfig_ChainSetIsShardDriven(t *testing.T) {
|
||||
|
||||
full, err := pgenesis.Parse(pgc, bytes)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, full.Chains, 10, "mainnet emits all 10 primary chains")
|
||||
require.Len(t, full.Chains, 11, "mainnet emits all 11 primary chains (LP-134: X,C,D,Q,A,B,F,Z,G,K,M)")
|
||||
|
||||
// Strip every chain shard. Allocations + validators stay intact —
|
||||
// the P-Chain itself is the foundation, not a CreateChainTx entry.
|
||||
@@ -218,10 +218,11 @@ func TestFromConfig_ChainSetIsShardDriven(t *testing.T) {
|
||||
cfg.QChainGenesis = ""
|
||||
cfg.AChainGenesis = ""
|
||||
cfg.BChainGenesis = ""
|
||||
cfg.TChainGenesis = ""
|
||||
cfg.FChainGenesis = ""
|
||||
cfg.ZChainGenesis = ""
|
||||
cfg.GChainGenesis = ""
|
||||
cfg.KChainGenesis = ""
|
||||
cfg.MChainGenesis = ""
|
||||
|
||||
bytes, utxoAssetID, err = FromConfig(cfg)
|
||||
require.NoError(t, err, "P-only build must succeed")
|
||||
|
||||
@@ -39,7 +39,7 @@ func TestWire_PVMGenesisRoundtrip(t *testing.T) {
|
||||
gen, err := pgenesis.Parse(pgc, bytes1)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, gen)
|
||||
require.Equal(t, 10, len(gen.Chains), "mainnet ships all 10 primary chains")
|
||||
require.Equal(t, 11, len(gen.Chains), "mainnet ships all 11 primary chains (LP-134: T split into F+M)")
|
||||
|
||||
// Re-marshal.
|
||||
bytes2, err := gen.Bytes(pgc)
|
||||
|
||||
+34
-12
@@ -9,9 +9,12 @@
|
||||
// 3. IssueAddChainValidatorTx — adds every primary network validator
|
||||
// 4. Probes eth_blockNumber and info.isBootstrapped — fails if either is bad
|
||||
//
|
||||
// Designed to bootstrap the four canonical Lux devnet chains (hanzo, zoo,
|
||||
// pars, spc) in one pass, but the list is data-driven so it can bootstrap
|
||||
// any subset.
|
||||
// Creates lux-native chains on a luxd network. The chain list is data-driven
|
||||
// (--track-chain-ids). Brand names (hanzo/zoo/pars/spc/osage) are REFUSED:
|
||||
// per the brand_sovereign_node_one_way law luxd runs the LUX primary network
|
||||
// ONLY, and each brand runs its own sovereign node (zood/hanzod/parsd/…). The
|
||||
// historical "bootstrap the four brand L2s into luxd" purpose is retired
|
||||
// alongside cmd/createchaintx.
|
||||
//
|
||||
// Idempotency: before any P-chain spend, the tool queries
|
||||
// platform.getBlockchains and skips any chain whose alias already exists.
|
||||
@@ -22,9 +25,9 @@
|
||||
// by CreateChainTx. Three IDs, three roles, never aliased:
|
||||
//
|
||||
// - `networkID` — identifies a validator network. Comes in two scopes:
|
||||
// * primary networkID (uint32: 1=mainnet, 2=testnet, 3=local, 1337=dev)
|
||||
// * per-chain networkID (ids.ID 32 bytes) — the CreateNetworkTx ID
|
||||
// that owns one or more chains.
|
||||
// - primary networkID (uint32: 1=mainnet, 2=testnet, 3=local, 1337=dev)
|
||||
// - per-chain networkID (ids.ID 32 bytes) — the CreateNetworkTx ID
|
||||
// that owns one or more chains.
|
||||
// - `chainID` — the blockchain's own globally unique ID (ids.ID 32 bytes).
|
||||
// - `evmChainID` — EIP-155 chain ID (uint64). EVM JSON-RPC only.
|
||||
//
|
||||
@@ -36,7 +39,7 @@
|
||||
// --bip44-idx=5 \
|
||||
// --network-label=devnet \
|
||||
// --configs-dir=/path/to/genesis/configs \
|
||||
// --track-chain-ids=hanzo,zoo,pars,spc \
|
||||
// --track-chain-ids=<lux-native-chain-ids> \
|
||||
// --output=/dev/stdout
|
||||
package main
|
||||
|
||||
@@ -117,11 +120,17 @@ func main() {
|
||||
hrp := flag.String("hrp", "dev", "P-chain bech32 HRP: test|dev")
|
||||
bipIdx := flag.Uint("bip44-idx", 5, "BIP44 derivation index at m/44'/9000'/0'/0/<idx>")
|
||||
configsDir := flag.String("configs-dir", "", "directory containing <chain>-<network>/genesis.json files (required)")
|
||||
// --track-chain-ids mirrors luxd's existing --track-chain-ids flag. One
|
||||
// concept, one flag — this is the declared list of chains this network
|
||||
// serves. The tool reads it, queries the P-chain, and idempotently
|
||||
// creates the missing ones.
|
||||
trackChainIDs := flag.String("track-chain-ids", "hanzo,zoo,pars,spc", "comma-separated brand names (matches luxd --track-chain-ids). Each name resolves a (brand,env) → configs/<brand>-<env>/genesis.json and a content-hashed CreateChainTx name.")
|
||||
// --track-chain-ids is the declared list of non-brand chains to create on
|
||||
// the target luxd network. The tool reads it, queries the P-chain, and
|
||||
// idempotently creates the missing ones.
|
||||
//
|
||||
// DEFAULT IS EMPTY by design. The historical default "hanzo,zoo,pars,spc"
|
||||
// created brand L2 EVMs INSIDE luxd — the dead WAY-1 retired by the
|
||||
// brand_sovereign_node_one_way law: luxd runs the LUX primary network
|
||||
// ONLY, and each brand (hanzo/zoo/pars/spc/osage) runs its OWN sovereign
|
||||
// node (zood/hanzod/parsd/…). Brand names are now hard-refused below; this
|
||||
// flag exists only for legitimate lux-native chain creation.
|
||||
trackChainIDs := flag.String("track-chain-ids", "", "comma-separated chain ids to create on the target luxd network. Brand names (hanzo/zoo/pars/spc/osage) are REFUSED — brands run their own sovereign node, never inside luxd.")
|
||||
vmIDStr := flag.String("vm-id", defaultEVMID, "EVM VM ID present in luxd's --plugin-dir")
|
||||
// --chain-name-override pins an explicit CreateChainTx name for a single
|
||||
// brand (format: <brand>=<name>, repeatable). Bypasses the content-hash
|
||||
@@ -195,6 +204,19 @@ func main() {
|
||||
log.Fatal("--uri and --configs-dir are required")
|
||||
}
|
||||
|
||||
// brand_sovereign_node_one_way law: luxd runs the LUX primary network
|
||||
// ONLY. Brand L2 EVMs are NEVER created inside luxd — each brand runs its
|
||||
// own sovereign node (zood/hanzod/parsd/…) and the unified DEX is the
|
||||
// shared 0x9999 V4 precompile compiled into every brand EVM, not a chain
|
||||
// hosted on luxd. Refuse brand names so this tool can never re-create the
|
||||
// phantom brand chains that decayed into dangling chain-aliases.
|
||||
for _, name := range strings.Split(*trackChainIDs, ",") {
|
||||
switch strings.ToLower(strings.TrimSpace(name)) {
|
||||
case "hanzo", "zoo", "pars", "spc", "osage":
|
||||
log.Fatalf("refusing to bootstrap brand chain %q inside luxd: brands run their own sovereign node (zood/hanzod/parsd/…), not luxd — see brand_sovereign_node_one_way", strings.TrimSpace(name))
|
||||
}
|
||||
}
|
||||
|
||||
vmID, err := ids.FromString(*vmIDStr)
|
||||
if err != nil {
|
||||
log.Fatalf("invalid --vm-id: %v", err)
|
||||
|
||||
@@ -143,12 +143,14 @@ func networkIDFromName(t *testing.T, name string) uint32 {
|
||||
}
|
||||
|
||||
// TestGetGenesis_AllPrimaryChainsBakedIn locks the contract that every
|
||||
// primary network (mainnet, testnet, devnet, localnet) ships ALL 10
|
||||
// primary network (mainnet, testnet, devnet, localnet) ships ALL 11
|
||||
// primary-network chain shards baked into its genesis. This means the
|
||||
// chains spawn at network startup with NO post-launch CreateBlockchainTx —
|
||||
// chain set is fully data-driven by which shards are committed.
|
||||
//
|
||||
// The 10 primary-network chains, in canonical order:
|
||||
// The 11 primary-network chains, in canonical order (LP-134: the legacy
|
||||
// T-Chain/ThresholdVM is retired and split into F-Chain + M-Chain, both
|
||||
// served by the same ThresholdVM substrate in FHE / MPC mode respectively):
|
||||
//
|
||||
// X XVM exchange / UTXO asset
|
||||
// C EVM contracts
|
||||
@@ -156,10 +158,11 @@ func networkIDFromName(t *testing.T, name string) uint32 {
|
||||
// Q QuantumVM post-quantum consensus (Quasar / ML-DSA / ML-KEM)
|
||||
// A AIVM AI verification / attestation
|
||||
// B BridgeVM cross-chain bridge (MPC signing)
|
||||
// T ThresholdVM threshold FHE encrypted compute (LP-?? F-chain semantic)
|
||||
// F ThresholdVM threshold-FHE confidential compute (LP-134; FHE mode, T's slot)
|
||||
// Z ZKVM zero-knowledge proofs / private state
|
||||
// G GraphVM graph database
|
||||
// K KeyVM KMS — MPC topology (LP-?? M-chain semantic)
|
||||
// K KeyVM KMS — key management
|
||||
// M ThresholdVM threshold-MPC bridge-custody signing (LP-134; MPC mode)
|
||||
//
|
||||
// P-Chain is the primary network itself and carries the validator set + chain
|
||||
// registry; it has no shard slot because it isn't a CreateChainTx entry.
|
||||
@@ -177,10 +180,11 @@ func TestGetGenesis_AllPrimaryChainsBakedIn(t *testing.T) {
|
||||
"qChainGenesis",
|
||||
"aChainGenesis",
|
||||
"bChainGenesis",
|
||||
"tChainGenesis",
|
||||
"fChainGenesis",
|
||||
"zChainGenesis",
|
||||
"gChainGenesis",
|
||||
"kChainGenesis",
|
||||
"mChainGenesis",
|
||||
}
|
||||
for _, name := range []string{"mainnet", "testnet", "devnet", "localnet"} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
@@ -214,11 +218,16 @@ func TestGetGenesis_AllPrimaryChainsBakedIn(t *testing.T) {
|
||||
// for the D/Q/A/... shards below; C is the one cell pinned by the
|
||||
// canonical map rather than derived from the arithmetic.
|
||||
//
|
||||
// LP-134: the legacy T-Chain (idx 5, 96869-series) is retired. F-Chain and
|
||||
// M-Chain take the next free indices 9 and 10 — fresh IDs, T's are not
|
||||
// recycled. (localnet base = 31337 + 110*idx.)
|
||||
//
|
||||
// This produces:
|
||||
//
|
||||
// C(96369/96368/96367), D(96469/96468/96470), Q(96569/96568/96570),
|
||||
// A(96669/96668/96670), B(96769/96768/96770), T(96869/96868/96870),
|
||||
// Z(96969/96968/96970), G(97069/97068/97070), K(97169/97168/97170)
|
||||
// A(96669/96668/96670), B(96769/96768/96770), F(97269/97268/97270),
|
||||
// Z(96969/96968/96970), G(97069/97068/97070), K(97169/97168/97170),
|
||||
// M(97369/97368/97370)
|
||||
//
|
||||
// Each ID is unique across {network × letter} so a misrouted tx cannot
|
||||
// be replayed against the wrong chain.
|
||||
@@ -226,19 +235,19 @@ func TestPrimaryChainShards_PerChainCanonicalChainID(t *testing.T) {
|
||||
want := map[string]map[string]int{
|
||||
"mainnet": {
|
||||
"d": 96469, "q": 96569, "a": 96669, "b": 96769,
|
||||
"t": 96869, "z": 96969, "g": 97069, "k": 97169,
|
||||
"f": 97269, "z": 96969, "g": 97069, "k": 97169, "m": 97369,
|
||||
},
|
||||
"testnet": {
|
||||
"d": 96468, "q": 96568, "a": 96668, "b": 96768,
|
||||
"t": 96868, "z": 96968, "g": 97068, "k": 97168,
|
||||
"f": 97268, "z": 96968, "g": 97068, "k": 97168, "m": 97368,
|
||||
},
|
||||
"devnet": {
|
||||
"d": 96470, "q": 96570, "a": 96670, "b": 96770,
|
||||
"t": 96870, "z": 96970, "g": 97070, "k": 97170,
|
||||
"f": 97270, "z": 96970, "g": 97070, "k": 97170, "m": 97370,
|
||||
},
|
||||
"localnet": {
|
||||
"d": 31447, "q": 31557, "a": 31667, "b": 31777,
|
||||
"t": 31887, "z": 31997, "g": 32107, "k": 32217,
|
||||
"f": 32327, "z": 31997, "g": 32107, "k": 32217, "m": 32437,
|
||||
},
|
||||
}
|
||||
for net, byLetter := range want {
|
||||
|
||||
+17
-7
@@ -201,7 +201,7 @@ func loadEmbeddedGenesisWithDynamic(networkName string, dynamicPChain *genesis.P
|
||||
// Runtime gate is luxd's --track-chains, not bake-time env knobs.
|
||||
//
|
||||
// To run a P-only network (a regulated securities L1, etc.), ship a config tree
|
||||
// that omits every {x,c,d,q,a,b,t,z,g,k}chain.json. No knob, no
|
||||
// that omits every {x,c,d,q,a,b,f,z,g,k,m}chain.json. No knob, no
|
||||
// hack — chain set is purely data-driven by which shards are
|
||||
// present.
|
||||
chainShards, err := loadAllChainShards(networkName)
|
||||
@@ -237,10 +237,11 @@ func loadEmbeddedGenesisWithDynamic(networkName string, dynamicPChain *genesis.P
|
||||
QChainGenesis: chainShards.Q,
|
||||
AChainGenesis: chainShards.A,
|
||||
BChainGenesis: chainShards.B,
|
||||
TChainGenesis: chainShards.T,
|
||||
FChainGenesis: chainShards.F,
|
||||
ZChainGenesis: chainShards.Z,
|
||||
GChainGenesis: chainShards.G,
|
||||
KChainGenesis: chainShards.K,
|
||||
MChainGenesis: chainShards.M,
|
||||
SecurityProfile: securityProfile,
|
||||
CertPolicy: certPolicy,
|
||||
Message: network.Message,
|
||||
@@ -255,13 +256,19 @@ func loadEmbeddedGenesisWithDynamic(networkName string, dynamicPChain *genesis.P
|
||||
// in the builder's chains slice — the operator's filesystem is the
|
||||
// declarative source of truth for which primary-network chains exist.
|
||||
type chainSet struct {
|
||||
X, C, D, Q, A, B, T, Z, G, K string
|
||||
X, C, D, Q, A, B, F, Z, G, K, M string
|
||||
}
|
||||
|
||||
// primaryChainShardFiles lists every primary-network chain shard
|
||||
// filename in canonical order. Order matters: builder.FromConfig
|
||||
// preserves it when assembling the chains slice, so changing this
|
||||
// list shifts the P-Chain genesis byte layout. Append-only.
|
||||
//
|
||||
// LP-134: the legacy tchain.json (ThresholdVM) is retired; the threshold
|
||||
// substrate is split into fchain.json (F-Chain, threshold-FHE) — which
|
||||
// takes T's vacated slot since it runs the same ThresholdVM — and
|
||||
// mchain.json (M-Chain, threshold-MPC bridge custody), appended at the
|
||||
// end. Z/G/K positions are unchanged so their genesis layout is stable.
|
||||
var primaryChainShardFiles = [...]string{
|
||||
"xchain.json",
|
||||
"cchain.json",
|
||||
@@ -269,10 +276,11 @@ var primaryChainShardFiles = [...]string{
|
||||
"qchain.json",
|
||||
"achain.json",
|
||||
"bchain.json",
|
||||
"tchain.json",
|
||||
"fchain.json",
|
||||
"zchain.json",
|
||||
"gchain.json",
|
||||
"kchain.json",
|
||||
"mchain.json",
|
||||
}
|
||||
|
||||
// chainSetSlots returns the address-of-field slots for s in the
|
||||
@@ -280,7 +288,7 @@ var primaryChainShardFiles = [...]string{
|
||||
// FS loaders to bind shard files to ConfigOutput fields without
|
||||
// repeating the per-chain switch.
|
||||
func (s *chainSet) slots() []*string {
|
||||
return []*string{&s.X, &s.C, &s.D, &s.Q, &s.A, &s.B, &s.T, &s.Z, &s.G, &s.K}
|
||||
return []*string{&s.X, &s.C, &s.D, &s.Q, &s.A, &s.B, &s.F, &s.Z, &s.G, &s.K, &s.M}
|
||||
}
|
||||
|
||||
// loadAllChainShards reads every primary-network chain shard from the
|
||||
@@ -535,10 +543,11 @@ func buildCanonicalGenesisFromSplitFiles(networkName string) ([]byte, error) {
|
||||
QChainGenesis: chainShards.Q,
|
||||
AChainGenesis: chainShards.A,
|
||||
BChainGenesis: chainShards.B,
|
||||
TChainGenesis: chainShards.T,
|
||||
FChainGenesis: chainShards.F,
|
||||
ZChainGenesis: chainShards.Z,
|
||||
GChainGenesis: chainShards.G,
|
||||
KChainGenesis: chainShards.K,
|
||||
MChainGenesis: chainShards.M,
|
||||
Message: network.Message,
|
||||
}
|
||||
|
||||
@@ -642,10 +651,11 @@ func buildGenesisFromDir(dir string) ([]byte, error) {
|
||||
QChainGenesis: chainShards.Q,
|
||||
AChainGenesis: chainShards.A,
|
||||
BChainGenesis: chainShards.B,
|
||||
TChainGenesis: chainShards.T,
|
||||
FChainGenesis: chainShards.F,
|
||||
ZChainGenesis: chainShards.Z,
|
||||
GChainGenesis: chainShards.G,
|
||||
KChainGenesis: chainShards.K,
|
||||
MChainGenesis: chainShards.M,
|
||||
SecurityProfile: securityProfile,
|
||||
Message: network.Message,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE confidential compute — off-EVM threshold DECRYPT (TFHE, ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"fhePrecompilePrefix": "0x07",
|
||||
"message": "Lux F-Chain Genesis",
|
||||
"mode": "fhe",
|
||||
"name": "F-Chain",
|
||||
"networkId": 3,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 97270
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
"K",
|
||||
"key",
|
||||
"keyvm",
|
||||
"kms"
|
||||
],
|
||||
"description": "KMS \u2014 MPC key management + threshold sigs",
|
||||
"description": "KMS — key management (ML-KEM / ML-DSA / BLS)",
|
||||
"message": "Lux K-Chain Genesis",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"name": "K-Chain",
|
||||
"networkId": 3,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "KeyVM",
|
||||
"chainId": 97170
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
],
|
||||
"description": "Threshold MPC signing — off-EVM CGGMP21/FROST ceremony for bridge custody of external wallets",
|
||||
"message": "Lux M-Chain Genesis",
|
||||
"mode": "mpc",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"mpcVerifyPrecompiles": [
|
||||
"0x0800000000000000000000000000000000000002",
|
||||
"0x0800000000000000000000000000000000000003"
|
||||
],
|
||||
"name": "M-Chain",
|
||||
"networkId": 3,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 97370
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE encrypted compute (ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"message": "Lux T-Chain Genesis",
|
||||
"name": "T-Chain",
|
||||
"networkId": 3,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 96870
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE confidential compute — off-EVM threshold DECRYPT (TFHE, ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"fhePrecompilePrefix": "0x07",
|
||||
"message": "Lux F-Chain Genesis",
|
||||
"mode": "fhe",
|
||||
"name": "F-Chain",
|
||||
"networkId": 1337,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1735689600,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 32327
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
"K",
|
||||
"key",
|
||||
"keyvm",
|
||||
"kms"
|
||||
],
|
||||
"description": "KMS \u2014 MPC key management + threshold sigs",
|
||||
"description": "KMS — key management (ML-KEM / ML-DSA / BLS)",
|
||||
"message": "Lux K-Chain Genesis",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"name": "K-Chain",
|
||||
"networkId": 1337,
|
||||
"timestamp": 1735689600,
|
||||
"version": 1,
|
||||
"vm": "KeyVM",
|
||||
"chainId": 32217
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
],
|
||||
"description": "Threshold MPC signing — off-EVM CGGMP21/FROST ceremony for bridge custody of external wallets",
|
||||
"message": "Lux M-Chain Genesis",
|
||||
"mode": "mpc",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"mpcVerifyPrecompiles": [
|
||||
"0x0800000000000000000000000000000000000002",
|
||||
"0x0800000000000000000000000000000000000003"
|
||||
],
|
||||
"name": "M-Chain",
|
||||
"networkId": 1337,
|
||||
"timestamp": 1735689600,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 32437
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE encrypted compute (ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"message": "Lux T-Chain Genesis",
|
||||
"name": "T-Chain",
|
||||
"networkId": 1337,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1735689600,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 31887
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
// Copyright (C) 2019-2026, Lux Industries, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package configs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// LP-134 chain-level decomplect invariants.
|
||||
//
|
||||
// The legacy T-Chain (ThresholdVM serving BOTH threshold-FHE and
|
||||
// threshold-MPC) is split into two orthogonal chains — F-Chain (FHE only,
|
||||
// confidential DECRYPT) and M-Chain (MPC only, CGGMP21/FROST bridge-custody
|
||||
// SIGNING) — plus a K-Chain (KeyVM/KMS) cleaned of the MPC conflation
|
||||
// ("K stays keyvm"). Both F and M run the same ThresholdVM substrate but are
|
||||
// distinct chains with disjoint purposes, params, precompile families, and
|
||||
// aliases. These tests fail closed if any concern leaks across the split:
|
||||
// - no MPC field/alias/precompile-family on F-Chain,
|
||||
// - no FHE field/alias/precompile-family on M-Chain,
|
||||
// - no alias claimed by two of {F, M, K},
|
||||
// - the retired tchain.json is gone (forward-only).
|
||||
|
||||
var lp134Nets = []string{"mainnet", "testnet", "devnet", "localnet"}
|
||||
|
||||
func lp134ShardPath(net, letter string) string {
|
||||
return filepath.Join("..", "configs", net, letter+"chain.json")
|
||||
}
|
||||
|
||||
func lp134ReadShard(t *testing.T, net, letter string) map[string]any {
|
||||
t.Helper()
|
||||
data, err := os.ReadFile(lp134ShardPath(net, letter))
|
||||
if err != nil {
|
||||
t.Fatalf("%s/%schain.json: %v", net, letter, err)
|
||||
}
|
||||
var m map[string]any
|
||||
if err := json.Unmarshal(data, &m); err != nil {
|
||||
t.Fatalf("%s/%schain.json parse: %v", net, letter, err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func lp134ShardText(t *testing.T, net, letter string) string {
|
||||
t.Helper()
|
||||
data, err := os.ReadFile(lp134ShardPath(net, letter))
|
||||
if err != nil {
|
||||
t.Fatalf("%s/%schain.json: %v", net, letter, err)
|
||||
}
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func lp134AliasSet(t *testing.T, m map[string]any) map[string]bool {
|
||||
t.Helper()
|
||||
raw, ok := m["aliases"].([]any)
|
||||
if !ok {
|
||||
t.Fatalf("aliases missing or wrong type: %T", m["aliases"])
|
||||
}
|
||||
out := make(map[string]bool, len(raw))
|
||||
for _, a := range raw {
|
||||
s, _ := a.(string)
|
||||
out[strings.ToLower(s)] = true
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// TestLP134_TChainRetired: the legacy tchain.json is gone on every net
|
||||
// (forward-only split — F-Chain + M-Chain supersede it).
|
||||
func TestLP134_TChainRetired(t *testing.T) {
|
||||
for _, net := range lp134Nets {
|
||||
if _, err := os.Stat(lp134ShardPath(net, "t")); !os.IsNotExist(err) {
|
||||
t.Fatalf("%s/tchain.json must be retired (LP-134 forward-only split); stat err=%v", net, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestLP134_FChainIsFHEOnly: F-Chain carries FHE concepts only — ThresholdVM
|
||||
// in FHE mode, FHE ring params, the 0x07 FHE precompile family, and NO MPC
|
||||
// field, alias, or 0x08 (threshold-signature) precompile-family reference.
|
||||
func TestLP134_FChainIsFHEOnly(t *testing.T) {
|
||||
for _, net := range lp134Nets {
|
||||
t.Run(net, func(t *testing.T) {
|
||||
m := lp134ReadShard(t, net, "f")
|
||||
if got, _ := m["vm"].(string); got != "ThresholdVM" {
|
||||
t.Fatalf("F-Chain vm = %q, want ThresholdVM", got)
|
||||
}
|
||||
if got, _ := m["mode"].(string); got != "fhe" {
|
||||
t.Fatalf("F-Chain mode = %q, want fhe", got)
|
||||
}
|
||||
if m["ringDegreeN"] == nil || m["ringModulusQ"] == nil {
|
||||
t.Fatalf("F-Chain must carry the FHE ring params (ringDegreeN/ringModulusQ)")
|
||||
}
|
||||
if got, _ := m["fhePrecompilePrefix"].(string); got != "0x07" {
|
||||
t.Fatalf("F-Chain fhePrecompilePrefix = %q, want 0x07", got)
|
||||
}
|
||||
// Decomplect: no MPC concepts on F-Chain.
|
||||
for _, banned := range []string{"mpcParties", "mpcThreshold", "mpcVerifyPrecompiles"} {
|
||||
if m[banned] != nil {
|
||||
t.Fatalf("F-Chain must not carry MPC field %q (LP-134 decomplect)", banned)
|
||||
}
|
||||
}
|
||||
if strings.Contains(lp134ShardText(t, net, "f"), "0x08") {
|
||||
t.Fatalf("F-Chain must not reference the 0x08 threshold-signature precompile family")
|
||||
}
|
||||
al := lp134AliasSet(t, m)
|
||||
for _, want := range []string{"f", "fhe", "fhevm"} {
|
||||
if !al[want] {
|
||||
t.Fatalf("F-Chain aliases must include %q", want)
|
||||
}
|
||||
}
|
||||
for _, banned := range []string{"m", "mpc", "mpcvm", "t", "threshold", "thresholdvm"} {
|
||||
if al[banned] {
|
||||
t.Fatalf("F-Chain must not claim alias %q", banned)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestLP134_MChainIsMPCOnly: M-Chain carries MPC concepts only — ThresholdVM
|
||||
// in MPC mode, MPC params, the CGGMP21 (0x0800..03) + FROST (0x0800..02)
|
||||
// verify precompiles, and NO FHE field, alias, or 0x07 precompile-family ref.
|
||||
func TestLP134_MChainIsMPCOnly(t *testing.T) {
|
||||
const (
|
||||
frostAddr = "0x0800000000000000000000000000000000000002"
|
||||
cggmp21Addr = "0x0800000000000000000000000000000000000003"
|
||||
)
|
||||
for _, net := range lp134Nets {
|
||||
t.Run(net, func(t *testing.T) {
|
||||
m := lp134ReadShard(t, net, "m")
|
||||
if got, _ := m["vm"].(string); got != "ThresholdVM" {
|
||||
t.Fatalf("M-Chain vm = %q, want ThresholdVM", got)
|
||||
}
|
||||
if got, _ := m["mode"].(string); got != "mpc" {
|
||||
t.Fatalf("M-Chain mode = %q, want mpc", got)
|
||||
}
|
||||
if m["mpcParties"] == nil || m["mpcThreshold"] == nil {
|
||||
t.Fatalf("M-Chain must carry the MPC params (mpcParties/mpcThreshold)")
|
||||
}
|
||||
// EVM verify surface: exactly the two threshold-signature precompiles.
|
||||
pcs, ok := m["mpcVerifyPrecompiles"].([]any)
|
||||
if !ok || len(pcs) != 2 {
|
||||
t.Fatalf("M-Chain must declare its 2 MPC verify precompiles, got %v", m["mpcVerifyPrecompiles"])
|
||||
}
|
||||
seen := map[string]bool{frostAddr: false, cggmp21Addr: false}
|
||||
for _, p := range pcs {
|
||||
ps, _ := p.(string)
|
||||
ps = strings.ToLower(ps)
|
||||
if _, known := seen[ps]; !known {
|
||||
t.Fatalf("M-Chain unexpected precompile %q (want only FROST/CGGMP21)", ps)
|
||||
}
|
||||
seen[ps] = true
|
||||
}
|
||||
for addr, ok := range seen {
|
||||
if !ok {
|
||||
t.Fatalf("M-Chain missing MPC verify precompile %s", addr)
|
||||
}
|
||||
}
|
||||
// Decomplect: no FHE concepts on M-Chain.
|
||||
for _, banned := range []string{"ringDegreeN", "ringModulusQ", "dkgParties", "dkgThreshold", "fhePrecompilePrefix"} {
|
||||
if m[banned] != nil {
|
||||
t.Fatalf("M-Chain must not carry FHE field %q (LP-134 decomplect)", banned)
|
||||
}
|
||||
}
|
||||
if strings.Contains(lp134ShardText(t, net, "m"), "0x07") {
|
||||
t.Fatalf("M-Chain must not reference the 0x07 FHE precompile family")
|
||||
}
|
||||
al := lp134AliasSet(t, m)
|
||||
for _, want := range []string{"m", "mpc", "mpcvm"} {
|
||||
if !al[want] {
|
||||
t.Fatalf("M-Chain aliases must include %q", want)
|
||||
}
|
||||
}
|
||||
for _, banned := range []string{"f", "fhe", "fhevm", "t", "threshold", "thresholdvm"} {
|
||||
if al[banned] {
|
||||
t.Fatalf("M-Chain must not claim alias %q", banned)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestLP134_KChainIsKMSOnly: K-Chain is pure KeyVM/KMS — the M/mpc aliases and
|
||||
// MPC params moved to M-Chain ("K stays keyvm" per LP-134).
|
||||
func TestLP134_KChainIsKMSOnly(t *testing.T) {
|
||||
for _, net := range lp134Nets {
|
||||
t.Run(net, func(t *testing.T) {
|
||||
m := lp134ReadShard(t, net, "k")
|
||||
if got, _ := m["vm"].(string); got != "KeyVM" {
|
||||
t.Fatalf("K-Chain vm = %q, want KeyVM", got)
|
||||
}
|
||||
for _, banned := range []string{"mpcParties", "mpcThreshold", "mpcVerifyPrecompiles", "mode", "ringDegreeN"} {
|
||||
if m[banned] != nil {
|
||||
t.Fatalf("K-Chain must not carry %q (LP-134: MPC/FHE concerns live on M/F)", banned)
|
||||
}
|
||||
}
|
||||
al := lp134AliasSet(t, m)
|
||||
if !al["k"] {
|
||||
t.Fatalf("K-Chain must claim alias K")
|
||||
}
|
||||
for _, banned := range []string{"m", "mpc", "mpcvm", "f", "fhe", "fhevm"} {
|
||||
if al[banned] {
|
||||
t.Fatalf("K-Chain must not claim alias %q (LP-134 decomplect)", banned)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestLP134_NoAliasCollision: the threshold-family chains {F, M, K} claim
|
||||
// mutually-disjoint alias sets — the core decomplect invariant (a single alias
|
||||
// resolving to two chains is the exact bug LP-134 removes).
|
||||
func TestLP134_NoAliasCollision(t *testing.T) {
|
||||
for _, net := range lp134Nets {
|
||||
t.Run(net, func(t *testing.T) {
|
||||
f := lp134AliasSet(t, lp134ReadShard(t, net, "f"))
|
||||
mm := lp134AliasSet(t, lp134ReadShard(t, net, "m"))
|
||||
k := lp134AliasSet(t, lp134ReadShard(t, net, "k"))
|
||||
for _, pair := range []struct {
|
||||
a, b map[string]bool
|
||||
an, bn string
|
||||
}{
|
||||
{f, mm, "F", "M"},
|
||||
{f, k, "F", "K"},
|
||||
{mm, k, "M", "K"},
|
||||
} {
|
||||
for alias := range pair.a {
|
||||
if pair.b[alias] {
|
||||
t.Fatalf("%s-Chain alias %q collides with %s-Chain (LP-134: aliases must be disjoint)", pair.an, alias, pair.bn)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE confidential compute — off-EVM threshold DECRYPT (TFHE, ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"fhePrecompilePrefix": "0x07",
|
||||
"message": "Lux F-Chain Genesis",
|
||||
"mode": "fhe",
|
||||
"name": "F-Chain",
|
||||
"networkId": 1,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1730446786,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 97269
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
"K",
|
||||
"key",
|
||||
"keyvm",
|
||||
"kms"
|
||||
],
|
||||
"description": "KMS \u2014 MPC key management + threshold sigs",
|
||||
"description": "KMS — key management (ML-KEM / ML-DSA / BLS)",
|
||||
"message": "Lux K-Chain Genesis",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"name": "K-Chain",
|
||||
"networkId": 1,
|
||||
"timestamp": 1730446786,
|
||||
"version": 1,
|
||||
"vm": "KeyVM",
|
||||
"chainId": 97169
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
],
|
||||
"description": "Threshold MPC signing — off-EVM CGGMP21/FROST ceremony for bridge custody of external wallets",
|
||||
"message": "Lux M-Chain Genesis",
|
||||
"mode": "mpc",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"mpcVerifyPrecompiles": [
|
||||
"0x0800000000000000000000000000000000000002",
|
||||
"0x0800000000000000000000000000000000000003"
|
||||
],
|
||||
"name": "M-Chain",
|
||||
"networkId": 1,
|
||||
"timestamp": 1730446786,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 97369
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE encrypted compute (ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"message": "Lux T-Chain Genesis",
|
||||
"name": "T-Chain",
|
||||
"networkId": 1,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1730446786,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 96869
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE confidential compute — off-EVM threshold DECRYPT (TFHE, ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"fhePrecompilePrefix": "0x07",
|
||||
"message": "Lux F-Chain Genesis",
|
||||
"mode": "fhe",
|
||||
"name": "F-Chain",
|
||||
"networkId": 2,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 97268
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
"K",
|
||||
"key",
|
||||
"keyvm",
|
||||
"kms"
|
||||
],
|
||||
"description": "KMS \u2014 MPC key management + threshold sigs",
|
||||
"description": "KMS — key management (ML-KEM / ML-DSA / BLS)",
|
||||
"message": "Lux K-Chain Genesis",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"name": "K-Chain",
|
||||
"networkId": 2,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "KeyVM",
|
||||
"chainId": 97168
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"aliases": [
|
||||
"M",
|
||||
"mpc",
|
||||
"mpcvm"
|
||||
],
|
||||
"description": "Threshold MPC signing — off-EVM CGGMP21/FROST ceremony for bridge custody of external wallets",
|
||||
"message": "Lux M-Chain Genesis",
|
||||
"mode": "mpc",
|
||||
"mpcParties": 10,
|
||||
"mpcThreshold": 7,
|
||||
"mpcVerifyPrecompiles": [
|
||||
"0x0800000000000000000000000000000000000002",
|
||||
"0x0800000000000000000000000000000000000003"
|
||||
],
|
||||
"name": "M-Chain",
|
||||
"networkId": 2,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 97368
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"aliases": [
|
||||
"F",
|
||||
"fhe",
|
||||
"fhevm"
|
||||
],
|
||||
"description": "Threshold FHE encrypted compute (ring N=1024 q=12289)",
|
||||
"dkgParties": 10,
|
||||
"dkgThreshold": 7,
|
||||
"message": "Lux T-Chain Genesis",
|
||||
"name": "T-Chain",
|
||||
"networkId": 2,
|
||||
"ringDegreeN": 1024,
|
||||
"ringModulusQ": 12289,
|
||||
"timestamp": 1730531602,
|
||||
"version": 1,
|
||||
"vm": "ThresholdVM",
|
||||
"chainId": 96868
|
||||
}
|
||||
@@ -79,11 +79,11 @@ github.com/luxfi/cache v1.2.1 h1:kAzOS55/hmYeNKR+0HAKv4ma48Y6JjkI8UQeqdZ8bfI=
|
||||
github.com/luxfi/cache v1.2.1/go.mod h1:co7JTxZZHpKT31Yh01LFp5aZOxmoUg157FhBLQdQHVU=
|
||||
github.com/luxfi/codec v1.1.4 h1:Yl8ZalMNkqo7cD6R9AjczAajkLOmsjyZ9+DASVYHrvg=
|
||||
github.com/luxfi/codec v1.1.4/go.mod h1:oGQ3j6E8c2P0pL0irYtWkrB1hmDUFIE0puXHK4gV5KI=
|
||||
github.com/luxfi/constants v1.5.7 h1:a1tCMdxd+pClPMIPOaI9vcYGNy6cQIc2rubac2Trc0k=
|
||||
github.com/luxfi/constants v1.5.7 h1:wGGcFAvFuKNyAiWpubcMuHFtpkSMZo+pdETQWH9Xc1o=
|
||||
github.com/luxfi/constants v1.5.7/go.mod h1:z+Wc7skybZAA+xuBWNcmtv402S/BFqixL+FiSQXPg8U=
|
||||
github.com/luxfi/container v0.0.4 h1:BXhF82WyfqVP5mjlNcr7tP0Fcnvl0Ap1rkiu+rq5XuM=
|
||||
github.com/luxfi/container v0.0.4/go.mod h1:Z3SpmMF5d4t77MM0nHYXURpn+EMVaeu1fhbd/3BGaek=
|
||||
github.com/luxfi/crypto v1.19.15 h1:Tf+iPRXv08Rlj9k7iNtYy0e1tJWIgRcY0pTR4rQax6w=
|
||||
github.com/luxfi/crypto v1.19.15 h1:pypmy1GhlMIIk+/PXe5pIv2uzHcEyB2xij7F2IcuP5U=
|
||||
github.com/luxfi/crypto v1.19.15/go.mod h1:INjdZtke85k8hX/QAmTMAY8bbZ4gzGZQLqURg3xf6Gk=
|
||||
github.com/luxfi/geth v1.16.98 h1:w187TtKuGStf3tm2bshuHVKBv2Frjx0lT54kQVXyNHA=
|
||||
github.com/luxfi/geth v1.16.98/go.mod h1:6kEzSExdk9CPQDPXALt6P3HfQqBq7KF1Jrrv9gBpxbU=
|
||||
|
||||
@@ -14,17 +14,21 @@ import (
|
||||
type ChainRole string
|
||||
|
||||
const (
|
||||
RoleProtocol ChainRole = "P" // Protocol chain — validator set, chain registry, ordering
|
||||
RoleExchange ChainRole = "X" // Exchange/asset transfer chain
|
||||
RoleContract ChainRole = "C" // Contract/EVM chain
|
||||
RoleQuantum ChainRole = "Q" // Quantum-resistant chain
|
||||
RoleAttest ChainRole = "A" // Attestation chain
|
||||
RoleBridge ChainRole = "B" // Bridge chain
|
||||
RoleThreshold ChainRole = "T" // Threshold/MPC chain
|
||||
RoleZK ChainRole = "Z" // Zero-knowledge chain
|
||||
RoleGraph ChainRole = "G" // Graph/data chain (future)
|
||||
RoleIdentity ChainRole = "I" // Identity chain (future)
|
||||
RoleKMS ChainRole = "K" // KMS chain (future)
|
||||
RoleProtocol ChainRole = "P" // Protocol chain — validator set, chain registry, ordering
|
||||
RoleExchange ChainRole = "X" // Exchange/asset transfer chain
|
||||
RoleContract ChainRole = "C" // Contract/EVM chain
|
||||
RoleQuantum ChainRole = "Q" // Quantum-resistant chain
|
||||
RoleAttest ChainRole = "A" // Attestation chain
|
||||
RoleBridge ChainRole = "B" // Bridge chain
|
||||
// LP-134: the retired RoleThreshold ("T") is split into RoleFHE ("F") and
|
||||
// RoleMPC ("M"). The ThresholdVM substrate serves both — F-Chain in FHE
|
||||
// mode (confidential compute) and M-Chain in MPC mode (bridge custody).
|
||||
RoleFHE ChainRole = "F" // Threshold-FHE chain (confidential compute)
|
||||
RoleMPC ChainRole = "M" // Threshold-MPC chain (bridge custody signing)
|
||||
RoleZK ChainRole = "Z" // Zero-knowledge chain
|
||||
RoleGraph ChainRole = "G" // Graph/data chain (future)
|
||||
RoleIdentity ChainRole = "I" // Identity chain (future)
|
||||
RoleKMS ChainRole = "K" // KMS chain (future)
|
||||
)
|
||||
|
||||
// ChainConfig represents a single chain's configuration
|
||||
@@ -228,12 +232,28 @@ func DefaultMainnetMapping() *ChainMapping {
|
||||
Name: "Bridge Chain",
|
||||
Aliases: []string{"B", "bridge"},
|
||||
},
|
||||
RoleThreshold: {
|
||||
ChainID: ids.TChainID,
|
||||
VMID: ids.Empty, // Threshold VM ID
|
||||
Role: RoleThreshold,
|
||||
Name: "Threshold Chain",
|
||||
Aliases: []string{"T", "threshold", "mpc"},
|
||||
RoleFHE: {
|
||||
// LP-134: F-Chain runs ThresholdVM in FHE mode. The canonical
|
||||
// native chain ID awaits luxfi/ids.FChainID — the ids native-
|
||||
// chain set (P/C/X/Q/A/B/T/Z/G/I/K/D) is closed, so adding F/M
|
||||
// is a separate luxfi/ids change. The active genesis path pins
|
||||
// the EVM chainId in fchain.json (97269/97268/97270/32327).
|
||||
ChainID: ids.Empty,
|
||||
VMID: ids.Empty, // ThresholdVM (FHE mode)
|
||||
Role: RoleFHE,
|
||||
Name: "F-Chain",
|
||||
Aliases: []string{"F", "fhe", "fhevm"},
|
||||
},
|
||||
RoleMPC: {
|
||||
// LP-134: M-Chain runs ThresholdVM in MPC mode (CGGMP21 / FROST
|
||||
// bridge custody). Canonical native chain ID awaits
|
||||
// luxfi/ids.MChainID; the active genesis path pins the EVM
|
||||
// chainId in mchain.json (97369/97368/97370/32437).
|
||||
ChainID: ids.Empty,
|
||||
VMID: ids.Empty, // ThresholdVM (MPC mode)
|
||||
Role: RoleMPC,
|
||||
Name: "M-Chain",
|
||||
Aliases: []string{"M", "mpc", "mpcvm"},
|
||||
},
|
||||
RoleZK: {
|
||||
ChainID: ids.ZChainID,
|
||||
|
||||
@@ -104,10 +104,11 @@ func GetConfigFile(filepath string) (*Config, error) {
|
||||
QChainGenesis: output.QChainGenesis,
|
||||
AChainGenesis: output.AChainGenesis,
|
||||
BChainGenesis: output.BChainGenesis,
|
||||
TChainGenesis: output.TChainGenesis,
|
||||
FChainGenesis: output.FChainGenesis,
|
||||
ZChainGenesis: output.ZChainGenesis,
|
||||
GChainGenesis: output.GChainGenesis,
|
||||
KChainGenesis: output.KChainGenesis,
|
||||
MChainGenesis: output.MChainGenesis,
|
||||
SecurityProfile: output.SecurityProfile,
|
||||
CertPolicy: output.CertPolicy,
|
||||
Message: output.Message,
|
||||
@@ -247,10 +248,11 @@ var optionalChainShards = []struct {
|
||||
{"qchain.json", func(c *Config) *string { return &c.QChainGenesis }},
|
||||
{"achain.json", func(c *Config) *string { return &c.AChainGenesis }},
|
||||
{"bchain.json", func(c *Config) *string { return &c.BChainGenesis }},
|
||||
{"tchain.json", func(c *Config) *string { return &c.TChainGenesis }},
|
||||
{"fchain.json", func(c *Config) *string { return &c.FChainGenesis }},
|
||||
{"zchain.json", func(c *Config) *string { return &c.ZChainGenesis }},
|
||||
{"gchain.json", func(c *Config) *string { return &c.GChainGenesis }},
|
||||
{"kchain.json", func(c *Config) *string { return &c.KChainGenesis }},
|
||||
{"mchain.json", func(c *Config) *string { return &c.MChainGenesis }},
|
||||
}
|
||||
|
||||
// readOptionalShard reads filename from dir, returning the file contents on
|
||||
@@ -390,10 +392,11 @@ func ParseConfigOutput(output *ConfigOutput, networkID uint32) (*Config, error)
|
||||
QChainGenesis: output.QChainGenesis,
|
||||
AChainGenesis: output.AChainGenesis,
|
||||
BChainGenesis: output.BChainGenesis,
|
||||
TChainGenesis: output.TChainGenesis,
|
||||
FChainGenesis: output.FChainGenesis,
|
||||
ZChainGenesis: output.ZChainGenesis,
|
||||
GChainGenesis: output.GChainGenesis,
|
||||
KChainGenesis: output.KChainGenesis,
|
||||
MChainGenesis: output.MChainGenesis,
|
||||
Chains: output.Chains,
|
||||
SecurityProfile: output.SecurityProfile,
|
||||
CertPolicy: output.CertPolicy,
|
||||
|
||||
@@ -26,14 +26,15 @@ type Config struct {
|
||||
QChainGenesis string `json:"qChainGenesis,omitempty"` // Q-Chain: Quantum VM genesis
|
||||
AChainGenesis string `json:"aChainGenesis,omitempty"` // A-Chain: Attestation/AI VM genesis
|
||||
BChainGenesis string `json:"bChainGenesis,omitempty"` // B-Chain: Bridge VM genesis
|
||||
TChainGenesis string `json:"tChainGenesis,omitempty"` // T-Chain: Threshold VM genesis
|
||||
FChainGenesis string `json:"fChainGenesis,omitempty"` // F-Chain: Threshold-FHE VM genesis (LP-134; supersedes T-Chain)
|
||||
ZChainGenesis string `json:"zChainGenesis,omitempty"` // Z-Chain: ZK VM genesis
|
||||
GChainGenesis string `json:"gChainGenesis,omitempty"` // G-Chain: Graph VM genesis
|
||||
KChainGenesis string `json:"kChainGenesis,omitempty"` // K-Chain: KMS VM genesis
|
||||
MChainGenesis string `json:"mChainGenesis,omitempty"` // M-Chain: Threshold-MPC VM genesis (LP-134; supersedes T-Chain)
|
||||
Message string `json:"message"`
|
||||
|
||||
// Chains defines additional chains to include in genesis beyond the
|
||||
// built-in alphabet chains (C, D, Q, B, T, Z, G, K). Each entry becomes
|
||||
// built-in alphabet chains (C, D, Q, A, B, F, Z, G, K, M). Each entry becomes
|
||||
// a CreateChainTx in the P-Chain genesis. This allows chains to be
|
||||
// embedded directly for automatic bootstrap.
|
||||
Chains []ChainEntry `json:"chains,omitempty"`
|
||||
@@ -73,7 +74,8 @@ type Config struct {
|
||||
//
|
||||
// EVMAddr is the 20-byte H160 EVM address (C-Chain and other EVM chains).
|
||||
// UTXOAddr is the 20-byte ShortID used by both P-Chain and X-Chain UTXOs
|
||||
// (same bytes; bech32 prefix differentiates the chain).
|
||||
//
|
||||
// (same bytes; bech32 prefix differentiates the chain).
|
||||
type Allocation struct {
|
||||
EVMAddr ids.ShortID `json:"evmAddr"`
|
||||
UTXOAddr ids.ShortID `json:"utxoAddr"`
|
||||
@@ -201,7 +203,6 @@ type StakerJSON struct {
|
||||
EndTime uint64 `json:"endTime,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
// CChainConfig is the C-Chain genesis configuration
|
||||
type CChainConfig struct {
|
||||
Config CChainParams `json:"config"`
|
||||
@@ -308,10 +309,11 @@ type ConfigOutput struct {
|
||||
QChainGenesis string `json:"qChainGenesis,omitempty"` // Q-Chain: Quantum VM genesis
|
||||
AChainGenesis string `json:"aChainGenesis,omitempty"` // A-Chain: Attestation/AI VM genesis
|
||||
BChainGenesis string `json:"bChainGenesis,omitempty"` // B-Chain: Bridge VM genesis
|
||||
TChainGenesis string `json:"tChainGenesis,omitempty"` // T-Chain: Threshold VM genesis
|
||||
FChainGenesis string `json:"fChainGenesis,omitempty"` // F-Chain: Threshold-FHE VM genesis (LP-134; supersedes T-Chain)
|
||||
ZChainGenesis string `json:"zChainGenesis,omitempty"` // Z-Chain: ZK VM genesis
|
||||
GChainGenesis string `json:"gChainGenesis,omitempty"` // G-Chain: Graph VM genesis
|
||||
KChainGenesis string `json:"kChainGenesis,omitempty"` // K-Chain: KMS VM genesis
|
||||
MChainGenesis string `json:"mChainGenesis,omitempty"` // M-Chain: Threshold-MPC VM genesis (LP-134; supersedes T-Chain)
|
||||
Chains []ChainEntry `json:"chains,omitempty"` // Additional genesis chains
|
||||
SecurityProfile *SecurityProfile `json:"securityProfile,omitempty"`
|
||||
CertPolicy *CertPolicy `json:"certPolicy,omitempty"`
|
||||
@@ -370,10 +372,11 @@ func (c *Config) ToJSON(hrp string) *ConfigOutput {
|
||||
QChainGenesis: c.QChainGenesis,
|
||||
AChainGenesis: c.AChainGenesis,
|
||||
BChainGenesis: c.BChainGenesis,
|
||||
TChainGenesis: c.TChainGenesis,
|
||||
FChainGenesis: c.FChainGenesis,
|
||||
ZChainGenesis: c.ZChainGenesis,
|
||||
GChainGenesis: c.GChainGenesis,
|
||||
KChainGenesis: c.KChainGenesis,
|
||||
MChainGenesis: c.MChainGenesis,
|
||||
SecurityProfile: c.SecurityProfile,
|
||||
CertPolicy: c.CertPolicy,
|
||||
Message: c.Message,
|
||||
@@ -385,4 +388,3 @@ func (c *Config) MarshalJSON() ([]byte, error) {
|
||||
hrp := constants.GetHRP(c.NetworkID)
|
||||
return json.Marshal(c.ToJSON(hrp))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user