mirror of
https://github.com/luxfi/sdk.git
synced 2026-10-30 15:19:23 +00:00
github.com/luxfi/codec is gone from this module — no import, no call, no require. Nothing here marshals or unmarshals a transaction any more. WHY IT BROKE. codec deleted its jsonrpc subpackage (1b67d6a, "delete dead subpackages") while nine files imported it. It looked dead because the PUBLISHED [email protected] still ships it, so only a workspace build — which resolves codec from the local checkout — ever saw the break. THE WIRE. A tx already carries its own ZAP encoding, so the codec was re-deriving what the tx could hand over: txs.Codec.Marshal(txs.CodecVersion, &tx.Unsigned) -> tx.Unsigned.Bytes() txs.UnsignedBytes(tx.Unsigned) txs.Codec.Marshal(txs.CodecVersion, tx) -> tx.Initialize() txs.Codec.Unmarshal(txBytes, &tx) -> txs.Parse(txBytes) codec.Unmarshal(utxoBytes, &utxo) -> utxo.ParseUTXO(...) These are the same calls the node makes in txs.Tx.Sign. AddAllUTXOs no longer takes a codec.Manager, and SortTransferableOutputs / state.Sort / SortOperations no longer get one — upstream dropped the parameter. PARALLEL IMPLEMENTATIONS, DELETED. wallet/chain/{p,x} carried a second copy of the builder and signer beside the subpackages that already held them — p/signer_visitor.go and p/signer/visitor.go were both 399 lines of the same thing, and each defect had to be fixed twice. The flat files are gone; the package keeps the facade it already had in wallet_exports.go, which re-exports the subpackage. -4787 lines. wallet/chain/c is deleted. Its whole reason to exist was a codec.Manager scaffold for C-chain atomic-tx wire that nothing runs: NewWallet was passed nil for it, and the builder was commented out. The two symbols anything used move to where they are read — Account, a balance and a nonce off an EVM client, and EVMKeychain, the geth-address half of a keychain. Wallet no longer advertises a C() that only ever returned nil. ALIGNED. XAssetID -> UTXOAssetID, matching runtime.Runtime and netrunner, which already expected it. Keychain GetEth -> GetByEVM, EthAddrs -> EVMAddrs. warp UnsignedMessage and Message collapsed into one flat Message, so a signature is an Envelope rather than a second message type. netrunner's HealthResponse is read as a field: the getter form is protobuf, behind //go:build grpc, and the default build is ZAP-native. VERIFIED on a machine with the native libraries: go build ./... exits 0 with no codec require in go.mod, and go test ./... is 23 ok. Three packages still fail to build their tests — profiles, wallet/keychain, wallet/primary — and all three fail identically on the tree before this change: Consensus, VerifyHybridSecp256k1MLDSA and isXChainNotEnabled are referenced by tests and defined nowhere. evm failed there too and now passes.
182 lines
5.0 KiB
Go
182 lines
5.0 KiB
Go
// Copyright (C) 2020-2025, Lux Industries Inc All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Package netrunner provides integration with the Lux netrunner tool
|
|
// for managing test networks and blockchain deployments.
|
|
package netrunner
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
log "github.com/luxfi/log"
|
|
"github.com/luxfi/netrunner/client"
|
|
"github.com/luxfi/netrunner/rpcpb"
|
|
)
|
|
|
|
// Client wraps the netrunner client with additional functionality
|
|
type Client struct {
|
|
client client.Client
|
|
logger log.Logger
|
|
config *Config
|
|
}
|
|
|
|
// Config holds configuration for the netrunner client
|
|
type Config struct {
|
|
Endpoint string
|
|
DialTimeout time.Duration
|
|
LogLevel string
|
|
}
|
|
|
|
// DefaultConfig returns default netrunner configuration
|
|
func DefaultConfig() *Config {
|
|
return &Config{
|
|
Endpoint: "localhost:8080",
|
|
DialTimeout: 30 * time.Second,
|
|
LogLevel: "info",
|
|
}
|
|
}
|
|
|
|
// NewClient creates a new netrunner client
|
|
func NewClient(config *Config, logger log.Logger) (*Client, error) {
|
|
if config == nil {
|
|
config = DefaultConfig()
|
|
}
|
|
|
|
if logger == nil {
|
|
logger = log.NewNoOpLogger()
|
|
}
|
|
|
|
// Create netrunner client
|
|
netrunnerClient, err := client.New(client.Config{
|
|
Endpoint: config.Endpoint,
|
|
DialTimeout: config.DialTimeout,
|
|
}, logger)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create netrunner client: %w", err)
|
|
}
|
|
|
|
return &Client{
|
|
client: netrunnerClient,
|
|
logger: logger,
|
|
config: config,
|
|
}, nil
|
|
}
|
|
|
|
// Start starts a new network with the given configuration
|
|
func (c *Client) Start(ctx context.Context, execPath string, opts ...client.OpOption) (*rpcpb.StartResponse, error) {
|
|
c.logger.Info("starting network", "execPath", execPath)
|
|
resp, err := c.client.Start(ctx, execPath, opts...)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to start network: %w", err)
|
|
}
|
|
c.logger.Info("network started", "clusterInfo", resp.ClusterInfo)
|
|
return resp, nil
|
|
}
|
|
|
|
// Stop stops the running network
|
|
func (c *Client) Stop(ctx context.Context) error {
|
|
c.logger.Info("stopping network")
|
|
_, err := c.client.Stop(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to stop network: %w", err)
|
|
}
|
|
c.logger.Info("network stopped")
|
|
return nil
|
|
}
|
|
|
|
// Health checks the health of the network
|
|
func (c *Client) Health(ctx context.Context) (*rpcpb.HealthResponse, error) {
|
|
return c.client.Health(ctx)
|
|
}
|
|
|
|
// Status returns the current network status
|
|
func (c *Client) Status(ctx context.Context) (*rpcpb.StatusResponse, error) {
|
|
return c.client.Status(ctx)
|
|
}
|
|
|
|
// URIs returns the URIs of all nodes in the network
|
|
func (c *Client) URIs(ctx context.Context) ([]string, error) {
|
|
return c.client.URIs(ctx)
|
|
}
|
|
|
|
// CreateChains creates new blockchains with the given specifications
|
|
func (c *Client) CreateChains(ctx context.Context, specs []*rpcpb.BlockchainSpec) (*rpcpb.CreateBlockchainsResponse, error) {
|
|
c.logger.Info("creating blockchains", "count", len(specs))
|
|
resp, err := c.client.CreateChains(ctx, specs)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create blockchains: %w", err)
|
|
}
|
|
c.logger.Info("blockchains created")
|
|
return resp, nil
|
|
}
|
|
|
|
// AddNode adds a new node to the network
|
|
func (c *Client) AddNode(ctx context.Context, name string, execPath string, opts ...client.OpOption) (*rpcpb.AddNodeResponse, error) {
|
|
c.logger.Info("adding node", "name", name)
|
|
resp, err := c.client.AddNode(ctx, name, execPath, opts...)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to add node: %w", err)
|
|
}
|
|
c.logger.Info("node added", "clusterInfo", resp.ClusterInfo)
|
|
return resp, nil
|
|
}
|
|
|
|
// RemoveNode removes a node from the network
|
|
func (c *Client) RemoveNode(ctx context.Context, name string) error {
|
|
c.logger.Info("removing node", "name", name)
|
|
_, err := c.client.RemoveNode(ctx, name)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to remove node: %w", err)
|
|
}
|
|
c.logger.Info("node removed", "name", name)
|
|
return nil
|
|
}
|
|
|
|
// RestartNode restarts a node in the network
|
|
func (c *Client) RestartNode(ctx context.Context, name string, opts ...client.OpOption) error {
|
|
c.logger.Info("restarting node", "name", name)
|
|
_, err := c.client.RestartNode(ctx, name, opts...)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to restart node: %w", err)
|
|
}
|
|
c.logger.Info("node restarted", "name", name)
|
|
return nil
|
|
}
|
|
|
|
// WaitForHealthy waits for all nodes in the network to be healthy
|
|
func (c *Client) WaitForHealthy(ctx context.Context, timeout time.Duration) error {
|
|
c.logger.Info("waiting for network to be healthy", "timeout", timeout)
|
|
|
|
ctx, cancel := context.WithTimeout(ctx, timeout)
|
|
defer cancel()
|
|
|
|
ticker := time.NewTicker(1 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return errors.New("timeout waiting for network to be healthy")
|
|
case <-ticker.C:
|
|
health, err := c.Health(ctx)
|
|
if err != nil {
|
|
c.logger.Debug("health check failed", "error", err)
|
|
continue
|
|
}
|
|
// Check if health response indicates healthy
|
|
if health.ClusterInfo != nil {
|
|
c.logger.Info("network is healthy")
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Close closes the netrunner client connection
|
|
func (c *Client) Close() error {
|
|
return c.client.Close()
|
|
}
|