Files
zeekay 7cf87b230b node-unified is the node
The module already called itself github.com/luxfi/node while containing no node
in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and
the Go column of the matrix measured a VM plugin. A repo that fetches the thing
it claims to be has not replaced it, so the Go sources move in — 1515 files,
the daemon and everything under it — and the build reaches outside this module
for nothing.

Rust and C++ sit beside it unchanged and are still measured against it by the
differential. That is the point of one repo: the reference implementation and
the two ports are the same checkout, so parity is a thing you can run rather
than a thing you assert.

Verified: builds, and the closure carries no lux-private — checked at build time
rather than believed. The daemon starts twelve chains on a local network
(P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
2026-09-07 16:15:25 -07:00

155 lines
4.2 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package lux
import (
"errors"
"fmt"
"github.com/luxfi/runtime"
"github.com/luxfi/address"
"github.com/luxfi/constants"
"github.com/luxfi/ids"
"github.com/luxfi/math/set"
)
var (
_ AddressManager = (*addressManager)(nil)
ErrMismatchedChainIDs = errors.New("mismatched chainIDs")
)
// BCLookup provides blockchain alias lookup
type BCLookup interface {
Lookup(string) (ids.ID, error)
PrimaryAlias(ids.ID) (string, error)
}
type AddressManager interface {
// ParseLocalAddress takes in an address for this chain and produces the ID
ParseLocalAddress(addrStr string) (ids.ShortID, error)
// ParseAddress takes in an address and produces the ID of the chain it's
// for and the ID of the address
ParseAddress(addrStr string) (ids.ID, ids.ShortID, error)
// FormatLocalAddress takes in a raw address and produces the formatted
// address for this chain
FormatLocalAddress(addr ids.ShortID) (string, error)
// FormatAddress takes in a chainID and a raw address and produces the
// formatted address for that chain
FormatAddress(chainID ids.ID, addr ids.ShortID) (string, error)
}
type addressManager struct {
rt *runtime.Runtime
}
func NewAddressManager(rt *runtime.Runtime) AddressManager {
return &addressManager{
rt: rt,
}
}
func (a *addressManager) ParseLocalAddress(addrStr string) (ids.ShortID, error) {
chainID, addr, err := a.ParseAddress(addrStr)
if err != nil {
return ids.ShortID{}, err
}
expectedChainID := a.rt.ChainID
if chainID != expectedChainID {
return ids.ShortID{}, fmt.Errorf(
"%w: expected %q but got %q",
ErrMismatchedChainIDs,
expectedChainID,
chainID,
)
}
return addr, nil
}
func (a *addressManager) ParseAddress(addrStr string) (ids.ID, ids.ShortID, error) {
chainIDAlias, hrp, addrBytes, err := address.Parse(addrStr)
if err != nil {
return ids.Empty, ids.ShortID{}, err
}
// Try to parse chainIDAlias as an ID directly since Runtime doesn't have BCLookup
chainID, err := ids.FromString(chainIDAlias)
if err != nil {
return ids.ID{}, ids.ShortID{}, fmt.Errorf("failed to parse chain ID %q: %w", chainIDAlias, err)
}
networkID := a.rt.NetworkID
expectedHRP := constants.GetHRP(networkID)
if hrp != expectedHRP {
return ids.Empty, ids.ShortID{}, fmt.Errorf(
"expected hrp %q but got %q",
expectedHRP,
hrp,
)
}
addr, err := ids.ToShortID(addrBytes)
if err != nil {
return ids.Empty, ids.ShortID{}, err
}
return chainID, addr, nil
}
func (a *addressManager) FormatLocalAddress(addr ids.ShortID) (string, error) {
chainID := a.rt.ChainID
return a.FormatAddress(chainID, addr)
}
func (a *addressManager) FormatAddress(chainID ids.ID, addr ids.ShortID) (string, error) {
// Use ChainID directly - Runtime doesn't have BCLookup
chainIDAlias := chainID.String()
hrp := constants.GetHRP(a.rt.NetworkID)
return address.Format(chainIDAlias, hrp, addr.Bytes())
}
func ParseLocalAddresses(a AddressManager, addrStrs []string) (set.Set[ids.ShortID], error) {
addrs := make(set.Set[ids.ShortID], len(addrStrs))
for _, addrStr := range addrStrs {
addr, err := a.ParseLocalAddress(addrStr)
if err != nil {
return nil, fmt.Errorf("couldn't parse address %q: %w", addrStr, err)
}
addrs.Add(addr)
}
return addrs, nil
}
// ParseServiceAddress get address ID from address string, being it either localized (using address manager,
// doing also components validations), or not localized.
// If both attempts fail, reports error from localized address parsing
func ParseServiceAddress(a AddressManager, addrStr string) (ids.ShortID, error) {
addr, err := ids.ShortFromString(addrStr)
if err == nil {
return addr, nil
}
addr, err = a.ParseLocalAddress(addrStr)
if err != nil {
return addr, fmt.Errorf("couldn't parse address %q: %w", addrStr, err)
}
return addr, nil
}
// ParseServiceAddress get addresses IDs from addresses strings, being them either localized or not
func ParseServiceAddresses(a AddressManager, addrStrs []string) (set.Set[ids.ShortID], error) {
addrs := set.NewSet[ids.ShortID](len(addrStrs))
for _, addrStr := range addrStrs {
addr, err := ParseServiceAddress(a, addrStr)
if err != nil {
return nil, err
}
addrs.Add(addr)
}
return addrs, nil
}