mirror of
https://github.com/luxfi/proto.git
synced 2026-10-30 15:21:09 +00:00
The platform and exchange VMs are the last chain code living in luxfi/node and the reason the node cannot be retired. This brings over the part of them proto did not already have: the adopt registry, the ZAP wire generators for signer, warp and validator fees, the hybrid and runtime proof-of-possession signers, the native admission check, the zwarp client and server, the X-chain network layer, the xvmroot state root, the batch verifier and owner root, and the credential policy the P and X mempools share, which lands beside the mempool it gates as proto/txs/auth. The X-chain genesis builder moves into proto/x/genesis, where the codec it calls already lives, so it no longer reaches for the xvm package to build primary-asset bytes. Imports point at the packages that already have homes: cache, upgrade, version and util as their own modules, and gas, verify and index in luxfi/vm. The three generated files bring github.com/zap-proto/go with them, which requires go 1.26.5. Most of the remaining difference between the node's trees and proto is not a backlog. proto restructured this code in August and the node's copies predate it, so files that look absent are largely present here under other names. What genuinely cannot come yet is anything reaching for node/server/http, node/vms or node/wallet, and the tests written against tx constructors proto's tx layer no longer exports. Co-authored-by: Hanzo Dev <[email protected]>
98 lines
3.4 KiB
Go
98 lines
3.4 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Package genesis builds X-Chain (XVM) genesis bytes from a small,
|
|
// caller-supplied descriptor, and owns the codec those bytes are
|
|
// written with. A caller (e.g. a primary-network genesis builder)
|
|
// describes the primary asset and gets bytes back; the asset shape and
|
|
// its serialization sit together here.
|
|
//
|
|
// The package is intentionally narrow: it owns the
|
|
// AssetDescriptor + Holder + BuildBytes contract, and nothing else.
|
|
// Bech32 formatting, allocation sorting, memo composition, and the
|
|
// "is X-Chain opt-in for this network?" policy all stay in the
|
|
// caller — those are network-level concerns, not XVM concerns.
|
|
package genesis
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/luxfi/ids"
|
|
)
|
|
|
|
// AssetDescriptor is the JSON-shaped primary-asset descriptor that
|
|
// callers carry on their network config (e.g. genesiscfg.XChainGenesis).
|
|
// The JSON tags mirror the existing on-disk xChainGenesis shard shape:
|
|
//
|
|
// {"symbol":"LUX","name":"Lux","denomination":9}
|
|
type AssetDescriptor struct {
|
|
Name string `json:"name"`
|
|
Symbol string `json:"symbol"`
|
|
Denomination byte `json:"denomination"`
|
|
}
|
|
|
|
// Holder is one (bech32-address, amount) initial fixed-cap holder.
|
|
// Address is the already-formatted bech32 string for the target
|
|
// network's HRP — this package does no HRP resolution.
|
|
type Holder struct {
|
|
Amount uint64
|
|
Address string
|
|
}
|
|
|
|
// BuildBytes constructs the canonical XVM genesis bytes for a network
|
|
// whose primary asset is `asset`, with the supplied initial fixed-cap
|
|
// holders and an optional opaque memo. The asset is registered in the
|
|
// genesis under `asset.Symbol` (the same key callers use today).
|
|
//
|
|
// The returned bytes are stable across calls with identical inputs
|
|
// because NewGenesis sorts both the asset set and each asset's
|
|
// states deterministically.
|
|
func BuildBytes(
|
|
networkID uint32,
|
|
asset AssetDescriptor,
|
|
holders []Holder,
|
|
memo []byte,
|
|
) ([]byte, error) {
|
|
def := GenesisAssetDefinition{
|
|
Name: asset.Name,
|
|
Symbol: asset.Symbol,
|
|
Denomination: asset.Denomination,
|
|
InitialState: AssetInitialState{},
|
|
Memo: memo,
|
|
}
|
|
for _, h := range holders {
|
|
def.InitialState.FixedCap = append(def.InitialState.FixedCap, GenesisHolder{
|
|
Amount: h.Amount,
|
|
Address: h.Address,
|
|
})
|
|
}
|
|
|
|
g, err := NewGenesis(networkID, map[string]GenesisAssetDefinition{
|
|
asset.Symbol: def,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b, err := g.Bytes()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("couldn't serialize xvm genesis: %w", err)
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
// AssetIDFromBytes returns the runtime X-Chain native asset ID derived
|
|
// from the canonical XVM genesis bytes (the same blob BuildBytes
|
|
// produces). This is the value vm.initGenesis assigns to the first
|
|
// genesis CreateAssetTx — the ID under which the X-Chain's fee asset is
|
|
// indexed in state.
|
|
//
|
|
// Callers (genesis/builder, config.getGenesisData) use this to derive
|
|
// the X-Chain native asset ID from genesis content rather than
|
|
// constants.UTXOAssetIDFor(networkID). On sovereign L1s the two values
|
|
// differ: the constant is network-id-keyed and identical across every
|
|
// L1 sharing a primary-network ID, while the genesis-derived ID
|
|
// captures the asset's actual on-chain identity (different per L1).
|
|
func AssetIDFromBytes(genesisBytes []byte) (ids.ID, error) {
|
|
return AssetIDFromGenesisBytes(genesisBytes)
|
|
}
|