19 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 0a66629314 builder: flip F/M off shared ThresholdVMID → FHEVMID/MPCVMID (LP-134 decomplect)
The last thresholdvm braid: F-Chain and M-Chain shared constants.ThresholdVMID
and were disambiguated by BlockchainName string-match (mode dispatch). Flip to
distinct VMs per LP-134/LP-7050:
  - builder.go:604 F-Chain VMID ThresholdVMID -> FHEVMID
  - builder.go:608 M-Chain VMID ThresholdVMID -> MPCVMID
  - alias map + Aliases() now dispatch directly on FHEVMID/MPCVMID (no
    BlockchainName string-match, no shared-VM path)
  - zero ThresholdVMID remains in live genesis wiring
Shard JSON 'vm' fields left as-is to preserve per-chain GenesisData byte-stability
(routing is by builder VMID). Fixed a pre-existing self-contradictory test
(TestLP134_MChainIsMPCOnly required AND banned alias 'mpcvm').

Gate: configs + builder suites green (chainID locks + LP-134 split tests pass).
Prod unaffected — node pins genesis v1.13.16 (T-model); this is un-adopted branch
state pending a coordinated node release.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-03 01:21:33 -07:00
zeekay b81715a57a genesis: split T-Chain into F-Chain (FHE) + M-Chain (MPC) per LP-134
The legacy T-Chain conflated two orthogonal threshold primitives on one
ThresholdVM substrate. LP-134 decomplects them into two distinct
primary-network chains, both served by the shared ThresholdVM library:

  F-Chain (F/fhe/fhevm)  — threshold FHE, confidential compute / off-EVM
                            threshold DECRYPT. ThresholdVM in FHE mode.
  M-Chain (M/mpc/mpcvm)  — threshold MPC, CGGMP21/FROST bridge-custody
                            SIGNING. ThresholdVM in MPC mode. EVM verify
                            surface = 0x0800..02 (FROST) + 0x0800..03
                            (CGGMP21), verify-only, ceremony off-EVM.

Forward-only: tchain.json is retired on all 4 nets (T was never bootstrapped
with live state — a clean 404 forward-split, no state migration). F-Chain
occupies T's vacated shard slot (same VM, keeps Z/G/K byte-stable); M-Chain
is appended. Fresh non-colliding chainIds at the next free indices 9/10
(F: 97269/97268/97270/32327, M: 97369/97368/97370/32437); T's 96869-series
is not recycled.

K-Chain decomplect ("K stays keyvm" per LP-134): the M/mpc/mpcvm aliases and
MPC params were erroneously carried on the KeyVM shard (the "mpc->K backwards"
wiring). Moved them to M-Chain; kchain.json is now pure KMS key management.

