Files
node/vms/xvm/genesis.go
T
Hanzo AI 3774075c95 feat: clean up dead code, update deps, add xvm genesis/fx and genesis builder
Remove unused bloom filter, test helpers, metrics scaffolding, and
linearizable VM wrapper. Trim stale go.sum entries. Add genesis builder
helpers and xvm FX/genesis initialization.
2026-04-19 17:05:59 -07:00

175 lines
4.4 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package xvm
import (
"cmp"
"fmt"
"github.com/luxfi/address"
"github.com/luxfi/codec"
"github.com/luxfi/ids"
lux "github.com/luxfi/utxo"
"github.com/luxfi/node/vms/xvm/fxs"
"github.com/luxfi/node/vms/xvm/txs"
"github.com/luxfi/utils"
"github.com/luxfi/utxo/bls12381fx"
"github.com/luxfi/utxo/ed25519fx"
"github.com/luxfi/utxo/mldsafx"
"github.com/luxfi/utxo/schnorrfx"
"github.com/luxfi/utxo/secp256k1fx"
"github.com/luxfi/utxo/secp256r1fx"
"github.com/luxfi/utxo/slhdsafx"
)
// Genesis represents the genesis state of the XVM
type Genesis struct {
Txs []*GenesisAsset `serialize:"true"`
}
// GenesisAsset represents an asset in the genesis block
type GenesisAsset struct {
Alias string `serialize:"true"`
txs.CreateAssetTx `serialize:"true"`
}
// Compare implements utils.Sortable for GenesisAsset
func (g *GenesisAsset) Compare(other *GenesisAsset) int {
return cmp.Compare(g.Alias, other.Alias)
}
// AssetInitialState describes the initial state of an asset
type AssetInitialState struct {
FixedCap []GenesisHolder
VariableCap []GenesisOwners
}
// GenesisAssetDefinition describes a genesis asset and its initial state
type GenesisAssetDefinition struct {
Name string
Symbol string
Denomination byte
InitialState AssetInitialState
Memo []byte
}
// GenesisHolder describes how much asset is owned by an address
type GenesisHolder struct {
Amount uint64
Address string
}
// GenesisOwners describes who can perform an action
type GenesisOwners struct {
Threshold uint32
Minters []string
}
// NewGenesis creates a new Genesis from genesis data
func NewGenesis(
networkID uint32,
genesisData map[string]GenesisAssetDefinition,
) (*Genesis, error) {
g := &Genesis{}
for assetAlias, assetDefinition := range genesisData {
asset := GenesisAsset{
Alias: assetAlias,
CreateAssetTx: txs.CreateAssetTx{
BaseTx: txs.BaseTx{BaseTx: lux.BaseTx{
NetworkID: networkID,
BlockchainID: ids.Empty,
Memo: assetDefinition.Memo,
}},
Name: assetDefinition.Name,
Symbol: assetDefinition.Symbol,
Denomination: assetDefinition.Denomination,
},
}
initialState := &txs.InitialState{
FxIndex: 0, // secp256k1fx
}
for _, holder := range assetDefinition.InitialState.FixedCap {
_, addrbuff, err := address.ParseBech32(holder.Address)
if err != nil {
return nil, fmt.Errorf("problem parsing holder address: %w", err)
}
addr, err := ids.ToShortID(addrbuff)
if err != nil {
return nil, fmt.Errorf("problem parsing holder address: %w", err)
}
initialState.Outs = append(initialState.Outs, &secp256k1fx.TransferOutput{
Amt: holder.Amount,
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{addr},
},
})
}
for _, owners := range assetDefinition.InitialState.VariableCap {
out := &secp256k1fx.MintOutput{
OutputOwners: secp256k1fx.OutputOwners{
Threshold: owners.Threshold,
},
}
for _, addrStr := range owners.Minters {
_, addrBytes, err := address.ParseBech32(addrStr)
if err != nil {
return nil, fmt.Errorf("problem parsing minters address: %w", err)
}
addr, err := ids.ToShortID(addrBytes)
if err != nil {
return nil, fmt.Errorf("problem parsing minters address: %w", err)
}
out.Addrs = append(out.Addrs, addr)
}
out.Sort()
initialState.Outs = append(initialState.Outs, out)
}
if len(initialState.Outs) > 0 {
codec, err := newGenesisCodec()
if err != nil {
return nil, err
}
initialState.Sort(codec)
asset.States = append(asset.States, initialState)
}
utils.Sort(asset.States)
g.Txs = append(g.Txs, &asset)
}
utils.Sort(g.Txs)
return g, nil
}
// Bytes serializes the Genesis to bytes using the XVM genesis codec
func (g *Genesis) Bytes() ([]byte, error) {
codec, err := newGenesisCodec()
if err != nil {
return nil, err
}
return codec.Marshal(txs.CodecVersion, g)
}
func newGenesisCodec() (codec.Manager, error) {
parser, err := txs.NewParser(
[]fxs.Fx{
&secp256k1fx.Fx{},
&mldsafx.Fx{},
&slhdsafx.Fx{},
&ed25519fx.Fx{},
&secp256r1fx.Fx{},
&schnorrfx.Fx{},
&bls12381fx.Fx{},
},
)
if err != nil {
return nil, fmt.Errorf("problem creating parser: %w", err)
}
return parser.GenesisCodec(), nil
}