genesis/builder: use UTXO_ASSET_ID constant + EVMAddr/UTXOAddr field names

- constants v1.5.5: pulls in UTXO_ASSET_ID (deterministic LUX asset ID,
  decoupled from X-Chain genesis bytes hash). Makes X-Chain optional —
  P-only L2s can ship without X-Chain bake.
- genesis v1.11.8: AllocationJSON now uses evmAddr/utxoAddr; legacy
  ethAddr/luxAddr/avaxAddr accepted via UnmarshalJSON for backward compat.
- builder.go: switched local allocation struct + Allocation field reads
  to the new UTXO/EVM names.

Build + tests green. Unblocks "P+Q-only" L2 topology.
This commit is contained in:
Hanzo AI
2026-05-20 16:11:51 -07:00
parent 2fa06a91c4
commit f471f9e98a
4 changed files with 37 additions and 31 deletions
+25 -19
View File
@@ -366,16 +366,16 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
// Sort allocations for deterministic output
type allocation struct {
ETHAddr ids.ShortID
LUXAddr ids.ShortID
EVMAddr ids.ShortID
UTXOAddr ids.ShortID
InitialAmount uint64
}
xAllocations := []allocation{}
for _, a := range config.Allocations {
if a.InitialAmount > 0 {
xAllocations = append(xAllocations, allocation{
ETHAddr: a.ETHAddr,
LUXAddr: a.LUXAddr,
EVMAddr: a.EVMAddr,
UTXOAddr: a.UTXOAddr,
InitialAmount: a.InitialAmount,
})
}
@@ -386,7 +386,7 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
for _, a := range xAllocations {
// Format address as bech32 for the X-Chain
bech32Addr, err := address.FormatBech32(hrp, a.LUXAddr[:])
bech32Addr, err := address.FormatBech32(hrp, a.UTXOAddr[:])
if err != nil {
return nil, ids.Empty, fmt.Errorf("failed to format bech32 address: %w", err)
}
@@ -395,7 +395,7 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
Address: bech32Addr,
})
// Add ETH address to memo for reference
ethAddrStr := a.ETHAddr.Hex()
ethAddrStr := a.EVMAddr.Hex()
if len(ethAddrStr) > 2 { // "0x" prefix
memoBytes = append(memoBytes, []byte(ethAddrStr[2:])...)
}
@@ -416,10 +416,16 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
return nil, ids.Empty, fmt.Errorf("couldn't serialize xvm genesis: %w", err)
}
xAssetID, err := XAssetID(xvmGenesisBytes)
if err != nil {
return nil, ids.Empty, fmt.Errorf("couldn't generate LUX asset ID: %w", err)
}
// LUX asset ID is a network-wide constant (constants.UTXO_ASSET_ID), not
// derived from X-Chain genesis bytes. This decouples the asset from the
// X-Chain so X-Chain can be made optional for P-only L2s.
//
// We still build xvmGenesisBytes above so X-Chain (when baked) has a
// consistent initial-supply view, but the asset ID itself is the
// deterministic constant — all chains reference the same ID regardless
// of whether X-Chain is part of the chain set.
_ = xvmGenesisBytes // bytes still used downstream when X-Chain is baked
xAssetID := constants.UTXO_ASSET_ID
genesisTime := time.Unix(int64(config.StartTime), 0)
@@ -441,14 +447,14 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
platformAllocations := []genesis.Allocation{}
skippedAllocations := []genesiscfg.Allocation{}
for _, a := range config.Allocations {
if initiallyStaked.Contains(a.LUXAddr) {
if initiallyStaked.Contains(a.UTXOAddr) {
skippedAllocations = append(skippedAllocations, a)
continue
}
for _, unlock := range a.UnlockSchedule {
if unlock.Amount > 0 {
// Format address as bech32 for the P-Chain
bech32Addr, err := address.FormatBech32(hrp, a.LUXAddr[:])
bech32Addr, err := address.FormatBech32(hrp, a.UTXOAddr[:])
if err != nil {
return nil, ids.Empty, fmt.Errorf("failed to format bech32 address for P-chain: %w", err)
}
@@ -456,14 +462,14 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
Locktime: unlock.Locktime,
Amount: unlock.Amount,
Address: bech32Addr,
Message: a.ETHAddr.Bytes(),
Message: a.EVMAddr.Bytes(),
})
}
}
// Also create P-Chain UTXO for initialAmount (spendable, no locktime)
if a.InitialAmount > 0 {
bech32Addr, err := address.FormatBech32(hrp, a.LUXAddr[:])
bech32Addr, err := address.FormatBech32(hrp, a.UTXOAddr[:])
if err != nil {
return nil, ids.Empty, fmt.Errorf("failed to format bech32 address for P-chain initialAmount: %w", err)
}
@@ -471,7 +477,7 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
Locktime: 0, // immediately spendable
Amount: a.InitialAmount,
Address: bech32Addr,
Message: a.ETHAddr.Bytes(),
Message: a.EVMAddr.Bytes(),
})
}
}
@@ -506,7 +512,7 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
for _, a := range nodeAllocations {
for _, unlock := range a.UnlockSchedule {
// Format address as bech32 for staker allocations
bech32Addr, err := address.FormatBech32(hrp, a.LUXAddr[:])
bech32Addr, err := address.FormatBech32(hrp, a.UTXOAddr[:])
if err != nil {
return nil, ids.Empty, fmt.Errorf("failed to format bech32 address for staker allocation: %w", err)
}
@@ -514,7 +520,7 @@ func FromConfig(config *genesiscfg.Config) ([]byte, ids.ID, error) {
Locktime: unlock.Locktime,
Amount: unlock.Amount,
Address: bech32Addr,
Message: a.ETHAddr.Bytes(),
Message: a.EVMAddr.Bytes(),
})
}
}
@@ -892,8 +898,8 @@ func ForDevMode(cfg DevModeConfig, stakingCfg *StakingConfig) ([]byte, ids.ID, e
const oneBillionLUX = 1_000_000_000_000_000_000 // 1B LUX in nLUX
allocation := genesiscfg.Allocation{
ETHAddr: cfg.RewardAddress, // Same as LUX addr for simplicity
LUXAddr: cfg.RewardAddress,
EVMAddr: cfg.RewardAddress, // Same as LUX addr for simplicity
UTXOAddr: cfg.RewardAddress,
InitialAmount: oneMillionLUX, // Initial unlocked amount
UnlockSchedule: []genesiscfg.LockedAmount{
{
+6 -6
View File
@@ -278,16 +278,16 @@ func TestFromConfigExplicitStakers(t *testing.T) {
NetworkID: constants.LocalID,
Allocations: []genesiscfg.Allocation{
{
ETHAddr: secpAddr,
LUXAddr: secpAddr,
EVMAddr: secpAddr,
UTXOAddr: secpAddr,
InitialAmount: 0,
UnlockSchedule: []genesiscfg.LockedAmount{
{Amount: oneBillionLUX, Locktime: 0},
},
},
{
ETHAddr: ethShortID,
LUXAddr: ethShortID,
EVMAddr: ethShortID,
UTXOAddr: ethShortID,
InitialAmount: oneMillionLUX,
},
},
@@ -369,8 +369,8 @@ func TestFromConfigExplicitStakersNoStakedFunds(t *testing.T) {
NetworkID: constants.LocalID,
Allocations: []genesiscfg.Allocation{
{
ETHAddr: deployerAddr,
LUXAddr: deployerAddr,
EVMAddr: deployerAddr,
UTXOAddr: deployerAddr,
InitialAmount: oneMillionLUX,
},
},
+2 -2
View File
@@ -128,10 +128,10 @@ require (
github.com/luxfi/atomic v1.0.0
github.com/luxfi/chains v1.2.3
github.com/luxfi/compress v0.0.5
github.com/luxfi/constants v1.5.2
github.com/luxfi/constants v1.5.5
github.com/luxfi/container v0.0.4
github.com/luxfi/filesystem v0.0.1
github.com/luxfi/genesis v1.11.1
github.com/luxfi/genesis v1.11.8
github.com/luxfi/geth v1.16.98
github.com/luxfi/go-bip39 v1.1.2
github.com/luxfi/lattice/v7 v7.1.0
+4 -4
View File
@@ -270,8 +270,8 @@ github.com/luxfi/concurrent v0.0.3 h1:eJyv1fhaC0jMLMw6+QS774cUmp7GK+ouMgvLCqnC7c
github.com/luxfi/concurrent v0.0.3/go.mod h1:Aj/FR5NpM0cB2P4Nt3+tz9+dV6V+LUW4HuMgSjwq5hw=
github.com/luxfi/consensus v1.24.0 h1:vyBPYPeZbbZutUCMxKBW7Ief9+8OZB7cu3MfNc87xYE=
github.com/luxfi/consensus v1.24.0/go.mod h1:eFknd+fzTmGEa/FzxgoL6unccnHGVxxOrZUZdReWII0=
github.com/luxfi/constants v1.5.2 h1:fwQepO6viKAwf8ACnP9YV0TVUxndZuZM7U/aKcqe9EM=
github.com/luxfi/constants v1.5.2/go.mod h1:hOszZ2NDQ8gMZKncfcZ67PXkb5OIbnwAzXC3oFbQwW0=
github.com/luxfi/constants v1.5.5 h1:s76GB/Bp+RN5ggg3nGb2ZduWRRlh1YVwGj5SHTB6w2k=
github.com/luxfi/constants v1.5.5/go.mod h1:XF0Plq5fzvYZR9TDhoosQpyOYu+H5R3Q1izHEztMqVU=
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/corona v0.4.1 h1:DGMdZMrENl6vmJf9CgiQMD8c5ORSTMymL0z9KgcZstk=
@@ -286,8 +286,8 @@ github.com/luxfi/filesystem v0.0.1 h1:VZ6xMFKaAPBW/ddlMsDnI2G0VU1lV5rYaVcW5d+KwE
github.com/luxfi/filesystem v0.0.1/go.mod h1:OQVSU6XNwqrr1AI+MqkID2taHUclx7NYmmr3svgttec=
github.com/luxfi/formatting v1.0.1 h1:ZnE1rAdEUds9yAegdVdGDOBGN6hLMPOv6E03Fp8IEYo=
github.com/luxfi/formatting v1.0.1/go.mod h1:mYzNf5DJOiqSSKUPzNj5dKy4tstFbN3pZlkI5716eKc=
github.com/luxfi/genesis v1.11.1 h1:JQZNhZjmnNGk221S1kh2Mq8U7isqWbkL6coYuiMV4Vs=
github.com/luxfi/genesis v1.11.1/go.mod h1:FclUFoXgU+/FrTDS5NQGZg53tnHTYhHtfQ8XFDNLPI4=
github.com/luxfi/genesis v1.11.8 h1:bzaM4qKE5cU+L5VR2z7dDmv+JPUbjhGpe3GaAB+ntT4=
github.com/luxfi/genesis v1.11.8/go.mod h1:FclUFoXgU+/FrTDS5NQGZg53tnHTYhHtfQ8XFDNLPI4=
github.com/luxfi/geth v1.16.98 h1:w187TtKuGStf3tm2bshuHVKBv2Frjx0lT54kQVXyNHA=
github.com/luxfi/geth v1.16.98/go.mod h1:6kEzSExdk9CPQDPXALt6P3HfQqBq7KF1Jrrv9gBpxbU=
github.com/luxfi/go-bip32 v1.0.2 h1:7vFbb+Wr4Z499q2tuCLdd7wWjtn8sH+HWBlx76mhH9Y=