Chain-level wiring (one way, data-driven by shard presence):
  - pkg/genesis: ConfigOutput/Config gain FChainGenesis (T's slot) +
    MChainGenesis; TChainGenesis removed.
  - configs.go chainSet/primaryChainShardFiles/slots + config.go
    optionalChainShards: tchain.json -> fchain.json, append mchain.json.
  - builder: F and M both map to constants.ThresholdVMID (shared substrate)
    and are disambiguated in Aliases() by CreateChainTx.BlockchainName.
  - chain_mapping role taxonomy: RoleThreshold("T") retired -> RoleFHE("F")
    + RoleMPC("M"); RoleKMS unchanged. (Canonical native FChainID/MChainID
    await a luxfi/ids change; the closed P/C/X/Q/A/B/T/Z/G/I/K/D set is
    out of scope here. Active path pins EVM chainIds in the shards.)

Tests: chain_shards_test updated to 11 chains + new F/M chainIds; builder
emits 11 chains; new lp134_split_test asserts the decomplect invariants
(F is FHE-only, M is MPC-only, K is KMS-only, no alias collision across
{F,M,K}, tchain.json retired). go build/vet/test green (GOWORK=off).
2026-06-28 07:40:05 -07:00
Hanzo AI bba8e11fb4 genesis/builder: migrate from staging shim to proto/zap_codec
Wave 2G-Archive completes the genesis-builder migration: the staging
shim builder/zap_codec.go (created during Wave 2G-Genesis to mirror
proto/zap_codec's surface before it was tagged) is now deleted, and
builder.go imports proto/zap_codec directly.

Changes:
  - builder.go: pvmGenesisCodec / newXVMParserCodecs swap to
    proto/zap_codec.NewPVMGenesis / NewXVMParser
  - builder/zap_codec.go: deleted (staging shim no longer needed)
  - go.mod: bump luxfi/proto v1.1.0 → v1.3.0 (first tag that exposes
    proto/zap_codec; v1.3.0 also includes the proto/internal test
    helper migration from Wave 2G-Internal)

luxfi/codec demoted to // indirect — kept transitively via deps that
haven't re-tagged yet. Will drop on the next upstream tagging cascade.
2026-06-06 05:52:54 -07:00
Hanzo AI 8da1cca53b genesis/builder: ZAP-native genesis codec (Wave 2G-Genesis)
Migrates pvmGenesisCodec() and newXVMParserCodecs() off the legacy
linearcodec big-endian wire format onto the ZAP-native zapcodec
little-endian wire format. Aligned with LP-023 ZAP-native activation
(proto/zap_native: ZAPActivationUnix=0 — "ZAP mandatory from genesis"),
forward-only.

Wire-format verdict: BREAK.

ZAP-native bytes are NOT byte-equivalent to legacy linearcodec bytes —
endianness flips for every uint16/uint32/uint64/string-length prefix.
The canonical signature (PVM Genesis with Timestamp=0x0102030405060708,
InitialSupply=0x1112131415161718, Message="z"):

  legacy linearcodec (BE): ... 01 02 03 04 05 06 07 08  11 12 13 14 15 16 17 18 ...
  ZAP-native zapcodec (LE): ... 08 07 06 05 04 03 02 01  18 17 16 15 14 13 12 11 ...

No coordinated network upgrade needed: this is the first ZAP-native
genesis tag, and no production validator was running legacy linearcodec
in the post-LP-023 fleet. Mainnet/testnet/devnet/localnet all bootstrap
ZAP-only from genesis.

Code changes:

  - builder.go:
      Drop github.com/luxfi/codec + .../linearcodec direct imports.
      Drop math.MaxInt32 inline construction.
      pvmGenesisCodec()    calls newZapCodecPVMGenesis(CodecVersion)
                           + pchainblock.RegisterTypes(cm).
      newXVMParserCodecs() calls newZapCodecXVMParser(CodecVersion).
      Mirrors sdk/wallet/chain/p/pcodecs.NewPVMGenesisCodec and
      sdk/wallet/chain/x/constants.go::newXVMParserCodecs which already
      moved to proto/zap_codec in Wave 2G-Wallet.

  - zap_codec.go (new):
      Staging shim mirroring proto/zap_codec's public surface
      (NewPVMGenesis, NewXVMParser, Manager.{Marshal,Unmarshal,Size,
      RegisterType,SkipRegistrations}). When Wave 2G-Wallet lands and
      tags github.com/luxfi/proto/zap_codec, this file deletes and the
      two helpers in builder.go swap to that import — mechanical, no
      behavioural change because both shim and target wrap the same
      zapcodec.Codec backend.

  - wire_test.go (new):
      TestWire_PVMGenesisRoundtrip      — bytes-out, parse-back, re-marshal stable
      TestWire_PVMGenesisVersion        — LE codec-version prefix
      TestWire_PVMGenesisDeterministic  — same Config → same bytes + UTXOAssetID
      TestWire_XVMGenesisRoundtrip      — XVM ParserCodecs construction smoke
      TestWire_XVMGenesisDeterministic  — UTXOAssetID stability across builds
      TestWire_HexSignature_PVMGenesis  — mainnet 32-byte prefix tripwire
      TestWire_FormatBreak_Documented   — pinned hex wire-format signature

  - go.mod:
      luxfi/codec  v1.1.4 (indirect) → v1.1.5 (direct: zapcodec backend)
      luxfi/accel  v1.1.4 (indirect) → v1.1.8 (transitive)

Constraint-compliance:

  - NO github.com/luxfi/codec imports in builder.go (verified by grep).
  - NO snow/avalanche/subnet naming.
  - All builder tests pass (go test ./...).
  - All parent genesis + cmd modules build clean.
  - Race detector clean.

TODO (wave-2g-wallet): once luxfi/proto tags include the zap_codec
subpackage, swap zap_codec.go's shim for the canonical
github.com/luxfi/proto/zap_codec import in builder.go and delete the
shim file.
2026-06-06 04:58:12 -07:00
Hanzo AI ce38b045d1 genesis/builder: thread codec through proto/p Wave 2A genesis API
proto/p Wave 2A (#101) rips github.com/luxfi/codec from p/genesis —
genesis.New, Genesis.Bytes and genesis.Parse now take a block.Codec
parameter at the call site (the same genesis-sized codec.Manager
already constructed inline elsewhere in the wallet stack).

Adds pvmGenesisCodec() helper mirroring the existing
newXVMParserCodecs() pattern in this file. Uses math.MaxInt32 budget
because PVM genesis blobs (full set of initial validator stake txs
plus CreateChainTx entries for X/C/D/Q/A/B/T/Z/G/K) can exceed runtime
tx-size limits. block.RegisterTypes seeds the full Apricot/Banff/
Durango/Quasar block + tx type set.

Threads pvmGenesisCodec() through:
  - FromConfig:    genesis.New + Genesis.Bytes  (one codec, two uses)
  - VMGenesis:     genesis.Parse
  - Aliases:       genesis.Parse

Also fixes the X-chain genesis serialization path that was broken by
Wave 1A: xvmCodecs.GenesisCodec was used directly without going
through xchaintxs.NewParser, so the canonical XVM tx types
(BaseTx/CreateAsset/Operation/Import/Export) and fx-owned
secp256k1fx.TransferOutput were never registered. The xvm genesis now
flows through NewParser, mirroring how UTXOAssetID already uses it.

builder_test.go's TestFromConfig_ChainSetIsShardDriven gains a single
pvmGenesisCodec() construction and threads it through both pgenesis.Parse
call sites.

go build ./... + go test ./... green.

The proto pin remains at v1.1.0; the workspace go.work consumes the
local proto/ which is on branch chore/proto-p-codec-rip with the new
API. This commit goes live once proto v1.2.0 is tagged.
2026-06-06 02:07:40 -07:00
Hanzo AI 26e6de4734 builder: cascade proto/x Wave 1A API changes
Wave 1A inverted the proto/x codec design — proto/x carries no codec
import; consumers supply linearcodec.NewDefault() + codec.NewManager
externally via the new xchaintxs.ParserCodecs struct.

Mirrors sdk/wallet/chain/x/constants.go::newXVMParserCodecs by adding
the equivalent helper here. Updates 3 call sites:
- xgenesis.NewGenesis(networkID, defs, codec) — new 3rd param
- xvmGenesis.Bytes(codec) — new param
- xchaintxs.NewParser(codecs, fxs) — new ParserCodecs first arg

genesis builds clean.
2026-06-05 13:37:58 -07:00
Hanzo AI b69c33a8f8 scrub: subnet/l2 → chain (canonical vocabulary, forward-only)
Wire-format codec IDs unchanged. CLI aliases deleted; chain is the
command. No backwards-compat shims, no deprecation comments.
2026-05-31 14:49:54 -07:00
Hanzo DevandGitHub 514e996737 refactor: XAssetID → UTXOAssetID (genesis builder + bootstrap-l2) (#9) 2026-05-30 14:30:59 -07:00
Hanzo AI 4a0f19e47e chore: update 2026-05-25 15:13:09 -07:00
Hanzo AI c114107bac purge remaining eth* identifiers — single canonical EVMAddr/UTXOAddr
ParseETHAddress → ParseEVMAddress
  ValidatorKeyInfo.EthAddr → .EVMAddr
  local ethAddr / EthAddr vars → evmAddr / EVMAddr
  ethPrivKey / ethShortID / ethAddrStr → evmPrivKey / evmShortID / evmAddrStr
  privateKeyToETHAddress → privateKeyToEVMAddress
  comments: "Get ETH address" → "Get EVM address", "Ethereum address" → "EVM address (H160 hex)"
  test error strings + test loop vars also updated for consistency

The only ETH/Ethereum reference remaining is the upstream `ethcrypto`
import alias (github.com/luxfi/crypto, aliased ethcrypto) — that's an
external package name, kept as-is.
2026-05-22 20:56:48 -07:00
Hanzo AI 8948b4e1cb EVMAddr (Go) + UTXOAddr (Go) — pure chain-model naming, no eth/lux branding
Renames Go struct field ETHAddr → EVMAddr across types.go, keys.go,
allocations.go, validator_keys.go, config.go, builder/builder.go,
cmd/genesis, cmd/checkkeys. JSON tags stayed evmAddr already (from
v1.12.6). Result: matched pair EVMAddr+UTXOAddr on both Go and JSON
sides.

Kept ParseETHAddress as the input-parsing function name — it describes
what it parses (an Ethereum-format hex address), not the field it
populates (an EVMAddr).

LLM.md updated to state the canonical pair plainly; no rename history.
2026-05-22 20:37:30 -07:00
Hanzo AI 9eed1b8791 no backcompat — canonical address fields are ethAddr + utxoAddr
Renames Allocation.EVMAddr → ETHAddr (json tag `ethAddr`) and
KeyInfo.EVMAddr → ETHAddr across pkg/genesis, builder, cmd/genesis,
cmd/checkkeys. AllocationJSON drops the legacy `evmAddr` tag entirely
— there is no aliasing, no UnmarshalJSON normalizer, no fallback.
JSON files and Go code share one canonical pair: ethAddr + utxoAddr.

configs/getgenesis_test.go updated to assert against the canonical
field. parseAllocations error message says "invalid eth address"
to match the new identifier.

Tests:
  ok  github.com/luxfi/genesis/builder
  ok  github.com/luxfi/genesis/configs
  ok  github.com/luxfi/genesis/pkg/genesis
2026-05-21 12:51:40 -07:00
Hanzo AI 09558bb2e3 rename ETHAddr→EVMAddr, LUXAddr→UTXOAddr (uniform UTXO/EVM split)
Address types now reflect the actual two-address model that exists across
all chains:
  - EVMAddr (0x H160) — C-Chain and every other EVM chain
  - UTXOAddr (bech32, P-/X- prefix interchangeable) — P-Chain and X-Chain

The old names (ETHAddr / LUXAddr / avaxAddr / xAddr) confused two
orthogonal axes (Ethereum-vs-Lux brand × address-encoding-type) with
each other. UTXO/EVM is the actual technical distinction.

Backward compat:
  - JSON: AllocationJSON.UnmarshalJSON accepts evmAddr/ethAddr +
    utxoAddr/xAddr/luxAddr/avaxAddr (legacy upstream Avalanche).
  - Existing config files: bumped with both new + legacy fields present.

Builds + tests green on luxfi/genesis and luxfi/node/genesis/builder.

Also: each allocation gets 50M LUX on X (initialAmount) + 50M LUX on P
(unlockSchedule locktime=0). For 1000 accounts: 50B on each chain →
100B total per env across P+X. mainnet legacy retained at-is (1.08M
historic blocks reference original asset IDs).
2026-05-20 16:10:50 -07:00
Hanzo AI 2259308ffd feat: bake all 10 primary letter-chains into mainnet/testnet/devnet/localnet genesis
Every primary network now ships all 10 chain shards (X, C, D, Q, A, B, T, Z, G, K).
Each chain spawns at startup with zero post-launch CreateBlockchainTx — chain set
is fully data-driven by which shards the operator ships.

Per-letter EVM chainIds locked at 96369 + 100*Δ_from_C (mainnet base) with the
familiar testnet=-1 / devnet=+1 triple inherited from C-Chain:

  C 96369/96368/96370   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

Localnet uses a parallel 31337 + 110*Δ series.

F-Chain ≡ T-Chain (threshold FHE) and M-Chain ≡ K-Chain (KMS-MPC) wired in via
builder alias lists — letter taxonomy decomplected from canonical VM IDs.

Each shard carries:
  - chainId / networkId / timestamp (chain identity at boot)
  - vm + description (operator transparency)
  - per-VM seed extras (DEX fee config, T-Chain DKG params, B-Chain signer set,
    Q-Chain pq scheme pin, K-Chain MPC topology — all empty/default initial state)

Contract locked by configs.TestGetGenesis_AllPrimaryChainsBakedIn — every primary
network must ship all 10 letter-chain shards. Removing a chain on any network is
now a load-bearing test edit, not a silent operator switch.

Mainnet C-Chain invariants preserved: chainId=96369, genesisHash unchanged,
stateRoot=0x2d1cedac…, warp precompile in alloc, warpConfig.blockTimestamp=
1730446786, treasury 2T LUX.
2026-05-19 11:23:16 -07:00
Hanzo AI e263161762 rename: github.com/luxfi/protocol → github.com/luxfi/proto (imports + go.mod replace) 2026-05-18 21:19:09 -07:00
Hanzo AI 037147d3bd deps: bump consensus v1.23.5 -> v1.23.25 + gofmt cleanup
Closes the v1.9.14 CI build failure: pkg/genesis/security_profile_test.go
references consensusconfig.StrictPQ()/ProfileStrictPQ which were only
introduced when the Lux prefix was dropped from profile identifiers.
That symbol first ships in consensus v1.23.25.

Also fixes the gofmt drift on builder/builder.go, cmd/genesis/main.go,
and pkg/genesis/keys.go that was failing the Test job.
2026-05-16 17:59:42 -07:00
Hanzo AI a4b05b40f5 genesis: shard-driven primary chain set (X opt-in like C/Q/Z)
Make every primary-network chain (X/C/D/Q/A/B/T/Z/G/K) opt-in via its
own <x>chain.json shard. Absent shard -> empty ConfigOutput field ->
builder skips the CreateChainTx -> daemon doesn't start that chain.

Lux mainnet/testnet/devnet ship full chain set as shards; localnet and
local ship the same canonical X asset shard. P-only sovereign L1 boot
shape (<tenant> etc.) is achieved by shipping pchain.json+network.json
only — no env knob, no special builder branch.

X-Chain genesis was previously hardcoded inside FromConfig as a literal
{Symbol:"LUX",Name:"Lux",Denomination:9}. Now sourced from xchain.json
shard, which keeps the same canonical asset for Lux but lets a sibling
network (lqd / <tenant>) ship its own descriptor or ship none and
boot a P-only primary network.

builder.FromConfig:
  - HRP hoisted above the X-Chain conditional (used on both branches).
  - X-Chain construction gated on config.XChainGenesis != "".
  - Returns ids.Empty for xAssetID when X is absent.
  - Single chainEntries table replaces the per-chain switch and the
    DefaultChainGenesis stub-data fallback.
  - "platform" alias renamed to "protocol" (PChainAliases / VMAliases /
    Aliases output) — value is "P-Chain", served by ProtocolVM.

configs.loadAllChainShards / readAllChainShards:
  - Single dispatch over primaryChainShardFiles in canonical order
    (X,C,D,Q,A,B,T,Z,G,K). Adding a new primary chain is one entry +
    one slot, not a new env knob and not a new builder branch.

pkg/genesis/types.go:
  - ConfigOutput.XChainGenesis (omitempty) added; threaded through
    Config <-> ConfigOutput conversions.

Tests:
  - builder/builder_test.go: TestFromConfig_ChainSetIsShardDriven pins
    the contract — full mainnet emits 10 chains + non-empty xAssetID;
    same config with all chain shards stripped emits 0 chains + empty
    xAssetID, validators + UTXOs intact.
  - configs/chain_shards_test.go: TestGetGenesis_XChainShardPresent...
    asserts every Lux network embeds the canonical {LUX,Lux,9} asset;
    AbsentShardEmptyOptIn extended to cover xChainGenesis.
2026-05-14 12:32:53 -07:00
Hanzo AI 0ef529faab fix: rename custom → localnet, EVM chainId 31337
- custom/ → localnet/ (1337 is localnet, not custom)
- LocalnetID=1337 (P-Chain networkID)
- LocalnetChainID=31337 (C-Chain EVM chainId, matches Anvil convention)
- CustomID deprecated → use LocalID from luxfi/constants
- anything not mainnet/testnet/devnet/localnet is custom (--genesis-file)
2026-04-08 13:33:11 -07:00
Hanzo AI 1fd6379752 genesis: regenerate all network configs
- mainnet: 100 accounts x 500M LUX, 5 stakers, P-lux1 HRP, real IPs
- testnet: 100 accounts x 500M LUX, 2 stakers, P-test1 HRP, networkID=2
- devnet: 100 accounts x 500M LUX, 3 stakers, P-dev1 HRP, networkID=3
- bootstrappers: real validator IPs
- fix mnemonic env priority: MNEMONIC > LUX_MNEMONIC > LIGHT_MNEMONIC
- remove stale .bak files
2026-04-04 11:22:32 -07:00